From 1666498a36358725d8c790ed03da12d40c4bc820 Mon Sep 17 00:00:00 2001 From: Radislav Date: Sat, 22 Nov 2025 11:04:52 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=D0=B3=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D0=B0=20SelectionBar=20=D0=B8=20=D0=B5=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=BB=D0=BE=D0=BA=D0=B0=D1=82=D0=BE=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Добавлены новые локаторы для расширения функциональности - Улучшена инициализация компонента с поддержкой поиска по label - Добавлены методы для работы с ошибками валидации - Улучшена надежность открытия выпадающих списков --- components_derived/selection_bar_component.py | 100 ++++++++---------- locators/selection_bar_locators.py | 5 +- 2 files changed, 51 insertions(+), 54 deletions(-) diff --git a/components_derived/selection_bar_component.py b/components_derived/selection_bar_component.py index 75dc25e..52837a9 100644 --- a/components_derived/selection_bar_component.py +++ b/components_derived/selection_bar_component.py @@ -3,7 +3,6 @@ Содержит класс для работы с компонентом панели выбора значения через Playwright. """ -import re from playwright.sync_api import Page, Locator, expect from tools.logger import get_logger from locators.selection_bar_locators import SelectionBarLocators @@ -20,7 +19,7 @@ class SelectionBarComponent(BaseComponent): Предоставляет методы для взаимодействия с элементами компонента панели выбора значения. """ - def __init__(self, page: Page, locator_or_text: str | Locator): + def __init__(self, page: Page, locator_or_text: str | Locator) -> None: """Инициализирует компонент панели выбора значения. Args: @@ -45,15 +44,6 @@ class SelectionBarComponent(BaseComponent): # При нажатии на панель появляется выпадающий список с параметрами фильтрации для выбора self.selected_values_list = DropdownList(self.page) - def wait_for_timeout(self, timeout: int) -> None: - """ - Ожидает указанное количество миллисекунд. - - Args: - timeout: Время ожидания в миллисекундах - """ - self.page.wait_for_timeout(timeout) - # Действия: def clear_selections(self) -> None: """Удаление ранее выбранных значений""" @@ -64,39 +54,8 @@ class SelectionBarComponent(BaseComponent): ) clear_button_locator.click() - def get_selection_bar_title(self) -> str: - """Возвращает название панели выбора значения""" - title_locator = self.selection_bar_locator.locator(SelectionBarLocators.TITLE_LOCATOR) - return title_locator.text_content() - - def get_selected_values(self) -> list[str]: - """Возвращает список выбранных значений""" - selected_values_locator = self.selection_bar_locator.locator( - SelectionBarLocators.PARAMETERS_SELECTED - ) - selected_values = selected_values_locator.all_inner_texts() - return selected_values[0].splitlines() - - def open_values_list(self) -> None: - """Открытие выпадающего списка путем нажатия на панель выбора значения""" - expect(self.selection_bar_locator).to_be_visible() - - # Проверяем, не открыт ли уже список - parent_class = self.selection_bar_locator.get_attribute("class") - if parent_class and "v-select--is-menu-active" in parent_class: - logger.info("Values list is already open") - return - - # Используем force click для обхода перекрывающих элементов - logger.info("Using force click to open the list") - self.selection_bar_locator.click(force=True) - - # Ждем появления выпадающего списка - self.wait_for_timeout(1500) - def get_available_options(self) -> list[str]: - """ - Возвращает список всех доступных опций из выпадающего списка. + """Возвращает список всех доступных опций из выпадающего списка. Returns: list[str]: Список доступных опций @@ -121,14 +80,21 @@ class SelectionBarComponent(BaseComponent): logger.info(f"Found available options: {len(options)} - {options}") return options - def select_value(self, name: str) -> None: - """Выбор значения из списка""" - self.selected_values_list.check_item_with_text(name) - self.selected_values_list.click_item_with_text(name) + def get_selection_bar_title(self) -> str: + """Возвращает название панели выбора значения""" + title_locator = self.selection_bar_locator.locator(SelectionBarLocators.TITLE_LOCATOR) + return title_locator.text_content() + + def get_selected_values(self) -> list[str]: + """Возвращает список выбранных значений""" + selected_values_locator = self.selection_bar_locator.locator( + SelectionBarLocators.PARAMETERS_SELECTED + ) + selected_values = selected_values_locator.all_inner_texts() + return selected_values[0].splitlines() def clear_combobox_field(self, field_name: str, field_locator: str) -> None: - """ - Очищает значение в combobox поле с помощью кнопки закрытия (крестика). + """Очищает значение в combobox поле с помощью кнопки закрытия (крестика). Args: field_name: Название поля для очистки @@ -164,11 +130,40 @@ class SelectionBarComponent(BaseComponent): msg = f"Close button not found for field '{field_name}', clearing not performed" logger.info(msg) + def open_values_list(self) -> None: + """Открытие выпадающего списка путем нажатия на панель выбора значения""" + expect(self.selection_bar_locator).to_be_visible() + + # Проверяем, не открыт ли уже список + parent_class = self.selection_bar_locator.get_attribute("class") + if parent_class and SelectionBarLocators.MENU_ACTIVE_CLASS in parent_class: + logger.info("Values list is already open") + return + + # Используем force click для обхода перекрывающих элементов + logger.info("Using force click to open the list") + self.selection_bar_locator.click(force=True) + + # Ждем появления выпадающего списка + self.wait_for_timeout(1500) + + def select_value(self, name: str) -> None: + """Выбор значения из списка""" + self.selected_values_list.check_item_with_text(name) + self.selected_values_list.click_item_with_text(name) + + def wait_for_timeout(self, timeout: int) -> None: + """Ожидает указанное количество миллисекунд. + + Args: + timeout: Время ожидания в миллисекундах + """ + self.page.wait_for_timeout(timeout) + # Проверки: def check_field_highlighted_error(self, field_name: str, field_locator: str) -> None: - """ - Проверяет, что поле подсвечено цветом ошибки (валидация не пройдена). + """Проверяет, что поле подсвечено цветом ошибки (валидация не пройдена). Args: field_name: Название поля для проверки @@ -194,8 +189,7 @@ class SelectionBarComponent(BaseComponent): logger.info(f"Field '{field_name}' is correctly highlighted with error color") def check_field_not_highlighted_error(self, field_name: str, field_locator: str) -> None: - """ - Проверяет, что поле НЕ подсвечено цветом ошибки (валидация успешна). + """Проверяет, что поле НЕ подсвечено цветом ошибки (валидация успешна). Args: field_name: Название поля для проверки diff --git a/locators/selection_bar_locators.py b/locators/selection_bar_locators.py index acd6616..4f610c2 100644 --- a/locators/selection_bar_locators.py +++ b/locators/selection_bar_locators.py @@ -30,4 +30,7 @@ class SelectionBarLocators: # Локаторы для заголовков и поиска по тексту TITLE_LOCATOR = "//label" - COMBOBOX_BY_LABEL_XPATH = "//div[@role='combobox' and .//label[text()='{}']]" \ No newline at end of file + COMBOBOX_BY_LABEL_XPATH = "//div[@role='combobox' and .//label[text()='{}']]" + + # Класс для проверки активности меню + MENU_ACTIVE_CLASS = "v-select--is-menu-active"