e-nms_qa_automation/pages/users_tab.py

529 lines
20 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""Модуль вкладки 'Пользователи'.
Содержит класс UsersTab для работы с таблицей пользователей.
Позволяет управлять пользователями через модальные окна и проверять их состояние.
"""
import re
from playwright.sync_api import Page
from locators.table_locators import TableLocators
from components_derived.modal_edit_user import EditUserModalWindow
from components_derived.modal_add_user import AddUserModalWindow
from data.roles_dict import roles_dict
from components.toolbar_component import ToolbarComponent
from components.table_component import TableComponent
from components.modal_window_component import ModalWindowComponent
from components.alert_component import AlertComponent
from pages.base_page import BasePage
class UsersTab(BasePage):
"""Класс для работы с вкладкой 'Пользователи'.
Предоставляет методы для взаимодействия с таблицей пользователей,
модальными окнами и проверки состояния элементов.
Args:
page: Экземпляр страницы Playwright.
"""
def __init__(self, page: Page) -> None:
"""Инициализирует компоненты вкладки 'Пользователи'."""
super().__init__(page)
locator_button_1 = self.page.get_by_role("navigation").filter(
has_text=re.compile("Пользователи")
).get_by_role("button").nth(0)
locator_button_2 = self.page.get_by_role("navigation").filter(
has_text=re.compile("Пользователи")
).get_by_role("button").nth(1)
self.toolbar = ToolbarComponent(page, "Пользователи")
self.toolbar.add_tooltip_button(locator_button_1, "edit")
self.toolbar.add_tooltip_button(locator_button_1, "add_user")
self.toolbar.add_tooltip_button(locator_button_2, "close")
self.users_table = TableComponent(page)
self.modal_windows = {}
self.alert = AlertComponent(page)
# Действия:
def add_modal_window(self, window_type: str, title: str) -> None:
"""Добавляет модальное окно в коллекцию.
Args:
window_type: Тип окна ('add_user' или 'edit_user').
title: Заголовок окна.
Raises:
AssertionError: Если тип окна не поддерживается.
"""
if window_type == "add_user":
self.modal_windows["add_user"] = AddUserModalWindow(self.page)
elif window_type == "edit_user":
self.modal_windows[title] = EditUserModalWindow(self.page, title)
else:
assert False, "Unsupported modal window type"
def add_new_user(self, user_data: dict) -> bool:
"""Добавляет нового пользователя или обрабатывает ошибку при дубликате.
Args:
user_data: Данные пользователя (name, role, password).
Returns:
bool: True если пользователь успешно добавлен, False если пользователь уже существует.
Raises:
AssertionError: Если открылось alert окно отличное от success или error,
или если текст alert не соответствует ожидаемому.
"""
add_user_window = self.get_modal_window("add_user")
add_user_window.new_user(user_data)
is_added = False
alert_type = self.alert.get_alert_type()
if alert_type == "success":
self.alert.check_alert_presence(' Новый пользователь \n успешно добавлен! ')
self.alert.check_alert_absence(' Новый пользователь \n успешно добавлен! ')
is_added = True
elif alert_type == "error":
self.alert.check_alert_presence(f' Имя {user_data["name"]} уже \n используется ')
self.alert.check_alert_absence(f' Имя {user_data["name"]} уже \n используется ')
else:
assert False, f"Got unexpected alert type {alert_type}"
return is_added
def close_add_user_window(self) -> None:
"""Закрывает окно добавления пользователя."""
self.close_modal_window("add_user")
def close_add_user_window_by_toolbar_button(self) -> None:
"""Закрывает окно добавления пользователя через тулбар."""
self.close_modal_window_by_toolbar_button("add_user")
def close_edit_user_window(self, title: str) -> None:
"""Закрывает окно редактирования пользователя.
Args:
title: Имя пользователя (заголовок окна).
"""
self.close_modal_window(title)
def close_edit_user_window_by_toolbar_button(self, title: str) -> None:
"""Закрывает окно редактирования через кнопку в тулбаре.
Args:
title: Имя пользователя (заголовок окна).
"""
self.close_modal_window_by_toolbar_button(title)
def close_modal_window(self, title: str) -> None:
"""Закрывает модальное окно через кнопку закрытия.
Args:
title: Заголовок окна.
"""
modal_window = self.get_modal_window(title)
modal_window.close_window()
self.delete_modal_window(title)
def close_modal_window_by_toolbar_button(self, title: str) -> None:
"""Закрывает модальное окно через кнопку в тулбаре.
Args:
title: Заголовок окна.
"""
modal_window = self.get_modal_window(title)
modal_window.close_window_by_toolbar_button()
self.delete_modal_window(title)
def delete_modal_window(self, title: str) -> None:
"""Удаляет модальное окно из коллекции.
Args:
title: Заголовок окна.
Raises:
AssertionError: Если окно не найдено.
"""
if self.modal_windows.get(title) is None:
assert False, f"Modal window with title '{title}' not found"
self.modal_windows[title] = None
def delete_user(self, user_name: str) -> None:
"""Удаляет пользователя.
Args:
user_name: Имя пользователя.
Raises:
AssertionError: Если нет сообщения об успешном удалении.
"""
self.get_modal_window(user_name).delete_user()
alert_type = self.alert.get_alert_type()
assert alert_type == "success", f"Expected success alert, but got {alert_type} alert"
self.alert.check_alert_presence('\nПользователь удалён\n')
self.alert.check_alert_absence('\nПользователь удалён\n')
def edit_user(self, user_name: str, user_data: dict) -> None:
"""Редактирует данные пользователя.
Args:
user_name: Имя пользователя.
user_data: Новые данные пользователя.
Raises:
AssertionError: Если нет сообщения об успешном обновлении.
"""
self.get_modal_window(user_name).edit_user(user_data)
alert_type = self.alert.get_alert_type()
assert alert_type == "success", f"Expected success alert, but got {alert_type} alert"
self.alert.check_alert_presence('\nОбновление успешно\n')
self.alert.check_alert_absence('\nОбновление успешно\n')
def find_user_in_table(self, name: str, role: str) -> int:
"""Ищет пользователя в таблице.
Args:
name: Имя пользователя.
role: Роль пользователя.
Returns:
int: Индекс строки или -1 если не найден.
Raises:
AssertionError: Если таблица пуста.
"""
self.page.wait_for_timeout(1000)
table_content = self.users_table.read(TableLocators.TABLE_WORK_AREA)
if len(table_content) == 0:
assert False, "The contents of the table are missing"
# Удаляем заголовок
del table_content[0]
for row_index, user_info in enumerate(table_content):
if name in user_info and role in user_info:
return row_index
return -1
def get_modal_window(self, title: str) -> ModalWindowComponent:
"""Возвращает модальное окно по заголовку.
Args:
title: Заголовок окна.
Returns:
ModalWindowComponent: Экземпляр модального окна.
Raises:
AssertionError: Если окно не найдено.
"""
modal_window = self.modal_windows.get(title)
if modal_window is None:
assert False, f"Modal window with title '{title}' not found"
return modal_window
def open_add_user_window(self) -> None:
"""Открывает окно добавления пользователя.
Raises:
AssertionError: Если кнопки недоступны или окно не открылось.
"""
if self.toolbar.is_button_not_present("close"):
self.toolbar.check_button_visibility("edit")
self.toolbar.click_button("edit")
self.toolbar.check_button_visibility("add_user")
self.toolbar.click_button("add_user")
self.page.wait_for_timeout(700)
self.add_modal_window("add_user", "")
self.get_modal_window("add_user").check_by_window_title()
def open_edit_user_page_by_index(self, row_index: int) -> tuple:
"""Открывает окно редактирования по индексу строки.
Args:
row_index: Индекс строки в таблице.
Returns:
tuple: (имя пользователя, роль).
Raises:
AssertionError: Если таблица пуста или индекс вне диапазона.
"""
self.page.wait_for_timeout(2000)
tmp_dict = {"admin": "Администратор", "manager": "Контактное лицо",
"operator": "Оператор"}
table_content = self.users_table.read(TableLocators.TABLE_WORK_AREA)
if len(table_content) == 0:
assert False, "The contents of the table are missing"
# Удаляем заголовок
del table_content[0]
if row_index >= len(table_content):
assert False, "Row_index is out of range"
user_name = table_content[row_index][0]
for key, val in tmp_dict.items():
if user_name == val:
user_name = key
role = table_content[row_index][2]
self.page.locator(TableLocators.TABLE_WORK_AREA).locator(
"//tbody/tr").nth(row_index).click()
self.add_modal_window("edit_user", user_name)
self.get_modal_window(user_name).check_by_window_title()
return user_name, role
def open_edit_user_page_by_user(self, user_name: str, role: str) -> None:
"""Открывает окно редактирования по имени и роли.
Args:
user_name: Имя пользователя.
role: Роль пользователя.
Raises:
AssertionError: Если пользователь не найден.
"""
row_index = self.find_user_in_table(user_name, role)
if row_index == -1:
assert False, f"User with name {user_name} and role {role} has not been found"
self.page.locator(TableLocators.TABLE_WORK_AREA).locator("//tbody/tr").nth(row_index).click()
self.add_modal_window("edit_user", user_name)
self.get_modal_window(user_name).check_by_window_title()
def reset_password(self, user_name: str) -> str:
"""Сбрасывает пароль пользователя.
Args:
user_name: Имя пользователя.
Returns:
str: Новый пароль (если получен).
"""
new_password = ""
self.get_modal_window(user_name).reset_password()
self.alert.check_alert_presence("")
alert_message = self.alert.get_text()
if len(alert_message) > 0:
new_password = re.findall(r'[\d]+', alert_message)[0]
return new_password
# Проверки:
def check_add_user_window_content(self) -> None:
"""Проверяет содержимое окна добавления локального пользователя."""
self.get_modal_window("add_user").check_content()
def check_edit_user_window_content(self, user_name: str, role: str) -> None:
"""Проверяет содержимое окна редактирования.
Args:
user_name: Имя пользователя.
role: Роль пользователя.
"""
edit_user_window = self.get_modal_window(user_name)
edit_user_window.check_content(user_name, role)
def check_users_table_content(self, verify: bool = False) -> None:
"""Проверяет содержимое таблицы пользователей.
Args:
verify: Проверять соответствие данных из БД. По умолчанию False.
Raises:
AssertionError: Если таблица пуста или заголовки неверны.
"""
self.page.wait_for_timeout(2000)
expected_headers = ['Имя пользователя', 'Тип авторизации', 'Роль',
'E-mail', 'Номер для СМС']
table_content = self.users_table.read(TableLocators.TABLE_WORK_AREA)
if len(table_content) == 0:
assert False, "The contents of the table are missing"
actual_headers = table_content[0]
self.check_equals(
actual_headers,
expected_headers,
f"Expected table headers {expected_headers} are not equal {actual_headers}"
)
if len(table_content) == 1:
assert False, "Table body is missing"
if verify:
self.verify_users_table_content(table_content)
def should_be_toolbar(self) -> None:
"""Проверяет наличие тулбара.
Raises:
AssertionError: Если тулбар или кнопка редактирования отсутствуют.
"""
self.toolbar.check_toolbar_presence("Toolbar is missing")
self.toolbar.check_button_visibility("edit")
def should_be_toolbar_buttons(self) -> None:
"""Проверяет наличие и функциональность кнопок тулбара.
Raises:
AssertionError: Если кнопки недоступны или подсказки неверны.
"""
self.toolbar.check_button_visibility("edit")
self.toolbar.check_button_tooltip("edit", "Редактировать")
self.toolbar.get_button_by_name("edit").click()
self.toolbar.check_button_visibility("add_user")
self.toolbar.check_button_visibility("close")
self.toolbar.check_button_tooltip("add_user", "Добавить")
self.toolbar.check_button_tooltip("close", "Закрыть")
self.toolbar.get_button_by_name("close").click()
self.toolbar.check_button_visibility("edit")
def should_be_user_in_table(self, name: str, role: str) -> None:
"""Проверяет наличие пользователя в таблице.
Args:
name: Имя пользователя.
role: Роль пользователя.
Raises:
AssertionError: Если пользователь не найден.
"""
found = self.find_user_in_table(name, role)
if found == -1:
assert False, f"User with name {name} and role {role} has not been found"
def should_be_users_table(self) -> None:
"""Проверяет наличие таблицы пользователей.
Raises:
AssertionError: Если таблица отсутствует.
"""
self.users_table.check_visibility(TableLocators.TABLE_WORK_AREA,"Users table is missing")
def should_not_be_user_in_table(self, name: str, role: str) -> None:
"""Проверяет отсутствие пользователя в таблице.
Args:
name: Имя пользователя.
role: Роль пользователя.
Raises:
AssertionError: Если пользователь найден.
"""
found = self.find_user_in_table(name, role)
if found != -1:
assert False, f"User with name {name} and role {role} has been found"
def verify_users_table_content(self, users_table: list) -> None:
"""Сверяет данные таблицы с данными из БД.
Args:
users_table: Данные из таблицы на странице.
Raises:
AssertionError: Если данные не соответствуют.
"""
expected_users_list = []
query = {
"id": ["/catalogs/user"],
"data": {
"namePath": True,
"children": {"flatten": True}
}
}
response = self.send_post_api_request("e-cmdb/api/query", query)
response_body = self.get_response_body(response)
for item in response_body[0]["children"]:
user_info = []
user_name = item["name"]
# НЕ преобразуем имя пользователя - оставляем как есть из БД
user_info.append(user_name)
if item["type_auth"] is not None:
user_info.append(item["type_auth"])
else:
user_info.append("")
if item["role"] is not None:
role = item["role"]
# Убрали вызов .keys()
if role in roles_dict:
item["role"] = roles_dict[role]
user_info.append(item["role"])
else:
user_info.append("")
if item["email"] is not None:
user_info.append(item["email"])
else:
user_info.append("")
if item["sms_phone"] is not None:
user_info.append(item["sms_phone"])
else:
user_info.append("")
expected_users_list.append(user_info)
# Удаляем заголовок
del users_table[0]
self.check_lists_equals(
users_table,
expected_users_list,
"Actual users list is not equal expected users list on base db"
)