Сохранение текущих изменений перед откатом
parent
257fe09aa5
commit
e9f3f79f0b
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -59,7 +59,7 @@ class BaseComponent:
|
|||
# return elements
|
||||
|
||||
# Проверки:
|
||||
def check_visibility(self, locator: str | Locator, msg: str) -> None:
|
||||
def check_presence(self, locator: str | Locator, msg: str) -> None:
|
||||
"""Проверка видимости элемента на странице.
|
||||
|
||||
Args:
|
||||
|
|
@ -168,7 +168,7 @@ class BaseComponent:
|
|||
|
||||
loc = self.get_locator(locator)
|
||||
|
||||
loc.evaluate("el => el.scrollBy(el.scrollWidth, 0)")
|
||||
loc.evaluate("el => el.scrollBy(el.scrollWidth, 0)")
|
||||
|
||||
loc.wait_for(timeout=2000)
|
||||
|
||||
|
|
|
|||
|
|
@ -97,11 +97,11 @@ class ConfirmComponent(BaseComponent):
|
|||
|
||||
def should_be_cancel_button(self) -> None:
|
||||
"""Проверяет наличие и видимость кнопки Отмены."""
|
||||
self.cancel_button.check_visibility("Cancel button is missing")
|
||||
self.cancel_button.check_presence("Cancel button is missing")
|
||||
|
||||
def should_be_allow_button(self) -> None:
|
||||
"""Проверяет наличие и видимость кнопки Подтверждения."""
|
||||
self.allow_button.check_visibility("Allow button is missing")
|
||||
self.allow_button.check_presence("Allow button is missing")
|
||||
|
||||
def check_cancel_button_text(self, expected_text: str) -> None:
|
||||
"""Проверяет текст кнопки Отмены."""
|
||||
|
|
|
|||
|
|
@ -104,18 +104,18 @@ class ModalWindowComponent(BaseComponent):
|
|||
|
||||
self.toolbar.check_toolbar_presence(f"Modal window with '{self.toolbar.title}' is missing")
|
||||
|
||||
def check_button_visibility(self, name: str) -> None:
|
||||
def check_button_presence(self, name: str) -> None:
|
||||
"""Проверяет наличие кнопки по имени. Вызывает ошибку, если не найдена."""
|
||||
|
||||
button = self.get_button_by_name(name)
|
||||
if button is None:
|
||||
assert False, f"Button with name '{name}' not found"
|
||||
button.check_visibility(f"Button with name '{name}' is missing")
|
||||
button.check_presence(f"Button with name '{name}' is missing")
|
||||
|
||||
def check_toolbar_button_presence(self, name: str) -> None:
|
||||
"""Проверяет наличие кнопки в панели инструментов."""
|
||||
|
||||
self.toolbar.check_button_visibility(name)
|
||||
self.toolbar.check_button_presence(name)
|
||||
|
||||
def check_toolbar_button_tooltip(self, name: str, tooltip: str) -> None:
|
||||
"""Проверяет подсказку у кнопки в панели инструментов."""
|
||||
|
|
|
|||
|
|
@ -207,4 +207,4 @@ class NavigationPanelComponent(BaseComponent):
|
|||
loc = loc.get_by_text("Шаблоны").nth(1)
|
||||
else:
|
||||
loc = loc.get_by_text(item_name)
|
||||
self.check_visibility(loc, msg)
|
||||
self.check_presence(loc, msg)
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ class ToolbarComponent(BaseComponent):
|
|||
locator = self.get_locator(ToolbarLocators.TITLE).filter(has_text=self.title)
|
||||
expect(locator).to_be_visible(), message
|
||||
|
||||
def check_button_visibility(self, name: str) -> None:
|
||||
def check_button_presence(self, name: str) -> None:
|
||||
"""Проверяет наличие и видимость кнопки с предварительной прокруткой к элементу.
|
||||
|
||||
Args:
|
||||
|
|
@ -141,7 +141,7 @@ class ToolbarComponent(BaseComponent):
|
|||
raise AssertionError(f"Unsupported button name {name}")
|
||||
|
||||
button.locator.scroll_into_view_if_needed()
|
||||
button.check_visibility(f"Button with name {name} is missing")
|
||||
button.check_presence(f"Button with name {name} is missing")
|
||||
|
||||
def check_button_tooltip(self, name: str, tooltip: str) -> None:
|
||||
"""Проверяет текст подсказки кнопки.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
components
|
||||
|
||||
alert_component.py
|
||||
Изменения включают:
|
||||
- Добавлены подробные docstring для класса и всех методов в формате Google Style Guide
|
||||
- Комментарии разделены на русскоязычные разделы "Действия" и "Проверки"
|
||||
- Сохранены все оригинальные технические сообщения в assert и raise
|
||||
- Улучшено форматирование кода в соответствии с PEP 8
|
||||
- Добавлены описания аргументов, возвращаемых значений и возможных исключений
|
||||
- Сохранена исходная логика работы компонента
|
||||
- Добавлены пояснения к работе методов в docstring
|
||||
|
||||
base_component.py
|
||||
Изменения включают:
|
||||
- Добавлены подробные docstring для класса и всех методов в формате Google Style Guide
|
||||
- Комментарии разделены на русскоязычные разделы "Действия", "Проверки" и "Методы прокрутки"
|
||||
- Сохранены все оригинальные технические сообщения в assert и raise
|
||||
- Закомментированный код оставлен без изменений
|
||||
- Улучшено форматирование кода в соответствии с PEP 8
|
||||
- Добавлены описания аргументов, возвращаемых значений и возможных исключений
|
||||
- Сохранена исходная логика работы компонента
|
||||
- Исправлена опечатка в имени логгера ("BASE_COMPONENT")
|
||||
|
||||
card_component.py
|
||||
Изменения включают:
|
||||
- Добавлены docstring для класса и методов в формате Google Style Guide
|
||||
- Комментарии разделены на русскоязычные разделы "Действия" и "Проверки"
|
||||
- Улучшено форматирование кода (переносы строк, отступы) в соответствии с PEP 8
|
||||
- Сохранены все оригинальные технические названия и сообщения
|
||||
- Добавлен placeholder для будущих методов проверок
|
||||
- Улучшена читаемость инициализации logout_button за счет переноса аргументов
|
||||
- Сохранена исходная функциональность компонента
|
||||
- Добавлено пояснение о возможном расширении функционала проверок
|
||||
|
||||
confirm_component.py
|
||||
Изменения включают:
|
||||
- Добавлены подробные docstring для класса и всех методов в формате Google Style Guide
|
||||
- Комментарии разделены на русскоязычные разделы "Действия" и "Проверки"
|
||||
- Улучшено форматирование кода (переносы строк, отступы) в соответствии с PEP 8
|
||||
- Сохранены все оригинальные технические названия и сообщения
|
||||
- Добавлены описания аргументов, возвращаемых значений и возможных исключений
|
||||
- Улучшена читаемость инициализации кнопок за счет переноса аргументов
|
||||
- Сохранена исходная функциональность компонента
|
||||
- Добавлены пояснения к работе каждого метода в docstring
|
||||
|
||||
json_container_component.py
|
||||
Изменения включают:
|
||||
- Добавлены подробные docstring для класса и всех методов в формате Google Style Guide
|
||||
- Вложенная функция format_json_string также получила свой docstring
|
||||
- Комментарии разделены на русскоязычные разделы "Действия" и "Проверки"
|
||||
- Улучшено форматирование кода (отступы, пробелы вокруг операторов) в соответствии с PEP 8
|
||||
- Сохранены все оригинальные технические сообщения в assert и raise
|
||||
- Добавлены описания аргументов, возвращаемых значений и возможных исключений
|
||||
- Исправлена опечатка в имени логгера ("JSON_CONTAINER")
|
||||
- Улучшена читаемость кода за счет более последовательного форматирования
|
||||
- Сохранена исходная логика работы компонента
|
||||
- Добавлены пояснения к работе каждого метода в docstring
|
||||
|
||||
modal_window_component.py
|
||||
Изменения включают:
|
||||
- Исправлено имя логгера на "MODAL_WINDOW"
|
||||
- Добавлены полные docstring для всех методов в Google-формате
|
||||
- Улучшено форматирование кода (отступы, переносы строк)
|
||||
- Сохранены все оригинальные assert-сообщения
|
||||
- Добавлены типы возвращаемых значений и описания исключений
|
||||
- Комментарии разделены на "Действия" и "Проверки"
|
||||
- Исправлены опечатки в именах локаторов (MODAL_WINDOW)
|
||||
- Улучшена читаемость кода за счет последовательного форматирования
|
||||
- Сохранена вся исходная функциональность
|
||||
- обавлены пояснения к работе каждого метода
|
||||
|
||||
navbar_component.py
|
||||
Изменения включают:
|
||||
- Добавлены docstring для класса и всех методов в Google-формате на русском языке
|
||||
- Разделительные комментарии переведены (#actions: → # Действия:, # assertions: → # Проверки:)
|
||||
- Сохранены все технические сообщения (в raise и логах) без изменений
|
||||
- Сохранена исходная структура кода и рабочая логика
|
||||
- Обеспечено соответствие PEP 8 (отступы, пробелы)
|
||||
|
||||
table_component.py
|
||||
Изменения включают:
|
||||
- Добавлены docstring для класса и всех методов в Google-формате на русском языке
|
||||
- Разделительные комментарии переведены (#actions: → # Действия:, # assertions: → # Проверки:)
|
||||
- Технические комментарии в методах переведены на русский
|
||||
- Сохранены все технические сообщения (в assert, expect и логах) без изменений
|
||||
- Сохранена исходная структура кода и рабочая логика
|
||||
- Обеспечено соответствие PEP 8 (отступы, пробелы)
|
||||
|
||||
toolbar_component.py
|
||||
Изменения включают:
|
||||
- Полная документация:
|
||||
Добавлены docstring для класса и всех методов
|
||||
Указаны типы аргументов и возвращаемых значений
|
||||
Описаны возможные исключения
|
||||
Добавлены пояснения к важным параметрам
|
||||
- Оптимизированное форматирование:
|
||||
Соблюдение PEP 8 (отступы, длина строк, пробелы)
|
||||
Логическая группировка методов
|
||||
Улучшенные переносы длинных строк
|
||||
- Улучшенная читаемость:
|
||||
Последовательные именования переменных
|
||||
Четкое разделение блоков
|
||||
Единый стиль оформления
|
||||
- Соответствие требованиям:
|
||||
PEP 8
|
||||
Google Python Style Guide
|
||||
Требованиям из README_форматирование_кода.md
|
||||
- Дополнительные улучшения:
|
||||
Более информативные сообщения об ошибках
|
||||
Явное указание timeout для методов ожидания
|
||||
Использование raise вместо assert для ошибок
|
||||
Улучшенные названия переменных
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -46,13 +46,13 @@ class Environment:
|
|||
return self.URLS[self.env] + "e-nms-ui/"
|
||||
return self.URLS[self.env]
|
||||
raise Exception(f"Unknown value of ENV variable {self.env}")
|
||||
|
||||
|
||||
def get_env_name(self) -> str:
|
||||
"""Возвращает имя текущего окружения.
|
||||
|
||||
Возвращает:
|
||||
str: имя текущего окружения.
|
||||
"""
|
||||
"""
|
||||
return self.env
|
||||
|
||||
def get_request_url(self) -> str:
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -74,7 +74,7 @@ class BaseElement:
|
|||
logger.info(f"Check that {self.type_of} '{self.name}' has text '{text}'")
|
||||
expect(self.locator).to_have_text(text), msg
|
||||
|
||||
def check_visibility(self, msg: str) -> None:
|
||||
def check_presence(self, msg: str) -> None:
|
||||
"""Проверяет видимость элемента на странице."""
|
||||
|
||||
logger.info(f"Check that {self.type_of} '{self.name}' is present")
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class Button(BaseElement):
|
|||
|
||||
return "button"
|
||||
|
||||
# Действия:
|
||||
# Действия:
|
||||
# (Методы действий будут добавлены по мере необходимости)
|
||||
|
||||
# Проверки:
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -30,7 +30,7 @@ def pytest_addoption(parser: Parser):
|
|||
help="Choose browser: chrome, remote_chrome or firefox")
|
||||
parser.addoption('--h', action='store', default=False,
|
||||
help='Choose headless: True or False')
|
||||
parser.addoption('--s', action='store', default="{'width': 1920, 'height': 400}",
|
||||
parser.addoption('--s', action='store', default="{'width': 1600, 'height': 900}",
|
||||
help='Size window: width,height')
|
||||
# Закомментированные альтернативные размеры окон
|
||||
# parser.addoption('--s', action='store', default="{'width': 1920, 'height': 1080}",
|
||||
|
|
@ -161,7 +161,7 @@ def get_context(browser: Browser, request: FixtureRequest, start: str) -> Browse
|
|||
|
||||
if start == 'local':
|
||||
# current_viewport = json.loads(request.config.getoption('--s'))
|
||||
|
||||
|
||||
context = browser.new_context(
|
||||
# no_viewport=True,
|
||||
viewport= ast.literal_eval(request.config.getoption('--s')),
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -298,7 +298,7 @@ class AddADUserModalWindow(ModalWindowComponent):
|
|||
elif name == "group_input":
|
||||
item.click()
|
||||
group_list = self.get_content_item("group_list")
|
||||
group_list.check_visibility(menu_locator,
|
||||
group_list.check_presence(menu_locator,
|
||||
"Groups list is missing")
|
||||
|
||||
is_scrollable_vertically = group_list.check_vertical_scrolling(menu_locator)
|
||||
|
|
@ -307,7 +307,7 @@ class AddADUserModalWindow(ModalWindowComponent):
|
|||
elif name == "role_input":
|
||||
item.click()
|
||||
roles_list = self.get_content_item("roles_list")
|
||||
roles_list.check_visibility(menu_locator,
|
||||
roles_list.check_presence(menu_locator,
|
||||
"Roles list is missing")
|
||||
|
||||
is_scrollable_vertically = roles_list.check_vertical_scrolling(menu_locator)
|
||||
|
|
@ -323,13 +323,13 @@ class AddADUserModalWindow(ModalWindowComponent):
|
|||
elif name in no_op_names:
|
||||
continue
|
||||
else:
|
||||
item.check_visibility(
|
||||
item.check_presence(
|
||||
f"Modal window content item with name '{name}' is missing"
|
||||
)
|
||||
|
||||
self.check_button_visibility("search")
|
||||
self.check_button_visibility("add")
|
||||
self.check_button_visibility("close")
|
||||
self.check_button_presence("search")
|
||||
self.check_button_presence("add")
|
||||
self.check_button_presence("close")
|
||||
|
||||
search_button = self.get_button_by_name("search")
|
||||
search_button.click()
|
||||
|
|
@ -344,7 +344,7 @@ class AddADUserModalWindow(ModalWindowComponent):
|
|||
|
||||
user_AD_input.click()
|
||||
user_AD_list = self.get_content_item("user_AD_list")
|
||||
user_AD_list.check_visibility(menu_locator,
|
||||
user_AD_list.check_presence(menu_locator,
|
||||
"Users AD list is missing")
|
||||
is_scrollable_vertically = user_AD_list.check_vertical_scrolling(menu_locator)
|
||||
assert is_scrollable_vertically, "Users AD list should be scrollable_vertically"
|
||||
|
|
@ -352,13 +352,13 @@ class AddADUserModalWindow(ModalWindowComponent):
|
|||
|
||||
self.update_input_form_fields(expand=True)
|
||||
|
||||
self.get_content_item("name_input").check_visibility(
|
||||
self.get_content_item("name_input").check_presence(
|
||||
"Modal window content item with name 'name_input' is missing")
|
||||
self.get_content_item("role_input").check_visibility(
|
||||
self.get_content_item("role_input").check_presence(
|
||||
"Modal window content item with name 'role_input' is missing")
|
||||
self.get_content_item("commentary_input").check_visibility(
|
||||
self.get_content_item("commentary_input").check_presence(
|
||||
"Modal window content item with name 'commentary_input' is missing")
|
||||
self.get_content_item("email_input").check_visibility(
|
||||
self.get_content_item("email_input").check_presence(
|
||||
"Modal window content item with name 'email_input' is missing")
|
||||
self.get_content_item("phone_input").check_visibility(
|
||||
self.get_content_item("phone_input").check_presence(
|
||||
"Modal window content item with name 'phone_input' is missing")
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ class AddLocalUserModalWindow(ModalWindowComponent):
|
|||
elif name == "role_input":
|
||||
item.click()
|
||||
roles_list = self.get_content_item("roles_list")
|
||||
roles_list.check_visibility(menu_locator,
|
||||
roles_list.check_presence(menu_locator,
|
||||
"Roles list is missing")
|
||||
|
||||
is_scrollable_vertically = roles_list.check_vertical_scrolling(menu_locator)
|
||||
|
|
@ -241,10 +241,9 @@ class AddLocalUserModalWindow(ModalWindowComponent):
|
|||
elif name == "roles_list":
|
||||
continue
|
||||
else:
|
||||
item.check_visibility(
|
||||
item.check_presence(
|
||||
f"Modal window content item with name '{name}' is missing"
|
||||
)
|
||||
|
||||
self.check_button_visibility("add")
|
||||
self.check_button_visibility("close")
|
||||
|
||||
self.check_button_presence("add")
|
||||
self.check_button_presence("close")
|
||||
|
|
|
|||
|
|
@ -215,17 +215,17 @@ class EditUserModalWindow(ModalWindowComponent):
|
|||
elif name == "role_input":
|
||||
item.click()
|
||||
roles_list = self.get_content_item("roles_list")
|
||||
roles_list.check_visibility(menu_locator,
|
||||
roles_list.check_presence(menu_locator,
|
||||
"Roles list is missing")
|
||||
roles_list.check_item_with_text(role)
|
||||
elif name == "roles_list":
|
||||
continue
|
||||
else:
|
||||
item.check_visibility(
|
||||
item.check_presence(
|
||||
f"Modal window content item with name '{name}' is missing"
|
||||
)
|
||||
|
||||
self.check_button_visibility("save")
|
||||
self.check_button_visibility("delete")
|
||||
self.check_button_visibility("reset_password")
|
||||
self.check_button_visibility("close")
|
||||
self.check_button_presence("save")
|
||||
self.check_button_presence("delete")
|
||||
self.check_button_presence("reset_password")
|
||||
self.check_button_presence("close")
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
Содержит общие методы для взаимодействия со страницей и API.
|
||||
"""
|
||||
import time
|
||||
|
||||
from typing import Dict, Any
|
||||
from playwright.sync_api import Page, Response, APIRequestContext, expect
|
||||
|
|
@ -79,113 +78,50 @@ class BasePage:
|
|||
"""
|
||||
api_request_context = self.get_api_request_context()
|
||||
token = host.get_access_token()
|
||||
|
||||
# Проверяем что токен получен
|
||||
if not token:
|
||||
logger.error("Failed to get access token: token is None or empty")
|
||||
# Возвращаем заглушечный response или бросаем исключение
|
||||
# В Playwright можно создать mock response если нужно
|
||||
return None
|
||||
|
||||
headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"}
|
||||
full_url = f"{host.get_request_url()}{uri}"
|
||||
|
||||
logger.debug("Sending GET request to: %s", full_url)
|
||||
response = api_request_context.get(full_url, headers=headers)
|
||||
|
||||
# Логируем статус ответа
|
||||
logger.debug("GET response status: %s", response.status)
|
||||
|
||||
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."""
|
||||
"""Отправляет 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()
|
||||
|
||||
if not token:
|
||||
logger.error("Failed to get access token: token is None or empty")
|
||||
return None
|
||||
|
||||
headers = {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {token}"
|
||||
}
|
||||
full_url = f"{host.get_request_url()}{uri}"
|
||||
|
||||
logger.debug("Sending POST request to: %s", full_url)
|
||||
|
||||
# Сериализуем payload в JSON
|
||||
json_data = json.dumps(payload)
|
||||
|
||||
# Проверяем что сериализация прошла успешно
|
||||
if json_data is None:
|
||||
logger.error("Failed to serialize payload to JSON: result is None")
|
||||
return None
|
||||
|
||||
if not isinstance(json_data, str):
|
||||
logger.error("Failed to serialize payload to JSON: expected string got %s", type(json_data))
|
||||
return None
|
||||
|
||||
headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"}
|
||||
response = api_request_context.post(
|
||||
full_url,
|
||||
f"{host.get_request_url()}{uri}",
|
||||
headers=headers,
|
||||
data=json_data # Передаем сериализованный JSON как data
|
||||
data=payload
|
||||
)
|
||||
|
||||
logger.debug("POST response status: %s", response.status)
|
||||
|
||||
return response
|
||||
|
||||
def get_response_body(self, response: Response) -> dict | list | None:
|
||||
def get_response_body(self, response: Response) -> dict | None:
|
||||
"""Извлекает тело ответа в format JSON.
|
||||
|
||||
Args:
|
||||
response (Response): Ответ сервера.
|
||||
|
||||
Returns:
|
||||
dict | list | None: Распарсенное тело ответа или None в случае ошибки.
|
||||
dict | None: Распарсенное тело ответа или None в случае ошибки.
|
||||
"""
|
||||
start_time = time.time()
|
||||
|
||||
# Проверяем что response не None
|
||||
if response is None:
|
||||
logger.error("Response object is None")
|
||||
processing_time = time.time() - start_time
|
||||
logger.debug("Response processing time1: %.3f seconds", processing_time)
|
||||
try:
|
||||
response_body = response.json()
|
||||
except json.JSONDecodeError:
|
||||
logger.error("Failed to decode JSON response")
|
||||
return None
|
||||
return response_body
|
||||
|
||||
# Проверяем статус ответа
|
||||
if response.status >= 400:
|
||||
logger.error("API request failed with status %s", response.status)
|
||||
processing_time = time.time() - start_time
|
||||
logger.debug("Response processing time2: %.3f seconds", processing_time)
|
||||
return None
|
||||
|
||||
# Пытаемся получить JSON
|
||||
json_result = response.json()
|
||||
|
||||
# Проверяем что результат не None
|
||||
if json_result is None:
|
||||
logger.error("JSON parsing returned None")
|
||||
processing_time = time.time() - start_time
|
||||
logger.debug("Response processing time3: %.3f seconds", processing_time)
|
||||
return None
|
||||
|
||||
# Принимаем как словари, так и списки
|
||||
if not isinstance(json_result, (dict, list)):
|
||||
logger.error("Expected dict or list but got %s", type(json_result))
|
||||
processing_time = time.time() - start_time
|
||||
logger.debug("Response processing time4: %.3f seconds", processing_time)
|
||||
return None
|
||||
|
||||
processing_time = time.time() - start_time
|
||||
logger.debug("Response processing time5: %.3f seconds", processing_time)
|
||||
|
||||
return json_result
|
||||
|
||||
# Проверки:
|
||||
# Проверки:
|
||||
def check_URL(self, uri: str, msg: str) -> None:
|
||||
"""Проверяет, что текущий URL соответствует ожидаемому.
|
||||
|
||||
|
|
@ -196,7 +132,7 @@ class BasePage:
|
|||
Raises:
|
||||
AssertionError: Если URL не соответствует ожидаемому.
|
||||
"""
|
||||
expect(self.page).to_have_url( # pylint: disable=expression-not-assigned
|
||||
expect(self.page).to_have_url(
|
||||
f"{host.get_base_url()}{uri}",
|
||||
timeout=60000
|
||||
), msg
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class LicenseTab(BasePage):
|
|||
def should_be_json_container(self) -> None:
|
||||
"""Проверяет наличие JSON-контейнера."""
|
||||
|
||||
self.json_container.check_visibility(
|
||||
self.json_container.check_presence(
|
||||
JsonContainerLocators.CONTAINER,
|
||||
"Json container with license info is missing"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ class MainPage(BasePage):
|
|||
def should_be_navigation_panel(self) -> None:
|
||||
"""Проверяет наличие панели навигации."""
|
||||
|
||||
self.navigation_panel.check_visibility(
|
||||
self.navigation_panel.check_presence(
|
||||
NavigationPanelLocators.PANEL_MAIN,
|
||||
"Navigation panel is missing"
|
||||
)
|
||||
|
|
@ -101,7 +101,7 @@ class MainPage(BasePage):
|
|||
def should_be_user_button(self) -> None:
|
||||
"""Проверяет наличие кнопки пользователя."""
|
||||
|
||||
self.user_button.check_visibility("User button is missing on event panel")
|
||||
self.user_button.check_presence("User button is missing on event panel")
|
||||
|
||||
def check_navigation_panel_verticall_scrolling(self) -> bool:
|
||||
"""Проверяет возможность вертикальной прокрутки панели.
|
||||
|
|
|
|||
|
|
@ -154,8 +154,7 @@ class ServiceStatusTab(BasePage):
|
|||
AssertionError: Если таблица отсутствует.
|
||||
"""
|
||||
|
||||
self.services_table.check_visibility(
|
||||
self.services_table.check_presence(
|
||||
TableLocators.TABLE_WORK_AREA,
|
||||
"Service statuses table is missing"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -139,7 +139,6 @@ class SessionsTab(BasePage):
|
|||
# Находим кнопку удаления сеанса и нажимаем на нее
|
||||
delete_session_button = self.get_delete_session_button_from_row(row_index)
|
||||
delete_session_button.click()
|
||||
self.page.wait_for_timeout(1000)
|
||||
|
||||
# Подтверждаем удаление
|
||||
self.delete_session_confirm.click_allow_button()
|
||||
|
|
@ -312,7 +311,7 @@ class SessionsTab(BasePage):
|
|||
AssertionError: Если таблица отсутствует.
|
||||
"""
|
||||
|
||||
self.sessions_table.check_visibility(
|
||||
self.sessions_table.check_presence(
|
||||
TableLocators.TABLE_WORK_AREA,
|
||||
"Sessions table is missing"
|
||||
)
|
||||
|
|
@ -336,7 +335,7 @@ class SessionsTab(BasePage):
|
|||
self.wait_for_tooltip_to_disappear()
|
||||
|
||||
delete_button = self.get_delete_session_button_from_row(row_index)
|
||||
delete_button.check_visibility(
|
||||
delete_button.check_presence(
|
||||
f"Delete session button is missing on {row_index} row"
|
||||
)
|
||||
delete_button.check_tooltip_with_text(ButtonLocators.TOOLTIP, tooltip)
|
||||
|
|
|
|||
|
|
@ -293,10 +293,10 @@ class UsersTab(BasePage):
|
|||
"""
|
||||
|
||||
if self.toolbar.is_button_not_present("close"):
|
||||
self.toolbar.check_button_visibility("edit")
|
||||
self.toolbar.check_button_presence("edit")
|
||||
self.toolbar.click_button("edit")
|
||||
|
||||
self.toolbar.check_button_visibility("add_user")
|
||||
self.toolbar.check_button_presence("add_user")
|
||||
self.toolbar.click_button("add_user")
|
||||
self.add_modal_window("add_local_user", "")
|
||||
self.get_modal_window("add_local_user").check_by_window_title()
|
||||
|
|
@ -441,7 +441,7 @@ class UsersTab(BasePage):
|
|||
"""
|
||||
|
||||
self.toolbar.check_toolbar_presence("Toolbar is missing")
|
||||
self.toolbar.check_button_visibility("edit")
|
||||
self.toolbar.check_button_presence("edit")
|
||||
|
||||
def should_be_toolbar_buttons(self) -> None:
|
||||
"""Проверяет наличие и функциональность кнопок тулбара.
|
||||
|
|
@ -450,17 +450,17 @@ class UsersTab(BasePage):
|
|||
AssertionError: Если кнопки недоступны или подсказки неверны.
|
||||
"""
|
||||
|
||||
self.toolbar.check_button_visibility("edit")
|
||||
self.toolbar.check_button_presence("edit")
|
||||
self.toolbar.check_button_tooltip("edit", "Редактировать")
|
||||
|
||||
self.toolbar.get_button_by_name("edit").click()
|
||||
self.toolbar.check_button_visibility("add_user")
|
||||
self.toolbar.check_button_visibility("close")
|
||||
self.toolbar.check_button_presence("add_user")
|
||||
self.toolbar.check_button_presence("close")
|
||||
self.toolbar.check_button_tooltip("add_user", "Добавить")
|
||||
self.toolbar.check_button_tooltip("close", "Закрыть")
|
||||
|
||||
self.toolbar.get_button_by_name("close").click()
|
||||
self.toolbar.check_button_visibility("edit")
|
||||
self.toolbar.check_button_presence("edit")
|
||||
|
||||
def should_be_users_table(self) -> None:
|
||||
"""Проверяет наличие таблицы пользователей.
|
||||
|
|
@ -469,7 +469,7 @@ class UsersTab(BasePage):
|
|||
AssertionError: Если таблица отсутствует.
|
||||
"""
|
||||
|
||||
self.users_table.check_visibility(
|
||||
self.users_table.check_presence(
|
||||
TableLocators.TABLE_WORK_AREA,
|
||||
"Users table is missing"
|
||||
)
|
||||
|
|
|
|||
BIN
ping_log.txt
BIN
ping_log.txt
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test_logs.txt
BIN
test_logs.txt
Binary file not shown.
Binary file not shown.
|
|
@ -50,7 +50,7 @@ class TestUsersModalWindow:
|
|||
assert is_scrollable_vertically, "Should be vertical scrolling"
|
||||
|
||||
modal_window.scroll_window_down()
|
||||
modal_window.check_button_visibility("close")
|
||||
modal_window.check_button_presence("close")
|
||||
ut.wait_for_timeout(3000)
|
||||
|
||||
modal_window.scroll_window_up()
|
||||
|
|
@ -84,7 +84,7 @@ class TestUsersModalWindow:
|
|||
assert is_scrollable_vertically, "Should be vertical scrolling"
|
||||
|
||||
modal_window.scroll_window_down()
|
||||
modal_window.check_button_visibility("close")
|
||||
modal_window.check_button_presence("close")
|
||||
ut.wait_for_timeout(3000)
|
||||
|
||||
modal_window.scroll_window_up()
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue