463 lines
21 KiB
Python
463 lines
21 KiB
Python
"""Модуль modal_add_local_user содержит класс для работы
|
||
с модальным окном добавления локального пользователя.
|
||
|
||
Класс AddLocalUserModalWindow наследует базовый функционал ModalWindowComponent
|
||
и реализует специфичные методы для работы с формами добавления пользователей.
|
||
"""
|
||
|
||
import re
|
||
from playwright.sync_api import Page
|
||
from tools.logger import get_logger
|
||
from locators.modal_window_locators import ModalWindowLocators
|
||
from elements.text_input_element import TextInput
|
||
from elements.text_element import Text
|
||
from elements.checkbox_element import Checkbox
|
||
from components.modal_window_component import ModalWindowComponent
|
||
from components.dropdown_list_component import DropdownList
|
||
from components.confirm_component import ConfirmComponent
|
||
from components_derived.selection_bar_component import SelectionBarComponent
|
||
|
||
logger = get_logger("ADD_USER_MODAL_WINDOW")
|
||
|
||
class AddUserModalWindow(ModalWindowComponent):
|
||
"""Модальное окно добавления нового пользователя.
|
||
|
||
Наследует ModalWindowComponent и добавляет элементы формы:
|
||
- Поля ввода (имя, пароль, email и др.)
|
||
- Чекбоксы (Блокировка, Push-уведомления)
|
||
- Выпадающий список ролей
|
||
- Кнопки действий
|
||
"""
|
||
|
||
def __init__(self, page: Page):
|
||
"""Инициализирует элементы формы добавления пользователя."""
|
||
|
||
super().__init__(page)
|
||
|
||
# Локаторы элементов формы
|
||
input_form_locator = ModalWindowLocators.INPUT_FORM_USER_DATA
|
||
|
||
# Настройка заголовка и кнопки закрытия тулбара
|
||
self.window_title = "Добавить нового пользователя"
|
||
locator_button_toolbar_close = (
|
||
self.page.get_by_role("navigation")
|
||
.filter(has_text=re.compile(self.window_title))
|
||
.get_by_role("button")
|
||
)
|
||
|
||
self.add_toolbar_title(self.window_title)
|
||
self.add_toolbar_button(locator_button_toolbar_close, "close")
|
||
|
||
elements_locators = self.get_input_fields_locators(page.locator(input_form_locator))
|
||
|
||
# Поле Тип авторизации
|
||
loc = elements_locators.get("Тип авторизации")
|
||
if loc:
|
||
auth_type_selector = SelectionBarComponent(page, loc.get_by_role("combobox"))
|
||
self.add_content_item("auth_type_selector", auth_type_selector)
|
||
|
||
# Поле Имя
|
||
loc = elements_locators.get("Имя").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_NAME)
|
||
name_input = TextInput(page, loc, "name_input")
|
||
self.add_content_item("name_input", name_input)
|
||
|
||
# Метка "Блокировка"
|
||
label_blocking_locator = self.page.locator(input_form_locator). \
|
||
locator("//label").get_by_text("Блокировка")
|
||
label_blocking = Text(
|
||
page,
|
||
label_blocking_locator,
|
||
"blocking_checkbox_label"
|
||
)
|
||
|
||
self.add_content_item("blocking_checkbox_label", label_blocking)
|
||
|
||
# Чекбокс "Блокировка"
|
||
checkbox_blocking = Checkbox(
|
||
page,
|
||
page.locator(input_form_locator).locator(ModalWindowLocators.INPUT_FORM_USER_DATA_CHECKBOX_BLOCKED),
|
||
"blocking"
|
||
)
|
||
self.add_content_item("blocking_checkbox", checkbox_blocking)
|
||
|
||
# Поле Роль
|
||
role_loc = elements_locators.get("Роль").get_by_role("combobox").first
|
||
role_input = TextInput(page, role_loc, "role_input")
|
||
self.add_content_item("role_input", role_input)
|
||
self.add_content_item("roles_list", DropdownList(page))
|
||
|
||
# Поле Пароль
|
||
loc = elements_locators.get("Пароль").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_PASSWORD)
|
||
password_input = TextInput(page, loc, "password_input")
|
||
self.add_content_item("password_input", password_input)
|
||
|
||
# Поле Комментарий
|
||
loc = elements_locators.get("Комментарий").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_COMMENT)
|
||
commentary_input = TextInput(page, loc, "commentary_input")
|
||
self.add_content_item("commentary_input", commentary_input)
|
||
|
||
# Поле E-mail
|
||
loc = elements_locators.get("E-mail").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_EMAIL)
|
||
email_input = TextInput(page, loc, "email_input")
|
||
self.add_content_item("email_input", email_input)
|
||
|
||
# Поле Номер для СМС
|
||
loc = elements_locators.get("Номер для СМС").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_SMS)
|
||
phone_input = TextInput(page, loc, "phone_input")
|
||
self.add_content_item("phone_input", phone_input)
|
||
|
||
# Метка "Подписка на Push-уведомления"
|
||
label_push_locator = self.page.locator(input_form_locator). \
|
||
locator("//label").get_by_text("Подписка на Push-уведомления")
|
||
label_push = Text(
|
||
page,
|
||
label_push_locator,
|
||
"push_notification_checkbox_label"
|
||
)
|
||
self.add_content_item("push_notification_checkbox_label", label_push)
|
||
|
||
# Чекбокс "Подписка на Push-уведомления"
|
||
checkbox_push = Checkbox(
|
||
page,
|
||
page.locator(input_form_locator).locator(ModalWindowLocators.INPUT_FORM_USER_DATA_CHECKBOX_PUSH_ACTIVE),
|
||
"push_notification"
|
||
)
|
||
self.add_content_item("push_notification_checkbox", checkbox_push)
|
||
|
||
# Добавление кнопок действий
|
||
locator_button_add = self.page.get_by_role("button", name="Добавить")
|
||
self.add_button(locator_button_add, "add")
|
||
|
||
locator_button_close = self.page.get_by_role("button", name="Закрыть")
|
||
self.add_button(locator_button_close, "close")
|
||
|
||
# Добавление компонента подтверждения/отмены заведения пользователя
|
||
self.new_user_confirm = ConfirmComponent(page, " Отмена ", " Добавить ")
|
||
|
||
# Действия:
|
||
def check_blocking_checkbox(self):
|
||
"""Включает чек-бокс Блокировка."""
|
||
|
||
self.get_content_item("blocking_checkbox").check(force=True)
|
||
|
||
def uncheck_blocking_checkbox(self):
|
||
"""Выключает чек-бокс Блокировка."""
|
||
|
||
self.get_content_item("blocking_checkbox").uncheck(force=True)
|
||
|
||
def check_push_notification_checkbox(self):
|
||
"""Включает чек-бокс Push-уведомления."""
|
||
|
||
self.get_content_item("push_notification_checkbox").check(force=True)
|
||
|
||
def uncheck_push_notification_checkbox(self):
|
||
"""Выключает чек-бокс Push-уведомления."""
|
||
|
||
self.get_content_item("push_notification_checkbox").uncheck(force=True)
|
||
|
||
def get_auth_type(self) -> str | None:
|
||
"""Возвращает текущее значение поля 'Тип авторизации'"""
|
||
|
||
auth_type = None
|
||
auth_type_selector = self.get_content_item("auth_type_selector")
|
||
if auth_type_selector:
|
||
values = auth_type_selector.get_selected_values()
|
||
auth_type = values[0]
|
||
return auth_type
|
||
|
||
def select_auth_type(self, auth_type: str) -> None:
|
||
"""Выбирает заданное значение поля 'Тип авторизации' из списка"""
|
||
|
||
auth_type_selector = self.get_content_item("auth_type_selector")
|
||
if auth_type_selector:
|
||
auth_type_selector.open_values_list()
|
||
auth_type_selector.select_value(auth_type)
|
||
|
||
def new_user(self, user_data):
|
||
"""Заполняет форму и добавляет нового пользователя.
|
||
|
||
Args:
|
||
user_data (dict): Данные пользователя (имя, роль, пароль и др.)
|
||
"""
|
||
|
||
auth_type = user_data.get("auth_type")
|
||
if auth_type is None:
|
||
auth_type = 'local'
|
||
|
||
current_auth_type = self.get_auth_type()
|
||
if current_auth_type != auth_type:
|
||
self.select_auth_type(auth_type)
|
||
|
||
if auth_type == "LDAP":
|
||
menu_locator = self.page.locator(ModalWindowLocators.MENU_ACTIVE_INPUT_FORM)
|
||
|
||
elements_locators = self.get_input_fields_locators(
|
||
self.page.locator(ModalWindowLocators.INPUT_FORM_USER_DATA))
|
||
|
||
# Добавилось поле Группа
|
||
group_loc = elements_locators.get("Группа").get_by_role("combobox")
|
||
group_input = TextInput(self.page, group_loc, "group_input")
|
||
self.add_content_item("group_input", group_input)
|
||
self.add_content_item("group_list", DropdownList(self.page))
|
||
|
||
# Добавилась кнопка Поиск
|
||
locator_button_search = self.page.get_by_role("button", name="Поиск")
|
||
self.add_button(locator_button_search, "search")
|
||
|
||
# Поиск и выбор заданной группы из списка существующих
|
||
group_field = self.get_content_item("group_input")
|
||
group_field.click()
|
||
|
||
group_name = user_data["group"]
|
||
group_list = self.get_content_item("group_list")
|
||
group_list.scroll_until_end(menu_locator)
|
||
group_names = group_list.get_item_names(menu_locator)
|
||
if group_name not in group_names:
|
||
assert False, f"Required group name {group_name} is missing"
|
||
|
||
group_list.check_item_with_text(group_name)
|
||
group_list.click_item_with_text(group_name)
|
||
|
||
# Нажатие кнопки "Поиск"
|
||
search_button = self.get_button_by_name("search")
|
||
search_button.click()
|
||
|
||
# Если в группе есть пользователи, открывается новое поле, заново вычисляем локаторы
|
||
elements_locators = self.get_input_fields_locators(
|
||
self.page.locator(ModalWindowLocators.INPUT_FORM_USER_DATA))
|
||
users_ad_loc = elements_locators.get("Пользователи AD")
|
||
# users_ad_loc = elements_locators.get("Пользователи LDAP")
|
||
assert users_ad_loc, f"Selected group {group_name} is empty. Use another group."
|
||
|
||
# Поиск и выбор заданного пользователя AD из списка существующих
|
||
user_ldap_loc = users_ad_loc.get_by_role("combobox")
|
||
user_ldap_input = TextInput(self.page, user_ldap_loc, "user__input")
|
||
self.add_content_item("user_ldap_input", user_ldap_input)
|
||
self.add_content_item(
|
||
"user_ldap_list",
|
||
DropdownList(self.page)
|
||
)
|
||
|
||
user_ldap_input.click()
|
||
user_ldap_list = self.get_content_item("user_ldap_list")
|
||
user_ldap_list.scroll_until_end(menu_locator)
|
||
user_ldap_names = group_list.get_item_names(menu_locator)
|
||
name_ldap = user_data.get("name_ldap")
|
||
if name_ldap not in user_ldap_names:
|
||
assert False, f"Required user name {name_ldap} is missing"
|
||
|
||
user_ldap_list.check_item_with_text(name_ldap)
|
||
user_ldap_list.click_item_with_text(name_ldap)
|
||
|
||
# Заново вычисляем локаторы полей ввода
|
||
self.locators_recalculation(is_active_directory=True)
|
||
|
||
# Заполнение поля "Имя" (ручной ввод) если задано
|
||
name = user_data.get("name")
|
||
if name:
|
||
input_field = self.get_content_item("name_input")
|
||
input_field.input_value(name)
|
||
|
||
fields = user_data.keys()
|
||
|
||
if "role" in fields:
|
||
role_field = self.get_content_item("role_input")
|
||
role_field.click()
|
||
|
||
roles_list = self.get_content_item("roles_list")
|
||
roles_list.check_item_with_text(user_data["role"])
|
||
roles_list.click_item_with_text(user_data["role"])
|
||
|
||
if "password" in fields:
|
||
input_field = self.get_content_item("password_input")
|
||
input_field.input_value(user_data["password"])
|
||
|
||
if "commentary" in fields:
|
||
input_field = self.get_content_item("commentary_input")
|
||
input_field.input_value(user_data["commentary"])
|
||
|
||
if "email" in fields:
|
||
input_field = self.get_content_item("email_input")
|
||
input_field.input_value(user_data["email"])
|
||
|
||
if "phone_number" in fields:
|
||
input_field = self.get_content_item("phone_input")
|
||
input_field.input_value(user_data["phone_number"])
|
||
|
||
if "blocking_checked" in fields:
|
||
checkbox = self.get_content_item("blocking_checkbox")
|
||
if user_data["blocking_checked"]:
|
||
checkbox.check()
|
||
else:
|
||
checkbox.uncheck()
|
||
|
||
if "push_notification_checked" in fields:
|
||
checkbox = self.get_content_item("push_notification_checkbox")
|
||
if user_data["push_notification_checked"]:
|
||
checkbox.check()
|
||
else:
|
||
checkbox.uncheck()
|
||
|
||
# Отправка формы
|
||
add_button = self.get_button_by_name("add")
|
||
add_button.click()
|
||
|
||
# Подтверждение действия
|
||
title = "Добавить нового пользователя"
|
||
self.new_user_confirm.check_title(
|
||
title,
|
||
f"Confirmation dialog window with title '{title}' is missing"
|
||
)
|
||
self.new_user_confirm.click_allow_button()
|
||
|
||
def close_window(self):
|
||
"""Закрывает модальное окно через кнопку 'Закрыть'."""
|
||
|
||
close_button = self.get_button_by_name("close")
|
||
close_button.click()
|
||
|
||
def close_window_by_toolbar_button(self):
|
||
"""Закрывает модальное окно через кнопку в тулбаре."""
|
||
|
||
self.click_toolbar_close_button()
|
||
|
||
def locators_recalculation(self, is_active_directory=False) -> None:
|
||
"""Пересчет локаторов полей ввода"""
|
||
|
||
elements_locators = self.get_input_fields_locators(
|
||
self.page.locator(ModalWindowLocators.INPUT_FORM_USER_DATA))
|
||
|
||
new_loc = elements_locators.get("Имя").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_NAME)
|
||
self.get_content_item("name_input").update_locator(new_loc)
|
||
|
||
if not is_active_directory:
|
||
new_loc = elements_locators.get("Пароль").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_PASSWORD)
|
||
self.get_content_item("password_input").update_locator(new_loc)
|
||
|
||
new_loc = elements_locators.get("Роль").get_by_role("combobox").first
|
||
self.get_content_item("role_input").update_locator(new_loc)
|
||
|
||
new_loc = elements_locators.get("Комментарий").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_COMMENT)
|
||
self.get_content_item("commentary_input").update_locator(new_loc)
|
||
|
||
new_loc = elements_locators.get("E-mail").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_EMAIL)
|
||
self.get_content_item("email_input").update_locator(new_loc)
|
||
|
||
new_loc = elements_locators.get("Номер для СМС").locator(ModalWindowLocators.INPUT_FORM_USER_DATA_FIELD_SMS)
|
||
self.get_content_item("phone_input").update_locator(new_loc)
|
||
|
||
# Проверки:
|
||
def check_content(self):
|
||
"""Проверяет наличие и корректность всех элементов формы создания локального пользователя.
|
||
Форма для создания keycloack пользователя имеет тот же набор полей.
|
||
"""
|
||
|
||
expected_auth_types = ['local', 'LDAP', 'keycloack']
|
||
expected_roles = ['$collector', 'Администратор',
|
||
'Специалист информационной безопасности',
|
||
'Контактное лицо', 'Оператор']
|
||
|
||
menu_locator = self.page.locator(ModalWindowLocators.MENU_ACTIVE_INPUT_FORM)
|
||
items_locator = menu_locator.locator(ModalWindowLocators.MENU_ACTIVE_ITEMS)
|
||
|
||
self.check_by_window_title()
|
||
|
||
self.check_toolbar_button_visibility("close")
|
||
self.check_toolbar_button_tooltip("close", "Закрыть")
|
||
|
||
input_fields = ["name_input", "password_input",
|
||
"commentary_input", "email_input", "phone_input"]
|
||
|
||
for name in self.content_items:
|
||
item = self.get_content_item(name)
|
||
|
||
if name == "blocking_checkbox_label":
|
||
item.check_have_text(
|
||
"Блокировка",
|
||
"Label 'Блокировка' is missing"
|
||
)
|
||
elif name == "push_notification_checkbox_label":
|
||
item.check_have_text(
|
||
"Подписка на Push-уведомления",
|
||
"Label 'Подписка на Push-уведомления' is missing"
|
||
)
|
||
elif name == "auth_type_selector":
|
||
current_auth_type = self.get_auth_type()
|
||
if current_auth_type is None:
|
||
continue
|
||
assert current_auth_type == 'local', "Default Auth Type value should be 'local'"
|
||
|
||
actual_auth_types = item.get_available_options(items_locator)
|
||
assert actual_auth_types == expected_auth_types, \
|
||
f"Actual auth types {actual_auth_types} are not equal expected values {expected_auth_types}."
|
||
elif name == "role_input":
|
||
item.click()
|
||
roles_list = self.get_content_item("roles_list")
|
||
roles_list.check_visibility(menu_locator, "Roles list is missing")
|
||
|
||
is_scrollable_vertically = roles_list.check_vertical_scrolling(menu_locator)
|
||
assert not is_scrollable_vertically, (
|
||
"Roles list should not be scrollable_vertically"
|
||
)
|
||
|
||
for role in expected_roles:
|
||
roles_list.check_item_with_text(role)
|
||
elif name in input_fields:
|
||
item.check_editable_input(
|
||
f"Input field with name '{name}' should be editable"
|
||
)
|
||
elif name == "roles_list":
|
||
continue
|
||
else:
|
||
# print(f"check item: {name}")
|
||
# print(item)
|
||
item.check_visibility(
|
||
f"Modal window content item with name '{name}' is missing"
|
||
)
|
||
|
||
# Дополнительная проверка состояния чекбоксов
|
||
blocking_checkbox = self.get_content_item("blocking_checkbox")
|
||
is_blocking_checked = blocking_checkbox.is_checked()
|
||
assert not is_blocking_checked, (
|
||
"Checkbox 'Блокировка' should not be checked by default"
|
||
)
|
||
|
||
push_checkbox = self.get_content_item("push_notification_checkbox")
|
||
is_push_checked = push_checkbox.is_checked()
|
||
assert not is_push_checked, (
|
||
"Checkbox 'Подписка на Push-уведомления' should not be checked by default"
|
||
)
|
||
|
||
# Выбор типа авторизации LDAP и проверка появления поля Группа и кнопки Поиск
|
||
auth_type_selector = self.get_content_item("auth_type_selector")
|
||
if auth_type_selector:
|
||
self.select_auth_type("LDAP")
|
||
|
||
elements_locators = self.get_input_fields_locators(
|
||
self.page.locator(ModalWindowLocators.INPUT_FORM_USER_DATA))
|
||
|
||
# Добавилось поле Группа
|
||
group_loc = elements_locators.get("Группа").get_by_role("combobox")
|
||
group_input = TextInput(self.page, group_loc, "group_input")
|
||
self.add_content_item("group_input", group_input)
|
||
self.add_content_item("group_list", DropdownList(self.page))
|
||
|
||
group_field = self.get_content_item("group_input")
|
||
group_field.click()
|
||
|
||
group_list = self.get_content_item("group_list")
|
||
group_list.check_visibility(menu_locator,
|
||
"Groups list is missing")
|
||
|
||
is_scrollable_vertically = group_list.check_vertical_scrolling(menu_locator)
|
||
assert is_scrollable_vertically, "Groups list should be scrollable_vertically"
|
||
self.page.keyboard.press("Escape")
|
||
|
||
# Добавилась кнопка Поиск
|
||
locator_button_search = self.page.get_by_role("button", name="Поиск")
|
||
self.add_button(locator_button_search, "search")
|
||
self.check_button_visibility("search")
|
||
|
||
self.check_button_visibility("add")
|
||
self.check_button_visibility("close")
|