from pages.base_page import BasePage from Locators.session_locators import SessionLocators from data.assertions import Assertions from playwright.sync_api import Page, expect import time class SessionTab(BasePage): def __init__(self, page: Page) -> None: super().__init__(page) self.assertions = Assertions(page) self.expected_headers = ['ID сессии', 'ID пользователя', 'Время жизни', 'Роль', 'Адрес'] def should_be_session_table(self) -> None: """ Проверка таблицы сессий """ self.assertions.have_title( SessionLocators.TEXT_TITLE, 'Сессия', "Заголовок страницы не соответствует ожидаемому" ) # Проверка наименования заголовков таблицы сессий session_table_data = self.read_table_data(SessionLocators.TABLE_BODY) actual_headers = session_table_data[0] self.assertions.check_equals(actual_headers, self.expected_headers, "Заголовки таблицы не соответствуют ожидаемым") # Проверка, что таблица не пустая self.assertions.check_not_equals(len(session_table_data) - 1, 0, "Таблица сессий пуста") # Проверка наличия всех необходимых колонок required_columns = [ SessionLocators.TABLE_HEADER_CELL_SESSION_ID, SessionLocators.TABLE_HEADER_CELL_USER_ID, SessionLocators.TABLE_HEADER_CELL_LIFETIME, SessionLocators.TABLE_HEADER_CELL_ROLE, SessionLocators.TABLE_HEADER_CELL_ADDRESS ] for locator in required_columns: self.is_element_present(locator, 1000) def should_be_session_table_data_vs_api(self) -> None: """ Проверка соответствие данных в таблице сессий с данными из API """ ROLE_MAPPING = { 'user': 'Пользователь', 'administrator': 'Администратор' } # Получение данных из UI ui_session_id = self.get_text(SessionLocators.TABLE_HEADER_CELL_SESSION_ID, 0).strip() ui_session_userId = self.get_text(SessionLocators.TABLE_HEADER_CELL_USER_ID, 0).strip() ui_session_roles = self.get_text(SessionLocators.TABLE_HEADER_CELL_ROLE, 0).strip() ui_session_ip = self.get_text(SessionLocators.TABLE_HEADER_CELL_ADDRESS, 0).strip() # Получение данных из API response = self.send_get_api_request("e-nms/auth/sessions") response_body = self.get_response_body(response) api_session_id = response_body[0].get('id') api_session_userId = response_body[0].get('userId') api_session_roles = response_body[0].get('roles', []) api_session_ip = response_body[0].get('ip') # Преобразование и сортировка ролей из API translated_roles = [ROLE_MAPPING.get(role.lower(), role) for role in api_session_roles] api_session_roles_str = ', '.join(sorted(translated_roles)) # Сортировка ролей из UI для сравнения ui_roles_sorted = ', '.join(sorted(role.strip() for role in ui_session_roles.split(','))) # Проверки соответствия данных self.assertions.check_equals(ui_session_id, api_session_id, "ID сессии не совпадает") self.assertions.check_equals(ui_session_userId, api_session_userId, "ID пользователя не совпадает") self.assertions.check_equals(ui_roles_sorted, api_session_roles_str, "Роли не совпадают") self.assertions.check_equals(ui_session_ip, api_session_ip, "IP-адрес не совпадает") # Логирование для отладки #print(f"Session ID (UI/API): {ui_session_id}/{api_session_id}") #print(f"User ID (UI/API): {ui_session_userId}/{api_session_userId}") #print(f"Roles (UI/API): {ui_session_roles}/{api_session_roles}") #print(f"IP Address (UI/API): {ui_session_ip}/{api_session_ip}") def should_be_new_session_added(self) -> None: """ Проверка добавленных записей в таблицу сессий """ def should_be_vertical_scroll_session(self) -> None: """ Проверка вертикального скролла таблицы сессий """ self.should_be_vertical_scroll(SessionLocators.TABLE_SCROLL_CONTAINER) def open_last_session_modal(self) -> None: """Открывает модальное окно удаления через последнюю строку таблицы сессий""" print("\n=== Открытие модального окна через последнюю строку ===") # Ожидаем загрузки таблицы self.page.wait_for_selector(SessionLocators.TABLE_BODY, state="visible", timeout=5000) print("✓ Таблица сессий загружена") # Получаем все строки таблицы rows = self.page.locator(SessionLocators.TABLE_ROWS) row_count = rows.count() if row_count == 0: raise AssertionError("Таблица сессий пуста, нечего удалять!") print(f"Всего строк в таблице: {row_count}") # Берём последнюю строку last_row = rows.last print("✓ Последняя строка получена") # Прокручиваем к последней строке (если нужно) last_row.scroll_into_view_if_needed() # Локатор кнопки удаления в последней строке delete_button = last_row.locator(SessionLocators.BUTTON_DELETE_SESSION) # Проверяем и кликаем кнопку удаления expect(delete_button).to_be_visible(timeout=5000) print("Нажимаем кнопку удаления в последней строке...") delete_button.click() # Проверяем появление модального окна modal = self.page.locator(SessionLocators.MODAL_WINDOW) expect(modal).to_be_visible(timeout=5000) print("✓ Модальное окно удаления успешно открыто") # Проверка заголовка окна if hasattr(SessionLocators, 'MODAL_TITLE'): modal_title = self.page.locator(SessionLocators.MODAL_TITLE) expect(modal_title).to_contain_text("Удаление") print("✓ Заголовок модального окна корректен") print("=== Модальное окно через последнюю строку открыто успешно ===\n") def should_be_horizontal_scroll_session_modal(self) -> None: """ Проверка горизонтального скролла модального окна """ self.should_be_horizontal_scroll() def should_be_close_modal_window_by_button(self, button_type: str) -> None: """ Проверка кнопок модального окна подтверждения удаления сессии с детальным логированием :param button_type: Тип кнопки ('close', 'cancel', 'delete') """ print(f"\n=== Начало проверки модального окна для кнопки '{button_type}' ===") # 1. Проверка видимости модального окна перед действиями modal = self.page.locator(SessionLocators.MODAL_WINDOW) expect(modal).to_be_visible() print("✓ Модальное окно отображается перед взаимодействием") if button_type == 'close': # 2. Нажатие кнопки закрытия (X) print("Нажимаем кнопку закрытия (X)...") close_button = self.page.locator(SessionLocators.MODAL_CLOSE_BUTTON) close_button.click() # 3. Проверка закрытия окна expect(modal).not_to_be_visible() print("✓ Проверяем, что окно закрылось после нажатия 'X'") elif button_type == 'cancel': # 2. Нажатие кнопки "Отмена" print("Нажимаем кнопку 'Отмена'...") cancel_button = self.page.locator(SessionLocators.MODAL_CANCEL_BUTTON) cancel_button.click() # 3. Проверка закрытия окна expect(modal).not_to_be_visible() print("✓ Проверяем, что окно закрылось после нажатия 'Отмена'") elif button_type == 'delete': # 2. Подготовка к удалению rows_before = self.page.locator(SessionLocators.TABLE_ROWS).count() print(f"Количество строк до удаления: {rows_before}") # 3. Нажатие кнопки "Удалить" print("Нажимаем кнопку 'Удалить'...") delete_button = self.page.locator(SessionLocators.MODAL_DELETE_BUTTON) delete_button.click() """ # 4. Проверка сообщения об успехе success_msg = self.page.locator(SessionLocators.SUCCESS_MESSAGE) expect(success_msg).to_be_visible(timeout=5000) expect(success_msg).to_contain_text("Сессия успешно удалена") print("✓ Сообщение об успешном удалении отображается") """ # 5. Проверка закрытия окна expect(modal).not_to_be_visible() print("✓ Проверяем, что окно закрылось после нажатия 'Удалить'") """ # 6. Проверка исчезновения сообщения (если нужно) expect(success_msg).not_to_be_visible(timeout=10000) print("✓ Сообщение автоматически скрылось (если предусмотрено UI)") """ # 7. Проверка изменения таблицы rows_after = self.page.locator(SessionLocators.TABLE_ROWS).count() self.assertions.check_equals(rows_after, rows_before - 1, "Количество строк не изменилось после удаления") print(f"✓ Количество строк после удаления: {rows_after} (уменьшилось на 1)") print(f"=== Проверка для кнопки '{button_type}' успешно завершена ===\n") def delete_all_created_sessions(self, username) -> None: """ Проверка удаления созданных ссесий """ def delete_current_session(self) -> None: """ Проверка удаления текущей сессии """