183 lines
6.5 KiB
Python
183 lines
6.5 KiB
Python
"""Базовый модуль для работы с компонентами страницы.
|
||
|
||
Содержит базовый класс для взаимодействия с элементами страницы через Playwright.
|
||
"""
|
||
|
||
from playwright.sync_api import Page, Locator, expect
|
||
from tools.logger import get_logger
|
||
|
||
logger = get_logger("BASE_COMPONENT")
|
||
|
||
|
||
class BaseComponent:
|
||
"""Базовый компонент для работы с элементами страницы.
|
||
|
||
Предоставляет общие методы для взаимодействия с элементами:
|
||
- получение локаторов
|
||
- проверка видимости элементов
|
||
- работа с прокруткой
|
||
"""
|
||
|
||
def __init__(self, page: Page):
|
||
"""Инициализация базового компонента.
|
||
|
||
Args:
|
||
page: экземпляр страницы Playwright.
|
||
"""
|
||
|
||
self.page = page
|
||
|
||
# Действия:
|
||
def get_locator(self, locator: str | Locator) -> Locator:
|
||
"""Получение объекта Locator из строки или существующего Locator.
|
||
|
||
Args:
|
||
locator: строка с CSS/XPath селектором или объект Locator.
|
||
|
||
Returns:
|
||
Locator: объект для работы с элементом.
|
||
|
||
Raises:
|
||
TypeError: если передан некорректный тип локатора.
|
||
"""
|
||
|
||
if isinstance(locator, Locator):
|
||
return locator
|
||
elif isinstance(locator, str):
|
||
return self.page.locator(locator)
|
||
else:
|
||
raise TypeError("locator value should be string type or Locator type")
|
||
|
||
# Закомментированный код сохранен без изменений
|
||
# def wait_for_all_elements(self, locator: Locator, timeout=5000):
|
||
# loc = self.get_locator(locator)
|
||
# elements = self.page.locator(loc).all()
|
||
#
|
||
# for element in elements:
|
||
# self.page.locator(loc).wait_for(timeout=timeout)
|
||
#
|
||
# return elements
|
||
|
||
# Проверки:
|
||
def check_presence(self, locator: str | Locator, msg: str) -> None:
|
||
"""Проверка видимости элемента на странице.
|
||
|
||
Args:
|
||
locator: локатор элемента (строка или объект Locator).
|
||
msg: сообщение об ошибке при неудачной проверке.
|
||
|
||
Raises:
|
||
AssertionError: если элемент не виден на странице.
|
||
"""
|
||
|
||
loc = self.get_locator(locator)
|
||
expect(loc).to_be_visible(visible=True, timeout=12000), msg
|
||
|
||
def is_scrollable_vertically(self, locator: str | Locator) -> bool:
|
||
"""Проверка возможности вертикальной прокрутки элемента.
|
||
|
||
Args:
|
||
locator: локатор элемента.
|
||
|
||
Returns:
|
||
bool: True если элемент можно прокрутить вертикально.
|
||
"""
|
||
|
||
loc = self.get_locator(locator)
|
||
return loc.evaluate("el => el.scrollHeight > el.clientHeight")
|
||
|
||
def is_scrollable_horizontally(self, locator: str | Locator) -> bool:
|
||
"""Проверка возможности горизонтальной прокрутки элемента.
|
||
|
||
Args:
|
||
locator: локатор элемента.
|
||
|
||
Returns:
|
||
bool: True если элемент можно прокрутить горизонтально.
|
||
"""
|
||
|
||
loc = self.get_locator(locator)
|
||
return loc.evaluate("el => el.scrollWidth > el.clientWidth")
|
||
|
||
# Методы прокрутки:
|
||
def scroll_up(self, locator: str | Locator) -> None:
|
||
"""Прокрутка элемента вверх.
|
||
|
||
Args:
|
||
locator: локатор элемента.
|
||
|
||
Raises:
|
||
AssertionError: если прокрутка не выполнена до конца.
|
||
"""
|
||
|
||
loc = self.get_locator(locator)
|
||
loc.evaluate("el => el.scrollTo(0, 0)")
|
||
loc.wait_for(timeout=2000)
|
||
|
||
# Проверка позиции прокрутки
|
||
scroll_position = loc.evaluate("el => el.scrollTop")
|
||
assert scroll_position == 0, "Invalid postion after scroll up"
|
||
|
||
def scroll_down(self, locator: str | Locator) -> None:
|
||
"""Прокрутка элемента вниз.
|
||
|
||
Args:
|
||
locator: локатор элемента.
|
||
|
||
Raises:
|
||
AssertionError: если прокрутка не выполнена до конца.
|
||
"""
|
||
|
||
loc = self.get_locator(locator)
|
||
loc.evaluate("el => el.scrollTo(0, el.scrollHeight)")
|
||
loc.wait_for(timeout=2000)
|
||
|
||
# Проверка позиции прокрутки
|
||
scroll_position = loc.evaluate("el => el.scrollTop")
|
||
assert scroll_position > 0, "Invalid postion after scroll down"
|
||
|
||
def scroll_left(self, locator: str | Locator) -> None:
|
||
"""Прокрутка элемента влево.
|
||
|
||
Args:
|
||
locator: локатор элемента.
|
||
|
||
Raises:
|
||
AssertionError: если прокрутка не выполнена до конца.
|
||
"""
|
||
|
||
loc = self.get_locator(locator)
|
||
|
||
width = loc.evaluate("el => el.scrollWidth")
|
||
loc.scroll_into_view_if_needed()
|
||
self.page.mouse.wheel(-width, 0)
|
||
|
||
loc.wait_for(timeout=2000)
|
||
|
||
# Проверка позиции прокрутки
|
||
scroll_position = loc.evaluate("el => el.scrollLeft")
|
||
assert scroll_position == 0, "Invalid postion after scroll left"
|
||
|
||
def scroll_right(self, locator: str | Locator) -> None:
|
||
"""Прокрутка элемента вправо.
|
||
|
||
Args:
|
||
locator: локатор элемента.
|
||
|
||
Raises:
|
||
AssertionError: если прокрутка не выполнена до конца.
|
||
"""
|
||
|
||
loc = self.get_locator(locator)
|
||
|
||
width = loc.evaluate("el => el.scrollWidth")
|
||
loc.scroll_into_view_if_needed()
|
||
self.page.mouse.wheel(width, 0)
|
||
|
||
loc.wait_for(timeout=2000)
|
||
|
||
# Проверка позиции прокрутки
|
||
scroll_position = loc.evaluate("el => el.scrollLeft")
|
||
max_scroll_x = loc.evaluate("el => el.scrollWidth - el.clientWidth")
|
||
assert scroll_position >= max_scroll_x, "Invalid postion after scroll right"
|