Рефакторинг компонента SelectionBar и его локаторов
- Добавлены новые локаторы для расширения функциональности - Улучшена инициализация компонента с поддержкой поиска по label - Добавлены методы для работы с ошибками валидации - Улучшена надежность открытия выпадающих списковradislav/tests_rack
parent
50041c66c7
commit
1666498a36
|
|
@ -3,7 +3,6 @@
|
||||||
Содержит класс для работы с компонентом панели выбора значения через Playwright.
|
Содержит класс для работы с компонентом панели выбора значения через Playwright.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
|
||||||
from playwright.sync_api import Page, Locator, expect
|
from playwright.sync_api import Page, Locator, expect
|
||||||
from tools.logger import get_logger
|
from tools.logger import get_logger
|
||||||
from locators.selection_bar_locators import SelectionBarLocators
|
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:
|
Args:
|
||||||
|
|
@ -45,15 +44,6 @@ class SelectionBarComponent(BaseComponent):
|
||||||
# При нажатии на панель появляется выпадающий список с параметрами фильтрации для выбора
|
# При нажатии на панель появляется выпадающий список с параметрами фильтрации для выбора
|
||||||
self.selected_values_list = DropdownList(self.page)
|
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:
|
def clear_selections(self) -> None:
|
||||||
"""Удаление ранее выбранных значений"""
|
"""Удаление ранее выбранных значений"""
|
||||||
|
|
@ -64,39 +54,8 @@ class SelectionBarComponent(BaseComponent):
|
||||||
)
|
)
|
||||||
clear_button_locator.click()
|
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]:
|
def get_available_options(self) -> list[str]:
|
||||||
"""
|
"""Возвращает список всех доступных опций из выпадающего списка.
|
||||||
Возвращает список всех доступных опций из выпадающего списка.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[str]: Список доступных опций
|
list[str]: Список доступных опций
|
||||||
|
|
@ -121,14 +80,21 @@ class SelectionBarComponent(BaseComponent):
|
||||||
logger.info(f"Found available options: {len(options)} - {options}")
|
logger.info(f"Found available options: {len(options)} - {options}")
|
||||||
return options
|
return options
|
||||||
|
|
||||||
def select_value(self, name: str) -> None:
|
def get_selection_bar_title(self) -> str:
|
||||||
"""Выбор значения из списка"""
|
"""Возвращает название панели выбора значения"""
|
||||||
self.selected_values_list.check_item_with_text(name)
|
title_locator = self.selection_bar_locator.locator(SelectionBarLocators.TITLE_LOCATOR)
|
||||||
self.selected_values_list.click_item_with_text(name)
|
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:
|
def clear_combobox_field(self, field_name: str, field_locator: str) -> None:
|
||||||
"""
|
"""Очищает значение в combobox поле с помощью кнопки закрытия (крестика).
|
||||||
Очищает значение в combobox поле с помощью кнопки закрытия (крестика).
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
field_name: Название поля для очистки
|
field_name: Название поля для очистки
|
||||||
|
|
@ -164,11 +130,40 @@ class SelectionBarComponent(BaseComponent):
|
||||||
msg = f"Close button not found for field '{field_name}', clearing not performed"
|
msg = f"Close button not found for field '{field_name}', clearing not performed"
|
||||||
logger.info(msg)
|
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:
|
def check_field_highlighted_error(self, field_name: str, field_locator: str) -> None:
|
||||||
"""
|
"""Проверяет, что поле подсвечено цветом ошибки (валидация не пройдена).
|
||||||
Проверяет, что поле подсвечено цветом ошибки (валидация не пройдена).
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
field_name: Название поля для проверки
|
field_name: Название поля для проверки
|
||||||
|
|
@ -194,8 +189,7 @@ class SelectionBarComponent(BaseComponent):
|
||||||
logger.info(f"Field '{field_name}' is correctly highlighted with error color")
|
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:
|
def check_field_not_highlighted_error(self, field_name: str, field_locator: str) -> None:
|
||||||
"""
|
"""Проверяет, что поле НЕ подсвечено цветом ошибки (валидация успешна).
|
||||||
Проверяет, что поле НЕ подсвечено цветом ошибки (валидация успешна).
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
field_name: Название поля для проверки
|
field_name: Название поля для проверки
|
||||||
|
|
|
||||||
|
|
@ -31,3 +31,6 @@ class SelectionBarLocators:
|
||||||
# Локаторы для заголовков и поиска по тексту
|
# Локаторы для заголовков и поиска по тексту
|
||||||
TITLE_LOCATOR = "//label"
|
TITLE_LOCATOR = "//label"
|
||||||
COMBOBOX_BY_LABEL_XPATH = "//div[@role='combobox' and .//label[text()='{}']]"
|
COMBOBOX_BY_LABEL_XPATH = "//div[@role='combobox' and .//label[text()='{}']]"
|
||||||
|
|
||||||
|
# Класс для проверки активности меню
|
||||||
|
MENU_ACTIVE_CLASS = "v-select--is-menu-active"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue