feat(base_page): добавлены аннотации типов для базовой страницы

- Добавлены аннотации параметров:
  * uri: str в open(), send_get_api_request(), send_post_api_request(), check_URL()
  * timeout: int в wait_for_timeout()
  * payload: Dict[str, Any] в send_post_api_request()
  * response: Response в get_response_body()
  * msg: str в check_URL(), check_equals(), check_lists_equals()
  * actual/expected: Any в check_equals()
  * actual/expected: List[Any] в check_lists_equals()

- Добавлены возвращаемые типы:
  * -> Optional[Response] для open()
  * -> Optional[Dict[str, Any]] для get_response_body()
  * -> Response для send_get_api_request() и send_post_api_request()
  * -> None для методов без возвращаемого значения
  * -> bool для внутренней функции compare_lists()

Изменения улучшают статическую проверку типов и документирование.
pull/1/head
Radislav 2025-07-22 08:35:08 +03:00
parent 855d6810fa
commit a54358f900
1 changed files with 12 additions and 110 deletions

View File

@ -1,9 +1,7 @@
"""Базовый класс страницы для работы с Playwright.
Содержит общие методы для взаимодействия со страницей и API.
"""
"""Базовый класс страницы для работы с Playwright."""
from playwright.sync_api import Page, Response, APIRequestContext, expect
from typing import Any, Dict, List, Optional
from data.environment import host
from tools.logger import get_logger
import json
@ -12,69 +10,28 @@ logger = get_logger("BASE_PAGE")
class BasePage:
"""Базовый класс для работы со страницами через Playwright.
"""Базовый класс для работы со страницами через Playwright."""
Атрибуты:
page (Page): Экземпляр страницы Playwright.
"""
def __init__(self, page: Page):
"""Инициализирует базовую страницу.
Args:
page (Page): Экземпляр страницы Playwright.
"""
def __init__(self, page: Page) -> None:
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 в случае ошибки.
"""
def open(self, uri: str) -> Optional[Response]:
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): Время ожидания в миллисекундах.
"""
def wait_for_timeout(self, timeout: int) -> None:
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: Ответ сервера.
"""
def send_get_api_request(self, uri: str) -> Response:
api_request_context = self.get_api_request_context()
token = host.get_access_token()
headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"}
@ -84,16 +41,7 @@ class BasePage:
)
return response
def send_post_api_request(self, uri, payload) -> Response:
"""Отправляет POST-запрос к API.
Args:
uri (str): URI API-эндпоинта (без базового URL).
payload: Данные для отправки в теле запроса.
Returns:
Response: Ответ сервера.
"""
def send_post_api_request(self, uri: str, payload: Dict[str, Any]) -> Response:
api_request_context = self.get_api_request_context()
token = host.get_access_token()
headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"}
@ -104,15 +52,7 @@ class BasePage:
)
return response
def get_response_body(self, response) -> dict | None:
"""Извлекает тело ответа в формате JSON.
Args:
response (Response): Ответ сервера.
Returns:
dict | None: Распарсенное тело ответа или None в случае ошибки.
"""
def get_response_body(self, response: Response) -> Optional[Dict[str, Any]]:
try:
response_body = response.json()
except json.JSONDecodeError:
@ -122,54 +62,16 @@ class BasePage:
# Проверки:
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: Если значения не равны.
"""
def check_equals(self, actual: Any, expected: Any, msg: str) -> None:
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.
"""
def check_lists_equals(self, actual: List[Any], expected: List[Any], msg: str) -> None:
def compare_lists(list1: List[Any], list2: List[Any]) -> bool:
if len(list1) != len(list2):
return False
for item1, item2 in zip(list1, list2):