diff --git a/components/confirm_component.py b/components/confirm_component.py index 588f9fe..ba2f462 100644 --- a/components/confirm_component.py +++ b/components/confirm_component.py @@ -58,7 +58,7 @@ class ConfirmComponent(BaseComponent): """Нажимает кнопку закрытия окна подтверждения.""" self.close_button.click() - + def scroll_window_left(self) -> None: """Прокручивает содержимое окна влево.""" @@ -89,9 +89,24 @@ class ConfirmComponent(BaseComponent): """ self.text.check_have_text(text, msg) - + def check_window_horizontal_scrolling(self) -> bool: """Проверяет возможность горизонтальной прокрутки окна.""" return self.is_scrollable_horizontally(ConfirmLocators.CONFIRM) + def should_be_cancel_button(self) -> None: + """Проверяет наличие и видимость кнопки Отмены.""" + self.cancel_button.check_presence("Cancel button is missing") + + def should_be_allow_button(self) -> None: + """Проверяет наличие и видимость кнопки Подтверждения.""" + self.allow_button.check_presence("Allow button is missing") + + def check_cancel_button_text(self, expected_text: str) -> None: + """Проверяет текст кнопки Отмены.""" + self.cancel_button.check_have_text(expected_text, "Cancel button text doesn't match expected") + + def check_allow_button_text(self, expected_text: str) -> None: + """Проверяет текст кнопки Подтверждения.""" + self.allow_button.check_have_text(expected_text, "Allow button text doesn't match expected") diff --git a/pages/session_tab.py b/pages/session_tab.py index 761c840..d4bf184 100644 --- a/pages/session_tab.py +++ b/pages/session_tab.py @@ -1,6 +1,6 @@ -"""Модуль вкладки 'Сессия'. +"""Модуль вкладки 'Сеанс'. -Содержит класс SessionsTab для работы с таблицей сессий. +Содержит класс SessionsTab для работы с таблицей сеансов. Позволяет проверять состояние и взаимодействовать с элементами вкладки. """ @@ -16,9 +16,9 @@ from components.confirm_component import ConfirmComponent from pages.base_page import BasePage class SessionsTab(BasePage): - """Класс для работы с вкладкой 'Сессия'. + """Класс для работы с вкладкой 'Сеанс'. - Предоставляет методы для взаимодействия с таблицей сессий и проверки + Предоставляет методы для взаимодействия с таблицей сеансов и проверки её состояния. Args: @@ -26,7 +26,7 @@ class SessionsTab(BasePage): """ def __init__(self, page: Page) -> None: - """Инициализирует компоненты вкладки 'Сессия'.""" + """Инициализирует компоненты вкладки 'Сеанс'.""" super().__init__(page) @@ -55,7 +55,7 @@ class SessionsTab(BasePage): return rows_count - 1 def get_delete_session_button_from_row(self, row_index: int) -> TooltipButton: - """Возвращает кнопку удаления сессии для указанной строки. + """Возвращает кнопку удаления сеанса для указанной строки. Args: row_index: Индекс строки в таблице. @@ -89,7 +89,7 @@ class SessionsTab(BasePage): return host.get_access_token() def find_session_in_table(self, token: str) -> int: - """Ищет сессию пользователя в таблице по выданному ему токену. + """Ищет сеанс пользователя в таблице по выданному ему токену. Args: token (str): Токен пользователя @@ -111,28 +111,66 @@ class SessionsTab(BasePage): return row_index return -1 + def delete_session_by_token(self, token: str) -> None: + """Удаляет сеанс по токену. + + Args: + token (str): Токен сеанс для удаления + + Raises: + AssertionError: Если сеанс не найден или удаление не удалось. + """ + row_index = self.find_session_in_table(token) + if row_index == -1: + raise AssertionError(f"Session with token {token} not found") + + self.delete_session_by_index(row_index) + + def delete_session_by_index(self, row_index: int) -> None: + """Удаляет сеанс по индексу строки. + + Args: + row_index (int): Индекс строки в таблице + + Raises: + AssertionError: Если удаление не удалось. + """ + try: + # Находим кнопку удаления сеанса и нажимаем на нее + delete_session_button = self.get_delete_session_button_from_row(row_index) + delete_session_button.click() + + # Подтверждаем удаление + self.delete_session_confirm.click_allow_button() + + # Ждем обновления таблицы + self.page.wait_for_timeout(1000) + + except Exception as e: + raise AssertionError(f"Failed to delete session at index {row_index}: {e}") + def scroll_sessions_table_up(self) -> None: - """Прокручивает таблицу сессий вверх.""" + """Прокручивает таблицу сеансов вверх.""" self.sessions_table.scroll_up(TableLocators.TABLE_SCROLL_CONTAINER) def scroll_sessions_table_down(self) -> None: - """Прокручивает таблицу сессий вниз.""" + """Прокручивает таблицу сеансов вниз.""" 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() @@ -150,6 +188,16 @@ class SessionsTab(BasePage): "Confirmation dialog window text does not match what is expected" ) + # Проверка наличия и видимости кнопки "Отмена" + self.delete_session_confirm.should_be_cancel_button() + + # Проверка наличия и видимости кнопки "Удалить" + self.delete_session_confirm.should_be_allow_button() + + # Проверка текста на кнопках + self.delete_session_confirm.check_cancel_button_text(" Отмена ") + self.delete_session_confirm.check_allow_button_text(" Удалить ") + # Проверка горизонтального скроллинга is_scrollable_horizontally = self.delete_session_confirm.check_window_horizontal_scrolling() assert is_scrollable_horizontally, "Should be horizontal scrolling" @@ -163,7 +211,7 @@ class SessionsTab(BasePage): self.delete_session_confirm.click_cancel_button() def check_sessions_table_content(self, verify: bool = False) -> None: - """Проверяет содержимое таблицы сессий. + """Проверяет содержимое таблицы сеансов. Args: verify: Проверять соответствие данных из БД. По умолчанию False. @@ -257,7 +305,7 @@ class SessionsTab(BasePage): self.toolbar.check_toolbar_presence("Toolbar is missing") def should_be_sessions_table(self) -> None: - """Проверяет наличие таблицы сессий. + """Проверяет наличие таблицы сеансов. Raises: AssertionError: Если таблица отсутствует. @@ -297,26 +345,26 @@ class SessionsTab(BasePage): def should_be_session_in_table(self, token: str) -> None: - """Проверяет наличие сессии пользователя в таблице. + """Проверяет наличие сеанса пользователя в таблице. Args: token (str): Токен пользователя Raises: - AssertionError: Если сессия не найдена. + 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: Если сессия найдена. + AssertionError: Если сеанс найден. """ found = self.find_session_in_table(token) if found != -1: @@ -335,7 +383,7 @@ class SessionsTab(BasePage): expected_sessions_list = [] - # Отправка запроса к бэкенду для получения информации о сессиях + # Отправка запроса к бэкенду для получения информации о сеансах response = self.send_get_api_request("e-nms/auth/sessions") response_body = self.get_response_body(response) @@ -344,7 +392,7 @@ class SessionsTab(BasePage): session_info.append(item["id"]) session_info.append(item["userId"]) - # Временно неподдерживаемое поле: время жизни сессии + # Временно неподдерживаемое поле: время жизни сеанса session_info.append("") roles = [] diff --git a/tests/e2e/test_sessions_tab.py b/tests/e2e/test_sessions_tab.py index 3269c63..f18d990 100644 --- a/tests/e2e/test_sessions_tab.py +++ b/tests/e2e/test_sessions_tab.py @@ -1,7 +1,7 @@ """Модуль тестов вкладки 'Сеансы'. Содержит тесты для проверки функциональности -работы с пользовательтскими сессиями. +работы с пользовательтскими сеансами. """ from typing import Dict from playwright.sync_api import Page @@ -12,15 +12,25 @@ from pages.users_tab import UsersTab import pytest - class TestSessionsTab: """Набор тестов для вкладки 'Сеансы'. - Проверяет корректность отображения и функциональность элементов вкладки сеансов. + Проверяет корректность отображения и функциональность элементов вкладки сеансов, + включая работу с сеансами пользователей, их создание, удаление и автоматическую очистку. + + Тесты покрывают следующие сценарии: + 1. Тест содержимого вкладки 'Сеансы' + 2. Тест подсветки строк таблицы сеансов + 3. Тест окна подтверждения удаления сеанса + 4. Тест автоматического удаления сеанса после выхода пользователя из системы (отложено) + 5. Тест создания нескольких пользователей и их сеансов + 6. Тест удаления сеанса при удалении пользователя (отложено) + 7. Тест автоматического удаления сеанса через 15 минут после выхода пользователя (отложено) + 8. Тест проверки невозможности пользователя удалить свой собственный сеанс (отложено) """ @pytest.fixture(scope="function", autouse=True) - def setup(self, browser): + def setup(self, browser: Page) -> None: """Фикстура для подготовки тестового окружения. Выполняет: @@ -41,24 +51,41 @@ class TestSessionsTab: main_page.click_subpanel_item("Сеансы") @pytest.fixture(scope="function") - def cleanup_user(self, browser: Page) -> None: - """Фикстура для очистки пользователя NewUser после теста.""" - + def cleanup_users(self, browser: Page) -> None: + """Фикстура для очистки тестовых пользователей и их сеансов после теста.""" yield + # Выход из системы текущего пользователя mp = MainPage(browser) + mp.do_logout() + + # Авторизация администратором для очистки + login_page = LoginPage(browser) + login_page.do_login() + + # Удаляем тестовых пользователей + self._cleanup_test_users(browser) + + def _cleanup_test_users(self, browser: Page) -> None: + """Удаляет тестовых пользователей.""" + mp = MainPage(browser) + mp.click_main_navigation_panel_item("Настройки") mp.click_subpanel_item("Пользователи") ut = UsersTab(browser) - # Удаляем тестового пользователя после выполнения теста - user_data: Dict[str, str] = {"name": "NewUser", "role": "Администратор"} + # Удаляем тестовых пользователей + test_users = ["TestUser1", "TestUser2", "TestUser3", "TestUserForSessionDeletion", + "TestUserForManualDeletion", "UserForAutoSessionDeletion", + "TestUserFor15MinDeletion", "TestUserForSelfDeletion"] - # Проверяем существует ли пользователь и удаляем его - if ut.find_user_in_table(user_data["name"], user_data["role"]) != -1: - ut.open_edit_user_page_by_user(user_data["name"], user_data["role"]) - ut.delete_user(user_data["name"]) + for user_name in test_users: + # Проверяем существует ли пользователь и удаляем его + user_index = ut.find_user_in_table(user_name, "Администратор") + if user_index != -1: + ut.open_edit_user_page_by_user(user_name, "Администратор") + ut.delete_user(user_name) - def test_sessions_tab_content(self, browser): + def test_sessions_tab_content(self, browser: Page) -> None: """Тест содержимого вкладки 'Сеансы'. Проверяет: @@ -84,20 +111,22 @@ class TestSessionsTab: else: sessions_tab.check_sessions_table_content(verify=True) - # Проверка содержимого таблицы с верификацией данных из БД - # sessions_tab.check_sessions_table_content(verify=True) + # Проверка содержимого таблица с верификацией данных из БД + sessions_tab.check_sessions_table_content(verify=True) - def test_sessions_table_row_highlighting(self, browser): - """Тест содержимого вкладки 'Сеансы'. + def test_sessions_table_row_highlighting(self, browser: Page) -> None: + """Тест подсветки строк таблицы сеансов. Проверяет: 1. Наличие таблицы сеансов - 2. Проверка подсветки строки при наведении на нее курсором + 2. Подсветку строки при наведении курсора на первую строку + 3. Подсветку строки при наведении курсора на последнюю строку (если строк больше одной) + 4. Корректность визуального отображения подсветки строк """ # Инициализация страницы сеансов sessions_tab = SessionsTab(browser) - # Проверка элементов интерфейса + # Проверка наличия таблицы сеансов sessions_tab.should_be_sessions_table() # Получение количества строк в таблице без учета заголовка @@ -113,37 +142,39 @@ class TestSessionsTab: browser.wait_for_timeout(1000) sessions_tab.check_sessions_table_row_highlighting(rows_count - 1) - def test_delete_session_confirm_window(self, browser): - """Тест содержимого вкладки 'Сеансы'. + def test_delete_session_confirm_window(self, browser: Page) -> None: + """Тест окна подтверждения удаления сеанса. Проверяет: 1. Наличие таблицы сеансов - 2. Проверка контента и возможности горизонтального скроллинга окна подтверждения удаления сессии + 2. Содержимое окна подтверждения удаления сеанса + 3. Возможность горизонтального скроллинга в окне подтверждения + 4. Корректность отображения элементов интерфейса в окне подтверждения + 5. Функциональность кнопок в окне подтверждения удаления """ - # Инициализация страницы сеансов 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, cleanup_user): - """Тест содержимого вкладки 'Сеансы'. + @pytest.mark.skip(reason="Не реализовано разработчиком, заведен тикет") + def test_delete_session_after_logout(self, browser: Page, cleanup_users: None) -> None: + """Тест автоматического удаления сеанса после выхода пользователя из системы. Проверяет: 1. Создание нового пользователя 2. Вход нового пользователя в систему - 3. Проверка наличия сессии нового пользователя + 3. Проверка наличия сеанса нового пользователя 4. Выход нового пользователя из системы (logout) - 5. Вход в систему первоначального пользователя - 6. Проверка отсутствия сессии нового пользователя - 7. Удаление нового пользователя + 5. Вход в систему пользователя admin + 6. Проверка отсутствия сеанса нового пользователя + 7. Удаление пользователя выполняется автоматически фикстурой cleanup_users """ - user_data = {"name": "NewUser", "role": "Администратор", "password": "qwerty"} + user_data = {"name": "TestUserForSessionDeletion", "role": "Администратор", "password": "qwerty"} mp = MainPage(browser) ut = UsersTab(browser) @@ -176,10 +207,10 @@ class TestSessionsTab: # Инициализация страницы сеансов st = SessionsTab(browser) - # Проверка элементов интерфейса + # # Проверка наличия таблицы сеансов st.should_be_sessions_table() - # Проверка наличия записи о сессии текущего пользователя + # Проверка наличия записи о сеансе текущего пользователя session_token = st.get_session_token() st.should_be_session_in_table(session_token) @@ -187,25 +218,419 @@ class TestSessionsTab: new_mp.do_logout() # Авторизация в системе предыдущего пользователя - prev_lp = LoginPage(browser) - prev_lp.do_login() + admin_lp = LoginPage(browser) + admin_lp.do_login() # Инициализация главной страницы - prev_mp = MainPage(browser) + admin_mp = MainPage(browser) - # Открыть вкладку Сессии - prev_mp.should_be_navigation_panel() - prev_mp.click_main_navigation_panel_item("Настройки") - prev_mp.click_subpanel_item("Обслуживание и диагностика") - prev_mp.click_subpanel_item("Сеансы") + # Открыть вкладку Сеансы + admin_mp.should_be_navigation_panel() + admin_mp.click_main_navigation_panel_item("Настройки") + admin_mp.click_subpanel_item("Обслуживание и диагностика") + admin_mp.click_subpanel_item("Сеансы") - # Проверка элементов интерфейса - # st.should_be_sessions_table() + # Проверка наличия таблица сеансов + st.should_be_sessions_table() # Проверка отсутствия записи о сессии созданного пользователя после выхода из системы - # st.should_not_be_session_in_table(session_token) + 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"]) + # Удаление пользователя выполняется автоматически фикстурой cleanup_users после теста + + def test_delete_existed_session(self, browser: Page, cleanup_users: None) -> None: + """Тест удаления созданного сеанса. + + Проверяет: + 1. Создание нового пользователя + 2. Вход нового пользователя в систему + 3. Проверка наличия сеанса нового пользователя + 4. Выход нового пользователя из системы (logout) + 5. Вход в систему пользователя admin + 6. Удаление сеанса нового пользователя + 7. Проверка отсутствия сеанса нового пользователя + 8. Удаление пользователя выполняется автоматически фикстурой cleanup_users + """ + user_data = {"name": "TestUserForManualDeletion", "role": "Администратор", "password": "qwerty123"} + + mp = MainPage(browser) + ut = UsersTab(browser) + + # Создание нового пользователя NewUser + mp.click_subpanel_item("Пользователи") + ut.open_add_user_window() + ut.add_new_user(user_data) + + # Обновление списка пользователей (двойной клик - возможно баг?) + mp.click_subpanel_item("Пользователи") + mp.click_subpanel_item("Пользователи") + + # Проверка наличия пользователя в таблице + ut.should_be_user_in_table(user_data["name"], user_data["role"]) + + # Вход в систему для нового пользователя NewUser + 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_subpanel_item("Обслуживание и диагностика") + new_mp.click_subpanel_item("Сеансы") + + # Инициализация страницы сеансов + st = SessionsTab(browser) + + # Проверка наличия таблицы сеансов + st.should_be_sessions_table() + + # Проверка наличия записи о сеансе текущего пользователя + new_user_token = st.get_session_token() + st.should_be_session_in_table(new_user_token) + + # logout + new_mp.do_logout() + + # Авторизация в системе пользователя admin + admin_lp = LoginPage(browser) + admin_lp.do_login() + + # Переход на вкладку Сеансы + admin_mp = MainPage(browser) + admin_mp.should_be_navigation_panel() + admin_mp.click_main_navigation_panel_item("Настройки") + admin_mp.click_subpanel_item("Обслуживание и диагностика") + admin_mp.click_subpanel_item("Сеансы") + + # Удаление сеанса созданного пользователя по токену + admin_sessions_tab = SessionsTab(browser) + admin_sessions_tab.should_be_sessions_table() + admin_sessions_tab.delete_session_by_token(new_user_token) + + # Проверка отсутствия записи о сеансе созданного пользователя после удаления + admin_sessions_tab.should_not_be_session_in_table(new_user_token) + + # Удаление пользователя выполняется автоматически фикстурой cleanup_users после теста + + def test_multiple_users_sessions(self, browser: Page, cleanup_users: None) -> None: + """Тест создания нескольких пользователей и их сеансов. + + Проверяет: + 1. Создание нескольких пользователей User1..User3 + 2. Вход каждого пользователя в систему и создание сеансов + 3. Проверка наличия сеанса в таблице + 4. Проверка скроллинга таблицы с множеством сеансов + 5. Удаление пользователей выполняется автоматически фикстурой cleanup_users + """ + users_data = [ + {"name": "TestUser1", "role": "Администратор", "password": "password1"}, + {"name": "TestUser2", "role": "Администратор", "password": "password2"}, + {"name": "TestUser3", "role": "Администратор", "password": "password3"} + ] + + session_tokens = [] + + mp = MainPage(browser) + ut = UsersTab(browser) + mp.click_subpanel_item("Пользователи") + + # Создание нескольких пользователей + for user_data in users_data: + mp.click_subpanel_item("Пользователи") + mp.click_subpanel_item("Пользователи") + ut.open_add_user_window() + ut.add_new_user(user_data) + + # Проверка наличия пользователя в таблице + ut.should_be_user_in_table(user_data["name"], user_data["role"]) + + # Вход каждого пользователя и получение токенов сеансов + for user_data in users_data: + # Вход новым пользователем + login_page = LoginPage(browser) + login_page.do_login(username=user_data["name"], password=user_data["password"]) + + # Получение токена сеансов + sessions_tab = SessionsTab(browser) + #sessions_tab.should_be_sessions_table() + session_token = sessions_tab.get_session_token() + session_tokens.append(session_token) + + # Возврат администратора для проверки сеансов + login_page = LoginPage(browser) + login_page.do_login() + + mp = MainPage(browser) + mp.click_main_navigation_panel_item("Настройки") + mp.click_subpanel_item("Обслуживание и диагностика") + mp.click_subpanel_item("Сеансы") + + sessions_tab = SessionsTab(browser) + sessions_tab.should_be_sessions_table() + + # Проверка наличия сеансов всех пользователей + for session_token in session_tokens: + sessions_tab.should_be_session_in_table(session_token) + + # Проверка скроллинга таблицы с множеством сеансов + self._test_sessions_table_scrolling(sessions_tab) + + def _test_sessions_table_scrolling(self, sessions_tab: SessionsTab) -> None: + """Вспомогательный метод для проверки скроллинга таблицы сеансов. + + Проверяет: + 1. Возможность вертикального скроллинга таблицы + 2. Видимость первой и последней строк после скроллинга + """ + # Проверка возможности вертикального скроллинга + is_scrollable = sessions_tab.check_sessions_table_verticall_scrolling() + + if is_scrollable: + print("Таблица поддерживает вертикальный скроллинг") + + # Прокрутка вниз + sessions_tab.scroll_sessions_table_down() + + # Проверка видимости последней строки после прокрутки + sessions_tab.check_sessions_table_last_row_visibility() + + # Прокрутка вверх + sessions_tab.scroll_sessions_table_up() + + # Проверка видимости первой строки после прокрутки + sessions_tab.check_sessions_table_first_row_visibility() + else: + print("Таблица не поддерживает вертикальный скроллинг - проверяем базовую функциональность") + + # Проверка видимости первой строки + sessions_tab.check_sessions_table_first_row_visibility() + + @pytest.mark.skip(reason="Не реализовано разработчиком") + def test_session_removed_when_user_deleted(self, browser: Page, cleanup_users: None) -> None: + """Тест удаления сеанса при удалении пользователя. + + Проверяет: + 1. Создание нового пользователя + 2. Вход пользователя и создание сеанса + 3. Удаление пользователя администратором + 4. Проверка автоматического удаления сеанса пользователя + """ + user_data = {"name": "UserForAutoSessionDeletion", "role": "Администратор", "password": "qwerty123"} + + mp = MainPage(browser) + ut = UsersTab(browser) + + # Создание нового пользователя + mp.click_subpanel_item("Пользователи") + ut.open_add_user_window() + ut.add_new_user(user_data) + + # Обновление списка пользователей + mp.click_subpanel_item("Пользователи") + mp.click_subpanel_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_subpanel_item("Обслуживание и диагностика") + new_mp.click_subpanel_item("Сеансы") + + # Получаем токен сессии + sessions_tab = SessionsTab(browser) + new_user_token = sessions_tab.get_session_token() + + # Проверка наличия сессии в таблице + sessions_tab.should_be_session_in_table(new_user_token) + + # Выход из системы нового пользователя + new_mp.do_logout() + + # Авторизация администратором + admin_lp = LoginPage(browser) + admin_lp.do_login() + + # Переход на вкладку Пользователи + admin_mp = MainPage(browser) + admin_mp.click_main_navigation_panel_item("Настройки") + admin_mp.click_subpanel_item("Пользователи") + + # Удаление пользователя + admin_ut = UsersTab(browser) + admin_ut.open_edit_user_page_by_user(user_data["name"], user_data["role"]) + admin_ut.delete_user(user_data["name"]) + + # Переход на вкладку Сеансы + admin_mp.click_main_navigation_panel_item("Настройки") + admin_mp.click_main_navigation_panel_item("Настройки") + admin_mp.click_subpanel_item("Обслуживание и диагностика") + admin_mp.click_subpanel_item("Сеансы") + + # Проверка отсутствия сессии после удаления пользователя + admin_sessions_tab = SessionsTab(browser) + admin_sessions_tab.should_be_sessions_table() + + # Сессия должна автоматически удалиться при удалении пользователя + admin_sessions_tab.should_not_be_session_in_table(new_user_token) + + @pytest.mark.skip(reason="Требует настройки таймера очистки сеансов") + def test_session_auto_deletion_after_15_minutes(self, browser: Page, cleanup_users: None) -> None: + """Тест автоматического удаления сеанса через 15 минут после выхода пользователя. + + Проверяет: + 1. Создание нового пользователя + 2. Вход пользователя и создание сеанса + 3. Выход пользователя из системы + 4. Ожидание 15 минут + 5. Проверка автоматического удаления сеанса по истечении времени + 6. Удаление пользователя выполняется автоматически фикстурой cleanup_users + """ + user_data = {"name": "TestUserFor15MinDeletion", "role": "Администратор", "password": "qwerty123"} + + mp = MainPage(browser) + ut = UsersTab(browser) + + # Создание нового пользователя + mp.click_subpanel_item("Пользователи") + ut.open_add_user_window() + ut.add_new_user(user_data) + + # Обновление списка пользователей + mp.click_subpanel_item("Пользователи") + mp.click_subpanel_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_subpanel_item("Обслуживание и диагностика") + new_mp.click_subpanel_item("Сеансы") + + # Получаем токен сессии + sessions_tab = SessionsTab(browser) + session_token = sessions_tab.get_session_token() + + # Проверка наличия сессии в таблице + sessions_tab.should_be_session_in_table(session_token) + + # Выход из системы нового пользователя + new_mp.do_logout() + + # Авторизация администратором + admin_lp = LoginPage(browser) + admin_lp.do_login() + + # Переход на вкладку Сеансы + admin_mp = MainPage(browser) + admin_mp.should_be_navigation_panel() + admin_mp.click_main_navigation_panel_item("Настройки") + admin_mp.click_subpanel_item("Обслуживание и диагностика") + admin_mp.click_subpanel_item("Сеансы") + + # Проверка наличия сессии сразу после выхода + admin_sessions_tab = SessionsTab(browser) + admin_sessions_tab.should_be_session_in_table(session_token) + + admin_mp.do_logout() + + # Ожидание 15 минут 1 секунда (901 секунд) + print("Ожидание 15 минут для автоматического удаления сеанса...") + browser.wait_for_timeout(901000) # 15 минут 1 секунда в миллисекундах + + # Авторизация администратором + admin_lp = LoginPage(browser) + admin_lp.do_login() + + # Повторный переход на вкладку Сеансы после обновления + admin_mp = MainPage(browser) + admin_mp.should_be_navigation_panel() + admin_mp.click_main_navigation_panel_item("Настройки") + admin_mp.click_subpanel_item("Обслуживание и диагностика") + admin_mp.click_subpanel_item("Сеансы") + + # Проверка отсутствия сессии после 15 минут + admin_sessions_tab = SessionsTab(browser) + admin_sessions_tab.should_be_sessions_table() + admin_sessions_tab.should_not_be_session_in_table(session_token) + + # Удаление пользователя выполняется автоматически фикстурой cleanup_users после теста + + @pytest.mark.skip(reason="Не реализован разработчиком, требует проверки бизнес-логики") + def test_user_cannot_delete_own_session(self, browser: Page, cleanup_users: None) -> None: + """Тест проверки невозможности пользователя удалить свой собственный сеанс. + Проверяет: + 1. Создание нового пользователя + 2. Вход пользователя и создание сеанса + 3. Попытку удаления своего собственного сеанса + 4. Проверку, что кнопка удаления недоступна или скрыта + 5. Удаление пользователя выполняется автоматически фикстурой cleanup_users + """ + user_data = {"name": "TestUserForSelfDeletion", "role": "Администратор", "password": "qwerty123"} + + mp = MainPage(browser) + ut = UsersTab(browser) + + # Создание нового пользователя + mp.click_subpanel_item("Пользователи") + ut.open_add_user_window() + ut.add_new_user(user_data) + + # Обновление списка пользователей + mp.click_subpanel_item("Пользователи") + mp.click_subpanel_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_subpanel_item("Обслуживание и диагностика") + new_mp.click_subpanel_item("Сеансы") + + # Получаем токен сессии + sessions_tab = SessionsTab(browser) + session_token = sessions_tab.get_session_token() + + # Проверка наличия сессии в таблице + sessions_tab.should_be_session_in_table(session_token) + + # Попытка найти кнопку удаления для своего сеанса + row_index = sessions_tab.find_session_in_table(session_token) + + # Проверяем, что кнопка удаления либо отсутствует, либо неактивна + delete_button = sessions_tab.get_delete_session_button_from_row(row_index) + + # Проверяем, что кнопка либо не видима, либо отключена + expect(delete_button).not_to_be_visible() + + # Выход из системы + new_mp.do_logout() + + # Удаление пользователя выполняется автоматически фикстурой cleanup_users после теста