"""Модуль вкладки 'Пользователи'. Содержит класс UsersTab для работы с таблицей пользователей. Позволяет управлять пользователями через модальные окна и проверять их состояние. """ 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 locators.table_locators import TableLocators from data.roles_dict import roles_dict from components.toolbar_component import ToolbarComponent from components.table_component import TableComponent 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_button(locator_button_1, "edit") self.toolbar.add_button(locator_button_1, "add_user") self.toolbar.add_button(locator_button_2, "close") self.users_table = TableComponent(page) self.modal_windows = {} self.success_alert = AlertComponent(page, "success") 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 get_modal_window(self, title: str) -> None: """Возвращает модальное окно по заголовку. 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 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 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 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_add_user_window_by_toolbar_button(self) -> None: """Закрывает окно добавления пользователя через тулбар.""" self.close_modal_window_by_toolbar_button("add_user") def close_add_user_window(self) -> None: """Закрывает окно добавления пользователя.""" self.close_modal_window("add_user") def close_edit_user_window_by_toolbar_button(self, title: str) -> None: """Закрывает окно редактирования через кнопку в тулбаре. Args: title: Имя пользователя (заголовок окна). """ self.close_modal_window_by_toolbar_button(title) def close_edit_user_window(self, title: str) -> None: """Закрывает окно редактирования пользователя. Args: title: Имя пользователя (заголовок окна). """ self.close_modal_window(title) def add_new_user(self, user_data: dict) -> None: """Добавляет нового пользователя. Args: user_data: Данные пользователя. Raises: AssertionError: Если нет сообщения об успешном добавлении. """ self.get_modal_window("add_user").new_user(user_data) self.success_alert.check_alert_presence(' Новый пользователь \n успешно добавлен! ') self.success_alert.check_alert_absence(' Новый пользователь \n успешно добавлен! ') def delete_user(self, user_name: str) -> None: """Удаляет пользователя. Args: user_name: Имя пользователя. Raises: AssertionError: Если нет сообщения об успешном удалении. """ self.get_modal_window(user_name).delete_user() self.success_alert.check_alert_presence('\nПользователь удалён\n') self.success_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) self.success_alert.check_alert_presence('\nОбновление успешно\n') self.success_alert.check_alert_absence('\nОбновление успешно\n') def reset_password(self, user_name: str) -> str: """Сбрасывает пароль пользователя. Args: user_name: Имя пользователя. Returns: str: Новый пароль (если получен). """ new_password = "" self.get_modal_window(user_name).reset_password() self.success_alert.check_alert_presence("") alert_message = self.success_alert.get_text() if len(alert_message) > 0: new_password = re.findall(r'[\d]+', alert_message)[0] return new_password def find_user_in_table(self, name: str, role: str) -> int: """Ищет пользователя в таблице. Args: name: Имя пользователя. role: Роль пользователя. Returns: int: Индекс строки или -1 если не найден. Raises: AssertionError: Если таблица пуста. """ 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 open_add_user_window(self) -> None: """Открывает окно добавления пользователя. Raises: AssertionError: Если кнопки недоступны или окно не открылось. """ if self.toolbar.is_button_not_present("close"): self.toolbar.check_button_presence("edit") self.toolbar.click_button("edit") 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() def open_edit_user_page_by_index(self, row_index: int) -> tuple: """Открывает окно редактирования по индексу строки. Args: row_index: Индекс строки в таблице. Returns: tuple: (имя пользователя, роль). Raises: AssertionError: Если таблица пуста или индекс вне диапазона. """ 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 check_users_table_content(self, verify: bool = False) -> None: """Проверяет содержимое таблицы пользователей. Args: verify: Проверять соответствие данных из БД. По умолчанию False. Raises: AssertionError: Если таблица пуста или заголовки неверны. """ 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 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 should_be_toolbar(self) -> None: """Проверяет наличие тулбара. Raises: AssertionError: Если тулбар или кнопка редактирования отсутствуют. """ self.toolbar.check_toolbar_presence("Toolbar is missing") self.toolbar.check_button_presence("edit") def should_be_toolbar_buttons(self) -> None: """Проверяет наличие и функциональность кнопок тулбара. Raises: AssertionError: Если кнопки недоступны или подсказки неверны. """ self.toolbar.check_button_presence("edit") self.toolbar.check_button_tooltip("edit", "Редактировать") self.toolbar.get_button_by_name("edit").click() self.toolbar.check_button_presence("add_user") self.toolbar.check_button_presence("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_presence("edit") def should_be_users_table(self) -> None: """Проверяет наличие таблицы пользователей. Raises: AssertionError: Если таблица отсутствует. """ self.users_table.check_presence( TableLocators.TABLE_WORK_AREA, "Users table is missing" ) 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_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 = [] tmp_dict = {"admin": "Администратор", "manager": "Контактное лицо", "operator": "Оператор"} 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"] if user_name in tmp_dict.keys(): item["name"] = tmp_dict[user_name] user_info.append(item["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"] if role in roles_dict.keys(): 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" )