Интеграция SelectionBarComponent в CreateRackElementTab
- Замена DropdownList на SelectionBarComponent в CreateRackElementTab для единообразной работы с выбором - Добавление метода get_available_options() в SelectionBarComponent для получения всех доступных опций из выпадающего списка - Обновление selection_bar_locators.py с новыми локаторами LISTBOX и LIST_ITEMS для элементов выпадающего списка - Улучшение combobox_locators.py с дополнительным локатором LIST_ITEMS_SELECTOR для опций comboboxradislav/tests_rack
parent
c0459e0905
commit
a88d8ed54a
|
|
@ -247,8 +247,10 @@ class NavigationPanelComponent(BaseComponent):
|
||||||
Returns:
|
Returns:
|
||||||
bool: True если элемент видим, False если нет.
|
bool: True если элемент видим, False если нет.
|
||||||
"""
|
"""
|
||||||
try:
|
element_locator = self.page.locator(locator).filter(has_text=item_name)
|
||||||
self.check_item_visibility(locator, item_name)
|
|
||||||
return True
|
# Сначала проверяем что элемент вообще существует
|
||||||
except:
|
if element_locator.count() == 0:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
return element_locator.is_visible()
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
"""Модуль компонента панели выбора значения.
|
||||||
|
|
||||||
|
Содержит класс для работы с компонентом панели выбора значения через Playwright.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from playwright.sync_api import Page, Locator, expect
|
||||||
|
from tools.logger import get_logger
|
||||||
|
from locators.selection_bar_locators import SelectionBarLocators
|
||||||
|
from locators.combobox_locators import ComboboxLocators
|
||||||
|
from components.dropdown_list_component import DropdownList
|
||||||
|
from components.base_component import BaseComponent
|
||||||
|
|
||||||
|
logger = get_logger("FILTER_PARAMETER_BAR")
|
||||||
|
|
||||||
|
|
||||||
|
class SelectionBarComponent(BaseComponent):
|
||||||
|
"""Компонент панели выбора значения.
|
||||||
|
|
||||||
|
Предоставляет методы для взаимодействия с элементами компонента панели выбора значения.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, page: Page, locator: str | Locator):
|
||||||
|
"""Инициализирует компонент панели выбора значения.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
page: Экземпляр страницы Playwright.
|
||||||
|
locator: Локатор панели выбора значения (строка или объект Locator)
|
||||||
|
"""
|
||||||
|
|
||||||
|
super().__init__(page)
|
||||||
|
|
||||||
|
# Локатор панели параметра фильтрации
|
||||||
|
self.selection_bar_locator = self.get_locator(locator)
|
||||||
|
|
||||||
|
# При нажатии на панель появляется выпадающий список с параметрами фильтрации для выбора
|
||||||
|
self.selected_values_list = DropdownList(self.page)
|
||||||
|
|
||||||
|
# Действия:
|
||||||
|
def clear_selections(self) -> None:
|
||||||
|
""" Удаление ранее выбранных значений """
|
||||||
|
|
||||||
|
selected_values = self.get_selected_values()
|
||||||
|
if len(selected_values) > 0:
|
||||||
|
clear_button_locator = self.selection_bar_locator.\
|
||||||
|
locator(SelectionBarLocators.CLEAR_SELECTION_BUTTON)
|
||||||
|
clear_button_locator.click()
|
||||||
|
|
||||||
|
|
||||||
|
def get_selection_bar_title(self) -> str:
|
||||||
|
""" Возвращает название панели выбора значения """
|
||||||
|
|
||||||
|
title_locator = self.selection_bar_locator.locator("//label")
|
||||||
|
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()
|
||||||
|
self.selection_bar_locator.click()
|
||||||
|
|
||||||
|
def get_available_options(self) -> list[str]:
|
||||||
|
"""
|
||||||
|
Возвращает список всех доступных опций из выпадающего списка.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[str]: Список доступных опций
|
||||||
|
"""
|
||||||
|
logger.info("Получение списка доступных опций из выпадающего списка...")
|
||||||
|
|
||||||
|
# Открываем выпадающий список
|
||||||
|
self.open_values_list()
|
||||||
|
|
||||||
|
# Ждем появления списка
|
||||||
|
self.wait_for_timeout(1000)
|
||||||
|
|
||||||
|
# Получаем все элементы списка
|
||||||
|
options = self.selected_values_list.get_item_names(SelectionBarLocators.LIST_ITEMS)
|
||||||
|
|
||||||
|
# Закрываем список (кликаем вне его)
|
||||||
|
self.page.mouse.click(10, 10)
|
||||||
|
self.wait_for_timeout(500)
|
||||||
|
|
||||||
|
logger.info(f"Найдено доступных опций: {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)
|
||||||
|
|
||||||
|
# Проверки:
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
"""Модуль компонента боковой панели формы ввода полей фильтрации отображения данных в панели событий. Содержит класс для работы
|
||||||
|
с формами ввода, их элементами и проверками."""
|
||||||
|
|
||||||
|
from playwright.sync_api import Page, Locator
|
||||||
|
from tools.logger import get_logger
|
||||||
|
from elements.button_element import Button
|
||||||
|
from components_derived.selection_bar_component import SelectionBarComponent
|
||||||
|
from components_derived.date_input_component import DateInput
|
||||||
|
from components.toolbar_component import ToolbarComponent
|
||||||
|
from components.base_component import BaseComponent
|
||||||
|
|
||||||
|
logger = get_logger("SIDEBAR_FILTER")
|
||||||
|
|
||||||
|
|
||||||
|
class SidebarFilterComponent(BaseComponent):
|
||||||
|
"""Компонент боковой панели формы ввода полей фильтрации отображения данных в панели событий. Предоставляет методы для
|
||||||
|
взаимодействия с формой, ее содержимым и проверок."""
|
||||||
|
|
||||||
|
def __init__(self, page: Page, locator: str | Locator):
|
||||||
|
"""Инициализирует компонент боковой панели формы ввода параметров фильтрации.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
page: Экземпляр страницы Playwright
|
||||||
|
locator: Локатор контейнера (строка или объект Locator) для которого вызывается панель
|
||||||
|
"""
|
||||||
|
super().__init__(page)
|
||||||
|
|
||||||
|
self.sidebar_locator = self.get_locator(locator)
|
||||||
|
|
||||||
|
self.toolbar = ToolbarComponent(page, "Настройки и параметры")
|
||||||
|
|
||||||
|
# Поля ввода даты начала и даты окончания события
|
||||||
|
self.start_time_filter = DateInput(page,
|
||||||
|
self.sidebar_locator.locator(
|
||||||
|
"//div[contains(@class, 'scrollarea__body')]/div").nth(0))
|
||||||
|
self.finish_time_filter = DateInput(page,
|
||||||
|
self.sidebar_locator.locator(
|
||||||
|
"//div[contains(@class, 'scrollarea__body')]/div").nth(1))
|
||||||
|
|
||||||
|
# Поля задания параметров фильтрации (произвольное количество)
|
||||||
|
self.filtering_parameters = {}
|
||||||
|
|
||||||
|
# Кнопки задания/сброса параметров фильтрации
|
||||||
|
self.apply_button = Button(page,
|
||||||
|
self.sidebar_locator.get_by_role("button").filter(has_text='Применить Фильтры'),
|
||||||
|
"apply_button")
|
||||||
|
self.reset_button = Button(page,
|
||||||
|
self.sidebar_locator.get_by_role("button").filter(has_text='Сбросить Фильтры'),
|
||||||
|
"reset_button")
|
||||||
|
|
||||||
|
# Действия:
|
||||||
|
def add_filtering_parameter(self, name: str, title: str) -> None:
|
||||||
|
"""Добавляет поле задания параметров фильтрации по заданному имени."""
|
||||||
|
|
||||||
|
loc = self.sidebar_locator.locator("//div[contains(@class, 'scrollarea__body')]").\
|
||||||
|
get_by_role("combobox").filter(has_text=title)
|
||||||
|
self.filtering_parameters[name] = SelectionBarComponent(self.page, loc)
|
||||||
|
|
||||||
|
def get_filtering_parameter(self, name: str) -> SelectionBarComponent | None:
|
||||||
|
"""Возвращает поле задания параметров фильтрации по заданному или None, если не найдено."""
|
||||||
|
|
||||||
|
return self.filtering_parameters.get(name)
|
||||||
|
|
||||||
|
def get_start_time_filter(self) -> DateInput:
|
||||||
|
"""Возвращает поле задания параметров фильтрации даты начала."""
|
||||||
|
|
||||||
|
return self.start_time_filter
|
||||||
|
|
||||||
|
def get_finish_time_filter(self) -> DateInput:
|
||||||
|
"""Возвращает поле задания параметров фильтрации даты окончания."""
|
||||||
|
|
||||||
|
return self.finish_time_filter
|
||||||
|
|
||||||
|
def click_apply_button(self) -> None:
|
||||||
|
"""Клик по кнопке применения фильтра."""
|
||||||
|
|
||||||
|
self.apply_button.click()
|
||||||
|
|
||||||
|
def click_reset_button(self) -> None:
|
||||||
|
"""Клик по кнопке сброса фильтра."""
|
||||||
|
|
||||||
|
self.reset_button.click()
|
||||||
|
|
||||||
|
# Проверки:
|
||||||
|
def check_content(self) -> None:
|
||||||
|
"""Проверяет наличие постоянных полей панели параметров фильтрации."""
|
||||||
|
|
||||||
|
self.should_be_toolbar()
|
||||||
|
self.start_time_filter.check_content("Дата начала")
|
||||||
|
self.finish_time_filter.check_content("Дата окончания")
|
||||||
|
|
||||||
|
self.check_apply_button_visibility()
|
||||||
|
self.check_reset_button_visibility()
|
||||||
|
|
||||||
|
|
||||||
|
def check_vertical_scrolling(self, locator: str| Locator) -> bool:
|
||||||
|
"""Проверяет возможность вертикальной прокрутки формы."""
|
||||||
|
|
||||||
|
return self.is_scrollable_vertically(locator)
|
||||||
|
|
||||||
|
def check_apply_button_visibility(self) -> None:
|
||||||
|
"""Проверяет наличие кнопки применения фильтра."""
|
||||||
|
|
||||||
|
self.apply_button.check_visibility("Apply Filter Button is missing")
|
||||||
|
|
||||||
|
def check_reset_button_visibility(self) -> None:
|
||||||
|
"""Проверяет наличие кнопки сброса фильтра."""
|
||||||
|
|
||||||
|
self.reset_button.check_visibility("Reset Filter Button is missing")
|
||||||
|
|
||||||
|
def should_be_toolbar(self) -> None:
|
||||||
|
"""Проверяет наличие тулбара.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
AssertionError: Если тулбар отсутствует.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.toolbar.check_toolbar_presence_by_locator_and_title(self.sidebar_locator,
|
||||||
|
"Sidebar Filter form toolbar is missing")
|
||||||
|
|
@ -27,6 +27,7 @@ class ComboboxLocators:
|
||||||
|
|
||||||
# Выпадающие списки
|
# Выпадающие списки
|
||||||
LISTBOX_SELECTOR: str = "//div[contains(@class, 'v-menu__content')]//div[@role='list']"
|
LISTBOX_SELECTOR: str = "//div[contains(@class, 'v-menu__content')]//div[@role='list']"
|
||||||
|
LIST_ITEMS_SELECTOR: str = "//div[contains(@class, 'v-menu__content')]//div[@role='listitem']"
|
||||||
OPTIONS_SELECTOR: str = "//div[contains(@class, 'v-menu__content')]//div[@role='listitem']//span"
|
OPTIONS_SELECTOR: str = "//div[contains(@class, 'v-menu__content')]//div[@role='listitem']//span"
|
||||||
|
|
||||||
# Получение выбранного значения
|
# Получение выбранного значения
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
"""Модуль selection_bar_locators содержит локаторы компонента панели выбора значения.
|
||||||
|
|
||||||
|
Класс SelectionBarLocators предоставляет XPath/CSS локаторы для взаимодействия
|
||||||
|
с компонентом панели выбора значения.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class SelectionBarLocators:
|
||||||
|
"""Локаторы для компонента панели выбора значения.
|
||||||
|
|
||||||
|
Содержит XPath/CSS локаторы для:
|
||||||
|
- Кнопок открытия и очистки
|
||||||
|
- Выбранных значений
|
||||||
|
- Элементов выпадающего списка
|
||||||
|
"""
|
||||||
|
|
||||||
|
OPEN_PARAMETERS_LIST_BUTTON = "div.v-input__icon--append"
|
||||||
|
CLEAR_SELECTION_BUTTON = "div.v-input__icon--clear"
|
||||||
|
PARAMETERS_SELECTED = "div.v-select__selections"
|
||||||
|
|
||||||
|
# Локаторы для элементов выпадающего списка
|
||||||
|
LISTBOX = "//div[@role='listbox']"
|
||||||
|
LIST_ITEMS = "//div[@role='listbox']//div[@role='listitem']"
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -7,7 +7,7 @@ from playwright.sync_api import Page, expect
|
||||||
|
|
||||||
from elements.tooltip_button_element import TooltipButton
|
from elements.tooltip_button_element import TooltipButton
|
||||||
from components.toolbar_component import ToolbarComponent
|
from components.toolbar_component import ToolbarComponent
|
||||||
from components.dropdown_list_component import DropdownList
|
from components_derived.selection_bar_component import SelectionBarComponent
|
||||||
from pages.main_page import MainPage
|
from pages.main_page import MainPage
|
||||||
from pages.base_page import BasePage
|
from pages.base_page import BasePage
|
||||||
from components.base_component import BaseComponent
|
from components.base_component import BaseComponent
|
||||||
|
|
@ -82,8 +82,8 @@ class CreateRackElementTab(BasePage):
|
||||||
self.toolbar.add_tooltip_button(create_button_locator, "add")
|
self.toolbar.add_tooltip_button(create_button_locator, "add")
|
||||||
self.toolbar.add_tooltip_button(cancel_button_locator, "cancel")
|
self.toolbar.add_tooltip_button(cancel_button_locator, "cancel")
|
||||||
|
|
||||||
# Инициализация компонента выпадающего списка
|
# Инициализация компонента панели выбора значения для работы с combobox
|
||||||
self.dropdown = DropdownList(page)
|
self.selection_bar = SelectionBarComponent(page, ComboboxLocators.OBJECT_CLASS_COMBOBOX)
|
||||||
|
|
||||||
# =============== МЕТОДЫ ДЕЙСТВИЙ ========================
|
# =============== МЕТОДЫ ДЕЙСТВИЙ ========================
|
||||||
|
|
||||||
|
|
@ -104,11 +104,7 @@ class CreateRackElementTab(BasePage):
|
||||||
Открывает выпадающий список combobox 'Класс объекта учета'.
|
Открывает выпадающий список combobox 'Класс объекта учета'.
|
||||||
"""
|
"""
|
||||||
logger.info("Открытие combobox 'Класс объекта учета'...")
|
logger.info("Открытие combobox 'Класс объекта учета'...")
|
||||||
self.dropdown.open_combobox(
|
self.selection_bar.open_values_list()
|
||||||
ComboboxLocators.OBJECT_CLASS_COMBOBOX,
|
|
||||||
ComboboxLocators.LISTBOX_SELECTOR,
|
|
||||||
ComboboxLocators.COMBOBOX_ICON
|
|
||||||
)
|
|
||||||
|
|
||||||
def select_object_class(self, class_name: str) -> None:
|
def select_object_class(self, class_name: str) -> None:
|
||||||
"""
|
"""
|
||||||
|
|
@ -125,7 +121,8 @@ class CreateRackElementTab(BasePage):
|
||||||
# Открываем combobox
|
# Открываем combobox
|
||||||
self.open_object_class_combobox()
|
self.open_object_class_combobox()
|
||||||
|
|
||||||
self.dropdown.click_item_with_text(class_name)
|
# Выбираем значение из списка
|
||||||
|
self.selection_bar.select_value(class_name)
|
||||||
|
|
||||||
# Проверяем что выбор произошел
|
# Проверяем что выбор произошел
|
||||||
self.wait_for_timeout(1000)
|
self.wait_for_timeout(1000)
|
||||||
|
|
@ -139,6 +136,30 @@ class CreateRackElementTab(BasePage):
|
||||||
|
|
||||||
logger.info(f"Класс объекта '{class_name}' успешно выбран")
|
logger.info(f"Класс объекта '{class_name}' успешно выбран")
|
||||||
|
|
||||||
|
def get_object_class_options(self) -> list[str]:
|
||||||
|
"""
|
||||||
|
Получает список доступных опций из combobox.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[str]: Список доступных классов объектов
|
||||||
|
"""
|
||||||
|
logger.info("Получение списка опций combobox 'Класс объекта учета'...")
|
||||||
|
|
||||||
|
available_options = self.selection_bar.get_available_options()
|
||||||
|
|
||||||
|
logger.info(f"Доступные опции класса объекта: {available_options}")
|
||||||
|
return available_options
|
||||||
|
|
||||||
|
def get_selected_object_class(self) -> str:
|
||||||
|
"""
|
||||||
|
Получает выбранный класс объекта учета.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Выбранный класс объекта или пустая строка если ничего не выбрано
|
||||||
|
"""
|
||||||
|
# Получаем заголовок панели выбора
|
||||||
|
return self.selection_bar.get_selection_bar_title()
|
||||||
|
|
||||||
def fill_rack_data(self, name: str, height: str = "42", depth: str = "1000",
|
def fill_rack_data(self, name: str, height: str = "42", depth: str = "1000",
|
||||||
serial: str = "", inventory: str = "", comment: str = "",
|
serial: str = "", inventory: str = "", comment: str = "",
|
||||||
cable_entry: str = "", state: str = "", owner: str = "",
|
cable_entry: str = "", state: str = "", owner: str = "",
|
||||||
|
|
@ -349,31 +370,6 @@ class CreateRackElementTab(BasePage):
|
||||||
|
|
||||||
logger.info("Все поля формы стойки очищены")
|
logger.info("Все поля формы стойки очищены")
|
||||||
|
|
||||||
def get_object_class_options(self) -> list[str]:
|
|
||||||
"""
|
|
||||||
Получает список доступных опций из combobox.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list[str]: Список доступных классов объектов
|
|
||||||
"""
|
|
||||||
return self.dropdown.get_combobox_options(
|
|
||||||
ComboboxLocators.OBJECT_CLASS_COMBOBOX,
|
|
||||||
ComboboxLocators.LISTBOX_SELECTOR,
|
|
||||||
ComboboxLocators.COMBOBOX_ICON
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_selected_object_class(self) -> str:
|
|
||||||
"""
|
|
||||||
Получает выбранный класс объекта учета.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Выбранный класс объекта или пустая строка если ничего не выбрано
|
|
||||||
"""
|
|
||||||
return self.dropdown.get_selected_combobox_value(
|
|
||||||
ComboboxLocators.OBJECT_CLASS_COMBOBOX,
|
|
||||||
ComboboxLocators.SELECTED_VALUE_SPAN
|
|
||||||
)
|
|
||||||
|
|
||||||
# =============== МЕТОДЫ ПРОВЕРОК ========================
|
# =============== МЕТОДЫ ПРОВЕРОК ========================
|
||||||
def check_rack_exists(self, rack_name: str) -> bool:
|
def check_rack_exists(self, rack_name: str) -> bool:
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue