Сделан поиск элемента навигационной панели с учетом имени его родителя (при необходимости, для неуникальных имен)

pull/1/head
nsubbot 2025-09-23 13:11:30 +03:00
parent 1b92588168
commit 3cdc495fef
3 changed files with 31 additions and 14 deletions

View File

@ -46,7 +46,7 @@ class NavigationPanelComponent(BaseComponent):
loc = self.get_locator(locator) loc = self.get_locator(locator)
loc.get_by_text(item_name).click() loc.get_by_text(item_name).click()
def click_sub_item(self, node_root_locator: str | Locator, item_name: str) -> None: def click_sub_item(self, node_root_locator: str | Locator, item_name: str, parent: None|str) -> None:
"""Кликает по вложенному элементу с указанным текстом. """Кликает по вложенному элементу с указанным текстом.
Args: Args:
@ -54,18 +54,19 @@ class NavigationPanelComponent(BaseComponent):
item_name: Текст элемента для клика. item_name: Текст элемента для клика.
""" """
def find_and_click_item(page, root_locator, item_name: str) -> bool: def find_and_click_item(page, root_locator, item_name: str, parent: None|str) -> bool:
# Находим все локаторы корневых узлов на текущем уровне # Находим все локаторы корневых узлов на текущем уровне
root_node = root_locator.locator('>div.v-treeview-node') root_node = root_locator.locator('>div.v-treeview-node')
# Получаем список текстов # Получаем список текстов
root_node_texts = root_node.all_inner_texts() root_node_texts = root_node.all_inner_texts()
# Если искомый элемент находится на данном уровне, вычисляем локатор и делаем клик # Если искомый элемент находится на данном уровне, вычисляем локатор и делаем клик
for index, node_text in enumerate(root_node_texts): if parent is None:
node_text = node_text.replace("expand_more\n", "") for index, node_text in enumerate(root_node_texts):
if item_name == node_text: node_text = node_text.replace("expand_more\n", "")
root_node.nth(index).click() if item_name == node_text:
return True root_node.nth(index).click()
return True
# Если элемента нет, рекурсивно ищем дальше # Если элемента нет, рекурсивно ищем дальше
nodes_count = root_locator.locator('>div.v-treeview-node').count() nodes_count = root_locator.locator('>div.v-treeview-node').count()
@ -104,9 +105,14 @@ class NavigationPanelComponent(BaseComponent):
# Ищем дочерние элементы *внутри* текущего узла # Ищем дочерние элементы *внутри* текущего узла
if has_children and is_expanded: if has_children and is_expanded:
child_nodes_locator = root_locator.locator(f">div:nth-child({index + 1})").locator('>div.v-treeview-node__children') 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) is_found = find_and_click_item(page, child_nodes_locator, item_name, parent=None)
if is_found: if is_found:
return True if parent is None:
return True
else:
root_texts = root_locator.locator(f">div:nth-child({index + 1})").inner_text().splitlines()
if parent in root_texts:
return True
# закрываем узел, если в нем ничего не нашли # закрываем узел, если в нем ничего не нашли
if is_expanded: if is_expanded:
@ -117,7 +123,7 @@ class NavigationPanelComponent(BaseComponent):
return False return False
root_locator = self.get_locator(node_root_locator) root_locator = self.get_locator(node_root_locator)
found = find_and_click_item(self.page, root_locator, item_name) found = find_and_click_item(self.page, root_locator, item_name, parent)
assert found, f"Navigation panel item {item_name} is missing" assert found, f"Navigation panel item {item_name} is missing"
def traverse_panel_tree(self, node_root_locator: str | Locator, level=0, debug=False): def traverse_panel_tree(self, node_root_locator: str | Locator, level=0, debug=False):

View File

@ -43,14 +43,14 @@ class MainPage(BasePage):
self.navigation_panel.click_item(NavigationPanelLocators.PANEL_MAIN, item_name) self.navigation_panel.click_item(NavigationPanelLocators.PANEL_MAIN, item_name)
def click_subpanel_item(self, item_name: str) -> None: def click_subpanel_item(self, item_name: str, parent=None) -> None:
"""Выполняет рекурсивный поиск по панели навигации заданного элемента и делает клик по нему.""" """Выполняет рекурсивный поиск по панели навигации заданного элемента и делает клик по нему."""
active_item_locator = self.page.locator(NavigationPanelLocators.PANEL_MAIN).locator(NavigationPanelLocators.ACTIVE_CONTAINER) active_item_locator = self.page.locator(NavigationPanelLocators.PANEL_MAIN).locator(NavigationPanelLocators.ACTIVE_CONTAINER)
node_locator = active_item_locator.locator(NavigationPanelLocators.SUB_PANEL_MAIN).locator(NavigationPanelLocators.TREEVIEW).first node_locator = active_item_locator.locator(NavigationPanelLocators.SUB_PANEL_MAIN).locator(NavigationPanelLocators.TREEVIEW).first
# Рекурсивный поиск в дереве v-treeview заданного элемента и клик по нему # Рекурсивный поиск в дереве v-treeview заданного элемента и клик по нему
self.navigation_panel.click_sub_item(node_locator, item_name) self.navigation_panel.click_sub_item(node_locator, item_name, parent)
def click_events_panel_expand_less_button(self) -> None: def click_events_panel_expand_less_button(self) -> None:
"""Выполняет нажатие кнопки галочка вверх.""" """Выполняет нажатие кнопки галочка вверх."""

View File

@ -4,6 +4,7 @@
панели навигации в приложении. панели навигации в приложении.
""" """
# import pytest
from playwright.sync_api import Page from playwright.sync_api import Page
from pages.main_page import MainPage from pages.main_page import MainPage
from pages.login_page import LoginPage from pages.login_page import LoginPage
@ -50,6 +51,7 @@ class TestNavigationPanel:
mp.expand_navigation_subpanel() mp.expand_navigation_subpanel()
# @pytest.mark.develop
def test_sub_panel_item_click(self, browser: Page): def test_sub_panel_item_click(self, browser: Page):
"""Проверяет возможность клика заданного элемента в подпанели навигации. """Проверяет возможность клика заданного элемента в подпанели навигации.
@ -69,13 +71,22 @@ class TestNavigationPanel:
# Проверяем наличие панели навигации # Проверяем наличие панели навигации
mp.should_be_navigation_panel() mp.should_be_navigation_panel()
# Открываем все пункты панели # Открываем разные пункты панели
mp.click_main_navigation_panel_item("Настройки") mp.click_main_navigation_panel_item("Настройки")
mp.click_subpanel_item("Обслуживание и диагностика") mp.click_subpanel_item("Обслуживание и диагностика")
mp.click_subpanel_item("Статус обслуживания") mp.click_subpanel_item("Статус обслуживания")
mp.wait_for_timeout(500) mp.wait_for_timeout(500)
# Открываем/закрываем пункт панели
mp.click_subpanel_item("Пользователи") mp.click_subpanel_item("Пользователи")
mp.click_subpanel_item("Пользователи") mp.click_subpanel_item("Пользователи")
mp.wait_for_timeout(500)
# Открываем пункты панели с одинаковыми имнами, но разным расположением
mp.click_subpanel_item("Шаблоны")
mp.wait_for_timeout(500)
mp.click_subpanel_item("Zero Touch Provisioning")
mp.click_subpanel_item("Шаблоны", parent="Zero Touch Provisioning")
mp.wait_for_timeout(500)