Изменено: в методе click_sub_item, убрана проверка 'Если не нашли среди непосредственных детей, ищем рекурсивно
parent
ccbd7a6727
commit
8a9228e75e
|
|
@ -47,80 +47,125 @@ class NavigationPanelComponent(BaseComponent):
|
|||
loc.get_by_text(item_name).click()
|
||||
|
||||
def click_sub_item(self, node_root_locator: str | Locator, item_name: str, parent: None|str) -> None:
|
||||
"""Кликает по вложенному элементу с указанным текстом.
|
||||
|
||||
Args:
|
||||
node_root_locator: Локатор для поиска корневых элементов дерева (Локатор элемента или строка с CSS/XPath).
|
||||
item_name: Текст элемента для клика.
|
||||
"""
|
||||
"""Кликает по вложенному элементу с указанным текстом."""
|
||||
|
||||
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_texts = root_node.all_inner_texts()
|
||||
"""Рекурсивно ищет элемент в дереве и кликает по нему."""
|
||||
|
||||
# Если искомый элемент находится на данном уровне, вычисляем локатор и делаем клик
|
||||
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
|
||||
# Если указан родитель, сначала находим его
|
||||
if parent:
|
||||
# Ищем родительский элемент
|
||||
parent_found = False
|
||||
nodes_count = root_locator.locator('>div.v-treeview-node').count()
|
||||
|
||||
# Если элемента нет, рекурсивно ищем дальше
|
||||
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
|
||||
|
||||
for index in range(nodes_count):
|
||||
node = root_locator.locator(f">div:nth-child({index + 1})").first
|
||||
# Получаем текст контента для точного сравнения
|
||||
content_locator = node.locator('div.v-treeview-node__content')
|
||||
if content_locator.count() > 0:
|
||||
content_text = content_locator.first.inner_text().strip()
|
||||
|
||||
# Извлекаем аттрибуты из корневого узла
|
||||
node_class_attr = node.get_attribute('class')
|
||||
# Ищем родителя в тексте контента
|
||||
if parent == content_text:
|
||||
parent_found = True
|
||||
|
||||
is_expanded = False
|
||||
has_children = False
|
||||
# Раскрываем родительский элемент если нужно
|
||||
toggle_buttons = node.locator(NavigationPanelLocators.TOGGLE_BUTTON)
|
||||
if toggle_buttons.count() > 0:
|
||||
class_attr = toggle_buttons.first.get_attribute('class')
|
||||
is_expanded = class_attr and "v-treeview-node__toggle--open" in class_attr
|
||||
|
||||
# Проверяем лист это или начало поддерева
|
||||
if "v-treeview-node--leaf" not in node_class_attr:
|
||||
# Проверяем, является ли узел раскрытым
|
||||
class_attr = node.locator(NavigationPanelLocators.TOGGLE_BUTTON).get_attribute('class')
|
||||
if "v-treeview-node__toggle--open" in class_attr:
|
||||
is_expanded = True
|
||||
if not is_expanded:
|
||||
toggle_buttons.first.click()
|
||||
page.wait_for_timeout(1000)
|
||||
|
||||
# Если узел закрыт можем его раскрыть
|
||||
if is_expanded is False:
|
||||
toggle_button = node.locator(NavigationPanelLocators.TOGGLE_BUTTON)
|
||||
toggle_button.click()
|
||||
# Ждем, пока дочерние элементы прогрузятся/появятся
|
||||
page.wait_for_timeout(300)
|
||||
is_expanded = True
|
||||
# После раскрытия ждем появления дочерних элементов
|
||||
page.wait_for_timeout(500)
|
||||
|
||||
# Проверяем, имеет ли узел дочерние элементы
|
||||
children_count = node.locator('>div.v-treeview-node__children').count()
|
||||
content = node.locator('>div.v-treeview-node__children').inner_html()
|
||||
if children_count > 0 and len(content) != 0:
|
||||
has_children = True
|
||||
# Ищем целевой элемент как непосредственного ребенка родителя
|
||||
children_locator = node.locator('>div.v-treeview-node__children')
|
||||
if children_locator.count() > 0:
|
||||
# Ищем среди непосредственных детей
|
||||
direct_children = children_locator.locator('>div.v-treeview-node')
|
||||
direct_children_count = direct_children.count()
|
||||
|
||||
# Рекурсивный вызов для дочерних элементов
|
||||
# Ищем дочерние элементы *внутри* текущего узла
|
||||
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:
|
||||
if parent is None:
|
||||
for child_index in range(direct_children_count):
|
||||
child_node = direct_children.nth(child_index)
|
||||
child_content = child_node.locator('div.v-treeview-node__content')
|
||||
if child_content.count() > 0:
|
||||
child_text = child_content.first.inner_text().strip()
|
||||
|
||||
if child_text == item_name:
|
||||
child_content.first.click()
|
||||
return True
|
||||
|
||||
# Если не нашли среди непосредственных детей, ищем рекурсивно
|
||||
for child_index in range(direct_children_count):
|
||||
child_node = direct_children.nth(child_index)
|
||||
found = find_and_click_item(page, children_locator, item_name, parent=None)
|
||||
if found:
|
||||
return True
|
||||
break
|
||||
|
||||
if not parent_found:
|
||||
# Рекурсивный поиск родителя в дочерних элементах
|
||||
for index in range(nodes_count):
|
||||
node = root_locator.locator(f">div:nth-child({index + 1})").first
|
||||
|
||||
# Проверяем, имеет ли узел дочерние элементы
|
||||
toggle_buttons = node.locator(NavigationPanelLocators.TOGGLE_BUTTON)
|
||||
if toggle_buttons.count() > 0:
|
||||
class_attr = toggle_buttons.first.get_attribute('class')
|
||||
is_expanded = class_attr and "v-treeview-node__toggle--open" in class_attr
|
||||
|
||||
if not is_expanded:
|
||||
toggle_buttons.first.click()
|
||||
page.wait_for_timeout(500)
|
||||
|
||||
children_locator = node.locator('>div.v-treeview-node__children')
|
||||
if children_locator.count() > 0:
|
||||
found = find_and_click_item(page, children_locator, item_name, parent)
|
||||
if found:
|
||||
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:
|
||||
toggle_button = node.locator(NavigationPanelLocators.TOGGLE_BUTTON)
|
||||
toggle_button.click()
|
||||
return False
|
||||
|
||||
# элемент с заданным именем не найден
|
||||
return False
|
||||
else:
|
||||
# Поиск без указания родителя
|
||||
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
|
||||
|
||||
# Получаем только текст контента
|
||||
content_locator = node.locator('div.v-treeview-node__content')
|
||||
if content_locator.count() > 0:
|
||||
content_text = content_locator.first.inner_text().strip()
|
||||
|
||||
if content_text == item_name:
|
||||
content_locator.first.click()
|
||||
return True
|
||||
|
||||
# Рекурсивный поиск в дочерних элементах
|
||||
node_class_attr = node.get_attribute('class')
|
||||
if "v-treeview-node--leaf" not in node_class_attr:
|
||||
toggle_buttons = node.locator(NavigationPanelLocators.TOGGLE_BUTTON)
|
||||
if toggle_buttons.count() > 0:
|
||||
class_attr = toggle_buttons.first.get_attribute('class')
|
||||
is_expanded = class_attr and "v-treeview-node__toggle--open" in class_attr
|
||||
|
||||
if not is_expanded:
|
||||
toggle_buttons.first.click()
|
||||
page.wait_for_timeout(500)
|
||||
|
||||
children_locator = node.locator('>div.v-treeview-node__children')
|
||||
if children_locator.count() > 0:
|
||||
found = find_and_click_item(page, children_locator, item_name, parent=None)
|
||||
if found:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
root_locator = self.get_locator(node_root_locator)
|
||||
found = find_and_click_item(self.page, root_locator, item_name, parent)
|
||||
|
|
|
|||
Loading…
Reference in New Issue