Добавлены новые тесты для вкладки Сессия
parent
88e7e27c4a
commit
a7c3e953f7
|
|
@ -148,9 +148,7 @@ class BaseComponent:
|
||||||
|
|
||||||
loc = self.get_locator(locator)
|
loc = self.get_locator(locator)
|
||||||
|
|
||||||
width = loc.evaluate("el => el.scrollWidth")
|
loc.evaluate("el => el.scrollBy(-el.scrollWidth, 0)")
|
||||||
loc.scroll_into_view_if_needed()
|
|
||||||
self.page.mouse.wheel(-width, 0)
|
|
||||||
|
|
||||||
loc.wait_for(timeout=2000)
|
loc.wait_for(timeout=2000)
|
||||||
|
|
||||||
|
|
@ -170,9 +168,7 @@ class BaseComponent:
|
||||||
|
|
||||||
loc = self.get_locator(locator)
|
loc = self.get_locator(locator)
|
||||||
|
|
||||||
width = loc.evaluate("el => el.scrollWidth")
|
loc.evaluate("el => el.scrollBy(el.scrollWidth, 0)")
|
||||||
loc.scroll_into_view_if_needed()
|
|
||||||
self.page.mouse.wheel(width, 0)
|
|
||||||
|
|
||||||
loc.wait_for(timeout=2000)
|
loc.wait_for(timeout=2000)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,16 @@ class ConfirmComponent(BaseComponent):
|
||||||
|
|
||||||
self.close_button.click()
|
self.close_button.click()
|
||||||
|
|
||||||
|
def scroll_window_left(self) -> None:
|
||||||
|
"""Прокручивает содержимое окна влево."""
|
||||||
|
|
||||||
|
self.scroll_left(ConfirmLocators.CONFIRM)
|
||||||
|
|
||||||
|
def scroll_window_right(self) -> None:
|
||||||
|
"""Прокручивает содержимое окна вправо."""
|
||||||
|
|
||||||
|
self.scroll_right(ConfirmLocators.CONFIRM)
|
||||||
|
|
||||||
# Проверки:
|
# Проверки:
|
||||||
def check_title(self, title: str, msg: str) -> None:
|
def check_title(self, title: str, msg: str) -> None:
|
||||||
"""Проверяет текст заголовка окна подтверждения.
|
"""Проверяет текст заголовка окна подтверждения.
|
||||||
|
|
@ -79,3 +89,9 @@ class ConfirmComponent(BaseComponent):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.text.check_have_text(text, msg)
|
self.text.check_have_text(text, msg)
|
||||||
|
|
||||||
|
def check_window_horizontal_scrolling(self) -> bool:
|
||||||
|
"""Проверяет возможность горизонтальной прокрутки окна."""
|
||||||
|
|
||||||
|
return self.is_scrollable_horizontally(ConfirmLocators.CONFIRM)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
"""Модуль base_page содержит базовый класс для работы со страницами.
|
"""Базовый класс страницы для работы с Playwright.
|
||||||
|
|
||||||
Класс BasePage предоставляет общие методы для взаимодействия
|
Содержит общие методы для взаимодействия со страницей и API.
|
||||||
со страницами через Playwright и выполнения API-запросов.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
|
||||||
from typing import Any, Dict, List, Optional
|
|
||||||
from playwright.sync_api import Page, Response, APIRequestContext, expect
|
from playwright.sync_api import Page, Response, APIRequestContext, expect
|
||||||
from tools.logger import get_logger
|
|
||||||
from data.environment import host
|
from data.environment import host
|
||||||
|
from tools.logger import get_logger
|
||||||
|
import json
|
||||||
|
|
||||||
logger = get_logger("BASE_PAGE")
|
logger = get_logger("BASE_PAGE")
|
||||||
|
|
||||||
|
|
@ -16,54 +14,67 @@ logger = get_logger("BASE_PAGE")
|
||||||
class BasePage:
|
class BasePage:
|
||||||
"""Базовый класс для работы со страницами через Playwright.
|
"""Базовый класс для работы со страницами через Playwright.
|
||||||
|
|
||||||
Содержит общие методы для:
|
Атрибуты:
|
||||||
- Навигации по страницам
|
page (Page): Экземпляр страницы Playwright.
|
||||||
- Выполнения API-запросов
|
|
||||||
- Проверок состояния страницы
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, page: Page) -> None:
|
def __init__(self, page: Page):
|
||||||
"""Инициализирует базовую страницу.
|
"""Инициализирует базовую страницу.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
page: Экземпляр страницы Playwright
|
page (Page): Экземпляр страницы Playwright.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.page = page
|
self.page = page
|
||||||
|
|
||||||
# Действия:
|
# Действия:
|
||||||
def current_url(self) -> str:
|
def current_url(self) -> str:
|
||||||
"""Возвращает текущий URL страницы."""
|
"""Возвращает текущий URL страницы.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Текущий URL страницы.
|
||||||
|
"""
|
||||||
return self.page.url
|
return self.page.url
|
||||||
|
|
||||||
def open(self, uri: str) -> Optional[Response]:
|
def open(self, uri) -> Response | None:
|
||||||
"""Открывает указанный URI на базовом URL."""
|
"""Открывает указанный URI в браузере.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
uri (str): URI для открытия (без базового URL).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response | None: Ответ сервера или None в случае ошибки.
|
||||||
|
"""
|
||||||
return self.page.goto(f"{host.get_base_url()}{uri}", wait_until='domcontentloaded')
|
return self.page.goto(f"{host.get_base_url()}{uri}", wait_until='domcontentloaded')
|
||||||
|
|
||||||
def page_reload(self) -> None:
|
def page_reload(self) -> None:
|
||||||
"""Перезагружает текущую страницу."""
|
"""Перезагружает текущую страницу."""
|
||||||
|
|
||||||
self.page.reload()
|
self.page.reload()
|
||||||
|
|
||||||
def wait_for_timeout(self, timeout: int) -> None:
|
def wait_for_timeout(self, timeout):
|
||||||
"""Ожидает указанное количество миллисекунд."""
|
"""Ожидает указанное количество миллисекунд.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
timeout (int): Время ожидания в миллисекундах.
|
||||||
|
"""
|
||||||
self.page.wait_for_timeout(timeout)
|
self.page.wait_for_timeout(timeout)
|
||||||
|
|
||||||
def get_api_request_context(self) -> APIRequestContext:
|
def get_api_request_context(self) -> APIRequestContext:
|
||||||
"""Возвращает контекст для выполнения API-запросов."""
|
"""Возвращает контекст API-запросов.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
APIRequestContext: Контекст для выполнения API-запросов.
|
||||||
|
"""
|
||||||
return self.page.context.request
|
return self.page.context.request
|
||||||
|
|
||||||
def send_get_api_request(self, uri: str) -> Response:
|
def send_get_api_request(self, uri) -> Response:
|
||||||
"""Отправляет GET-запрос к API.
|
"""Отправляет GET-запрос к API.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
uri: URI для запроса
|
uri (str): URI API-эндпоинта (без базового URL).
|
||||||
"""
|
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response: Ответ сервера.
|
||||||
|
"""
|
||||||
api_request_context = self.get_api_request_context()
|
api_request_context = self.get_api_request_context()
|
||||||
token = host.get_access_token()
|
token = host.get_access_token()
|
||||||
headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"}
|
headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"}
|
||||||
|
|
@ -73,14 +84,16 @@ class BasePage:
|
||||||
)
|
)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def send_post_api_request(self, uri: str, payload: Dict[str, Any]) -> Response:
|
def send_post_api_request(self, uri, payload) -> Response:
|
||||||
"""Отправляет POST-запрос к API.
|
"""Отправляет POST-запрос к API.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
uri: URI для запроса
|
uri (str): URI API-эндпоинта (без базового URL).
|
||||||
payload: Тело запроса
|
payload: Данные для отправки в теле запроса.
|
||||||
"""
|
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response: Ответ сервера.
|
||||||
|
"""
|
||||||
api_request_context = self.get_api_request_context()
|
api_request_context = self.get_api_request_context()
|
||||||
token = host.get_access_token()
|
token = host.get_access_token()
|
||||||
headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"}
|
headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"}
|
||||||
|
|
@ -91,13 +104,15 @@ class BasePage:
|
||||||
)
|
)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def get_response_body(self, response: Response) -> Optional[Dict[str, Any]]:
|
def get_response_body(self, response) -> dict | None:
|
||||||
"""Возвращает тело ответа в формате JSON.
|
"""Извлекает тело ответа в формате JSON.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
response: Объект ответа
|
response (Response): Ответ сервера.
|
||||||
"""
|
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict | None: Распарсенное тело ответа или None в случае ошибки.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
response_body = response.json()
|
response_body = response.json()
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
|
|
@ -107,39 +122,54 @@ class BasePage:
|
||||||
|
|
||||||
# Проверки:
|
# Проверки:
|
||||||
def check_URL(self, uri: str, msg: str) -> None:
|
def check_URL(self, uri: str, msg: str) -> None:
|
||||||
"""Проверяет соответствие текущего URL ожидаемому.
|
"""Проверяет, что текущий URL соответствует ожидаемому.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
uri: Ожидаемый URI
|
uri (str): Ожидаемый URI (без базового URL).
|
||||||
msg: Сообщение об ошибке
|
msg (str): Сообщение об ошибке при несоответствии.
|
||||||
"""
|
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
AssertionError: Если URL не соответствует ожидаемому.
|
||||||
|
"""
|
||||||
expect(self.page).to_have_url(
|
expect(self.page).to_have_url(
|
||||||
f"{host.get_base_url()}{uri}",
|
f"{host.get_base_url()}{uri}",
|
||||||
timeout=60000
|
timeout=60000
|
||||||
), msg
|
), msg
|
||||||
|
|
||||||
def check_equals(self, actual: Any, expected: Any, msg: str) -> None:
|
def check_equals(self, actual, expected, msg: str) -> None:
|
||||||
"""Проверяет равенство фактического и ожидаемого значений.
|
"""Проверяет равенство фактического и ожидаемого значений.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
actual: Фактическое значение
|
actual: Фактическое значение.
|
||||||
expected: Ожидаемое значение
|
expected: Ожидаемое значение.
|
||||||
msg: Сообщение об ошибке
|
msg (str): Сообщение об ошибке при несоответствии.
|
||||||
"""
|
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
AssertionError: Если значения не равны.
|
||||||
|
"""
|
||||||
assert actual == expected, msg
|
assert actual == expected, msg
|
||||||
|
|
||||||
def check_lists_equals(self, actual: List[Any], expected: List[Any], msg: str) -> None:
|
def check_lists_equals(self, actual: list, expected: list, msg: str) -> None:
|
||||||
"""Рекурсивно проверяет равенство двух списков.
|
"""Рекурсивно проверяет равенство двух списков.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
actual: Фактический список
|
actual (list): Фактический список.
|
||||||
expected: Ожидаемый список
|
expected (list): Ожидаемый список.
|
||||||
msg: Сообщение об ошибке
|
msg (str): Сообщение об ошибке при несоответствии.
|
||||||
"""
|
|
||||||
|
|
||||||
def compare_lists(list1: List[Any], list2: List[Any]) -> bool:
|
Raises:
|
||||||
|
AssertionError: Если списки не равны.
|
||||||
|
"""
|
||||||
|
def compare_lists(list1: list, list2: list) -> bool:
|
||||||
|
"""Вспомогательная функция для рекурсивного сравнения списков.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
list1 (list): Первый список для сравнения.
|
||||||
|
list2 (list): Второй список для сравнения.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True если списки идентичны, иначе False.
|
||||||
|
"""
|
||||||
if len(list1) != len(list2):
|
if len(list1) != len(list2):
|
||||||
return False
|
return False
|
||||||
for item1, item2 in zip(list1, list2):
|
for item1, item2 in zip(list1, list2):
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,10 @@ from locators.table_locators import TableLocators
|
||||||
from locators.button_locators import ButtonLocators
|
from locators.button_locators import ButtonLocators
|
||||||
from elements.tooltip_button_element import TooltipButton
|
from elements.tooltip_button_element import TooltipButton
|
||||||
from data.roles_dict import roles_dict
|
from data.roles_dict import roles_dict
|
||||||
|
from data.environment import host
|
||||||
from components.toolbar_component import ToolbarComponent
|
from components.toolbar_component import ToolbarComponent
|
||||||
from components.table_component import TableComponent
|
from components.table_component import TableComponent
|
||||||
|
from components.confirm_component import ConfirmComponent
|
||||||
from pages.base_page import BasePage
|
from pages.base_page import BasePage
|
||||||
|
|
||||||
class SessionsTab(BasePage):
|
class SessionsTab(BasePage):
|
||||||
|
|
@ -31,6 +33,9 @@ class SessionsTab(BasePage):
|
||||||
self.toolbar = ToolbarComponent(page, "Сессия")
|
self.toolbar = ToolbarComponent(page, "Сессия")
|
||||||
self.sessions_table = TableComponent(page)
|
self.sessions_table = TableComponent(page)
|
||||||
|
|
||||||
|
self.delete_session_confirm = ConfirmComponent(page, " Отмена ", " Удалить ")
|
||||||
|
|
||||||
|
# Действия:
|
||||||
def get_rows_count(self) -> int:
|
def get_rows_count(self) -> int:
|
||||||
"""Возвращает количество строк в таблице (без заголовка).
|
"""Возвращает количество строк в таблице (без заголовка).
|
||||||
|
|
||||||
|
|
@ -71,6 +76,42 @@ class SessionsTab(BasePage):
|
||||||
button_locator = row_locator.locator(ButtonLocators.BUTTON_DELETE_SESSION)
|
button_locator = row_locator.locator(ButtonLocators.BUTTON_DELETE_SESSION)
|
||||||
return TooltipButton(self.page, button_locator, "delete_session_button")
|
return TooltipButton(self.page, button_locator, "delete_session_button")
|
||||||
|
|
||||||
|
def get_session_token(self) -> str:
|
||||||
|
"""Возвращает токен текущего пользователя.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Токен текущего пользователя
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
"""
|
||||||
|
return host.get_access_token()
|
||||||
|
|
||||||
|
def find_session_in_table(self, token: str) -> int:
|
||||||
|
"""Ищет сессию пользователя в таблице по выданному ему токену.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
token (str): Токен пользователя
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: Индекс строки или -1 если не найден
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
AssertionError: Если таблица пуста.
|
||||||
|
"""
|
||||||
|
table_content = self.sessions_table.read(TableLocators.TABLE_WORK_AREA)
|
||||||
|
if len(table_content) == 0:
|
||||||
|
assert False, "The contents of the table are missing"
|
||||||
|
|
||||||
|
del table_content[0] # Удаляем заголовок
|
||||||
|
|
||||||
|
for row_index, session_info in enumerate(table_content):
|
||||||
|
if token in session_info:
|
||||||
|
return row_index
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
def scroll_sessions_table_up(self) -> None:
|
def scroll_sessions_table_up(self) -> None:
|
||||||
"""Прокручивает таблицу сессий вверх."""
|
"""Прокручивает таблицу сессий вверх."""
|
||||||
|
|
||||||
|
|
@ -81,6 +122,46 @@ class SessionsTab(BasePage):
|
||||||
|
|
||||||
self.sessions_table.scroll_down(TableLocators.TABLE_SCROLL_CONTAINER)
|
self.sessions_table.scroll_down(TableLocators.TABLE_SCROLL_CONTAINER)
|
||||||
|
|
||||||
|
# Проверки:
|
||||||
|
def check_delete_session_confirm_window(self):
|
||||||
|
""" Проверяет контент и возможность горизонтального скроллинга окна подтверждения удаления сессии. """
|
||||||
|
|
||||||
|
# Поиск в таблице сессий сроки для текущего пользователя
|
||||||
|
session_token = self.get_session_token()
|
||||||
|
row_index = self.find_session_in_table(session_token)
|
||||||
|
if row_index == -1:
|
||||||
|
assert False, "Session for this token has not been found"
|
||||||
|
|
||||||
|
# Найти кнопку удаления сессии и нажать на нее
|
||||||
|
delete_session_button = self.get_delete_session_button_from_row(row_index)
|
||||||
|
delete_session_button.click()
|
||||||
|
|
||||||
|
# Проверка открытия окна подтверждения с заголовком "Удаление"
|
||||||
|
title = "Удаление"
|
||||||
|
self.delete_session_confirm.check_title(
|
||||||
|
title,
|
||||||
|
f"Confirmation dialog window text '{title}' is missing"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Проверка текста в окне подтверждения
|
||||||
|
confirm_message = f"Удалить сессию {session_token}?"
|
||||||
|
self.delete_session_confirm.check_text(
|
||||||
|
confirm_message,
|
||||||
|
"Confirmation dialog window text does not match what is expected"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Проверка горизонтального скроллинга
|
||||||
|
is_scrollable_horizontally = self.delete_session_confirm.check_window_horizontal_scrolling()
|
||||||
|
assert is_scrollable_horizontally, "Should be horizontal scrolling"
|
||||||
|
|
||||||
|
self.delete_session_confirm.scroll_window_right()
|
||||||
|
self.page.wait_for_timeout(3000)
|
||||||
|
self.delete_session_confirm.scroll_window_left()
|
||||||
|
self.page.wait_for_timeout(2000)
|
||||||
|
|
||||||
|
# Нажать кнопку "Отмена"
|
||||||
|
self.delete_session_confirm.click_cancel_button()
|
||||||
|
|
||||||
def check_sessions_table_content(self, verify: bool = False) -> None:
|
def check_sessions_table_content(self, verify: bool = False) -> None:
|
||||||
"""Проверяет содержимое таблицы сессий.
|
"""Проверяет содержимое таблицы сессий.
|
||||||
|
|
||||||
|
|
@ -208,6 +289,33 @@ class SessionsTab(BasePage):
|
||||||
)
|
)
|
||||||
delete_button.check_tooltip_with_text(ButtonLocators.TOOLTIP, tooltip)
|
delete_button.check_tooltip_with_text(ButtonLocators.TOOLTIP, tooltip)
|
||||||
|
|
||||||
|
def should_be_session_in_table(self, token: str) -> None:
|
||||||
|
"""Проверяет наличие сессии пользователя в таблице.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
token (str): Токен пользователя
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
AssertionError: Если сессия не найдена.
|
||||||
|
"""
|
||||||
|
found = self.find_session_in_table(token)
|
||||||
|
if found == -1:
|
||||||
|
assert False, "Session for this token has not been found"
|
||||||
|
|
||||||
|
def should_not_be_session_in_table(self, token: str) -> None:
|
||||||
|
"""Проверяет отсутствие сессии пользователя в таблице.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
token (str): Токен пользователя
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
AssertionError: Если сессия найдена.
|
||||||
|
"""
|
||||||
|
found = self.find_session_in_table(token)
|
||||||
|
if found != -1:
|
||||||
|
assert False, "Session for this token has been found"
|
||||||
|
|
||||||
|
|
||||||
def verify_sessions_table_content(self, sessions_table: list) -> None:
|
def verify_sessions_table_content(self, sessions_table: list) -> None:
|
||||||
"""Сверяет данные таблицы с данными из БД.
|
"""Сверяет данные таблицы с данными из БД.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,25 @@
|
||||||
"""Модуль тестов вкладки 'Сеансы'.
|
from pages.login_page import LoginPage
|
||||||
|
from pages.main_page import MainPage
|
||||||
Содержит тесты для проверки отображения и функциональности
|
from pages.session_tab import SessionsTab
|
||||||
элементов вкладки сеансов пользователей.
|
from pages.users_tab import UsersTab
|
||||||
"""
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from pages.session_tab import SessionsTab
|
|
||||||
from pages.main_page import MainPage
|
|
||||||
from pages.login_page import LoginPage
|
|
||||||
from playwright.sync_api import Page
|
|
||||||
|
|
||||||
|
|
||||||
class TestSessionsTab:
|
class TestSessionsTab:
|
||||||
"""Класс тестов для проверки вкладки 'Сеансы'."""
|
"""Набор тестов для вкладки 'Сеансы'.
|
||||||
|
|
||||||
|
Проверяет корректность отображения и функциональность элементов вкладки сеансов.
|
||||||
|
"""
|
||||||
|
|
||||||
@pytest.fixture(scope="function", autouse=True)
|
@pytest.fixture(scope="function", autouse=True)
|
||||||
def setup(self, browser: Page):
|
def setup(self, browser):
|
||||||
"""Подготавливает тестовое окружение.
|
"""Фикстура для подготовки тестового окружения.
|
||||||
|
|
||||||
Args:
|
Выполняет:
|
||||||
browser: Экземпляр страницы Playwright.
|
1. Авторизацию в системе
|
||||||
|
2. Переход на вкладку 'Сеансы' через панель навигации
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Авторизация в системе
|
# Авторизация в системе
|
||||||
login_page = LoginPage(browser)
|
login_page = LoginPage(browser)
|
||||||
login_page.do_login()
|
login_page.do_login()
|
||||||
|
|
@ -35,14 +33,14 @@ class TestSessionsTab:
|
||||||
main_page.click_configuration_navigation_panel_item("Обслуживание и диагностика")
|
main_page.click_configuration_navigation_panel_item("Обслуживание и диагностика")
|
||||||
main_page.click_maintenance_navigation_panel_item("Сеансы")
|
main_page.click_maintenance_navigation_panel_item("Сеансы")
|
||||||
|
|
||||||
|
def test_sessions_tab_content(self, browser):
|
||||||
|
"""Тест содержимого вкладки 'Сеансы'.
|
||||||
|
|
||||||
def test_sessions_tab_content(self, browser: Page):
|
Проверяет:
|
||||||
"""Проверяет содержимое вкладки 'Сеансы'.
|
1. Наличие и корректность тулбара
|
||||||
|
2. Наличие таблицы сеансов
|
||||||
Args:
|
3. Соответствие содержимого таблицы данным из БД
|
||||||
browser: Экземпляр страницы Playwright.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Инициализация страницы сеансов
|
# Инициализация страницы сеансов
|
||||||
sessions_tab = SessionsTab(browser)
|
sessions_tab = SessionsTab(browser)
|
||||||
|
|
||||||
|
|
@ -52,3 +50,123 @@ class TestSessionsTab:
|
||||||
|
|
||||||
# Проверка содержимого таблицы с верификацией данных из БД
|
# Проверка содержимого таблицы с верификацией данных из БД
|
||||||
sessions_tab.check_sessions_table_content(verify=True)
|
sessions_tab.check_sessions_table_content(verify=True)
|
||||||
|
|
||||||
|
def test_sessions_table_row_highlighting(self, browser):
|
||||||
|
"""Тест содержимого вкладки 'Сеансы'.
|
||||||
|
|
||||||
|
Проверяет:
|
||||||
|
1. Наличие таблицы сеансов
|
||||||
|
2. Проверка подсветки строки при наведении на нее курсором
|
||||||
|
"""
|
||||||
|
# Инициализация страницы сеансов
|
||||||
|
sessions_tab = SessionsTab(browser)
|
||||||
|
|
||||||
|
# Проверка элементов интерфейса
|
||||||
|
sessions_tab.should_be_sessions_table()
|
||||||
|
|
||||||
|
# Получение количества строк в таблице без учета заголовка
|
||||||
|
rows_count = sessions_tab.get_rows_count()
|
||||||
|
|
||||||
|
# Проверка подсветки первой строки
|
||||||
|
sessions_tab.check_sessions_table_row_highlighting(0)
|
||||||
|
|
||||||
|
# Проверка подсветки последней строки строки (если в таблице более одной строки)
|
||||||
|
if rows_count > 1:
|
||||||
|
sessions_tab.check_sessions_table_row_highlighting(rows_count - 1)
|
||||||
|
|
||||||
|
def test_delete_session_confirm_window(self, browser):
|
||||||
|
"""Тест содержимого вкладки 'Сеансы'.
|
||||||
|
|
||||||
|
Проверяет:
|
||||||
|
1. Наличие таблицы сеансов
|
||||||
|
2. Проверка контента и возможности горизонтального скроллинга окна подтверждения удаления сессии
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Инициализация страницы сеансов
|
||||||
|
sessions_tab = SessionsTab(browser)
|
||||||
|
|
||||||
|
# Проверка элементов интерфейса
|
||||||
|
sessions_tab.should_be_sessions_table()
|
||||||
|
|
||||||
|
# Проверка контента и скроллинга окна подтверждения удаления сессии
|
||||||
|
sessions_tab.check_delete_session_confirm_window()
|
||||||
|
|
||||||
|
#@pytest.mark.develop
|
||||||
|
def test_session_for_new_user(self, browser):
|
||||||
|
"""Тест содержимого вкладки 'Сеансы'.
|
||||||
|
|
||||||
|
Проверяет:
|
||||||
|
1. Создание нового пользователя
|
||||||
|
2. Вход нового пользователя в систему
|
||||||
|
3. Проверка наличия сессии нового пользователя
|
||||||
|
4. Выход нового пользователя из системы (logout)
|
||||||
|
5. Вход в систему первоначального пользователя
|
||||||
|
6. Проверка отсутствия сессии нового пользователя
|
||||||
|
7. Удаление нового пользователя
|
||||||
|
"""
|
||||||
|
user_data = {"name": "NewUser", "role": "Администратор", "password": "qwerty"}
|
||||||
|
|
||||||
|
mp = MainPage(browser)
|
||||||
|
ut = UsersTab(browser)
|
||||||
|
|
||||||
|
# Создание нового пользователя
|
||||||
|
mp.click_configuration_navigation_panel_item("Пользователи")
|
||||||
|
ut.open_add_user_window()
|
||||||
|
ut.add_new_user(user_data)
|
||||||
|
|
||||||
|
# Обновление списка пользователей (двойной клик - возможно баг?)
|
||||||
|
mp.click_configuration_navigation_panel_item("Пользователи")
|
||||||
|
mp.click_configuration_navigation_panel_item("Пользователи")
|
||||||
|
|
||||||
|
# Проверка наличия пользователя в таблице
|
||||||
|
ut.should_be_user_in_table(user_data["name"], user_data["role"])
|
||||||
|
|
||||||
|
# Вход в систему для нового пользователя
|
||||||
|
new_lp = LoginPage(browser)
|
||||||
|
new_lp.do_login(username=user_data["name"], password=user_data["password"])
|
||||||
|
|
||||||
|
# Инициализация главной страницы
|
||||||
|
new_mp = MainPage(browser)
|
||||||
|
|
||||||
|
# Открыть вкладку Сессии
|
||||||
|
new_mp.should_be_navigation_panel()
|
||||||
|
new_mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
new_mp.click_configuration_navigation_panel_item("Обслуживание и диагностика")
|
||||||
|
new_mp.click_maintenance_navigation_panel_item("Сеансы")
|
||||||
|
|
||||||
|
# Инициализация страницы сеансов
|
||||||
|
st = SessionsTab(browser)
|
||||||
|
|
||||||
|
# Проверка элементов интерфейса
|
||||||
|
st.should_be_sessions_table()
|
||||||
|
|
||||||
|
# Проверка наличия записи о сессии текущего пользователя
|
||||||
|
session_token = st.get_session_token()
|
||||||
|
st.should_be_session_in_table(session_token)
|
||||||
|
|
||||||
|
# logout
|
||||||
|
new_mp.do_logout()
|
||||||
|
|
||||||
|
# Авторизация в системе предыдущего пользователя
|
||||||
|
prev_lp = LoginPage(browser)
|
||||||
|
prev_lp.do_login()
|
||||||
|
|
||||||
|
# Инициализация главной страницы
|
||||||
|
prev_mp = MainPage(browser)
|
||||||
|
|
||||||
|
# Открыть вкладку Сессии
|
||||||
|
prev_mp.should_be_navigation_panel()
|
||||||
|
prev_mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
prev_mp.click_configuration_navigation_panel_item("Обслуживание и диагностика")
|
||||||
|
prev_mp.click_maintenance_navigation_panel_item("Сеансы")
|
||||||
|
|
||||||
|
# Проверка элементов интерфейса
|
||||||
|
st.should_be_sessions_table()
|
||||||
|
|
||||||
|
# Проверка отсутствия записи о сессии созданного пользователя после выхода из системы
|
||||||
|
st.should_not_be_session_in_table(session_token)
|
||||||
|
|
||||||
|
# Удаление созданного пользователя
|
||||||
|
prev_ut = UsersTab(browser)
|
||||||
|
prev_ut.open_edit_user_page_by_user(user_data["name"], user_data["role"])
|
||||||
|
prev_ut.delete_user(user_data["name"])
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue