diff --git a/.env b/.env index f4ddf1d..7571ece 100644 --- a/.env +++ b/.env @@ -1,3 +1,3 @@ -ENV=develop +ENV=test AUTH_LOGIN = admin AUTH_PASSWORD = enodemon-admin diff --git a/components/events_container_component.py b/components/events_container_component.py index 8caebc8..1a34f97 100644 --- a/components/events_container_component.py +++ b/components/events_container_component.py @@ -7,9 +7,9 @@ from locators.toolbar_locators import ToolbarLocators from elements.tooltip_button_element import TooltipButton from elements.tab_button_element import TabButton from elements.button_element import Button +from components_derived.sidebar_filter_component import SidebarFilterComponent from components.toolbar_component import ToolbarComponent from components.table_component import TableComponent -from components.sidebar_filter_component import SidebarFilterComponent from components.base_component import BaseComponent logger = get_logger("EVENTS_CONTANER") @@ -156,6 +156,11 @@ class EventsContainerComponent(BaseComponent): loc = self.container_locator.locator(self.table_locator) return self.events_table.get_rows_count(loc) + + def get_sidebar_filter(self) -> SidebarFilterComponent: + """Возвращает боковую панель фильтрации.""" + + return self.sidebar_filter def get_toolbar_filter_button(self) -> Button: """Возвращает кнопку фильтрации.""" diff --git a/components_derived/container_system_log_events.py b/components_derived/container_system_log_events.py index 9bcb829..f930ad3 100644 --- a/components_derived/container_system_log_events.py +++ b/components_derived/container_system_log_events.py @@ -31,6 +31,12 @@ class SystemLogEventsContainer(EventsContainerComponent): super().__init__(page, locator) self.add_tab_to_toolbar(ToolbarLocators.TABS, "events") + + sidebar_filter = self.get_sidebar_filter() + sidebar_filter.add_filtering_parameter("filter_type", "Тип") + sidebar_filter.add_filtering_parameter("filter_strictness", "Строгость") + sidebar_filter.add_filtering_parameter("filter_host", "Хост") + # Действия: # Проверки: def check_content(self) -> None: @@ -58,3 +64,18 @@ class SystemLogEventsContainer(EventsContainerComponent): assert False, "Table body is missing" self.should_be_pagination_buttons() + + sidebar_filter = self.click_filter_button() + sidebar_filter.check_content() + + filter_type_bar = sidebar_filter.get_filtering_parameter("filter_type") + filter_type_title = filter_type_bar.get_filter_parameter_title() + assert filter_type_title == "Тип", "Filtering parameter bar 'Тип' is missing" + + filter_strictness_bar = sidebar_filter.get_filtering_parameter("filter_strictness") + filter_strictness_title = filter_strictness_bar.get_filter_parameter_title() + assert filter_strictness_title == "Строгость", "Filtering parameter bar 'Строгость' is missing" + + filter_host_bar = sidebar_filter.get_filtering_parameter("filter_host") + filter_host_title = filter_host_bar.get_filter_parameter_title() + assert filter_host_title == "Хост", "Filtering parameter bar 'Хост' is missing" diff --git a/components_derived/selection_bar_component.py b/components_derived/selection_bar_component.py new file mode 100644 index 0000000..f8f371c --- /dev/null +++ b/components_derived/selection_bar_component.py @@ -0,0 +1,75 @@ +"""Модуль компонента панели выбора значения. + +Содержит класс для работы с компонентом панели выбора значения через Playwright. +""" + +from playwright.sync_api import Page, Locator, expect +from tools.logger import get_logger +from locators.selection_bar_locators import SelectionBarLocators +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) -> []: + """ Возвращает список выбранных значений """ + + 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 select_value(self, name: str) -> None: + """ Выбор значения из списка """ + + self.selected_values_list.check_item_with_text(name) + self.selected_values_list.click_item_with_text(name) + + # Проверки: diff --git a/components_derived/sidebar_filter_component.py b/components_derived/sidebar_filter_component.py index 6812b89..a047516 100644 --- a/components_derived/sidebar_filter_component.py +++ b/components_derived/sidebar_filter_component.py @@ -4,6 +4,7 @@ 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 @@ -37,7 +38,7 @@ class SidebarFilterComponent(BaseComponent): "//div[contains(@class, 'scrollarea__body')]/div").nth(1)) # Поля задания параметров фильтрации (произвольное количество) - self.filter_items = {} + self.filtering_parameters = {} # Кнопки задания/сброса параметров фильтрации self.apply_button = Button(page, @@ -48,15 +49,17 @@ class SidebarFilterComponent(BaseComponent): "reset_button") # Действия: - def add_filter_item(self, name: str, item: object) -> None: + def add_filtering_parameter(self, name: str, title: str) -> None: """Добавляет поле задания параметров фильтрации по заданному имени.""" - self.filter_items[name] = item + 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_filter_item(self, name: str) -> object | None: + def get_filtering_parameter(self, name: str) -> SelectionBarComponent | None: """Возвращает поле задания параметров фильтрации по заданному или None, если не найдено.""" - return self.filter_items.get(name) + return self.filtering_parameters.get(name) def get_start_time_filter(self) -> DateInput: """Возвращает поле задания параметров фильтрации даты начала.""" @@ -79,6 +82,17 @@ class SidebarFilterComponent(BaseComponent): 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: """Проверяет возможность вертикальной прокрутки формы.""" diff --git a/locators/selection_bar_locators.py b/locators/selection_bar_locators.py new file mode 100644 index 0000000..7b595d2 --- /dev/null +++ b/locators/selection_bar_locators.py @@ -0,0 +1,16 @@ +"""Модуль 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" diff --git a/tests/components/unit_tests/test_selection_bar.py b/tests/components/unit_tests/test_selection_bar.py new file mode 100644 index 0000000..30ccc2e --- /dev/null +++ b/tests/components/unit_tests/test_selection_bar.py @@ -0,0 +1,106 @@ +"""Модуль тестов для проверки операций с компонентом панели выбора значения. + +Содержит тесты для для проверки операций с компонентом панели выбора значения. +""" + +import pytest +from playwright.sync_api import Page +from pages.main_page import MainPage +from pages.login_page import LoginPage + + +# @pytest.mark.smoke +class TestSelectionBarComponent: + """Класс тестов для проверки операций с компонентом панели выбора значения на примере + панели выбора значения 'Тип' в боковой панели фильтрации вкладки 'Системный журнал' + панели событий. + + Атрибуты: + browser: Фикстура для работы с браузером. + """ + + # @pytest.mark.develop + def test_selection_bar_content(self, browser: Page) -> None: + """Проверяет содержимое компонента панели выбора значения. + + Args: + browser: Экземпляр страницы Playwright. + """ + + lp = LoginPage(browser) + lp.do_login() + + mp = MainPage(browser) + mp.should_be_event_panel() + + system_log_events_container = mp.click_events_panel_system_log_tab() + sidebar_filter = system_log_events_container.click_filter_button() + browser.wait_for_timeout(500) + + sidebar_filter.add_filtering_parameter("filter_type", "Тип") + filter_type_bar = sidebar_filter.get_filtering_parameter("filter_type") + filter_type_title = filter_type_bar.get_selection_bar_title() + assert filter_type_title == "Тип", "Filtering parameter bar 'Тип' is missing" + + # @pytest.mark.develop + def test_selection_values(self, browser: Page) -> None: + """Проверяет возможность выбора значений. + + Args: + browser: Экземпляр страницы Playwright. + """ + + lp = LoginPage(browser) + lp.do_login() + + mp = MainPage(browser) + mp.should_be_event_panel() + + system_log_events_container = mp.click_events_panel_system_log_tab() + sidebar_filter = system_log_events_container.click_filter_button() + browser.wait_for_timeout(500) + + sidebar_filter.add_filtering_parameter("filter_type", "Тип") + filter_type_bar = sidebar_filter.get_filtering_parameter("filter_type") + + filter_type_bar.open_values_list() + filter_type_bar.select_value("e-nms") + selected_values = filter_type_bar.get_selected_values() + assert len(selected_values) > 0, "No values has been selected" + assert selected_values[0] == "e-nms", f"Got unexpected selected value {selected_values[0]}" + + filter_type_bar.open_values_list() + filter_type_bar.select_value("Технический учет") + selected_values = filter_type_bar.get_selected_values() + assert len(selected_values) > 0, "No values has been selected" + assert selected_values[0] == "e-nms", f"Got unexpected selected value {selected_values[0]}" + assert selected_values[1] == "Технический учет", f"Got unexpected selected value {selected_values[1]}" + + # @pytest.mark.develop + def test_clear_selected_values(self, browser: Page) -> None: + """Проверяет возможность удаления ранее выбранных значений. + + Args: + browser: Экземпляр страницы Playwright. + """ + + lp = LoginPage(browser) + lp.do_login() + + mp = MainPage(browser) + mp.should_be_event_panel() + + system_log_events_container = mp.click_events_panel_system_log_tab() + sidebar_filter = system_log_events_container.click_filter_button() + browser.wait_for_timeout(500) + + sidebar_filter.add_filtering_parameter("filter_type", "Тип") + filter_type_bar = sidebar_filter.get_filtering_parameter("filter_type") + filter_type_bar.open_values_list() + filter_type_bar.select_value("e-nms") + browser.wait_for_timeout(300) + + filter_type_bar.clear_selections() + selected_values = filter_type_bar.get_selected_values() + assert len(selected_values) == 0, "Selected values should be deleted" + \ No newline at end of file