"""Модуль base_page содержит базовый класс для работы со страницами. Класс BasePage предоставляет общие методы для взаимодействия со страницами через Playwright и выполнения API-запросов. """ import json from typing import Any, Dict, List, Optional from playwright.sync_api import Page, Response, APIRequestContext, expect from tools.logger import get_logger from data.environment import host logger = get_logger("BASE_PAGE") class BasePage: """Базовый класс для работы со страницами через Playwright. Содержит общие методы для: - Навигации по страницам - Выполнения API-запросов - Проверок состояния страницы """ def __init__(self, page: Page) -> None: """Инициализирует базовую страницу. Args: page: Экземпляр страницы Playwright """ self.page = page # Действия: def current_url(self) -> str: """Возвращает текущий URL страницы.""" return self.page.url def open(self, uri: str) -> Optional[Response]: """Открывает указанный URI на базовом URL.""" 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: int) -> None: """Ожидает указанное количество миллисекунд.""" self.page.wait_for_timeout(timeout) def get_api_request_context(self) -> APIRequestContext: """Возвращает контекст для выполнения API-запросов.""" return self.page.context.request def send_get_api_request(self, uri: str) -> Response: """Отправляет GET-запрос к API. Args: uri: URI для запроса """ 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: str, payload: Dict[str, Any]) -> Response: """Отправляет POST-запрос к API. Args: uri: URI для запроса payload: Тело запроса """ 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: Response) -> Optional[Dict[str, Any]]: """Возвращает тело ответа в формате JSON. Args: response: Объект ответа """ 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: Ожидаемый URI msg: Сообщение об ошибке """ expect(self.page).to_have_url( f"{host.get_base_url()}{uri}", timeout=60000 ), msg def check_equals(self, actual: Any, expected: Any, msg: str) -> None: """Проверяет равенство фактического и ожидаемого значений. Args: actual: Фактическое значение expected: Ожидаемое значение msg: Сообщение об ошибке """ assert actual == expected, msg def check_lists_equals(self, actual: List[Any], expected: List[Any], msg: str) -> None: """Рекурсивно проверяет равенство двух списков. Args: actual: Фактический список expected: Ожидаемый список msg: Сообщение об ошибке """ def compare_lists(list1: List[Any], list2: List[Any]) -> bool: 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