From 632cf4ee407a89e7f7d1d65e277c73b81dcc2ef9 Mon Sep 17 00:00:00 2001 From: nsubbot Date: Tue, 28 Oct 2025 09:45:51 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D1=8F=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B4=D0=BF=D0=B0=D0=BD=D0=B5=D0=BB=D0=B8=20=D0=BF=D0=B0=D0=BD?= =?UTF-8?q?=D0=B5=D0=BB=D0=B8=20=D0=BD=D0=B0=D0=B2=D0=B8=D0=B3=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8=20=D1=81=20=D0=B1=D0=BE=D0=BB=D1=8C=D1=88=D0=B8?= =?UTF-8?q?=D0=BC=20=D1=83=D1=80=D0=BE=D0=B2=D0=BD=D0=B5=D0=BC=20=D0=B2?= =?UTF-8?q?=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/navbar_component.py | 63 +++++++++++++++-------- tests/e2e/test_expand_navigation_panel.py | 42 +++++++++++++-- 2 files changed, 79 insertions(+), 26 deletions(-) diff --git a/components/navbar_component.py b/components/navbar_component.py index 68339e9..6825859 100644 --- a/components/navbar_component.py +++ b/components/navbar_component.py @@ -54,23 +54,33 @@ class NavigationPanelComponent(BaseComponent): item_name: Текст элемента для клика. """ - def find_and_click_item(page, root_locator, item_name: str, parent: None|str) -> bool: + def find_and_click_item(page, root_locator, item_name: str, parent: None|str) -> Locator|None: # Находим все локаторы корневых узлов на текущем уровне - root_node = root_locator.locator('>div.v-treeview-node') - # Получаем список текстов - root_node_texts = root_node.all_inner_texts() + #root_node = root_locator.locator('>div.v-treeview-node') + nodes_count = root_locator.locator('>div.v-treeview-node').count() # Если искомый элемент находится на данном уровне, вычисляем локатор и делаем клик if parent is None: - for index, node_text in enumerate(root_node_texts): - node_text = node_text.replace("expand_more\n", "") - if item_name == node_text: - root_node.nth(index).click() - return True + for index in range(nodes_count): + node = root_locator.locator(f">div:nth-child({index + 1})").first + node_content = node.locator('div.v-treeview-node__content') + if node_content.count() > 0: + node_text = node_content.first.inner_text().strip() + if item_name == node_text: + node_attr = node.get_attribute('class') + if "v-treeview-node--leaf" not in node_attr: + toggle_button = node.\ + locator(NavigationPanelLocators.NODE_ROOT). \ + locator(NavigationPanelLocators.TOGGLE_BUTTON).first + toogle_class_attr = toggle_button.get_attribute('class') + if "v-treeview-node__toggle--open" not in toogle_class_attr: + toggle_button.click() + else: + node.locator(NavigationPanelLocators.NODE_ROOT).click() + page.wait_for_timeout(1000) + return node # Если элемента нет, рекурсивно ищем дальше - nodes_count = root_locator.locator('>div.v-treeview-node').count() - for index in range(nodes_count): node = root_locator.locator(f">div:nth-child({index + 1})").first @@ -83,16 +93,20 @@ class NavigationPanelComponent(BaseComponent): # Проверяем лист это или начало поддерева if "v-treeview-node--leaf" not in node_class_attr: # Проверяем, является ли узел раскрытым - class_attr = node.locator(NavigationPanelLocators.TOGGLE_BUTTON).get_attribute('class') + class_attr = node.\ + locator(NavigationPanelLocators.NODE_ROOT). \ + locator(NavigationPanelLocators.TOGGLE_BUTTON).first.get_attribute('class') if "v-treeview-node__toggle--open" in class_attr: is_expanded = True # Если узел закрыт можем его раскрыть if is_expanded is False: - toggle_button = node.locator(NavigationPanelLocators.TOGGLE_BUTTON) + toggle_button = node.\ + locator(NavigationPanelLocators.NODE_ROOT). \ + locator(NavigationPanelLocators.TOGGLE_BUTTON).first toggle_button.click() # Ждем, пока дочерние элементы прогрузятся/появятся - page.wait_for_timeout(300) + page.wait_for_timeout(1000) is_expanded = True # Проверяем, имеет ли узел дочерние элементы @@ -105,25 +119,32 @@ class NavigationPanelComponent(BaseComponent): # Ищем дочерние элементы *внутри* текущего узла if has_children and is_expanded: child_nodes_locator = root_locator.locator(f">div:nth-child({index + 1})").locator('>div.v-treeview-node__children') - is_found = find_and_click_item(page, child_nodes_locator, item_name, parent=None) - if is_found: + found_loc = find_and_click_item(page, child_nodes_locator, item_name, parent=None) + if found_loc: if parent is None: - return True + return found_loc else: root_texts = root_locator.locator(f">div:nth-child({index + 1})").inner_text().splitlines() if parent in root_texts: - return True + return found_loc # закрываем узел, если в нем ничего не нашли if is_expanded: - toggle_button = node.locator(NavigationPanelLocators.TOGGLE_BUTTON) + toggle_button = node.\ + locator(NavigationPanelLocators.NODE_ROOT). \ + locator(NavigationPanelLocators.TOGGLE_BUTTON).first toggle_button.click() + page.wait_for_timeout(1000) # элемент с заданным именем не найден - return False + return None root_locator = self.get_locator(node_root_locator) - found = find_and_click_item(self.page, root_locator, item_name, parent) + if parent: + parent_loc = find_and_click_item(self.page, root_locator, parent, parent=None) + found = find_and_click_item(self.page, parent_loc.locator('>div.v-treeview-node__children'), item_name, parent=None) + else: + found = find_and_click_item(self.page, root_locator, item_name, parent=None) assert found, f"Navigation panel item {item_name} is missing" def traverse_panel_tree(self, node_root_locator: str | Locator, level=0, debug=False): diff --git a/tests/e2e/test_expand_navigation_panel.py b/tests/e2e/test_expand_navigation_panel.py index 0c28c20..8998c93 100644 --- a/tests/e2e/test_expand_navigation_panel.py +++ b/tests/e2e/test_expand_navigation_panel.py @@ -4,7 +4,7 @@ панели навигации в приложении. """ -# import pytest +import pytest from playwright.sync_api import Page from pages.main_page import MainPage from pages.login_page import LoginPage @@ -52,6 +52,7 @@ class TestNavigationPanel: mp.expand_navigation_subpanel() + @pytest.mark.develop def test_sub_panel_item_click(self, browser: Page): """Проверяет возможность клика заданного элемента в подпанели навигации. @@ -76,17 +77,48 @@ class TestNavigationPanel: mp.click_subpanel_item("Обслуживание и диагностика") mp.click_subpanel_item("Статус обслуживания") - mp.wait_for_timeout(500) + mp.wait_for_timeout(2000) + + mp.click_subpanel_item("Сеансы") + mp.click_subpanel_item("Настройки", parent="Сеансы") # Открываем/закрываем пункт панели mp.click_subpanel_item("Пользователи") mp.click_subpanel_item("Пользователи") - mp.wait_for_timeout(500) + mp.wait_for_timeout(2000) # Открываем пункты панели с одинаковыми имнами, но разным расположением mp.click_subpanel_item("Шаблоны") - mp.wait_for_timeout(500) + mp.wait_for_timeout(2000) mp.click_subpanel_item("Zero Touch Provisioning") mp.click_subpanel_item("Шаблоны", parent="Zero Touch Provisioning") - mp.wait_for_timeout(500) + mp.wait_for_timeout(2000) + + # Переходим к Объектам + mp.click_main_navigation_panel_item("Объекты") + mp.wait_for_timeout(5000) + + + mp.click_subpanel_item("Физические устройства с опросом") + mp.wait_for_timeout(3000) + + # Переходим Здание ЦОД 4 + mp.click_subpanel_item("Здание ЦОД 4") + mp.wait_for_timeout(3000) + + # Переходим к Стойка КСПД с указанием родителя + mp.click_subpanel_item("Стойка КСПД", parent="Здание ЦОД 4") + mp.wait_for_timeout(5000) + + # Переходим к Объектам + mp.click_main_navigation_panel_item("Объекты") + mp.click_main_navigation_panel_item("Объекты") # баг + mp.wait_for_timeout(5000) + + mp.click_subpanel_item("Виртуальные устройства") + mp.wait_for_timeout(3000) + + # Переходим к Стойка систем питания с указанием родителя + mp.click_subpanel_item("Стойка систем питания", parent="Виртуальные устройства") + mp.wait_for_timeout(5000)