"""Базовый класс страницы для работы с Playwright. Содержит общие методы для взаимодействия со страницей и API. """ from playwright.sync_api import Page, Response, APIRequestContext, expect from data.environment import host from tools.logger import get_logger import json logger = get_logger("BASE_PAGE") class BasePage: """Базовый класс для работы со страницами через Playwright. Атрибуты: page (Page): Экземпляр страницы Playwright. """ def __init__(self, page: Page): """Инициализирует базовую страницу. Args: page (Page): Экземпляр страницы Playwright. """ self.page = page # Действия: def current_url(self) -> str: """Возвращает текущий URL страницы. Returns: str: Текущий URL страницы. """ return self.page.url def open(self, uri) -> Response | None: """Открывает указанный URI в браузере. Args: uri (str): URI для открытия (без базового URL). Returns: Response | None: Ответ сервера или None в случае ошибки. """ return self.page.goto(f"{host.get_base_url()}{uri}", wait_until='domcontentloaded') def page_reload(self) -> None: """Перезагружает текущую страницу.""" self.page.reload() def wait_for_timeout(self, timeout): """Ожидает указанное количество миллисекунд. Args: timeout (int): Время ожидания в миллисекундах. """ self.page.wait_for_timeout(timeout) def get_api_request_context(self) -> APIRequestContext: """Возвращает контекст API-запросов. Returns: APIRequestContext: Контекст для выполнения API-запросов. """ return self.page.context.request def send_get_api_request(self, uri) -> Response: """Отправляет GET-запрос к API. Args: uri (str): URI API-эндпоинта (без базового URL). Returns: Response: Ответ сервера. """ api_request_context = self.get_api_request_context() token = host.get_access_token() headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"} response = api_request_context.get( f"{host.get_request_url()}{uri}", headers=headers ) return response def send_post_api_request(self, uri, payload) -> Response: """Отправляет POST-запрос к API. Args: uri (str): URI API-эндпоинта (без базового URL). payload: Данные для отправки в теле запроса. Returns: Response: Ответ сервера. """ api_request_context = self.get_api_request_context() token = host.get_access_token() headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"} response = api_request_context.post( f"{host.get_request_url()}{uri}", headers=headers, data=payload ) return response def get_response_body(self, response) -> dict | None: """Извлекает тело ответа в формате JSON. Args: response (Response): Ответ сервера. Returns: dict | None: Распарсенное тело ответа или None в случае ошибки. """ try: response_body = response.json() except json.JSONDecodeError: logger.error("Failed to decode JSON response") return None return response_body # Проверки: def check_URL(self, uri: str, msg: str) -> None: """Проверяет, что текущий URL соответствует ожидаемому. Args: uri (str): Ожидаемый URI (без базового URL). msg (str): Сообщение об ошибке при несоответствии. Raises: AssertionError: Если URL не соответствует ожидаемому. """ expect(self.page).to_have_url( f"{host.get_base_url()}{uri}", timeout=60000 ), msg def check_equals(self, actual, expected, msg: str) -> None: """Проверяет равенство фактического и ожидаемого значений. Args: actual: Фактическое значение. expected: Ожидаемое значение. msg (str): Сообщение об ошибке при несоответствии. Raises: AssertionError: Если значения не равны. """ assert actual == expected, msg def check_lists_equals(self, actual: list, expected: list, msg: str) -> None: """Рекурсивно проверяет равенство двух списков. Args: actual (list): Фактический список. expected (list): Ожидаемый список. msg (str): Сообщение об ошибке при несоответствии. Raises: AssertionError: Если списки не равны. """ def compare_lists(list1: list, list2: list) -> bool: """Вспомогательная функция для рекурсивного сравнения списков. Args: list1 (list): Первый список для сравнения. list2 (list): Второй список для сравнения. Returns: bool: True если списки идентичны, иначе False. """ if len(list1) != len(list2): return False for item1, item2 in zip(list1, list2): if isinstance(item1, list) and isinstance(item2, list): if not compare_lists(item1, item2): return False elif item1 != item2: return False return True assert compare_lists(actual, expected), msg