refactor: переименовать InteractiveDropdownList в CheckboxGroupComponent
- Переименование и перенос компонента в папку components - Обновление импортов - Расширение функционала компонентаra6/create_rack
parent
0295852986
commit
b024fac0d8
|
|
@ -0,0 +1,155 @@
|
||||||
|
"""Модуль компонента группы чек-боксов.
|
||||||
|
|
||||||
|
Содержит класс CheckboxGroupComponent для работы с группами чек-боксов,
|
||||||
|
в том числе в выпадающих списках с множественным выбором.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
from playwright.sync_api import Page, Locator, expect
|
||||||
|
from tools.logger import get_logger
|
||||||
|
from components.base_component import BaseComponent
|
||||||
|
|
||||||
|
logger = get_logger("CHECKBOX_GROUP_COMPONENT")
|
||||||
|
|
||||||
|
class CheckboxGroupComponent(BaseComponent):
|
||||||
|
"""Компонент для работы с группами чек-боксов.
|
||||||
|
|
||||||
|
Позволяет выбирать/снимать выбор с чек-боксов в группе,
|
||||||
|
получать список выбранных элементов и проверять их состояние.
|
||||||
|
Может использоваться как для выпадающих списков с множественным выбором,
|
||||||
|
так и для любых других групп чек-боксов на странице.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, page: Page) -> None:
|
||||||
|
"""Инициализирует компонент группы чек-боксов.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
page: Экземпляр страницы Playwright.
|
||||||
|
"""
|
||||||
|
super().__init__(page)
|
||||||
|
|
||||||
|
def get_checkbox_locator(self, text: str, container_locator: Locator | None = None) -> Locator:
|
||||||
|
"""Возвращает локатор чек-бокса с указанным текстом.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
text (str): Текст элемента для выбора.
|
||||||
|
container_locator (Locator | None): Локатор контейнера с чек-боксами.
|
||||||
|
Если не указан, поиск по всей странице.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Locator: Локатор чек-бокса.
|
||||||
|
"""
|
||||||
|
if container_locator:
|
||||||
|
checkbox_locator = container_locator.get_by_role("listitem").filter(has_text=text).get_by_role("checkbox")
|
||||||
|
else:
|
||||||
|
checkbox_locator = self.page.get_by_role("listitem").filter(has_text=text).get_by_role("checkbox")
|
||||||
|
|
||||||
|
if checkbox_locator.count() > 1:
|
||||||
|
rtext = f"^{text}$"
|
||||||
|
if container_locator:
|
||||||
|
checkbox_locator = container_locator.get_by_role("listitem").filter(
|
||||||
|
has_text=re.compile(rtext)
|
||||||
|
).get_by_role("checkbox")
|
||||||
|
else:
|
||||||
|
checkbox_locator = self.page.get_by_role("listitem").filter(
|
||||||
|
has_text=re.compile(rtext)
|
||||||
|
).get_by_role("checkbox")
|
||||||
|
|
||||||
|
expect(checkbox_locator).to_be_visible(), \
|
||||||
|
f"Checkbox with text '{text}' is missing or not visible"
|
||||||
|
return checkbox_locator
|
||||||
|
|
||||||
|
def uncheck_by_text(self, text: str, container_locator: Locator | None = None) -> None:
|
||||||
|
"""Снимает выбор с чек-бокса по указанному тексту.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
text (str): Текст чек-бокса для снятия выбора.
|
||||||
|
container_locator (Locator | None): Локатор контейнера с чек-боксами.
|
||||||
|
"""
|
||||||
|
logger.info(f"Unchecking checkbox with text: {text}")
|
||||||
|
self.get_checkbox_locator(text, container_locator).uncheck(force=True)
|
||||||
|
|
||||||
|
def check_by_text(self, text: str, container_locator: Locator | None = None) -> None:
|
||||||
|
"""Выбирает чек-бокс по указанному тексту.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
text (str): Текст чек-бокса для выбора.
|
||||||
|
container_locator (Locator | None): Локатор контейнера с чек-боксами.
|
||||||
|
"""
|
||||||
|
logger.info(f"Checking checkbox with text: {text}")
|
||||||
|
self.get_checkbox_locator(text, container_locator).check(force=True)
|
||||||
|
|
||||||
|
def get_checked_items(self, container_locator: str | Locator) -> list[str]:
|
||||||
|
"""Возвращает список текстов отмеченных чек-боксов.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
container_locator (str | Locator): Локатор контейнера с группой чек-боксов.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[str]: Список текстов выбранных чек-боксов.
|
||||||
|
"""
|
||||||
|
checked_items = []
|
||||||
|
list_container = self.get_locator(container_locator)
|
||||||
|
items = list_container.get_by_role("listitem").all()
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
if item.get_by_role("checkbox").is_checked():
|
||||||
|
item_text = item.text_content().strip()
|
||||||
|
if item_text:
|
||||||
|
checked_items.append(item_text)
|
||||||
|
|
||||||
|
logger.info(f"Checked items: {checked_items}")
|
||||||
|
return checked_items
|
||||||
|
|
||||||
|
def are_items_checked(self, container_locator: str | Locator, expected_items: list[str]) -> bool:
|
||||||
|
"""Проверяет, что указанные чек-боксы выбраны.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
container_locator (str | Locator): Локатор контейнера с группой чек-боксов.
|
||||||
|
expected_items (list[str]): Список ожидаемых выбранных элементов.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True если все указанные чек-боксы выбраны.
|
||||||
|
"""
|
||||||
|
checked_items = self.get_checked_items(container_locator)
|
||||||
|
return all(item in checked_items for item in expected_items)
|
||||||
|
|
||||||
|
def check_all(self, container_locator: str | Locator) -> None:
|
||||||
|
"""Выбирает все чек-боксы в группе.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
container_locator (str | Locator): Локатор контейнера с группой чек-боксов.
|
||||||
|
"""
|
||||||
|
logger.info("Checking all checkboxes in group")
|
||||||
|
list_container = self.get_locator(container_locator)
|
||||||
|
checkboxes = list_container.get_by_role("checkbox").all()
|
||||||
|
|
||||||
|
for checkbox in checkboxes:
|
||||||
|
if not checkbox.is_checked():
|
||||||
|
checkbox.check(force=True)
|
||||||
|
|
||||||
|
def uncheck_all(self, container_locator: str | Locator) -> None:
|
||||||
|
"""Снимает выбор со всех чек-боксов в группе.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
container_locator (str | Locator): Локатор контейнера с группой чек-боксов.
|
||||||
|
"""
|
||||||
|
logger.info("Unchecking all checkboxes in group")
|
||||||
|
list_container = self.get_locator(container_locator)
|
||||||
|
checkboxes = list_container.get_by_role("checkbox").all()
|
||||||
|
|
||||||
|
for checkbox in checkboxes:
|
||||||
|
if checkbox.is_checked():
|
||||||
|
checkbox.uncheck(force=True)
|
||||||
|
|
||||||
|
def get_items_count(self, container_locator: str | Locator) -> int:
|
||||||
|
"""Возвращает количество чек-боксов в группе.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
container_locator (str | Locator): Локатор контейнера с группой чек-боксов.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: Количество чек-боксов.
|
||||||
|
"""
|
||||||
|
list_container = self.get_locator(container_locator)
|
||||||
|
return list_container.get_by_role("checkbox").count()
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
"""Модуль interactive_dropdown_list_component содержит класс для работы с интерактивными выпадающими списками,
|
|
||||||
позволяющими сделать выбор нескольких элементов.
|
|
||||||
|
|
||||||
Класс InteractiveDropdownList наследует базовый функционал BaseComponent и добавляет
|
|
||||||
методы для взаимодействия с интерактивными выпадающими списками на странице.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import re
|
|
||||||
from playwright.sync_api import Page, Locator, expect
|
|
||||||
from tools.logger import get_logger
|
|
||||||
from components.base_component import BaseComponent
|
|
||||||
|
|
||||||
logger = get_logger("INTERACTIVE_DROPDOWN_LIST")
|
|
||||||
|
|
||||||
class InteractiveDropdownList(BaseComponent):
|
|
||||||
"""Класс для работы с выпадающими списками.
|
|
||||||
|
|
||||||
Наследует функциональность BaseElement и добавляет специфичные
|
|
||||||
методы для выбора и проверки элементов списка.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, page: Page) -> None:
|
|
||||||
"""Инициализирует компонент интерактивного выпадающего списка.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
page: Экземпляр страницы Playwright.
|
|
||||||
"""
|
|
||||||
|
|
||||||
super().__init__(page)
|
|
||||||
|
|
||||||
# Действия:
|
|
||||||
def get_checkbox_locator(self, text: str) -> Locator:
|
|
||||||
"""Возвращает локатор чек-бокса для элемента списка с указанным текстом.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
text (str): Текст элемента для выбора.
|
|
||||||
"""
|
|
||||||
|
|
||||||
checkbox_locator = self.page.get_by_role("listitem").filter(has_text=text).get_by_role("checkbox")
|
|
||||||
if checkbox_locator.count() > 1:
|
|
||||||
rtext = f"^{text}$"
|
|
||||||
checkbox_locator = self.page.get_by_role("listitem").filter(
|
|
||||||
has_text=re.compile(rtext)
|
|
||||||
).get_by_role("checkbox")
|
|
||||||
|
|
||||||
expect(checkbox_locator).to_be_visible(), \
|
|
||||||
f"Checkbox for dropdown list item with text {text} is missing"
|
|
||||||
return checkbox_locator
|
|
||||||
|
|
||||||
def deselect_item_with_text(self, text: str) -> None:
|
|
||||||
"""Выбирает элемент списка по указанному тексту.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
text (str): Текст элемента для выбора.
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.get_checkbox_locator(text).uncheck(force=True)
|
|
||||||
|
|
||||||
def select_item_with_text(self, text: str) -> None:
|
|
||||||
"""Выбирает элемент списка по указанному тексту.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
text (str): Текст элемента для выбора.
|
|
||||||
"""
|
|
||||||
self.get_checkbox_locator(text).check(force=True)
|
|
||||||
|
|
||||||
def get_selected_items(self, locator: str|Locator) -> list[str]:
|
|
||||||
"""Возвращает список отмеченных элементов."""
|
|
||||||
|
|
||||||
selected_items = []
|
|
||||||
|
|
||||||
list_locator = self.get_locator(locator)
|
|
||||||
|
|
||||||
items = list_locator.get_by_role("listitem").all()
|
|
||||||
|
|
||||||
for item in items:
|
|
||||||
if item.get_by_role("checkbox").is_checked():
|
|
||||||
item_text = item.text_content().strip()
|
|
||||||
if item_text:
|
|
||||||
selected_items.append(item_text)
|
|
||||||
|
|
||||||
return selected_items
|
|
||||||
|
|
||||||
# Проверки:
|
|
||||||
|
|
@ -9,7 +9,7 @@ from locators.settings_form_locators import SettingsFormLocators
|
||||||
from elements.text_input_element import TextInput
|
from elements.text_input_element import TextInput
|
||||||
from components.alert_component import AlertComponent
|
from components.alert_component import AlertComponent
|
||||||
from components_derived.settings_form_component import SettingsFormComponent
|
from components_derived.settings_form_component import SettingsFormComponent
|
||||||
from components_derived.interactive_dropdown_list import InteractiveDropdownList
|
from components.checkbox_group_component import CheckboxGroupComponent # Изменен импорт
|
||||||
from pages.base_page import BasePage
|
from pages.base_page import BasePage
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -40,13 +40,13 @@ class PushNotificationsSettingsTab(BasePage):
|
||||||
message_setting_input = TextInput(page, loc_message_input, "message_setting_input")
|
message_setting_input = TextInput(page, loc_message_input, "message_setting_input")
|
||||||
self.settings_form.add_content_item("message_setting_input", message_setting_input)
|
self.settings_form.add_content_item("message_setting_input", message_setting_input)
|
||||||
|
|
||||||
|
|
||||||
loc = self.input_fields_locators.get("Пользователи")
|
loc = self.input_fields_locators.get("Пользователи")
|
||||||
users_setting_input = TextInput(page,
|
users_setting_input = TextInput(page,
|
||||||
loc.get_by_role("combobox"),
|
loc.get_by_role("combobox"),
|
||||||
"users_setting_input")
|
"users_setting_input")
|
||||||
self.settings_form.add_content_item("users_setting_input", users_setting_input)
|
self.settings_form.add_content_item("users_setting_input", users_setting_input)
|
||||||
self.settings_form.add_content_item("users_list", InteractiveDropdownList(page))
|
# Используем новый компонент CheckboxGroupComponent
|
||||||
|
self.settings_form.add_content_item("users_checkbox_group", CheckboxGroupComponent(page))
|
||||||
|
|
||||||
self.settings_form.add_tooltip_button(page.locator(SettingsFormLocators.PUSH_NOTIFICATIONS_BUTTON_SUBMIT),
|
self.settings_form.add_tooltip_button(page.locator(SettingsFormLocators.PUSH_NOTIFICATIONS_BUTTON_SUBMIT),
|
||||||
"submit_button")
|
"submit_button")
|
||||||
|
|
@ -104,10 +104,10 @@ class PushNotificationsSettingsTab(BasePage):
|
||||||
assert len(users) != 0, "Users list should not be empty"
|
assert len(users) != 0, "Users list should not be empty"
|
||||||
|
|
||||||
self.settings_form.get_content_item("users_setting_input").click()
|
self.settings_form.get_content_item("users_setting_input").click()
|
||||||
users_list = self.settings_form.get_content_item("users_list")
|
users_checkbox_group = self.settings_form.get_content_item("users_checkbox_group")
|
||||||
|
|
||||||
for user in users:
|
for user in users:
|
||||||
users_list.deselect_item_with_text(user)
|
users_checkbox_group.uncheck_by_text(user)
|
||||||
|
|
||||||
# Закрываем выпадающий список (кликаем вне его)
|
# Закрываем выпадающий список (кликаем вне его)
|
||||||
self.page.mouse.click(10, 10)
|
self.page.mouse.click(10, 10)
|
||||||
|
|
@ -118,10 +118,10 @@ class PushNotificationsSettingsTab(BasePage):
|
||||||
assert len(users) != 0, "Users list should not be empty"
|
assert len(users) != 0, "Users list should not be empty"
|
||||||
|
|
||||||
self.settings_form.get_content_item("users_setting_input").click()
|
self.settings_form.get_content_item("users_setting_input").click()
|
||||||
users_list = self.settings_form.get_content_item("users_list")
|
users_checkbox_group = self.settings_form.get_content_item("users_checkbox_group")
|
||||||
|
|
||||||
for user in users:
|
for user in users:
|
||||||
users_list.select_item_with_text(user)
|
users_checkbox_group.check_by_text(user)
|
||||||
|
|
||||||
# Закрываем выпадающий список (кликаем вне его)
|
# Закрываем выпадающий список (кликаем вне его)
|
||||||
self.page.mouse.click(10, 10)
|
self.page.mouse.click(10, 10)
|
||||||
|
|
@ -142,10 +142,10 @@ class PushNotificationsSettingsTab(BasePage):
|
||||||
f"Misscomparison input field names: Expected {expected_input_field_names}, Actual {actual_input_field_names}"
|
f"Misscomparison input field names: Expected {expected_input_field_names}, Actual {actual_input_field_names}"
|
||||||
|
|
||||||
for name in self.settings_form.content_items.keys():
|
for name in self.settings_form.content_items.keys():
|
||||||
if name == "users_list":
|
if name == "users_checkbox_group":
|
||||||
self.settings_form.get_content_item("users_setting_input").click()
|
self.settings_form.get_content_item("users_setting_input").click()
|
||||||
users_list = self.settings_form.get_content_item(name)
|
users_checkbox_group = self.settings_form.get_content_item(name)
|
||||||
selected_users = users_list.get_selected_items(SettingsFormLocators.DROPDOWN_LIST)
|
selected_users = users_checkbox_group.get_checked_items(SettingsFormLocators.DROPDOWN_LIST)
|
||||||
assert len(selected_users) == 0, "There should be no selected users"
|
assert len(selected_users) == 0, "There should be no selected users"
|
||||||
else:
|
else:
|
||||||
item = self.settings_form.get_content_item(name)
|
item = self.settings_form.get_content_item(name)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue