Skip to content

BasePage

Базовый класс страницы для работы с Playwright.

Содержит общие методы для взаимодействия со страницей и API.

BasePage

Базовый класс для работы со страницами через Playwright.

Атрибуты

page (Page): Экземпляр страницы Playwright.

Source code in pages\base_page.py
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
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: int) -> None:
        """Ожидает указанное количество миллисекунд.

        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: str) -> 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: str, payload: Dict) -> Response:
        """Отправляет POST-запрос к API.

        Args:
            uri (str): URI API-эндпоинта (без базового URL).
            payload (Dict): Данные для отправки в теле запроса.

        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: Response) -> dict | None:
        """Извлекает тело ответа в format 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: Any, expected: Any, msg: str) -> None:
        """Проверяет равенство фактического и ожидаемого значений.

        Args:
            actual (Any): Фактическое значение.
            expected (Any): Ожидаемое значение.
            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

__init__(page)

Инициализирует базовую страницу.

Parameters:

Name Type Description Default
page Page

Экземпляр страницы Playwright.

required
Source code in pages\base_page.py
22
23
24
25
26
27
28
def __init__(self, page: Page):
    """Инициализирует базовую страницу.

    Args:
        page (Page): Экземпляр страницы Playwright.
    """
    self.page = page

check_URL(uri, msg)

Проверяет, что текущий URL соответствует ожидаемому.

Parameters:

Name Type Description Default
uri str

Ожидаемый URI (без базового URL).

required
msg str

Сообщение об ошибке при несоответствии.

required

Raises:

Type Description
AssertionError

Если URL не соответствует ожидаемому.

Source code in pages\base_page.py
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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

check_equals(actual, expected, msg)

Проверяет равенство фактического и ожидаемого значений.

Parameters:

Name Type Description Default
actual Any

Фактическое значение.

required
expected Any

Ожидаемое значение.

required
msg str

Сообщение об ошибке при несоответствии.

required

Raises:

Type Description
AssertionError

Если значения не равны.

Source code in pages\base_page.py
140
141
142
143
144
145
146
147
148
149
150
151
def check_equals(self, actual: Any, expected: Any, msg: str) -> None:
    """Проверяет равенство фактического и ожидаемого значений.

    Args:
        actual (Any): Фактическое значение.
        expected (Any): Ожидаемое значение.
        msg (str): Сообщение об ошибке при несоответствии.

    Raises:
        AssertionError: Если значения не равны.
    """
    assert actual == expected, msg

check_lists_equals(actual, expected, msg)

Рекурсивно проверяет равенство двух списков.

Parameters:

Name Type Description Default
actual list

Фактический список.

required
expected list

Ожидаемый список.

required
msg str

Сообщение об ошибке при несоответствии.

required

Raises:

Type Description
AssertionError

Если списки не равны.

Source code in pages\base_page.py
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
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

current_url()

Возвращает текущий URL страницы.

Returns:

Name Type Description
str str

Текущий URL страницы.

Source code in pages\base_page.py
31
32
33
34
35
36
37
def current_url(self) -> str:
    """Возвращает текущий URL страницы.

    Returns:
        str: Текущий URL страницы.
    """
    return self.page.url

get_api_request_context()

Возвращает контекст API-запросов.

Returns:

Name Type Description
APIRequestContext APIRequestContext

Контекст для выполнения API-запросов.

Source code in pages\base_page.py
62
63
64
65
66
67
68
def get_api_request_context(self) -> APIRequestContext:
    """Возвращает контекст API-запросов.

    Returns:
        APIRequestContext: Контекст для выполнения API-запросов.
    """
    return self.page.context.request

get_response_body(response)

Извлекает тело ответа в format JSON.

Parameters:

Name Type Description Default
response Response

Ответ сервера.

required

Returns:

Type Description
dict | None

dict | None: Распарсенное тело ответа или None в случае ошибки.

Source code in pages\base_page.py
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def get_response_body(self, response: Response) -> dict | None:
    """Извлекает тело ответа в format 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

open(uri)

Открывает указанный URI в браузере.

Parameters:

Name Type Description Default
uri str

URI для открытия (без базового URL).

required

Returns:

Type Description
Response | None

Response | None: Ответ сервера или None в случае ошибки.

Source code in pages\base_page.py
39
40
41
42
43
44
45
46
47
48
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')

page_reload()

Перезагружает текущую страницу.

Source code in pages\base_page.py
50
51
52
def page_reload(self) -> None:
    """Перезагружает текущую страницу."""
    self.page.reload()

send_get_api_request(uri)

Отправляет GET-запрос к API.

Parameters:

Name Type Description Default
uri str

URI API-эндпоинта (без базового URL).

required

Returns:

Name Type Description
Response Response

Ответ сервера.

Source code in pages\base_page.py
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
def send_get_api_request(self, uri: str) -> 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

send_post_api_request(uri, payload)

Отправляет POST-запрос к API.

Parameters:

Name Type Description Default
uri str

URI API-эндпоинта (без базового URL).

required
payload Dict

Данные для отправки в теле запроса.

required

Returns:

Name Type Description
Response Response

Ответ сервера.

Source code in pages\base_page.py
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
def send_post_api_request(self, uri: str, payload: Dict) -> Response:
    """Отправляет POST-запрос к API.

    Args:
        uri (str): URI API-эндпоинта (без базового URL).
        payload (Dict): Данные для отправки в теле запроса.

    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

wait_for_timeout(timeout)

Ожидает указанное количество миллисекунд.

Parameters:

Name Type Description Default
timeout int

Время ожидания в миллисекундах.

required
Source code in pages\base_page.py
54
55
56
57
58
59
60
def wait_for_timeout(self, timeout: int) -> None:
    """Ожидает указанное количество миллисекунд.

    Args:
        timeout (int): Время ожидания в миллисекундах.
    """
    self.page.wait_for_timeout(timeout)