154 lines
5.3 KiB
Python
154 lines
5.3 KiB
Python
"""Модуль 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
|