feat: добавление метода is_item_visible в навигационную панель
- Добавлен метод для проверки видимости элемента без исключений - Возвращает boolean значение для условных проверокradislav/tests_rack
parent
610d13575d
commit
27ca4596fa
|
|
@ -21,20 +21,6 @@ class NavigationPanelComponent(BaseComponent):
|
||||||
super().__init__(page)
|
super().__init__(page)
|
||||||
|
|
||||||
# Действия:
|
# Действия:
|
||||||
def get_item_names(self, locator: str | Locator) -> list[str]:
|
|
||||||
"""Возвращает тексты всех элементов по указанному локатору.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
locator: Локатор элементов или строка с CSS/XPath.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Список текстов элементов.
|
|
||||||
"""
|
|
||||||
|
|
||||||
loc = self.get_locator(locator)
|
|
||||||
return loc.all_inner_texts()
|
|
||||||
|
|
||||||
|
|
||||||
def click_item(self, locator: str | Locator, item_name: str) -> None:
|
def click_item(self, locator: str | Locator, item_name: str) -> None:
|
||||||
"""Кликает по элементу с указанным текстом.
|
"""Кликает по элементу с указанным текстом.
|
||||||
|
|
||||||
|
|
@ -50,13 +36,12 @@ class NavigationPanelComponent(BaseComponent):
|
||||||
"""Кликает по вложенному элементу с указанным текстом.
|
"""Кликает по вложенному элементу с указанным текстом.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
node_root_locator: Локатор для поиска корневых элементов дерева (Локатор элемента или строка с CSS/XPath).
|
node_root_locator: Локатор для поиска корневых элементов дерева.
|
||||||
item_name: Текст элемента для клика.
|
item_name: Текст элемента для клика.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def find_and_click_item(page, root_locator, item_name: str, parent: None|str) -> Locator|None:
|
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')
|
|
||||||
nodes_count = root_locator.locator('>div.v-treeview-node').count()
|
nodes_count = root_locator.locator('>div.v-treeview-node').count()
|
||||||
|
|
||||||
# Если искомый элемент находится на данном уровне, вычисляем локатор и делаем клик
|
# Если искомый элемент находится на данном уровне, вычисляем локатор и делаем клик
|
||||||
|
|
@ -69,9 +54,9 @@ class NavigationPanelComponent(BaseComponent):
|
||||||
if item_name == node_text:
|
if item_name == node_text:
|
||||||
node_attr = node.get_attribute('class')
|
node_attr = node.get_attribute('class')
|
||||||
if "v-treeview-node--leaf" not in node_attr:
|
if "v-treeview-node--leaf" not in node_attr:
|
||||||
toggle_button = node.\
|
toggle_button = node.locator(
|
||||||
locator(NavigationPanelLocators.NODE_ROOT). \
|
NavigationPanelLocators.NODE_ROOT
|
||||||
locator(NavigationPanelLocators.TOGGLE_BUTTON).first
|
).locator(NavigationPanelLocators.TOGGLE_BUTTON).first
|
||||||
toogle_class_attr = toggle_button.get_attribute('class')
|
toogle_class_attr = toggle_button.get_attribute('class')
|
||||||
if "v-treeview-node__toggle--open" not in toogle_class_attr:
|
if "v-treeview-node__toggle--open" not in toogle_class_attr:
|
||||||
toggle_button.click()
|
toggle_button.click()
|
||||||
|
|
@ -93,17 +78,17 @@ class NavigationPanelComponent(BaseComponent):
|
||||||
# Проверяем лист это или начало поддерева
|
# Проверяем лист это или начало поддерева
|
||||||
if "v-treeview-node--leaf" not in node_class_attr:
|
if "v-treeview-node--leaf" not in node_class_attr:
|
||||||
# Проверяем, является ли узел раскрытым
|
# Проверяем, является ли узел раскрытым
|
||||||
class_attr = node.\
|
class_attr = node.locator(
|
||||||
locator(NavigationPanelLocators.NODE_ROOT). \
|
NavigationPanelLocators.NODE_ROOT
|
||||||
locator(NavigationPanelLocators.TOGGLE_BUTTON).first.get_attribute('class')
|
).locator(NavigationPanelLocators.TOGGLE_BUTTON).first.get_attribute('class')
|
||||||
if "v-treeview-node__toggle--open" in class_attr:
|
if "v-treeview-node__toggle--open" in class_attr:
|
||||||
is_expanded = True
|
is_expanded = True
|
||||||
|
|
||||||
# Если узел закрыт можем его раскрыть
|
# Если узел закрыт можем его раскрыть
|
||||||
if is_expanded is False:
|
if is_expanded is False:
|
||||||
toggle_button = node.\
|
toggle_button = node.locator(
|
||||||
locator(NavigationPanelLocators.NODE_ROOT). \
|
NavigationPanelLocators.NODE_ROOT
|
||||||
locator(NavigationPanelLocators.TOGGLE_BUTTON).first
|
).locator(NavigationPanelLocators.TOGGLE_BUTTON).first
|
||||||
toggle_button.click()
|
toggle_button.click()
|
||||||
# Ждем, пока дочерние элементы прогрузятся/появятся
|
# Ждем, пока дочерние элементы прогрузятся/появятся
|
||||||
page.wait_for_timeout(1000)
|
page.wait_for_timeout(1000)
|
||||||
|
|
@ -118,21 +103,27 @@ 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(
|
||||||
found_loc = find_and_click_item(page, child_nodes_locator, item_name, parent=None)
|
f">div:nth-child({index + 1})"
|
||||||
|
).locator('>div.v-treeview-node__children')
|
||||||
|
found_loc = find_and_click_item(
|
||||||
|
page, child_nodes_locator, item_name, parent=None
|
||||||
|
)
|
||||||
if found_loc:
|
if found_loc:
|
||||||
if parent is None:
|
if parent is None:
|
||||||
return found_loc
|
return found_loc
|
||||||
else:
|
else:
|
||||||
root_texts = root_locator.locator(f">div:nth-child({index + 1})").inner_text().splitlines()
|
root_texts = root_locator.locator(
|
||||||
|
f">div:nth-child({index + 1})"
|
||||||
|
).inner_text().splitlines()
|
||||||
if parent in root_texts:
|
if parent in root_texts:
|
||||||
return found_loc
|
return found_loc
|
||||||
|
|
||||||
# закрываем узел, если в нем ничего не нашли
|
# закрываем узел, если в нем ничего не нашли
|
||||||
if is_expanded:
|
if is_expanded:
|
||||||
toggle_button = node.\
|
toggle_button = node.locator(
|
||||||
locator(NavigationPanelLocators.NODE_ROOT). \
|
NavigationPanelLocators.NODE_ROOT
|
||||||
locator(NavigationPanelLocators.TOGGLE_BUTTON).first
|
).locator(NavigationPanelLocators.TOGGLE_BUTTON).first
|
||||||
toggle_button.click()
|
toggle_button.click()
|
||||||
page.wait_for_timeout(1000)
|
page.wait_for_timeout(1000)
|
||||||
|
|
||||||
|
|
@ -142,17 +133,33 @@ class NavigationPanelComponent(BaseComponent):
|
||||||
root_locator = self.get_locator(node_root_locator)
|
root_locator = self.get_locator(node_root_locator)
|
||||||
if parent:
|
if parent:
|
||||||
parent_loc = find_and_click_item(self.page, root_locator, parent, parent=None)
|
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)
|
found = find_and_click_item(
|
||||||
|
self.page, parent_loc.locator('>div.v-treeview-node__children'),
|
||||||
|
item_name, parent=None
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
found = find_and_click_item(self.page, root_locator, item_name, parent=None)
|
found = find_and_click_item(self.page, root_locator, item_name, parent=None)
|
||||||
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 get_item_names(self, locator: str | Locator) -> list[str]:
|
||||||
"""
|
"""Возвращает тексты всех элементов по указанному локатору.
|
||||||
Рекурсивно обходит дерево v-treeview и выводит информацию об элементах в режиме отладки (debug=True).
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
node_root_locator: Локатор для поиска корневых элементов дерева (Локатор элемента или строка с CSS/XPath).
|
locator: Локатор элементов или строка с CSS/XPath.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Список текстов элементов.
|
||||||
|
"""
|
||||||
|
|
||||||
|
loc = self.get_locator(locator)
|
||||||
|
return loc.all_inner_texts()
|
||||||
|
|
||||||
|
def traverse_panel_tree(self, node_root_locator: str | Locator, level=0, debug=False):
|
||||||
|
"""
|
||||||
|
Рекурсивно обходит дерево v-treeview и выводит информацию об элементах.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
node_root_locator: Локатор для поиска корневых элементов дерева.
|
||||||
"""
|
"""
|
||||||
def traverse_tree(page, root_locator, level=0, debug=False):
|
def traverse_tree(page, root_locator, level=0, debug=False):
|
||||||
# Находим все локаторы корневых узлов на текущем уровне
|
# Находим все локаторы корневых узлов на текущем уровне
|
||||||
|
|
@ -171,7 +178,8 @@ class NavigationPanelComponent(BaseComponent):
|
||||||
# Проверяем лист это или начало поддерева
|
# Проверяем лист это или начало поддерева
|
||||||
if "v-treeview-node--leaf" in node_class_attr:
|
if "v-treeview-node--leaf" in node_class_attr:
|
||||||
if debug:
|
if debug:
|
||||||
print(f'[{level}][{index}] {node_text} (LEAF, Expanded: {is_expanded}, Has Children: {has_children})')
|
leaf_msg = f'[{level}][{index}] {node_text} (LEAF, Expanded: {is_expanded}'
|
||||||
|
print(f"{leaf_msg}, Has Children: {has_children})")
|
||||||
print("-----------------------------------------")
|
print("-----------------------------------------")
|
||||||
else:
|
else:
|
||||||
# Проверяем, является ли узел раскрытым
|
# Проверяем, является ли узел раскрытым
|
||||||
|
|
@ -198,13 +206,16 @@ class NavigationPanelComponent(BaseComponent):
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
# Выводим информацию об узле
|
# Выводим информацию об узле
|
||||||
print(f'[{level}][{index}] {edited_node_text} (NODE, Expanded: {is_expanded}, Has Children: {has_children})')
|
node_msg = f'[{level}][{index}] {edited_node_text} (NODE, Expanded: {is_expanded}'
|
||||||
|
print(f"{node_msg}, Has Children: {has_children})")
|
||||||
print("-----------------------------------------")
|
print("-----------------------------------------")
|
||||||
|
|
||||||
# Рекурсивный вызов для дочерних элементов
|
# Рекурсивный вызов для дочерних элементов
|
||||||
# Ищем дочерние элементы *внутри* текущего узла
|
# Ищем дочерние элементы *внутри* текущего узла
|
||||||
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')
|
||||||
traverse_tree(page, child_nodes_locator, level+1, debug)
|
traverse_tree(page, child_nodes_locator, level+1, debug)
|
||||||
|
|
||||||
root_locator = self.get_locator(node_root_locator)
|
root_locator = self.get_locator(node_root_locator)
|
||||||
|
|
@ -235,3 +246,22 @@ class NavigationPanelComponent(BaseComponent):
|
||||||
else:
|
else:
|
||||||
loc = loc.get_by_text(item_name)
|
loc = loc.get_by_text(item_name)
|
||||||
self.check_visibility(loc, msg)
|
self.check_visibility(loc, msg)
|
||||||
|
|
||||||
|
def is_item_visible(self, locator: str | Locator, item_name: str) -> bool:
|
||||||
|
"""
|
||||||
|
Проверяет видимость элемента с указанным текстом без выбрасывания исключения.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
locator: Локатор элемента или строка с CSS/XPath.
|
||||||
|
item_name: Текст элемента для проверки.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True если элемент видим, False если нет.
|
||||||
|
"""
|
||||||
|
element_locator = self.page.locator(locator).filter(has_text=item_name)
|
||||||
|
|
||||||
|
# Сначала проверяем что элемент вообще существует
|
||||||
|
if element_locator.count() == 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return element_locator.is_visible()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue