From 13608f7e4bb7f90cfa9d649f25c8a1213ce78429 Mon Sep 17 00:00:00 2001 From: Radislav Date: Tue, 25 Nov 2025 10:43:17 +0300 Subject: [PATCH] =?UTF-8?q?refactor(alert):=20=D1=83=D0=BB=D1=83=D1=87?= =?UTF-8?q?=D1=88=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=84=D1=83=D0=BD=D0=BA=D1=86?= =?UTF-8?q?=D0=B8=D0=BE=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=B8=20=D0=B8=20=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83?= =?UTF-8?q?=D1=80=D1=8B=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=20alert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Добавлен импорт модуля локаторов и использование AlertLocators для лучшей поддерживаемости - Реализован метод close_alert_by_text() с проверками видимости - Добавлено комплексное логирование для всех операций с alert-окнами - Улучшены подсказки типов с явными аннотациями возвращаемых значений - Обновлено использование логгера с consistent форматированием сообщений --- components/alert_component.py | 95 ++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 23 deletions(-) diff --git a/components/alert_component.py b/components/alert_component.py index 2bc1437..98547ba 100644 --- a/components/alert_component.py +++ b/components/alert_component.py @@ -6,6 +6,7 @@ alert-окон (error, success, info, warning) и проверки их сост from playwright.sync_api import Page, expect from tools.logger import get_logger +from locators.alert_locators import AlertLocators from elements.text_element import Text from components.base_component import BaseComponent @@ -19,7 +20,7 @@ class AlertComponent(BaseComponent): Позволяет проверять наличие, отсутствие и текст сообщений. """ - def __init__(self, page: Page): + def __init__(self, page: Page) -> None: """Инициализирует компонент alert-окна. Args: @@ -28,9 +29,41 @@ class AlertComponent(BaseComponent): super().__init__(page) - self.text = Text(page, "//div[contains(@class,'v-alert')]/div", "Alert message") + self.text = Text(page, AlertLocators.ALERT_MESSAGE, "Alert message") # Действия: + def close_alert_by_text(self, text: str) -> None: + """Закрывает alert-окно с заданным текстом с помощью кнопки закрытия. + + Args: + text: Текст alert-окна, которое нужно закрыть. + + Raises: + AssertionError: Если не удалось найти или закрыть alert-окно. + """ + # Находим alert с нужным текстом + alert_locator = self.page.get_by_role( + AlertLocators.ALERT_ROLE + ).filter(has_text=text) + + # Проверяем, что alert видим + expect(alert_locator).to_be_visible() + + # Находим кнопку закрытия внутри alert + close_button = alert_locator.locator(AlertLocators.ALERT_DISMISS_BUTTON) + + # Проверяем, что кнопка закрытия доступна и кликаем + expect(close_button).to_be_visible() + expect(close_button).to_be_enabled() + + # Кликаем по кнопке закрытия + close_button.click() + + # Проверяем, что alert исчез после закрытия + expect(alert_locator).to_be_hidden() + + logger.info(f"Alert with text '{text}' closed successfully") + def get_alert_type(self) -> str: """Возвращает тип alert-окна. @@ -41,7 +74,9 @@ class AlertComponent(BaseComponent): ValueError: Если получен неподдерживаемый тип alert-окна. """ - class_attr = self.page.get_by_role("alert").locator('>div').get_attribute('class') + class_attr = self.page.get_by_role(AlertLocators.ALERT_ROLE).locator( + '>div' + ).get_attribute('class') alert_type = None if 'v-alert' in class_attr: @@ -63,24 +98,7 @@ class AlertComponent(BaseComponent): return self.text.get_text(0) # Проверки: - def check_alert_presence(self, text: str): - """Проверяет наличие alert-окна с заданным текстом. - - Args: - text: Текст для проверки. Если пустая строка - проверяет только - наличие окна. - - Raises: - AssertionError: Если alert-окно не найдено. - """ - - msg = "Alert window is missing" - if text == "": - expect(self.page.get_by_role("alert")).to_be_visible(), msg - else: - expect(self.page.get_by_role("alert").filter(has_text=text)).to_be_visible(), msg - - def check_alert_absence(self, text: str, timeout: int = 30000): + def check_alert_absence(self, text: str, timeout: int = 30000) -> None: """Проверяет отсутствие alert-окна с заданным текстом. Args: @@ -93,9 +111,40 @@ class AlertComponent(BaseComponent): seconds = int(timeout/1000) 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): + if text == "": + expect(self.page.get_by_role( + AlertLocators.ALERT_ROLE + )).to_be_hidden(timeout=timeout), msg + logger.info(f"Alert window successfully disappeared") + else: + expect(self.page.get_by_role( + AlertLocators.ALERT_ROLE + ).filter(has_text=text)).to_be_hidden(timeout=timeout), msg + logger.info(f"Alert window with text '{text}' successfully disappeared") + + def check_alert_presence(self, text: str) -> None: + """Проверяет наличие alert-окна с заданным текстом. + + Args: + text: Текст для проверки. Если пустая строка - проверяет только + наличие окна. + + Raises: + AssertionError: Если alert-окно не найдено. + """ + + msg = "Alert window is missing" + if text == "": + expect(self.page.get_by_role(AlertLocators.ALERT_ROLE)).to_be_visible(), msg + logger.info(f"Alert window successfully displayed") + else: + expect(self.page.get_by_role( + AlertLocators.ALERT_ROLE + ).filter(has_text=text)).to_be_visible(), msg + logger.info(f"Alert window with text '{text}' successfully displayed") + + def check_text(self, alert_text: str) -> None: """Проверяет точное соответствие текста в alert-окне. Args: