Merge branch 'main' of http://192.168.2.61/AlexL/e-nms_qa_automation
commit
73123bceda
|
|
@ -3,8 +3,8 @@
|
|||
Класс DropdownList наследует базовый функционал BaseComponent и добавляет
|
||||
методы для взаимодействия с выпадающими списками на странице.
|
||||
"""
|
||||
|
||||
from playwright.sync_api import Page
|
||||
import re
|
||||
from playwright.sync_api import Page, Locator
|
||||
from tools.logger import get_logger
|
||||
from components.base_component import BaseComponent
|
||||
|
||||
|
|
@ -34,7 +34,59 @@ class DropdownList(BaseComponent):
|
|||
text (str): Текст элемента для выбора.
|
||||
"""
|
||||
|
||||
self.page.get_by_role("listitem").filter(has_text=text).click()
|
||||
element = self.page.get_by_role("listitem").filter(has_text=text)
|
||||
if element.count() > 1:
|
||||
rtext = f"^{text}$"
|
||||
element = self.page.get_by_role("listitem").filter(has_text=re.compile(rtext))
|
||||
element.click()
|
||||
|
||||
def get_item_names(self, locator: str | Locator) -> list[str]:
|
||||
"""Возвращает тексты всех элементов по указанному локатору.
|
||||
|
||||
Args:
|
||||
locator: Локатор элементов или строка с CSS/XPath.
|
||||
|
||||
Returns:
|
||||
Список текстов элементов.
|
||||
"""
|
||||
|
||||
loc = self.get_locator(locator)
|
||||
texts = loc.all_inner_texts()
|
||||
return texts[0].splitlines()
|
||||
|
||||
def scroll_until_end(self, locator: str | Locator) -> None:
|
||||
"""
|
||||
Скроллит список до тех пор, пока не перестанут подгружаться новые элементы.
|
||||
|
||||
Args:
|
||||
locator: Локатор элементов или строка с CSS/XPath.
|
||||
"""
|
||||
|
||||
loc = self.get_locator(locator)
|
||||
|
||||
items_count = 0
|
||||
attempts = 0
|
||||
max_attempts = 3
|
||||
last_item_name = ""
|
||||
|
||||
while attempts < max_attempts:
|
||||
self.page.wait_for_timeout(300)
|
||||
|
||||
item_names = self.get_item_names(loc)
|
||||
current_count = len(item_names)
|
||||
|
||||
if current_count == items_count:
|
||||
attempts += 1
|
||||
else:
|
||||
items_count = current_count
|
||||
attempts = 0
|
||||
|
||||
last_item_name = item_names[current_count-1]
|
||||
element = self.page.get_by_role("listitem").filter(has_text=last_item_name)
|
||||
element.scroll_into_view_if_needed()
|
||||
|
||||
self.page.wait_for_timeout(300)
|
||||
self.check_item_with_text(last_item_name)
|
||||
|
||||
# Проверки:
|
||||
def check_item_with_text(self, text: str) -> None:
|
||||
|
|
@ -47,6 +99,36 @@ class DropdownList(BaseComponent):
|
|||
AssertionError: Если элемент отсутствует или недоступен.
|
||||
"""
|
||||
|
||||
enabled = self.page.get_by_role("listitem").filter(has_text=text).is_enabled()
|
||||
element = self.page.get_by_role("listitem").filter(has_text=text)
|
||||
if element.count() > 1:
|
||||
rtext = f"^{text}$"
|
||||
element = self.page.get_by_role("listitem").filter(has_text=re.compile(rtext))
|
||||
enabled = element.is_enabled()
|
||||
if not enabled:
|
||||
assert False, f"Dropdown list item '{text}' is missing or disabled"
|
||||
|
||||
def check_vertical_scrolling(self, locator: str | Locator) -> bool:
|
||||
"""
|
||||
Проверяет функцию вертикального скроллинга списка.
|
||||
|
||||
Args:
|
||||
locator: Локатор элементов или строка с CSS/XPath.
|
||||
|
||||
Returns:
|
||||
True или False значение в зависимости от скроллируемый список или нет.
|
||||
"""
|
||||
|
||||
loc = self.get_locator(locator)
|
||||
|
||||
is_scrollable_vertically = self.is_scrollable_vertically(loc)
|
||||
if is_scrollable_vertically:
|
||||
self.scroll_until_end(loc)
|
||||
|
||||
item_names = self.get_item_names(loc)
|
||||
first_item_name = item_names[0]
|
||||
|
||||
self.scroll_up(loc)
|
||||
self.page.wait_for_timeout(300)
|
||||
self.check_item_with_text(first_item_name)
|
||||
|
||||
return is_scrollable_vertically
|
||||
|
|
|
|||
|
|
@ -55,6 +55,12 @@ class BaseElement:
|
|||
logger.info(f"Get text for {self.type_of} '{self.name}'")
|
||||
return self.locator.nth(index).text_content()
|
||||
|
||||
def update_locator(self, new_locator: Locator) -> None:
|
||||
"""Меняет значение локатора для элемента"""
|
||||
|
||||
logger.info(f"Update locator for {self.type_of} '{self.name}'")
|
||||
self.locator = new_locator
|
||||
|
||||
def wait_for_element(self, timeout: int = 12000) -> None:
|
||||
"""Ожидает появление элемента в течение заданного времени."""
|
||||
|
||||
|
|
|
|||
|
|
@ -28,17 +28,23 @@ class Checkbox(BaseElement):
|
|||
return "checkbox"
|
||||
|
||||
# Действия:
|
||||
def check(self) -> None:
|
||||
def check(self, force=False) -> None:
|
||||
"""Отмечает чекбокс (устанавливает галочку)."""
|
||||
|
||||
logger.info(f"Checking checkbox '{self.name}'")
|
||||
self.locator.check()
|
||||
if force:
|
||||
self.locator.check(force=True)
|
||||
else:
|
||||
self.locator.check()
|
||||
|
||||
def uncheck(self) -> None:
|
||||
def uncheck(self, force=False) -> None:
|
||||
"""Снимает отметку с чекбокса (убирает галочку)."""
|
||||
|
||||
logger.info(f"Unchecking checkbox '{self.name}'")
|
||||
self.locator.uncheck()
|
||||
if force:
|
||||
self.locator.uncheck(force=True)
|
||||
else:
|
||||
self.locator.uncheck()
|
||||
|
||||
# Проверки:
|
||||
def is_checked(self) -> bool:
|
||||
|
|
|
|||
|
|
@ -11,10 +11,7 @@ class ModalWindowLocators:
|
|||
MODAL_WINDOW (str): активного модального окна
|
||||
INPUT_FORM_USER_DATA (str): формы ввода пользовательских данных
|
||||
TEXT_FIELD_INPUT_FORM_USER_DATA (str): текстового поля ввода
|
||||
|
||||
ROLES_FIELD_INPUT_FORM_USER_DATA (str): поля выбора ролей
|
||||
|
||||
ROLES_MENU_INPUT_FORM_USER_DATA (str): меню выбора ролей
|
||||
MENU_INPUT_FORM_USER_DATA (str): меню выбора ролей
|
||||
LABEL_INPUT_FORM_USER_DATA (str): метки поля ввода
|
||||
"""
|
||||
|
||||
|
|
@ -22,6 +19,5 @@ class ModalWindowLocators:
|
|||
|
||||
INPUT_FORM_USER_DATA = "//form[@class='v-form']"
|
||||
TEXT_FIELD_INPUT_FORM_USER_DATA = "xpath=div[2]/div/div/div/div/input"
|
||||
ROLES_FIELD_INPUT_FORM_USER_DATA = "xpath=div[2]/div/div/div/div/div[1]"
|
||||
ROLES_MENU_INPUT_FORM_USER_DATA = "//div[contains(@class, 'menuable__content__active')]"
|
||||
MENU_INPUT_FORM_USER_DATA = "//div[contains(@class, 'menuable__content__active')]"
|
||||
LABEL_INPUT_FORM_USER_DATA = "//label[contains(@class,'v-label')]/span"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,364 @@
|
|||
"""Модуль modal_add_user содержит класс для работы с модальным окном добавления пользователя.
|
||||
|
||||
Класс AddUserModalWindow наследует базовый функционал 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 data.roles_dict import roles_dict
|
||||
from components.modal_window_component import ModalWindowComponent
|
||||
from components.dropdown_list_component import DropdownList
|
||||
from components.confirm_component import ConfirmComponent
|
||||
|
||||
|
||||
logger = get_logger("ADD_USER_FROM_ACTIVE_DIRECTORY_MODAL_WINDOW")
|
||||
|
||||
|
||||
class AddADUserModalWindow(ModalWindowComponent):
|
||||
"""Модальное окно добавления нового пользователя.
|
||||
|
||||
Наследует ModalWindowComponent и добавляет элементы формы:
|
||||
- Поля ввода (имя, пароль, email и др.)
|
||||
- Чекбоксы (Active Directory, Push-уведомления)
|
||||
- Выпадающие списки групп, пользователей AD, ролей
|
||||
- Кнопки действий
|
||||
"""
|
||||
|
||||
def __init__(self, page: Page):
|
||||
"""Инициализирует элементы формы добавления пользователя."""
|
||||
|
||||
super().__init__(page)
|
||||
|
||||
# Локаторы элементов формы
|
||||
input_form_locator = page.locator(ModalWindowLocators.INPUT_FORM_USER_DATA)
|
||||
text_field_locator = ModalWindowLocators.TEXT_FIELD_INPUT_FORM_USER_DATA
|
||||
label_locator = ModalWindowLocators.LABEL_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")
|
||||
|
||||
# Добавление элементов формы
|
||||
checkbox_1 = Checkbox(
|
||||
page,
|
||||
self.page.get_by_role("checkbox").nth(0),
|
||||
"active_directory"
|
||||
)
|
||||
self.add_content_item("active_directory_checkbox", checkbox_1)
|
||||
|
||||
label_1 = Text(
|
||||
page,
|
||||
self.page.locator(label_locator).nth(0),
|
||||
"active_directory_checkbox_label"
|
||||
)
|
||||
self.add_content_item("active_directory_checkbox_label", label_1)
|
||||
|
||||
# Начальный набор полей формы
|
||||
group_loc = input_form_locator.get_by_role("combobox").nth(0)
|
||||
group_input = TextInput(page, group_loc, "group_input")
|
||||
self.add_content_item("group_input", group_input)
|
||||
self.add_content_item(
|
||||
"group_list",
|
||||
DropdownList(page)
|
||||
)
|
||||
|
||||
locator_button_search = self.page.get_by_role("button", name="Поиск")
|
||||
self.add_button(locator_button_search, "search")
|
||||
|
||||
loc = input_form_locator.locator("xpath=div[3]").locator(text_field_locator)
|
||||
name_input = TextInput(page, loc, "name_input")
|
||||
self.add_content_item("name_input", name_input)
|
||||
|
||||
role_loc = input_form_locator.get_by_role("combobox").nth(1)
|
||||
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 = input_form_locator.locator("xpath=div[6]").locator(text_field_locator)
|
||||
commentary_input = TextInput(page, loc, "commentary_input")
|
||||
self.add_content_item("commentary_input", commentary_input)
|
||||
|
||||
loc = input_form_locator.locator("xpath=div[7]").locator(text_field_locator)
|
||||
email_input = TextInput(page, loc, "email_input")
|
||||
self.add_content_item("email_input", email_input)
|
||||
|
||||
loc = input_form_locator.locator("xpath=div[8]").locator(text_field_locator)
|
||||
phone_input = TextInput(page, loc, "phone_input")
|
||||
self.add_content_item("phone_input", phone_input)
|
||||
|
||||
checkbox_2 = Checkbox(
|
||||
page,
|
||||
page.get_by_role("checkbox").nth(1),
|
||||
"push_notification"
|
||||
)
|
||||
self.add_content_item("push_notification_checkbox", checkbox_2)
|
||||
|
||||
label_2 = Text(
|
||||
page,
|
||||
self.page.locator(label_locator).nth(1),
|
||||
"push_notification_checkbox_label"
|
||||
)
|
||||
self.add_content_item("push_notification_checkbox_label", label_2)
|
||||
|
||||
# Добавление кнопок действий
|
||||
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_active_directory_checkbox(self):
|
||||
"""Включает чек-бокс Active Directory. """
|
||||
|
||||
self.get_content_item("active_directory_checkbox").check(force=True)
|
||||
|
||||
def uncheck_active_directory_checkbox(self):
|
||||
"""Выключает чек-бокс Active Directory. """
|
||||
|
||||
self.get_content_item("active_directory_checkbox").uncheck(force=True)
|
||||
|
||||
def update_input_form_fields(self, expand):
|
||||
"""Персчитывает локаторы полей формы ввода при добавлении/удалении дополнительного поля. """
|
||||
|
||||
input_form_locator = self.page.locator(ModalWindowLocators.INPUT_FORM_USER_DATA)
|
||||
text_field_locator = ModalWindowLocators.TEXT_FIELD_INPUT_FORM_USER_DATA
|
||||
|
||||
if expand:
|
||||
new_loc = input_form_locator.locator("xpath=div[4]").locator(text_field_locator)
|
||||
self.get_content_item("name_input").update_locator(new_loc)
|
||||
|
||||
new_loc = input_form_locator.locator("xpath=div[7]").locator(text_field_locator)
|
||||
self.get_content_item("commentary_input").update_locator(new_loc)
|
||||
|
||||
new_loc = input_form_locator.locator("xpath=div[8]").locator(text_field_locator)
|
||||
self.get_content_item("email_input").update_locator(new_loc)
|
||||
|
||||
new_loc = input_form_locator.locator("xpath=div[9]").locator(text_field_locator)
|
||||
self.get_content_item("phone_input").update_locator(new_loc)
|
||||
|
||||
role_loc = input_form_locator.get_by_role("combobox").nth(2)
|
||||
self.get_content_item("role_input").update_locator(role_loc)
|
||||
else:
|
||||
new_loc = input_form_locator.locator("xpath=div[3]").locator(text_field_locator)
|
||||
self.get_content_item("name_input").update_locator(new_loc)
|
||||
|
||||
new_loc = input_form_locator.locator("xpath=div[6]").locator(text_field_locator)
|
||||
self.get_content_item("commentary_input").update_locator(new_loc)
|
||||
|
||||
new_loc = input_form_locator.locator("xpath=div[7]").locator(text_field_locator)
|
||||
self.get_content_item("email_input").update_locator(new_loc)
|
||||
|
||||
new_loc = input_form_locator.locator("xpath=div[8]").locator(text_field_locator)
|
||||
self.get_content_item("phone_input").update_locator(new_loc)
|
||||
|
||||
role_loc = input_form_locator.get_by_role("combobox").nth(1)
|
||||
self.get_content_item("role_input").update_locator(role_loc)
|
||||
|
||||
def new_user(self, user_data):
|
||||
"""Заполняет форму и добавляет нового пользователя.
|
||||
|
||||
Args:
|
||||
user_data (dict): Данные пользователя (имя, роль, пароль и др.)
|
||||
"""
|
||||
|
||||
menu_locator = self.page.locator(ModalWindowLocators.MENU_INPUT_FORM_USER_DATA)
|
||||
input_form_locator = self.page.locator(ModalWindowLocators.INPUT_FORM_USER_DATA)
|
||||
|
||||
group_name = user_data.get("group")
|
||||
if group_name is None:
|
||||
assert False, "Value of 'group' is missing"
|
||||
|
||||
name = user_data.get("name")
|
||||
if name is None:
|
||||
assert False, "Value of 'name' is missing"
|
||||
|
||||
role = user_data.get("role")
|
||||
if role is None:
|
||||
assert False, "Value of 'role' is missing"
|
||||
|
||||
group_field = self.get_content_item("group_input")
|
||||
group_field.click()
|
||||
|
||||
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()
|
||||
|
||||
count = input_form_locator.get_by_role("combobox").count()
|
||||
if count == 2:
|
||||
assert False, f"Selected group {group_name} is empty. Use another group."
|
||||
|
||||
user_AD_loc = input_form_locator.get_by_role("combobox").nth(1)
|
||||
user_AD_input = TextInput(self.page, user_AD_loc, "user_AD_input")
|
||||
self.add_content_item("user_AD_input", user_AD_input)
|
||||
self.add_content_item(
|
||||
"user_AD_list",
|
||||
DropdownList(self.page)
|
||||
)
|
||||
|
||||
user_AD_input.click()
|
||||
user_AD_list = self.get_content_item("user_AD_list")
|
||||
user_AD_list.scroll_until_end(menu_locator)
|
||||
user_AD_names = group_list.get_item_names(menu_locator)
|
||||
if name not in user_AD_names:
|
||||
assert False, f"Required user name {name} is missing"
|
||||
|
||||
user_AD_list.check_item_with_text(name)
|
||||
user_AD_list.click_item_with_text(name)
|
||||
|
||||
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"])
|
||||
|
||||
# Отправка формы
|
||||
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_cancel_button()
|
||||
self.close_window()
|
||||
|
||||
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 check_content(self):
|
||||
"""Проверяет наличие и корректность всех элементов формы."""
|
||||
|
||||
input_form_locator = self.page.locator(ModalWindowLocators.INPUT_FORM_USER_DATA)
|
||||
menu_locator = self.page.locator(ModalWindowLocators.MENU_INPUT_FORM_USER_DATA)
|
||||
|
||||
self.check_by_window_title()
|
||||
|
||||
is_checked = self.get_content_item("active_directory_checkbox").is_checked()
|
||||
if not is_checked:
|
||||
assert False, \
|
||||
"The checkbox 'Active Directory'should be checked for the add user from Active Directory window"
|
||||
|
||||
self.check_toolbar_button_presence("close")
|
||||
self.check_toolbar_button_tooltip("close", "Закрыть")
|
||||
|
||||
no_op_names = ["roles_list", "group_list"]
|
||||
|
||||
for name in self.content_items.keys():
|
||||
item = self.get_content_item(name)
|
||||
|
||||
if name == "active_directory_checkbox_label":
|
||||
item.check_have_text(
|
||||
"Active Directory",
|
||||
"Label 'Active Directory' is missing"
|
||||
)
|
||||
elif name == "push_notification_checkbox_label":
|
||||
item.check_have_text(
|
||||
"Подписка на Push-уведомления",
|
||||
"Label 'Подписка на Push-уведомления' is missing"
|
||||
)
|
||||
elif name == "group_input":
|
||||
item.click()
|
||||
group_list = self.get_content_item("group_list")
|
||||
group_list.check_presence(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")
|
||||
elif name == "role_input":
|
||||
item.click()
|
||||
roles_list = self.get_content_item("roles_list")
|
||||
roles_list.check_presence(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 roles_dict.values():
|
||||
# временно, пока есть несоответствие со списком ролей в вкладке Сессии
|
||||
if role == "Пользователь":
|
||||
continue
|
||||
roles_list.check_item_with_text(role)
|
||||
self.page.keyboard.press("Escape")
|
||||
elif name in no_op_names:
|
||||
continue
|
||||
else:
|
||||
item.check_presence(
|
||||
f"Modal window content item with name '{name}' is missing"
|
||||
)
|
||||
|
||||
self.check_button_presence("search")
|
||||
self.check_button_presence("add")
|
||||
self.check_button_presence("close")
|
||||
|
||||
search_button = self.get_button_by_name("search")
|
||||
search_button.click()
|
||||
|
||||
user_AD_loc = input_form_locator.get_by_role("combobox").nth(1)
|
||||
user_AD_input = TextInput(self.page, user_AD_loc, "user_AD_input")
|
||||
self.add_content_item("user_AD_input", user_AD_input)
|
||||
self.add_content_item(
|
||||
"user_AD_list",
|
||||
DropdownList(self.page)
|
||||
)
|
||||
|
||||
user_AD_input.click()
|
||||
user_AD_list = self.get_content_item("user_AD_list")
|
||||
user_AD_list.check_presence(menu_locator,
|
||||
"Users AD list is missing")
|
||||
is_scrollable_vertically = user_AD_list.check_vertical_scrolling(menu_locator)
|
||||
assert is_scrollable_vertically, "Users AD list should be scrollable_vertically"
|
||||
self.page.keyboard.press("Escape")
|
||||
|
||||
self.update_input_form_fields(expand=True)
|
||||
|
||||
self.get_content_item("name_input").check_presence(
|
||||
"Modal window content item with name 'name_input' is missing")
|
||||
self.get_content_item("role_input").check_presence(
|
||||
"Modal window content item with name 'role_input' is missing")
|
||||
self.get_content_item("commentary_input").check_presence(
|
||||
"Modal window content item with name 'commentary_input' is missing")
|
||||
self.get_content_item("email_input").check_presence(
|
||||
"Modal window content item with name 'email_input' is missing")
|
||||
self.get_content_item("phone_input").check_presence(
|
||||
"Modal window content item with name 'phone_input' is missing")
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
"""Модуль modal_add_user содержит класс для работы с модальным окном добавления пользователя.
|
||||
"""Модуль modal_add_local_user содержит класс для работы с модальным окном добавления локального пользователя.
|
||||
|
||||
Класс AddUserModalWindow наследует базовый функционал ModalWindowComponent
|
||||
Класс AddLocalUserModalWindow наследует базовый функционал ModalWindowComponent
|
||||
и реализует специфичные методы для работы с формами добавления пользователей.
|
||||
"""
|
||||
|
||||
|
|
@ -17,10 +17,10 @@ from components.dropdown_list_component import DropdownList
|
|||
from components.confirm_component import ConfirmComponent
|
||||
|
||||
|
||||
logger = get_logger("ADD_USER_MODAL_WINDOW")
|
||||
logger = get_logger("ADD_LOCAL_USER_MODAL_WINDOW")
|
||||
|
||||
|
||||
class AddUserModalWindow(ModalWindowComponent):
|
||||
class AddLocalUserModalWindow(ModalWindowComponent):
|
||||
"""Модальное окно добавления нового пользователя.
|
||||
|
||||
Наследует ModalWindowComponent и добавляет элементы формы:
|
||||
|
|
@ -37,7 +37,6 @@ class AddUserModalWindow(ModalWindowComponent):
|
|||
|
||||
# Локаторы элементов формы
|
||||
text_field_locator = ModalWindowLocators.TEXT_FIELD_INPUT_FORM_USER_DATA
|
||||
roles_field_locator = ModalWindowLocators.ROLES_FIELD_INPUT_FORM_USER_DATA
|
||||
input_form_locator = ModalWindowLocators.INPUT_FORM_USER_DATA
|
||||
label_locator = ModalWindowLocators.LABEL_INPUT_FORM_USER_DATA
|
||||
|
||||
|
|
@ -53,9 +52,10 @@ class AddUserModalWindow(ModalWindowComponent):
|
|||
# Добавление элементов формы
|
||||
checkbox_1 = Checkbox(
|
||||
page,
|
||||
self.page.get_by_role("checkbox").nth(0),
|
||||
self.page.locator(input_form_locator).get_by_role("checkbox").nth(0),
|
||||
"active_directory"
|
||||
)
|
||||
|
||||
self.add_content_item("active_directory_checkbox", checkbox_1)
|
||||
|
||||
label_1 = Text(
|
||||
|
|
@ -69,7 +69,7 @@ class AddUserModalWindow(ModalWindowComponent):
|
|||
name_input = TextInput(page, loc, "name_input")
|
||||
self.add_content_item("name_input", name_input)
|
||||
|
||||
role_loc = self.page.locator(input_form_locator).locator("xpath=div[3]").locator(roles_field_locator)
|
||||
role_loc = self.page.locator(input_form_locator).get_by_role("combobox").nth(0)
|
||||
role_input = TextInput(page, role_loc, "role_input")
|
||||
self.add_content_item("role_input", role_input)
|
||||
self.add_content_item(
|
||||
|
|
@ -95,7 +95,7 @@ class AddUserModalWindow(ModalWindowComponent):
|
|||
|
||||
checkbox_2 = Checkbox(
|
||||
page,
|
||||
page.get_by_role("checkbox").nth(1),
|
||||
self.page.locator(input_form_locator).get_by_role("checkbox").nth(1),
|
||||
"push_notification"
|
||||
)
|
||||
self.add_content_item("push_notification_checkbox", checkbox_2)
|
||||
|
|
@ -116,6 +116,17 @@ class AddUserModalWindow(ModalWindowComponent):
|
|||
|
||||
self.new_user_confirm = ConfirmComponent(page, " Отмена ", " Добавить ")
|
||||
|
||||
# Действия:
|
||||
def check_active_directory_checkbox(self):
|
||||
"""Включает чек-бокс Active Directory. """
|
||||
|
||||
self.get_content_item("active_directory_checkbox").check(force=True)
|
||||
|
||||
def uncheck_active_directory_checkbox(self):
|
||||
"""Выключает чек-бокс Active Directory. """
|
||||
|
||||
self.get_content_item("active_directory_checkbox").uncheck(force=True)
|
||||
|
||||
def new_user(self, user_data):
|
||||
"""Заполняет форму и добавляет нового пользователя.
|
||||
|
||||
|
|
@ -125,13 +136,6 @@ class AddUserModalWindow(ModalWindowComponent):
|
|||
|
||||
fields = user_data.keys()
|
||||
|
||||
if "active_directory_checked" in fields:
|
||||
checkbox = self.get_content_item("active_directory_checkbox")
|
||||
if user_data["active_directory_checked"]:
|
||||
checkbox.check()
|
||||
else:
|
||||
checkbox.uncheck()
|
||||
|
||||
if "name" in fields:
|
||||
input_field = self.get_content_item("name_input")
|
||||
input_field.input_value(user_data["name"])
|
||||
|
|
@ -190,11 +194,19 @@ class AddUserModalWindow(ModalWindowComponent):
|
|||
|
||||
self.click_toolbar_close_button()
|
||||
|
||||
# Проверки:
|
||||
def check_content(self):
|
||||
"""Проверяет наличие и корректность всех элементов формы."""
|
||||
|
||||
menu_locator = self.page.locator(ModalWindowLocators.MENU_INPUT_FORM_USER_DATA)
|
||||
|
||||
self.check_by_window_title()
|
||||
|
||||
is_checked = self.get_content_item("active_directory_checkbox").is_checked()
|
||||
if is_checked:
|
||||
assert False, \
|
||||
"The checkbox 'Active Directory'should not be checked for the add local user window"
|
||||
|
||||
self.check_toolbar_button_presence("close")
|
||||
self.check_toolbar_button_tooltip("close", "Закрыть")
|
||||
|
||||
|
|
@ -214,9 +226,13 @@ class AddUserModalWindow(ModalWindowComponent):
|
|||
elif name == "role_input":
|
||||
item.click()
|
||||
roles_list = self.get_content_item("roles_list")
|
||||
roles_list.check_presence(self.page.locator(ModalWindowLocators.ROLES_MENU_INPUT_FORM_USER_DATA),
|
||||
roles_list.check_presence(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 roles_dict.values():
|
||||
# временно, пока есть несоответствие со списком ролей в вкладке Сессии
|
||||
if role == "Пользователь":
|
||||
|
|
@ -35,7 +35,6 @@ class EditUserModalWindow(ModalWindowComponent):
|
|||
|
||||
# Локаторы элементов формы
|
||||
text_field_locator = ModalWindowLocators.TEXT_FIELD_INPUT_FORM_USER_DATA
|
||||
roles_field_locator = ModalWindowLocators.ROLES_FIELD_INPUT_FORM_USER_DATA
|
||||
input_form_locator = ModalWindowLocators.INPUT_FORM_USER_DATA
|
||||
label_locator = ModalWindowLocators.LABEL_INPUT_FORM_USER_DATA
|
||||
|
||||
|
|
@ -53,7 +52,7 @@ class EditUserModalWindow(ModalWindowComponent):
|
|||
name_input = TextInput(page, loc, "name_input")
|
||||
self.add_content_item("name_input", name_input)
|
||||
|
||||
role_loc = self.page.locator(input_form_locator).locator("xpath=div[2]").locator(roles_field_locator)
|
||||
role_loc = self.page.locator(input_form_locator).get_by_role("combobox").nth(0)
|
||||
role_input = TextInput(page, role_loc, "role_input")
|
||||
self.add_content_item("role_input", role_input)
|
||||
self.add_content_item(
|
||||
|
|
@ -193,6 +192,8 @@ class EditUserModalWindow(ModalWindowComponent):
|
|||
role (str): Ожидаемая роль пользователя
|
||||
"""
|
||||
|
||||
menu_locator = self.page.locator(ModalWindowLocators.MENU_INPUT_FORM_USER_DATA)
|
||||
|
||||
self.check_by_window_title()
|
||||
self.check_toolbar_button_presence("close")
|
||||
self.check_toolbar_button_tooltip("close", "Закрыть")
|
||||
|
|
@ -214,7 +215,7 @@ class EditUserModalWindow(ModalWindowComponent):
|
|||
elif name == "role_input":
|
||||
item.click()
|
||||
roles_list = self.get_content_item("roles_list")
|
||||
roles_list.check_presence(self.page.locator(ModalWindowLocators.ROLES_MENU_INPUT_FORM_USER_DATA),
|
||||
roles_list.check_presence(menu_locator,
|
||||
"Roles list is missing")
|
||||
roles_list.check_item_with_text(role)
|
||||
elif name == "roles_list":
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
import re
|
||||
from playwright.sync_api import Page
|
||||
from modal_windows.modal_edit_user import EditUserModalWindow
|
||||
from modal_windows.modal_add_user import AddUserModalWindow
|
||||
from modal_windows.modal_add_local_user import AddLocalUserModalWindow
|
||||
from modal_windows.modal_add_AD_user import AddADUserModalWindow
|
||||
from locators.table_locators import TableLocators
|
||||
from data.roles_dict import roles_dict
|
||||
from components.toolbar_component import ToolbarComponent
|
||||
|
|
@ -58,14 +59,16 @@ class UsersTab(BasePage):
|
|||
AssertionError: Если тип окна не поддерживается.
|
||||
"""
|
||||
|
||||
if window_type == "add_user":
|
||||
self.modal_windows["add_user"] = AddUserModalWindow(self.page)
|
||||
if window_type == "add_local_user":
|
||||
self.modal_windows["add_local_user"] = AddLocalUserModalWindow(self.page)
|
||||
elif window_type == "add_AD_user":
|
||||
self.modal_windows["add_AD_user"] = AddADUserModalWindow(self.page)
|
||||
elif window_type == "edit_user":
|
||||
self.modal_windows[title] = EditUserModalWindow(self.page, title)
|
||||
else:
|
||||
assert False, "Unsupported modal window type"
|
||||
|
||||
def get_modal_window(self, title: str) -> None:
|
||||
def get_modal_window(self, title: str):
|
||||
"""Возвращает модальное окно по заголовку.
|
||||
|
||||
Args:
|
||||
|
|
@ -119,15 +122,25 @@ class UsersTab(BasePage):
|
|||
modal_window.close_window()
|
||||
self.delete_modal_window(title)
|
||||
|
||||
def close_add_AD_user_window_by_toolbar_button(self) -> None:
|
||||
"""Закрывает окно добавления пользователя через тулбар."""
|
||||
|
||||
self.close_modal_window_by_toolbar_button("add_AD_user")
|
||||
|
||||
def close_add_AD_user_window(self) -> None:
|
||||
"""Закрывает окно добавления пользователя."""
|
||||
|
||||
self.close_modal_window("add_AD_user")
|
||||
|
||||
def close_add_user_window_by_toolbar_button(self) -> None:
|
||||
"""Закрывает окно добавления пользователя через тулбар."""
|
||||
|
||||
self.close_modal_window_by_toolbar_button("add_user")
|
||||
self.close_modal_window_by_toolbar_button("add_local_user")
|
||||
|
||||
def close_add_user_window(self) -> None:
|
||||
"""Закрывает окно добавления пользователя."""
|
||||
|
||||
self.close_modal_window("add_user")
|
||||
self.close_modal_window("add_local_user")
|
||||
|
||||
def close_edit_user_window_by_toolbar_button(self, title: str) -> None:
|
||||
"""Закрывает окно редактирования через кнопку в тулбаре.
|
||||
|
|
@ -147,6 +160,7 @@ class UsersTab(BasePage):
|
|||
|
||||
self.close_modal_window(title)
|
||||
|
||||
|
||||
def add_new_user(self, user_data: dict) -> bool:
|
||||
"""Добавляет нового пользователя или обрабатывает ошибку при дубликате.
|
||||
|
||||
|
|
@ -161,7 +175,17 @@ class UsersTab(BasePage):
|
|||
или если текст alert не соответствует ожидаемому.
|
||||
"""
|
||||
|
||||
self.get_modal_window("add_user").new_user(user_data)
|
||||
add_user_window = self.get_modal_window("add_local_user")
|
||||
|
||||
auth_type = user_data.get("auth_type")
|
||||
if auth_type == "active_directory":
|
||||
add_user_window.check_active_directory_checkbox()
|
||||
self.add_modal_window("add_AD_user", "")
|
||||
add_user_window = self.get_modal_window("add_AD_user")
|
||||
add_user_window.new_user(user_data)
|
||||
return True
|
||||
|
||||
add_user_window.new_user(user_data)
|
||||
|
||||
is_added = False
|
||||
alert_type = self.alert.get_alert_type()
|
||||
|
|
@ -274,8 +298,8 @@ class UsersTab(BasePage):
|
|||
|
||||
self.toolbar.check_button_presence("add_user")
|
||||
self.toolbar.click_button("add_user")
|
||||
self.add_modal_window("add_user", "")
|
||||
self.get_modal_window("add_user").check_by_window_title()
|
||||
self.add_modal_window("add_local_user", "")
|
||||
self.get_modal_window("add_local_user").check_by_window_title()
|
||||
|
||||
def open_edit_user_page_by_index(self, row_index: int) -> tuple:
|
||||
"""Открывает окно редактирования по индексу строки.
|
||||
|
|
@ -335,6 +359,28 @@ class UsersTab(BasePage):
|
|||
self.add_modal_window("edit_user", user_name)
|
||||
self.get_modal_window(user_name).check_by_window_title()
|
||||
|
||||
def transform_to_add_AD_user_window(self):
|
||||
"""Трансформирует модальное окно добавления локального пользователя
|
||||
в окно добавления пользователя Active Directory с помощью нажатия
|
||||
чек-бокса Active Directory.
|
||||
"""
|
||||
|
||||
self.get_modal_window("add_local_user").check_active_directory_checkbox()
|
||||
modal_window = self.modal_windows.get("add_AD_user")
|
||||
if modal_window is None:
|
||||
self.add_modal_window("add_AD_user", "")
|
||||
|
||||
def transform_to_add_user_window(self):
|
||||
"""Трансформирует модальное окно добавления пользователя Active Directory
|
||||
в окно добавления локального пользователя с помощью снятия отметки с
|
||||
чек-бокса Active Directory.
|
||||
"""
|
||||
|
||||
self.get_modal_window("add_AD_user").uncheck_active_directory_checkbox()
|
||||
modal_window = self.modal_windows.get("add_local_user")
|
||||
if modal_window is None:
|
||||
self.add_modal_window("add_local_user", "")
|
||||
|
||||
# Проверки:
|
||||
def check_users_table_content(self, verify: bool = False) -> None:
|
||||
"""Проверяет содержимое таблицы пользователей.
|
||||
|
|
@ -367,9 +413,14 @@ class UsersTab(BasePage):
|
|||
self.verify_users_table_content(table_content)
|
||||
|
||||
def check_add_user_window_content(self) -> None:
|
||||
"""Проверяет содержимое окна добавления пользователя."""
|
||||
"""Проверяет содержимое окна добавления локального пользователя."""
|
||||
|
||||
self.get_modal_window("add_user").check_content()
|
||||
self.get_modal_window("add_local_user").check_content()
|
||||
|
||||
def check_add_AD_user_window_content(self) -> None:
|
||||
"""Проверяет содержимое окна добавления пользователя через Active Directory."""
|
||||
|
||||
self.get_modal_window("add_AD_user").check_content()
|
||||
|
||||
def check_edit_user_window_content(self, user_name: str, role: str) -> None:
|
||||
"""Проверяет содержимое окна редактирования.
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class TestUsersModalWindow:
|
|||
|
||||
ut = UsersTab(browser)
|
||||
ut.open_add_user_window()
|
||||
modal_window = ut.get_modal_window("add_user")
|
||||
modal_window = ut.get_modal_window("add_local_user")
|
||||
|
||||
is_scrollable_vertically = modal_window.check_window_vertical_scrolling()
|
||||
assert is_scrollable_vertically, "Should be vertical scrolling"
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ class TestUsersTab:
|
|||
ut = UsersTab(browser)
|
||||
ut.should_be_toolbar_buttons()
|
||||
|
||||
# pytest.mark.develop
|
||||
def test_add_user_window_content(self, browser: Page) -> None:
|
||||
"""Проверяет содержимое окна добавления пользователя.
|
||||
|
||||
|
|
@ -95,6 +96,8 @@ class TestUsersTab:
|
|||
ut = UsersTab(browser)
|
||||
ut.open_add_user_window()
|
||||
ut.check_add_user_window_content()
|
||||
ut.transform_to_add_AD_user_window()
|
||||
ut.check_add_AD_user_window_content()
|
||||
|
||||
def test_add_user_window_close_buttons(self, browser: Page) -> None:
|
||||
"""Проверяет кнопки закрытия окна добавления.
|
||||
|
|
@ -110,6 +113,14 @@ class TestUsersTab:
|
|||
ut.open_add_user_window()
|
||||
ut.close_add_user_window()
|
||||
|
||||
ut.open_add_user_window()
|
||||
ut.transform_to_add_AD_user_window()
|
||||
ut.close_add_AD_user_window_by_toolbar_button()
|
||||
|
||||
ut.open_add_user_window()
|
||||
ut.transform_to_add_AD_user_window()
|
||||
ut.close_add_AD_user_window()
|
||||
|
||||
def test_edit_user_window_content(self, browser: Page) -> None:
|
||||
"""Проверяет содержимое окна редактирования.
|
||||
|
||||
|
|
@ -134,6 +145,7 @@ class TestUsersTab:
|
|||
user_name, _ = ut.open_edit_user_page_by_index(0)
|
||||
ut.close_edit_user_window(user_name)
|
||||
|
||||
# @pytest.mark.develop
|
||||
def test_add_and_delete_user(self, browser: Page, cleanup_user: None) -> None:
|
||||
"""Проверяет добавление и удаление пользователя.
|
||||
|
||||
|
|
@ -181,6 +193,25 @@ class TestUsersTab:
|
|||
mp.click_subpanel_item("Пользователи")
|
||||
ut.should_not_be_user_in_table(user_data["name"], user_data["role"])
|
||||
|
||||
# @pytest.mark.develop
|
||||
def test_add_AD_user(self, browser: Page, cleanup_user: None) -> None:
|
||||
"""Проверяет добавление пользователя Active Directory.
|
||||
|
||||
Args:
|
||||
browser: Экземпляр страницы Playwright.
|
||||
cleanup_user: Фикстура для очистки пользователя.
|
||||
"""
|
||||
|
||||
user_data: Dict[str, str] = {"auth_type":"active_directory",
|
||||
"group": "Администраторы",
|
||||
"name": "Администратор",
|
||||
"role": "Администратор"}
|
||||
|
||||
ut = UsersTab(browser)
|
||||
|
||||
ut.open_add_user_window()
|
||||
ut.add_new_user(user_data)
|
||||
|
||||
def test_reset_password(self, browser: Page, cleanup_autoadmin: None) -> None:
|
||||
"""Проверяет сброс пароля пользователя.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue