From 51adc848382a383a76ee4913c612d245b7d4a99d Mon Sep 17 00:00:00 2001 From: nsubbot Date: Tue, 26 Aug 2025 14:24:09 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=20=D0=B5?= =?UTF-8?q?=D0=B4=D0=B8=D0=BD=D1=8B=D0=B9=20alert=20component=20=D0=BD?= =?UTF-8?q?=D0=B5=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D1=8F=D1=89=D0=B8=D0=B9?= =?UTF-8?q?=20=D0=BE=D1=82=20=D1=82=D0=B8=D0=BF=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/alert_component.py | 35 ++++++++++++++++++++-------- pages/license_tab.py | 19 ++++++++------- pages/login_page.py | 12 ++++++---- pages/users_tab.py | 44 ++++++++++++++++++++++++++--------- 4 files changed, 77 insertions(+), 33 deletions(-) diff --git a/components/alert_component.py b/components/alert_component.py index 6b782cb..2bc1437 100644 --- a/components/alert_component.py +++ b/components/alert_component.py @@ -19,25 +19,39 @@ class AlertComponent(BaseComponent): Позволяет проверять наличие, отсутствие и текст сообщений. """ - def __init__(self, page: Page, alert_type: str): + def __init__(self, page: Page): """Инициализирует компонент alert-окна. Args: page: Экземпляр страницы Playwright. - alert_type: Тип alert-окна (error/success/info/warning). - - Raises: - ValueError: Если передан неподдерживаемый тип alert-окна. """ super().__init__(page) + self.text = Text(page, "//div[contains(@class,'v-alert')]/div", "Alert message") + + # Действия: + def get_alert_type(self) -> str: + """Возвращает тип alert-окна. + + Returns: + str: Тип alert-окна. + + Raises: + ValueError: Если получен неподдерживаемый тип alert-окна. + """ + + class_attr = self.page.get_by_role("alert").locator('>div').get_attribute('class') + + alert_type = None + if 'v-alert' in class_attr: + alert_type = class_attr.replace("v-alert ", "") + alert_types = ["error", "success", "info", "warning"] if alert_type not in alert_types: raise ValueError("Unsupported type of alert window") - self.alert_type = alert_type - self.text = Text(page, f"//div[@class='v-alert {self.alert_type}']/div", "Alert message") + return alert_type def get_text(self) -> str: """Возвращает текст сообщения из alert-окна. @@ -48,6 +62,7 @@ class AlertComponent(BaseComponent): return self.text.get_text(0) + # Проверки: def check_alert_presence(self, text: str): """Проверяет наличие alert-окна с заданным текстом. @@ -59,7 +74,7 @@ class AlertComponent(BaseComponent): AssertionError: Если alert-окно не найдено. """ - msg = f"No {self.alert_type} alert window on page" + msg = "Alert window is missing" if text == "": expect(self.page.get_by_role("alert")).to_be_visible(), msg else: @@ -77,7 +92,7 @@ class AlertComponent(BaseComponent): """ seconds = int(timeout/1000) - msg = f"Alert {self.alert_type} window should disappear after {seconds} seconds" + msg = f"Alert window should disappear after {seconds} seconds" expect(self.page.get_by_role("alert").filter(has_text=text)).to_be_hidden(timeout=timeout), msg def check_text(self, alert_text: str): @@ -91,4 +106,4 @@ class AlertComponent(BaseComponent): """ self.text.check_have_text(alert_text, - f"Unexpected message in alert {self.alert_type} window") + "Unexpected message in alert window") diff --git a/pages/license_tab.py b/pages/license_tab.py index e97312a..94fe899 100644 --- a/pages/license_tab.py +++ b/pages/license_tab.py @@ -44,7 +44,7 @@ class LicenseTab(BasePage): self.license_id_input = TextInput(page, InputLocators.LICENSE_ID_UPDATE, "license id input") self.update_button = Button(page, ButtonLocators.BUTTON_LICENSE_UPDATE, "update license button") - self.error_alert = AlertComponent(page, "error") + self.alert = AlertComponent(page) # Действия: def fill_license_input_form(self, value: str) -> None: @@ -89,7 +89,7 @@ class LicenseTab(BasePage): self.should_be_input_form_title() self.should_be_empty_input_form() self.should_be_update_button() - + self.verify_json_container_content() def should_be_error_alert_window_with_text(self, text: str) -> None: @@ -99,8 +99,11 @@ class LicenseTab(BasePage): text: Текст для проверки """ - self.error_alert.check_alert_presence(text) - self.error_alert.check_alert_absence(text) + alert_type = self.alert.get_alert_type() + assert alert_type=="error", f"Expected error alert, but got {alert_type} alert" + + self.alert.check_alert_presence(text) + self.alert.check_alert_absence(text) def should_be_toolbar(self) -> None: """Проверяет наличие панели инструментов.""" @@ -155,13 +158,13 @@ class LicenseTab(BasePage): actual_data = self.json_container.read_data(JsonContainerLocators.CONTAINER) env_name = host.get_env_name() - + # temporarily because of difference in version if env_name == "test": # send request to backend to get license info response = self.send_get_api_request("e-cmdb/api/lic") response_body = self.get_response_body(response) - + del response_body["netManagment"] response_body["ui"]["lcc"].pop("lcc_object") response_body["ui"]["lcc"].pop("lcc_reference_book") @@ -172,7 +175,7 @@ class LicenseTab(BasePage): response_body["ui"]["cmdb"].pop("logical_ip") response_body["ui"]["cmdb"].pop("logical_vlan") response_body["ui"]["cmdb"].pop("logical_vm") - + # compare actual and response from cmdb self.json_container.check_json_equals( actual_data, @@ -183,7 +186,7 @@ class LicenseTab(BasePage): # send request to backend to get license info response = self.send_get_api_request("api/service-manager/license") response_body = self.get_response_body(response) - + # compare actual and response from cmdb self.json_container.check_json_equals( actual_data, diff --git a/pages/login_page.py b/pages/login_page.py index 81b9622..70c7e96 100644 --- a/pages/login_page.py +++ b/pages/login_page.py @@ -20,7 +20,7 @@ class LoginPage(BasePage): login_input: Поле ввода логина. password_input: Поле ввода пароля. login_button: Кнопка входа. - error_alert: Компонент алерта с ошибкой. + alert: Алерт окно с сообщением об ошибке. """ def __init__(self, page: Page) -> None: @@ -36,8 +36,9 @@ class LoginPage(BasePage): self.password_input = TextInput(page, page.get_by_label("Пароль"), "password input") self.login_button = Button(page, page.get_by_role("button"), "login button") - self.error_alert = AlertComponent(page, "error") + self.alert = AlertComponent(page) + # Действия: def do_login(self, username: str = None, password: str = None) -> None: """Выполняет вход в систему. @@ -98,5 +99,8 @@ class LoginPage(BasePage): self.login_button.click() - self.error_alert.check_alert_presence("Неверная пара логин/пароль") - self.error_alert.check_alert_absence("Неверная пара логин/пароль") + alert_type = self.alert.get_alert_type() + assert alert_type=="error", f"Expected error alert, but got {alert_type} alert" + + self.alert.check_alert_presence("Неверная пара логин/пароль") + self.alert.check_alert_absence("Неверная пара логин/пароль") diff --git a/pages/users_tab.py b/pages/users_tab.py index 2fc0dae..3232163 100644 --- a/pages/users_tab.py +++ b/pages/users_tab.py @@ -44,8 +44,9 @@ class UsersTab(BasePage): self.users_table = TableComponent(page) self.modal_windows = {} - self.success_alert = AlertComponent(page, "success") + self.alert = AlertComponent(page) + # Действия: def add_modal_window(self, window_type: str, title: str) -> None: """Добавляет модальное окно в коллекцию. @@ -146,19 +147,31 @@ class UsersTab(BasePage): self.close_modal_window(title) - def add_new_user(self, user_data: dict) -> None: + def add_new_user(self, user_data: dict) -> bool: """Добавляет нового пользователя. Args: user_data: Данные пользователя. Raises: - AssertionError: Если нет сообщения об успешном добавлении. + AssertionError: Если открылось alert окно отличное от success или error. """ self.get_modal_window("add_user").new_user(user_data) - self.success_alert.check_alert_presence(' Новый пользователь \n успешно добавлен! ') - self.success_alert.check_alert_absence(' Новый пользователь \n успешно добавлен! ') + + 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"]} уже используется ') + self.alert.check_alert_absence(f' Имя {user_data["name"]} уже используется ') + else: + assert False, f"Got unexpected alert type {alert_type}" + + return is_added def delete_user(self, user_name: str) -> None: """Удаляет пользователя. @@ -171,8 +184,12 @@ class UsersTab(BasePage): """ self.get_modal_window(user_name).delete_user() - self.success_alert.check_alert_presence('\nПользователь удалён\n') - self.success_alert.check_alert_absence('\nПользователь удалён\n') + + 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: """Редактирует данные пользователя. @@ -186,8 +203,12 @@ class UsersTab(BasePage): """ 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') + + 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 reset_password(self, user_name: str) -> str: """Сбрасывает пароль пользователя. @@ -202,8 +223,8 @@ class UsersTab(BasePage): new_password = "" self.get_modal_window(user_name).reset_password() - self.success_alert.check_alert_presence("") - alert_message = self.success_alert.get_text() + 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] @@ -306,6 +327,7 @@ class UsersTab(BasePage): 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: """Проверяет содержимое таблицы пользователей.