"""Модуль вкладки 'Конфигурация' в модуле Zero Touch Provisioning. Содержит класс ZTPConfigTab для работы с таблицей конфигурации ZTP. Позволяет проверять состояние и взаимодействовать с элементами вкладки. """ from playwright.sync_api import Page, Locator from tools.logger import get_logger from locators.table_locators import TableLocators from components.toolbar_component import ToolbarComponent from components.table_component import TableComponent from pages.base_page import BasePage logger = get_logger("ZTP_CONFIG_TAB") class ZTPConfigTab(BasePage): """Класс для работы с вкладкой 'Конфигурация' в модуле Zero Touch Provisioning. Предоставляет методы для взаимодействия с таблицей конфигурации ZTP и проверки состояния элементов интерфейса. Включает функциональность для: - Проверки содержимого и структуры таблицы конфигурации - Прокрутки таблицы и проверки видимости строк - Выделения строк таблицы - Работы с кнопкой синхронизации (Reload) в заголовке таблицы - Проверки видимости и подсказок кнопок синхронизации Args: page (Page): Экземпляр страницы Playwright. """ def __init__(self, page: Page) -> None: """Инициализирует компоненты вкладки 'Конфигурация'. Args: page: Экземпляр страницы Playwright для взаимодействия с браузером. """ super().__init__(page) # Компонент тулбара вкладки конфигурации self.toolbar = ToolbarComponent(page, "Конфигурация") # Компонент таблицы конфигурации ZTP self.ztp_config_table = TableComponent(page) # Словарь для хранения кнопок синхронизации по индексам self.sync_buttons = {} def get_rows_count(self) -> int: """Возвращает количество строк в таблице конфигурации (без заголовка). Returns: int: Количество строк с данными конфигурации ZTP. Raises: AssertionError: Если таблица пуста или не загружена. """ return self.ztp_config_table.get_rows_count(TableLocators.TABLE_WORK_AREA) def scroll_config_table_up(self) -> None: """Прокручивает таблицу конфигурации вверх до начала.""" self.ztp_config_table.scroll_up(TableLocators.TABLE_SCROLL_CONTAINER) def scroll_config_table_down(self) -> None: """Прокручивает таблицу конфигурации вниз до конца.""" self.ztp_config_table.scroll_down(TableLocators.TABLE_SCROLL_CONTAINER) def check_config_table_content(self) -> None: """Проверяет содержимое таблицы конфигурации ZTP. Проверяет соответствие заголовков таблицы ожидаемым значениям и наличие данных в таблице. Raises: AssertionError: Если таблица пуста или заголовки не соответствуют ожидаемым. """ # Ожидаемые заголовки столбцов таблицы конфигурации ZTP expected_headers = [ 'sync', 'IDENTIFIER', 'MAC', 'DHCPRELAY', 'ШАБЛОН', 'IPSETTODEVICE', 'СТАТУС', 'ДЕЙСТВИЯ' ] self.ztp_config_table.check_content( TableLocators.TABLE_WORK_AREA, expected_headers, False ) def should_be_config_table(self) -> None: """Проверяет наличие и видимость таблицы конфигурации ZTP. Raises: AssertionError: Если таблица конфигурации отсутствует на странице. """ self.ztp_config_table.check_visibility( TableLocators.TABLE_WORK_AREA, "Configuration table is missing" ) def get_sync_button(self, index: int) -> Locator: """Получает кнопку синхронизации (Reload) по индексу ячейки заголовка таблицы. Args: index: Индекс ячейки в заголовке таблицы (0-based). Returns: Locator: Локатор кнопки синхронизации (Reload) для взаимодействия. Raises: AssertionError: Если индекс выходит за пределы диапазона ячеек или кнопка не найдена в указанной ячейке. """ table_locator = TableLocators.TABLE_WORK_AREA # Получаем локатор таблицы через компонент таблицы table = self.ztp_config_table.get_locator(table_locator) # Проверяем количество ячеек в заголовке таблицы header_cells_count = table.locator("//thead/tr/th").count() assert index in range(header_cells_count), "Header cell index is out of range" # Ищем кнопку в указанной ячейке заголовка sync_button = table.locator("//thead/tr/th").nth(index).get_by_role("button") assert sync_button.is_enabled(), f"Sync button is missing in {index} header cell" return sync_button def add_sync_button_to_toolbar(self, index: int) -> None: """Добавляет кнопку синхронизации (Reload) в тулбар для управления подсказками. Регистрирует кнопку в компоненте тулбара, что позволяет использовать стандартные методы проверки подсказок. Args: index: Индекс ячейки в заголовке таблицы. """ sync_button = self.get_sync_button(index) button_name = f"sync_button_{index}" # Добавляем кнопку в тулбар компонент как кнопку с подсказкой self.toolbar.add_tooltip_button(sync_button, button_name) # Сохраняем связь между индексом и именем кнопки для последующего доступа self.sync_buttons[index] = button_name logger.info("Кнопка синхронизации (Reload) добавлена в тулбар как '%s'", button_name) def check_sync_button_visibility(self, index: int) -> None: """Проверяет видимость кнопки синхронизации (Reload) в указанной ячейке заголовка. Args: index: Индекс ячейки в заголовке таблицы. Raises: AssertionError: Если кнопка не видна на странице. """ sync_button = self.get_sync_button(index) # Прокручиваем к элементу для гарантии видимости sync_button.scroll_into_view_if_needed() # Проверяем видимость кнопки assert sync_button.is_visible(), f"Sync button in header cell {index} is not visible" logger.info("Кнопка синхронизации (Reload) видима") def check_sync_button_tooltip(self, index: int, expected_tooltip: str = "reload") -> None: """Проверяет текст подсказки кнопки синхронизации (Reload). Использует стандартный механизм проверки подсказок из ToolbarComponent. Args: index: Индекс ячейки в заголовке таблицы. expected_tooltip: Ожидаемый текст подсказки (по умолчанию 'reload'). Raises: AssertionError: Если подсказка не соответствует ожидаемой или отсутствует. """ # Убеждаемся, что кнопка зарегистрирована в тулбаре if index not in self.sync_buttons: self.add_sync_button_to_toolbar(index) button_name = self.sync_buttons[index] # Проверка подсказки self.toolbar.check_button_tooltip(button_name, expected_tooltip) logger.info( "Подсказка кнопки синхронизации (Reload) в ячейке %d: '%s'", index, expected_tooltip ) def click_sync_button(self, index: int) -> None: """Нажимает кнопку 'Reload' в указанной ячейке заголовка таблицы. Перед кликом проверяет видимость кнопки. Args: index: Индекс ячейки в заголовке таблицы. Raises: AssertionError: Если индекс выходит за пределы или кнопка не найдена. """ sync_button = self.get_sync_button(index) # Проверяем видимость перед кликом self.check_sync_button_visibility(index) # Выполняем клик по кнопке sync_button.click() logger.info("Нажата кнопка синхронизации (Reload)") def check_config_table_vertical_scrolling(self) -> bool: """Проверяет возможность вертикальной прокрутки таблицы конфигурации. Returns: bool: True если таблица поддерживает вертикальную прокрутку, иначе False. """ return self.ztp_config_table.is_scrollable_vertically( TableLocators.TABLE_SCROLL_CONTAINER ) def check_config_table_first_row_visibility(self) -> None: """Проверяет видимость первой строки таблицы конфигурации. Raises: AssertionError: Если первая строка таблицы не видна. """ self.ztp_config_table.check_first_row_visibility(TableLocators.TABLE_WORK_AREA) def check_config_table_last_row_visibility(self) -> None: """Проверяет видимость последней строки таблицы конфигурации. Raises: AssertionError: Если последняя строка таблицы не видна. """ self.ztp_config_table.check_last_row_visibility(TableLocators.TABLE_WORK_AREA) def check_config_table_row_highlighting(self, row_index: int) -> None: """Проверяет выделение указанной строки таблицы конфигурации. Args: row_index: Индекс проверяемой строки (0-based, без учета заголовка). Raises: AssertionError: Если строка не выделена после взаимодействия. """ self.ztp_config_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_config_table(self) -> None: """Проверяет наличие и видимость таблицы конфигурации ZTP. Raises: AssertionError: Если таблица конфигурации отсутствует на странице. """ self.ztp_config_table.check_visibility( TableLocators.TABLE_WORK_AREA, "Configuration table is missing" )