diff --git a/components_derived/modal_view_template.py b/components_derived/modal_view_template.py index a53e5f0..ed582fc 100644 --- a/components_derived/modal_view_template.py +++ b/components_derived/modal_view_template.py @@ -7,6 +7,7 @@ import re from playwright.sync_api import Page from tools.logger import get_logger +from locators.modal_window_locators import ModalWindowLocators from components.modal_window_component import ModalWindowComponent @@ -25,7 +26,6 @@ class ViewTemplateModalWindow(ModalWindowComponent): def __init__(self, page: Page, template_name: str): """Инициализирует элементы формы модального окна шаблона.""" - super().__init__(page) # Настройка заголовка и кнопки закрытия @@ -37,12 +37,18 @@ class ViewTemplateModalWindow(ModalWindowComponent): self.add_toolbar_title(self.window_title) self.add_toolbar_button(locator_button_toolbar_close, "close") + locator_button_close = self.page.get_by_role("button", name="Закрыть") + self.add_button(locator_button_close, "close") + def close_window(self) -> None: """Закрывает окно через кнопку 'Закрыть'.""" - close_button = self.get_button_by_name("close") close_button.click() + def close_window_by_toolbar_button(self): + """Закрывает окно через кнопку в тулбаре.""" + self.click_toolbar_close_button() + def check_content(self) -> None: """Проверяет наличие и корректность элементов окна. @@ -51,24 +57,111 @@ class ViewTemplateModalWindow(ModalWindowComponent): 2. Видимость кнопки закрытия 3. Подсказку кнопки закрытия """ - self.check_by_window_title() self.check_toolbar_button_visibility("close") self.check_toolbar_button_tooltip("close", "Закрыть") - # Разрабатывается ========================================================= - def _get_config_data(self) -> dict: - """Получает конфигурационные данные из модального окна. + def get_modal_window_data(self) -> dict: + """Извлекает данные из модального окна шаблона и структурирует по кодам и значениям. Returns: - dict: Словарь с конфигурационными данными или пустой словарь + dict: Данные в формате {'код': 'значение'} как в API """ - config_data = {} + modal_data = {} - # Ищем контейнер с конфигурационными данными - config_container = self.page.locator( - "//*[@id='app']/div[2]/div/div/div/div/div/div/div/div/div[2]/div/div/div" - ) + # Получаем все значения из input полей + input_locator = self.get_locator(ModalWindowLocators.MODAL_WINDOW_TEXT_FIELD_INPUT) - return config_data + # Проверка наличия элементов + input_count = input_locator.count() + if input_count == 0: + logger.warning("Поля ввода не найдены в модальном окне") + return modal_data + all_values = [] + + # Обрабатываем каждое поле с обработкой возможных ошибок + for i in range(input_count): + input_field = input_locator.nth(i) + + # Проверяем, что элемент видим и доступен + if not input_field.is_visible(): + logger.debug("Поле %s не видимо, пропускаем", i) + continue + + # Получаем значение с обработкой возможных ошибок состояния элемента + if input_field.is_visible(): + value = input_field.input_value().strip() + if value: # Игнорируем пустые значения + all_values.append(value) + else: + logger.debug("Поле %s стало невидимым после проверки, пропускаем", i) + + logger.info("Все значения из полей: %s", all_values) + + # Анализируем пары код-значение + i = 0 + while i < len(all_values) - 1: + current_value = all_values[i] + next_value = all_values[i + 1] + + # Определяем, является ли текущее значение кодом (число) + if current_value.isdigit(): + # Текущее значение - код, следующее - значение + modal_data[current_value] = next_value + i += 2 # Перескакиваем через пару + else: + # Если текущее значение не число, ищем следующую пару + i += 1 + + # Добавляем имя шаблона с ключом 'Шаблон' вместо 'template' + if all_values: + modal_data['Шаблон'] = all_values[-1] + + logger.info("Структурированные данные из модального окна: %s", modal_data) + return modal_data + + def compare_modal_with_api_data(self, modal_data: dict, api_data: dict, + template_name: str) -> None: + """Сравнивает данные из модального окна с данными из API.""" + errors = [] + + # Создаем копию API данных с заменой 'template' на 'Шаблон' + api_data_adapted = api_data.copy() + if 'template' in api_data_adapted: + api_data_adapted['Шаблон'] = api_data_adapted.pop('template') + + # Сравниваем все поля + for code, expected_value in api_data_adapted.items(): + if code in modal_data: + actual_value = modal_data[code] + if actual_value != expected_value: + error_msg = ( + f"Расхождение для кода {code}: " + f"модальное окно='{actual_value}', API='{expected_value}'" + ) + logger.error(error_msg) + errors.append(error_msg) + else: + error_msg = f"Код {code} не найден в модальном окне" + logger.error(error_msg) + errors.append(error_msg) + + # Дополнительная проверка имени шаблона + modal_template = modal_data.get('Шаблон', '') + if modal_template != template_name: + error_msg = ( + f"Расхождение в имени шаблона: " + f"модальное окно='{modal_template}', ожидается='{template_name}'" + ) + logger.error(error_msg) + errors.append(error_msg) + + # Если есть расхождения, выбрасываем ошибку + if errors: + error_details = "\n".join(errors) + assert False, ( + f"Обнаружены расхождения для шаблона '{template_name}':\n{error_details}" + ) + + logger.info("Данные модального окна соответствуют API для шаблона '%s'", template_name) diff --git a/locators/modal_window_locators.py b/locators/modal_window_locators.py index 917c62f..d30043c 100644 --- a/locators/modal_window_locators.py +++ b/locators/modal_window_locators.py @@ -14,11 +14,14 @@ class ModalWindowLocators: MENU_INPUT_FORM_USER_DATA (str): меню выбора ролей LABEL_INPUT_FORM_USER_DATA (str): метки поля ввода MODAL_WINDOW_SCROLL_CONTAINER (str): контейнера с прокруткой модального окна + MODAL_WINDOW_TITLE (str): заголовка тулбара + MODAL_WINDOW_TEXT_FIELD_INPUT (str): текстового поля ввода """ MODAL_WINDOW = "//div[contains(@class, 'v-dialog--active')]" MODAL_WINDOW_SCROLL_CONTAINER = f"{MODAL_WINDOW}//div[contains(@class, 'scrollarea__body')]" - + MODAL_WINDOW_TITLE = f"{MODAL_WINDOW}//div[contains(@class, 'v-toolbar__title')]" + MODAL_WINDOW_TEXT_FIELD_INPUT = f"{MODAL_WINDOW}//input" INPUT_FORM_USER_DATA = "//form[@class='v-form']" TEXT_FIELD_INPUT_FORM_USER_DATA = "xpath=div[2]/div/div/div/div/input" diff --git a/pages/ztp_templates_tab.py b/pages/ztp_templates_tab.py new file mode 100644 index 0000000..acf5595 --- /dev/null +++ b/pages/ztp_templates_tab.py @@ -0,0 +1,312 @@ +"""Модуль вкладки 'Шаблоны' в модуле Zero Touch Provisioning. + +Содержит класс ZTPTemplatesTab для работы с таблицей шаблонов. +Позволяет проверять состояние и взаимодействовать с элементами вкладки. +""" + +from playwright.sync_api import Page +from tools.logger import get_logger +from locators.table_locators import TableLocators +from locators.modal_window_locators import ModalWindowLocators +from components_derived.modal_view_template import ViewTemplateModalWindow +from components.modal_window_component import ModalWindowComponent +from components.toolbar_component import ToolbarComponent +from components.table_component import TableComponent +from pages.base_page import BasePage + +logger = get_logger("ZTP_TEMPLATES_TAB") + + +class ZTPTemplatesTab(BasePage): + """Класс для работы с вкладкой 'Шаблоны' в модуле Zero Touch Provisioning. + + Предоставляет методы для взаимодействия с таблицей шаблонов, модальными окнами + и проверки состояния элементов интерфейса. Включает функциональность для: + - Работы с таблицей шаблонов (прокрутка, проверка строк, выделение) + - Управления модальными окнами просмотра шаблонов + - Сравнения данных UI с API ответами + + Args: + page (Page): Экземпляр страницы Playwright. + """ + + def __init__(self, page: Page) -> None: + """Инициализирует компоненты вкладки 'Шаблоны'.""" + super().__init__(page) + + self.toolbar = ToolbarComponent(page, "Шаблоны") + self.ztp_templates_table = TableComponent(page) + self.modal_windows = {} + + def add_modal_window(self, title: str) -> None: + """Добавляет модальное окно в коллекцию. + + Args: + title: Заголовок окна. + """ + self.modal_windows[title] = ViewTemplateModalWindow(self.page, title) + + def get_modal_window(self, title: str) -> ViewTemplateModalWindow: + """Возвращает модальное окно по заголовку. + + Args: + title: Заголовок окна. + + Returns: + ViewTemplateModalWindow: Экземпляр модального окна шаблона. + + Raises: + AssertionError: Если окно не найдено. + """ + modal_window = self.modal_windows.get(title) + + if modal_window is None: + assert False, f"Modal window with title '{title}' not found" + return modal_window + + def delete_modal_window(self, title: str) -> None: + """Удаляет модальное окно из коллекции. + + Args: + title: Заголовок окна. + + Raises: + AssertionError: Если окно не найдено. + """ + if self.modal_windows.get(title) is None: + assert False, f"Modal window with title '{title}' not found" + self.modal_windows[title] = None + + def open_template_modal_by_index(self, row_index: int = 0) -> str: + """Открывает модальное окно шаблона по клику на строку таблицы. + + Args: + row_index: Индекс строки для клика (по умолчанию 0 - первая строка). + + Returns: + str: Имя шаблона. + """ + row_locator = self.ztp_templates_table.get_row_locator( + TableLocators.TABLE_WORK_AREA, row_index + ) + row_locator.click() + + # Создаем временный экземпляр модального окна для получения заголовка + temp_modal = ViewTemplateModalWindow(self.page, "") + template_name = temp_modal.toolbar.get_toolbar_title_text( + ModalWindowLocators.MODAL_WINDOW_TITLE + ) + + # Добавляем модальное окно в коллекцию после открытия + self.add_modal_window(template_name) + return template_name + + def close_modal_window_by_toolbar_button(self, title: str) -> None: + """Закрывает модальное окно через кнопку в тулбаре. + + Args: + title: Заголовок окна. + """ + modal_window = self.get_modal_window(title) + modal_window.close_window_by_toolbar_button() + self.delete_modal_window(title) + + def close_modal_window(self, title: str) -> None: + """Закрывает модальное окно через кнопку 'Закрыть'. + + Args: + title: Заголовок окна. + """ + modal_window = self.get_modal_window(title) + modal_window.close_window() + self.delete_modal_window(title) + + def get_rows_count(self) -> int: + """Возвращает количество строк в таблице (без заголовка). + + Returns: + int: Количество строк с данными. + + Raises: + AssertionError: Если таблица пуста. + """ + return self.ztp_templates_table.get_rows_count(TableLocators.TABLE_WORK_AREA) + + def scroll_templates_table_up(self) -> None: + """Прокручивает таблицу шаблонов вверх.""" + self.ztp_templates_table.scroll_up(TableLocators.TABLE_SCROLL_CONTAINER) + + def scroll_templates_table_down(self) -> None: + """Прокручивает таблицу шаблонов вниз.""" + self.ztp_templates_table.scroll_down(TableLocators.TABLE_SCROLL_CONTAINER) + + def scroll_modal_up(self) -> None: + """Прокручивает содержимое модального окна вверх.""" + temp_modal = ModalWindowComponent(self.page) + temp_modal.scroll_window_up() + + def scroll_modal_down(self) -> None: + """Прокручивает содержимое модального окна вниз.""" + temp_modal = ModalWindowComponent(self.page) + temp_modal.scroll_window_down() + + def check_templates_modal_content(self, template_name: str) -> None: + """Проверяет наличие и корректность элементов модального окна шаблона. + + Args: + template_name: Имя шаблона для проверки заголовка окна. + + Raises: + AssertionError: Если элементы окна некорректны. + """ + modal_window = self.get_modal_window(template_name) + modal_window.check_content() + + def check_templates_table_content(self) -> None: + """Проверяет содержимое таблицы шаблонов. + + Проверяет заголовки и наличие данных в таблице. + + Raises: + AssertionError: Если таблица пуста или заголовки неверны. + """ + expected_headers = [ + 'Производитель', + 'vendorCode', + 'authentication', + 'deviceType', + 'authenticationOption' + ] + + self.ztp_templates_table.check_content(TableLocators.TABLE_WORK_AREA, expected_headers) + + def check_templates_table_vertical_scrolling(self) -> bool: + """Проверяет возможность вертикальной прокрутки таблицы. + + Returns: + bool: True если прокрутка возможна, иначе False. + """ + return self.ztp_templates_table.is_scrollable_vertically( + TableLocators.TABLE_SCROLL_CONTAINER + ) + + def check_templates_table_first_row_visibility(self) -> None: + """Проверяет видимость первой строки таблицы. + + Raises: + AssertionError: Если строка не видна. + """ + self.ztp_templates_table.check_first_row_visibility(TableLocators.TABLE_WORK_AREA) + + def check_templates_table_last_row_visibility(self) -> None: + """Проверяет видимость последней строки таблицы. + + Raises: + AssertionError: Если строка не видна. + """ + self.ztp_templates_table.check_last_row_visibility(TableLocators.TABLE_WORK_AREA) + + def check_templates_table_row_highlighting(self, row_index: int) -> None: + """Проверяет выделение указанной строки таблицы. + + Args: + row_index: Индекс проверяемой строки. + + Raises: + AssertionError: Если строка не выделена. + """ + self.ztp_templates_table.check_row_highlighting( + TableLocators.TABLE_WORK_AREA, row_index + ) + + def should_be_toolbar(self) -> None: + """Проверяет наличие тулбара на вкладке. + + Raises: + AssertionError: Если тулбар отсутствует. + """ + self.toolbar.check_toolbar_presence("Toolbar is missing") + + def should_be_templates_table(self) -> None: + """Проверяет наличие таблицы шаблонов. + + Raises: + AssertionError: Если таблица отсутствует. + """ + self.ztp_templates_table.check_visibility( + TableLocators.TABLE_WORK_AREA, "Templates table is missing" + ) + + def should_be_modal_window(self) -> None: + """Проверяет наличие модального окна. + + Raises: + AssertionError: Если модальное окно отсутствует. + """ + self.ztp_templates_table.check_visibility( + ModalWindowLocators.MODAL_WINDOW, "Modal window is not visible" + ) + + def should_not_be_modal_window(self) -> None: + """Проверяет, что модальное окно отсутствует. + + Raises: + AssertionError: Если модальное окно все еще видно. + """ + is_visible = self.page.locator( + ModalWindowLocators.MODAL_WINDOW + ).is_visible(timeout=1000) + if is_visible: + assert False, "Modal window should not be visible" + + def check_modal_vertical_scrolling(self) -> bool: + """Проверяет возможность вертикального скроллинга в модальном окне. + + Returns: + bool: True если скроллинг возможен, иначе False. + """ + temp_modal = ModalWindowComponent(self.page) + return temp_modal.check_window_vertical_scrolling() + + def verify_template_data_with_api(self, template_name: str) -> None: + """Проверяет соответствие данных модального окна данным из API. + + Процесс проверки: + 1. Получает модальное окно по имени шаблона + 2. Извлекает данные из полей ввода модального окна + 3. Отправляет API запрос для получения эталонных данных шаблона + 4. Сравнивает данные из UI с данными из API + 5. Выбрасывает assertion при обнаружении расхождений + + Args: + template_name: Имя шаблона для проверки (должно совпадать с id в API). + + Raises: + AssertionError: Если: + - Модальное окно не найдено + - API запрос завершился с ошибкой (status != 200) + - Обнаружены расхождения между данными UI и API + - Имя шаблона в модальном окне не соответствует ожидаемому + """ + # Получаем модальное окно + modal_window = self.get_modal_window(template_name) + + # Читаем данные модального окна (метод теперь в ViewTemplateModalWindow) + actual_data = modal_window.get_modal_window_data() + + # Читаем данные из API + encoded_template_name = template_name.replace(" ", "%20") + url = f"e-nms/DHCP/showOptPattern?template={encoded_template_name}" + response = self.send_get_api_request(url) + + # Проверяем статус ответа + if response.status != 200: + logger.error("API request failed with status: %s", response.status) + assert False, f"API request failed with status: {response.status}" + + # Извлекаем данные из ответа + response_data = response.json() + template_data = response_data['data'] + + # Сравниваем actual_data с данными конкретного шаблона (метод теперь в ViewTemplateModalWindow) + modal_window.compare_modal_with_api_data(actual_data, template_data, template_name) diff --git a/tests/e2e/test_ztp_templates_tab.py b/tests/e2e/test_ztp_templates_tab.py new file mode 100644 index 0000000..50d87bc --- /dev/null +++ b/tests/e2e/test_ztp_templates_tab.py @@ -0,0 +1,326 @@ +"""Модуль тестов вкладки 'Шаблоны' в модуле Zero Touch Provisioning. + +Содержит тесты для проверки функциональности +работы с шаблонами. +""" +import pytest + +from playwright.sync_api import Page +from pages.login_page import LoginPage +from pages.main_page import MainPage +from pages.ztp_templates_tab import ZTPTemplatesTab + + +class TestZTPTemplatesTab: + """Набор тестов для вкладки 'Шаблоны' в модуле Zero Touch Provisioning. + + Проверяет корректность отображения, функциональность элементов интерфейса + и консистентность данных между UI и API на вкладке шаблонов ZTP. + + Тесты покрывают следующие функциональные области: + 1. test_templates_tab_content - Базовая структура и содержимое вкладки + 2. test_templates_table_row_highlighting - Визуальное выделение строк таблицы + 3. test_templates_table_scrolling - Навигация по таблице с большим объемом данных + 4. test_templates_modal_window_close_buttons - Закрытие модальных окон разными способами + 5. test_templates_modal_window_content - Структура и содержимое модальных окон + 6. test_templates_modal_window_scrolling - Навигация в модальных окнах + 7. test_templates_modal_window_api_data_consistency - Синхронизация данных UI и API + + Фикстура setup обеспечивает подготовку тестового окружения: + - Авторизацию в системе + - Навигацию к целевой вкладке через панель настроек + - Инициализацию необходимых компонентов страницы + """ + + @pytest.fixture(scope="function", autouse=True) + def setup(self, browser: Page) -> None: + """Фикстура для подготовки тестового окружения. + + Выполняет: + 1. Авторизацию в системе + 2. Переход на вкладку 'Шаблоны' через панель навигации + """ + # Авторизация в системе + login_page = LoginPage(browser) + login_page.do_login() + + # Инициализация главной страницы + main_page = MainPage(browser) + + # Проверка и взаимодействие с элементами навигации + main_page.should_be_navigation_panel() + main_page.click_main_navigation_panel_item("Настройки") + main_page.click_subpanel_item("Zero Touch Provisioning") + main_page.click_subpanel_item("Шаблоны", parent="Zero Touch Provisioning") + main_page.wait_for_timeout(5000) + + #@pytest.mark.skip(reason=" Временно исключено из тестирования") + def test_templates_tab_content(self, browser: Page) -> None: + """Тест содержимого вкладки 'Шаблоны'. + + Проверяет: + 1. Наличие и корректность тулбара + 2. Наличие таблицы шаблонов + 3. Соответствие содержимого таблицы + """ + # Инициализация страницы сеансов + ztp_templates_tab = ZTPTemplatesTab(browser) + + # Проверка тулбара вкладки + ztp_templates_tab.should_be_toolbar() + + # Проверка наличия таблицы шаблонов + ztp_templates_tab.should_be_templates_table() + + browser.wait_for_timeout(5000) + + # Проверка содержимого таблицы шаблонов + ztp_templates_tab.check_templates_table_content() + + #@pytest.mark.skip(reason=" Временно исключено из тестирования") + def test_templates_table_row_highlighting(self, browser: Page) -> None: + """Проверка выделения строк в таблице шаблонов. + + Проверяет корректность выделения строк при клике на различные позиции: + 1. Первая строка + 2. Последняя строка + 3. Строка в середине таблицы + """ + + ztp_templates_tab = ZTPTemplatesTab(browser) + + # Проверка тулбара вкладки + ztp_templates_tab.should_be_toolbar() + + # Проверка наличия таблицы шаблонов + ztp_templates_tab.should_be_templates_table() + + # Получение количества строк в таблице + rows_count = ztp_templates_tab.get_rows_count() + + # Проверка выделения строк + ztp_templates_tab.check_templates_table_row_highlighting(0) + ztp_templates_tab.check_templates_table_row_highlighting(rows_count - 1) + ztp_templates_tab.check_templates_table_row_highlighting(int(rows_count / 2)) + + #@pytest.mark.skip(reason=" Временно исключено из тестирования") + def test_templates_table_scrolling(self, browser: Page) -> None: + """Проверка вертикального скроллинга таблицы шаблонов. + + Проверяет: + 1. Возможность вертикальной прокрутки таблицы + 2. Видимость строк после прокрутки вниз и вверх + 3. Корректность отображения данных после скроллинга + """ + + ztp_templates_tab = ZTPTemplatesTab(browser) + + browser.wait_for_timeout(2000) + + # Проверка возможности вертикального скроллинга + is_scrollable = ztp_templates_tab.check_templates_table_vertical_scrolling() + + if is_scrollable: + print("Таблица поддерживает вертикальный скроллинг") + + # Прокрутка вниз + ztp_templates_tab.scroll_templates_table_down() + + browser.wait_for_timeout(1000) + + # Проверка видимости последней строки после прокрутки + ztp_templates_tab.check_templates_table_last_row_visibility() + + # Прокрутка вверх + ztp_templates_tab.scroll_templates_table_up() + + browser.wait_for_timeout(1000) + + # Проверка видимости первой строки после прокрутки + ztp_templates_tab.check_templates_table_first_row_visibility() + else: + print("Таблица не поддерживает вертикальный скроллинг") + + # Проверка видимости первой строки + ztp_templates_tab.check_templates_table_first_row_visibility() + + #@pytest.mark.skip(reason=" Временно исключено из тестирования") + def test_templates_modal_window_close_buttons(self, browser: Page) -> None: + """Тест закрытия модального окна шаблона разными способами. + + Проверяет: + 1. Закрытие модального окна через кнопку 'Закрыть' в содержимом окна + 2. Закрытие модального окна через кнопку закрытия в тулбаре + 3. Корректность закрытия окна в обоих случаях + + Args: + browser (Page): Экземпляр страницы Playwright для взаимодействия с UI. + """ + # Инициализация страницы шаблонов + ztp_templates_tab = ZTPTemplatesTab(browser) + + # Проверка наличия таблицы шаблонов + ztp_templates_tab.should_be_templates_table() + + # Добавляем задержку для загрузки данных + browser.wait_for_timeout(2000) + + # Тест 1: Закрытие через кнопку 'Закрыть' в содержимом окна + print("Тест 1: Закрытие через кнопку 'Закрыть'") + template_name = ztp_templates_tab.open_template_modal_by_index(0) + browser.wait_for_timeout(1000) + + # Проверка открытия модального окна + ztp_templates_tab.should_be_modal_window() + + # Закрытие через кнопку 'Закрыть' + ztp_templates_tab.close_modal_window(template_name) + + # Проверяем, что модальное окно закрылось + ztp_templates_tab.should_not_be_modal_window() + browser.wait_for_timeout(1000) + + # Тест 2: Закрытие через кнопку в тулбаре + print("Тест 2: Закрытие через кнопку в тулбаре") + template_name = ztp_templates_tab.open_template_modal_by_index(0) + browser.wait_for_timeout(1000) + + # Проверка открытия модального окна + ztp_templates_tab.should_be_modal_window() + + # Закрытие через кнопку в тулбаре + ztp_templates_tab.close_modal_window_by_toolbar_button(template_name) + + # Проверяем, что модальное окно закрылось + ztp_templates_tab.should_not_be_modal_window() + + print("Оба способа закрытия модального окна работают корректно") + + #@pytest.mark.skip(reason=" Временно исключено из тестирования") + def test_templates_modal_window_content(self, browser: Page) -> None: + """Тест содержимого модального окна шаблона. + + Проверяет: + 1. Открытие модального окна при клике на строку таблицы + 2. Наличие и содержимое модального окна + 3. Наличие тулбара в модальном окне + 4. Проверка кнопки закрытия и её подсказки + 5. Закрытие модального окна + """ + # Инициализация страницы шаблонов + ztp_templates_tab = ZTPTemplatesTab(browser) + + # Проверка наличия таблицы шаблонов + ztp_templates_tab.should_be_templates_table() + + # Добавляем задержку для загрузки данных + browser.wait_for_timeout(2000) + + # Открываем модальное окно, кликая на первую строку таблицы + template_name = ztp_templates_tab.open_template_modal_by_index(0) + + # Добавляем задержку для открытия модального окна + browser.wait_for_timeout(1000) + + # Проверка открытия модального окна + ztp_templates_tab.should_be_modal_window() + + # Проверка содержимого модального окна + ztp_templates_tab.check_templates_modal_content(template_name) + + # Закрытие модального окна через кнопку 'Закрыть' + ztp_templates_tab.close_modal_window(template_name) + + # Проверяем, что модальное окно закрылось + ztp_templates_tab.should_not_be_modal_window() + + #@pytest.mark.skip(reason=" Временно исключено из тестирования") + def test_templates_modal_window_scrolling(self, browser: Page) -> None: + """Тест скроллинга модального окна шаблона. + + Проверяет: + 1. Открытие модального окна при клике на строку таблицы + 2. Возможность вертикального скроллинга содержимого модального окна + 3. Закрытие модального окна + """ + + # Инициализация страницы шаблонов + ztp_templates_tab = ZTPTemplatesTab(browser) + + # Проверка наличия таблицы шаблонов + ztp_templates_tab.should_be_templates_table() + + # Добавляем задержку для загрузки данных + browser.wait_for_timeout(2000) + + # Открываем модальное окно, кликая на первую строку таблицы + template_name = ztp_templates_tab.open_template_modal_by_index(0) + + # Добавляем задержку для открытия модального окна + browser.wait_for_timeout(1000) + + # Проверка открытия модального окна + ztp_templates_tab.should_be_modal_window() + + # Проверка вертикального скроллинга модального окна + is_scrollable = ztp_templates_tab.check_modal_vertical_scrolling() + + if is_scrollable: + print("Модальное окно поддерживает вертикальный скроллинг") + + # Прокрутка вниз модального окна + ztp_templates_tab.scroll_modal_down() + browser.wait_for_timeout(1000) + + # Прокрутка вверх модального окна + ztp_templates_tab.scroll_modal_up() + browser.wait_for_timeout(1000) + else: + print("Модальное окно не поддерживает вертикальный скроллинг") + + # Закрытие модального окна через кнопку 'Закрыть' + ztp_templates_tab.close_modal_window(template_name) + + # Проверяем, что модальное окно закрылось + ztp_templates_tab.should_not_be_modal_window() + + #@pytest.mark.skip(reason=" Временно исключено из тестирования") + def test_templates_modal_window_api_data_consistency(self, browser: Page) -> None: + """Тест соответствия данных модального окна шаблона данным из API. + + Проверяет консистентность данных между интерфейсом пользователя и API: + 1. Открытие модального окна просмотра шаблона по клику на строку таблицы + 2. Получение и валидация данных из полей модального окна + 3. Сравнение данных UI с эталонными данными из API запроса + 4. Проверка корректности отображения всех параметров шаблона + 5. Закрытие модального окна после проверки + + Args: + browser (Page): Экземпляр страницы Playwright для взаимодействия с UI. + """ + # Инициализация страницы шаблонов + ztp_templates_tab = ZTPTemplatesTab(browser) + + # Проверка наличия таблицы шаблонов + ztp_templates_tab.should_be_templates_table() + + # Добавляем задержку для загрузки данных + browser.wait_for_timeout(5000) + + # Открываем модальное окно, кликая на первую строку таблицы и возвращаем имя заголовка + template_name = ztp_templates_tab.open_template_modal_by_index(0) + + # Добавляем задержку для открытия модального окна + browser.wait_for_timeout(2000) + + # Проверка открытия модального окна + ztp_templates_tab.should_be_modal_window() + + # Проверка соответствия данных модального окна данным из API + ztp_templates_tab.verify_template_data_with_api(template_name) + + # Закрытие модального окна через кнопку закрытия + ztp_templates_tab.close_modal_window_by_toolbar_button(template_name) + + # Проверяем, что модальное окно закрылось + ztp_templates_tab.should_not_be_modal_window()