"""Модуль вкладки 'Шаблоны' в модуле 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_ztp_template import ViewZTPTemplateModalWindow 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] = ViewZTPTemplateModalWindow(self.page, title) def get_modal_window(self, title: str) -> ViewZTPTemplateModalWindow: """Возвращает модальное окно по заголовку. Args: title: Заголовок окна. Returns: ViewZTPTemplateModalWindow: Экземпляр модального окна шаблона. 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 = ViewZTPTemplateModalWindow(self.page, "") title = temp_modal.toolbar.get_toolbar_title_text( ModalWindowLocators.MODAL_WINDOW_TITLE ) # Добавляем модальное окно в коллекцию после открытия self.add_modal_window(title) return title 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_ztp_templates_modal_content(self, title: str) -> None: """Проверяет наличие и корректность элементов модального окна шаблона. Args: title: Имя шаблона для проверки заголовка окна. Raises: AssertionError: Если элементы окна некорректны. """ modal_window = self.get_modal_window(title) modal_window.check_content() def check_ztp_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, title: str) -> None: """Проверяет соответствие данных модального окна данным из API. Процесс проверки: 1. Получает модальное окно по имени шаблона 2. Извлекает данные из полей ввода модального окна 3. Отправляет API запрос для получения эталонных данных шаблона 4. Сравнивает данные из UI с данными из API 5. Выбрасывает assertion при обнаружении расхождений Args: title: Имя шаблона для проверки (должно совпадать с id в API). Raises: AssertionError: Если: - Модальное окно не найдено - API запрос завершился с ошибкой (status != 200) - Обнаружены расхождения между данными UI и API - Имя шаблона в модальном окне не соответствует ожидаемому """ # Получаем модальное окно modal_window = self.get_modal_window(title) # Читаем данные модального окна actual_data = modal_window.get_modal_window_data() # Читаем данные из API encoded_title = title.replace(" ", "%20") url = f"e-nms/DHCP/showOptPattern?template={encoded_title}" 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 с данными конкретного шаблона modal_window.compare_modal_with_api_data(actual_data, template_data, title)