Compare commits

..

No commits in common. "69606d7b0538067197f2f7c43dee3497ffaae6a8" and "35401be507131a3f5acf336192768b427457d0c2" have entirely different histories.

9 changed files with 116 additions and 423 deletions

View File

@ -4,12 +4,11 @@
from playwright.sync_api import Page, Locator
from tools.logger import get_logger
from locators.settings_form_locators import SettingsFormLocators
from elements.tooltip_button_element import TooltipButton
from elements.button_element import Button
from components.toolbar_component import ToolbarComponent
from components.base_component import BaseComponent
logger = get_logger("SETTINGS_FORM")
logger = get_logger("MODAL_WINDOW")
class SettingsFormComponent(BaseComponent):
@ -43,12 +42,7 @@ class SettingsFormComponent(BaseComponent):
self.buttons.append(Button(self.page, locator, name))
def add_tooltip_button(self, locator: str, name: str) -> None:
"""Добавляет кнопку в форму."""
self.buttons.append(TooltipButton(self.page, locator, name))
def get_button_by_name(self, name: str) -> Button | TooltipButton | None:
def get_button_by_name(self, name: str) -> Button | None:
"""Ищет и возвращает кнопку по имени или None, если не найдена."""
for button in self.buttons:
@ -70,14 +64,6 @@ class SettingsFormComponent(BaseComponent):
return self.is_scrollable_vertically(locator)
def check_button_tooltip(self, name: str, tooltip: str) -> None:
"""Проверяет текст подсказки кнопки. """
button = self.get_button_by_name(name)
if button is None:
raise AssertionError(f"Unsupported button name {name}")
button.check_tooltip_with_text(tooltip)
def check_button_visibility(self, name: str) -> None:
"""Проверяет наличие кнопки по имени. Вызывает ошибку, если не найдена."""

View File

@ -47,6 +47,7 @@ class SystemLogEventsContainer(EventsContainerComponent):
events_tab = self.get_toolbar_tab_button("events")
events_tab_text = events_tab.get_text(0)
assert events_tab_text.find("chevron_right") != -1, "Should be icon 'chevron_right'"
assert events_tab_text.find("События") != -1, "Tab button with text События is missing on toolbar"
self.should_be_events_table()

View File

@ -1,78 +0,0 @@
"""Модуль interactive_dropdown_list_component содержит класс для работы с интерактивными выпадающими списками,
позволяющими сделать выбор нескольких элементов.
Класс InteractiveDropdownList наследует базовый функционал BaseComponent и добавляет
методы для взаимодействия с интерактивными выпадающими списками на странице.
"""
from playwright.sync_api import Page, Locator, expect
from tools.logger import get_logger
from components.base_component import BaseComponent
logger = get_logger("INTERACTIVE_DROPDOWN_LIST")
class InteractiveDropdownList(BaseComponent):
"""Класс для работы с выпадающими списками.
Наследует функциональность BaseElement и добавляет специфичные
методы для выбора и проверки элементов списка.
"""
def __init__(self, page: Page) -> None:
"""Инициализирует компонент интерактивного выпадающего списка.
Args:
page: Экземпляр страницы Playwright.
"""
super().__init__(page)
# Действия:
def get_checkbox_locator(self, text: str) -> Locator:
"""Возвращает локатор чек-бокса для элемента списка с указанным текстом.
Args:
text (str): Текст элемента для выбора.
"""
checkbox_locator = self.get_locator('div.v-list__tile__title').get_by_text(text). \
locator("../..").locator("//input[@role='checkbox']")
expect(checkbox_locator).to_be_visible(), \
f"Checkbox for dropdown list item with text {text} is missing"
return checkbox_locator
def deselect_item_with_text(self, text: str) -> None:
"""Выбирает элемент списка по указанному тексту.
Args:
text (str): Текст элемента для выбора.
"""
self.get_checkbox_locator(text).uncheck(force=True)
def select_item_with_text(self, text: str) -> None:
"""Выбирает элемент списка по указанному тексту.
Args:
text (str): Текст элемента для выбора.
"""
self.get_checkbox_locator(text).check(force=True)
def get_selected_items(self, locator: str|Locator) -> list[str]:
"""Возвращает список отмеченных элементов."""
selected_items = []
list_locator = self.get_locator(locator)
items = list_locator.get_by_role("listitem").all()
for item in items:
if item.get_by_role("checkbox").is_checked():
item_text = item.text_content().strip()
if item_text:
selected_items.append(item_text)
return selected_items
# Проверки:

View File

@ -7,17 +7,10 @@
class SettingsFormLocators:
"""Локаторы для компонента формы ввода и отображения полей настроек.
Содержит XPath/CSS локаторы для:
Содержит XPath локаторы для:
SETTTINGS_FORM_SCROLL_CONTAINER (str): контейнера с прокруткой модального окна
SETTTINGS_FORM_TITLE (str): заголовка тулбара
DROPDOWN_LIST (str): выпадающего списка
SELECTED_VALUES (str): строки с выбранными из списка значениями
CLEAR_SELECTION_BUTTON (str): кнопки удаления строки с выбранными из списка значениями
"""
SETTTINGS_FORM_SCROLL_CONTAINER = "//div[contains(@class, 'scrollarea__body')]"
SETTTINGS_FORM_TITLE = f"{SETTTINGS_FORM_SCROLL_CONTAINER}//div[contains(@class, 'v-toolbar__title')]"
DROPDOWN_LIST = "//div[contains(@class, 'menuable__content__active')]"
SELECTED_VALUES = "//div[@class='v-select__selections']"
CLEAR_SELECTION_BUTTON = "div.v-input__icon--clear"

111
mkdocs.yml Normal file
View File

@ -0,0 +1,111 @@
site_name: Документация тестов eNODE-Мониторинг
theme:
name: material
plugins:
- search
- mkdocstrings:
default_handler: python
handlers:
python:
paths: [".", "pages"]
options:
show_source: true
nav:
- Главная: index.md
- Данные и конфигурации:
- Constants: data/constants.md
- Environment: data/environment.md
- Roles_dict: data/roles_dict.md
- Фикстуры Pytest:
- Browser Fixtures: fixtures/pages.md
- Элементы UI:
- BaseElement: elements/base_element.md
- Button: elements/button_element.md
- Checkbox: elements/checkbox_element.md
- Icon: elements/icon_element.md
- TabButton: elements/tab_button_element.md
- Text: elements/text_element.md
- TextInput: elements/text_input_element.md
- ToolbarButton: elements/tooltip_button_element.md
- Компоненты UI:
- AlertComponent: components/alert_component.md
- BaseComponent: components/base_component.md
- CardComponent: components/card_component.md
- ConfirmComponent: components/confirm_component.md
- DropdownList: components/dropdown_list_component.md
- EventPanelComponent: components/eventbar_component.md
- EventsContainerComponent: components/events_container_component.md
- JsonContainerComponent: components/json_container_component.md
- ModalWindowComponent: components/modal_window_component.md
- NavigationPanelComponent: components/navbar_component.md
- TableComponent: components/table_component.md
- ToolbarComponent: components/toolbar_component.md
- Компоненты производные UI:
- SystemLogEventsContainer: components_derived/container_system_log_events.md
- AddADUserModalWindow: components_derived/modal_add_AD_user.md
- AddLocalUserModalWindow: components_derived/modal_add_local_user.md
- ChangePasswordModalWindow: components_derived/modal_change_password.md
- EditUserModalWindow: components_derived/modal_edit_user.md
- ViewTemplateModalWindow: components_derived/modal_view_template.md
- ViewZTPTemplateModalWindow: components_derived/modal_view_ztp_template.md
- UserCard: components_derived/user_card.md
- Локаторы:
- ButtonLocators: locators/button_locators.md
- ConfirmLocators: locators/confirm_locators.md
- EventPanelLocators: locators/event_panel_locators.md
- InputLocators: locators/input_locators.md
- JsonContainerLocators: locators/json_container_locators.md
- ModalWindowLocators: locators/modal_window_locators.md
- NavigationPanelLocators: locators/navigation_panel_locators.md
- RackLocators: locators/rack_locators.md # new
- SettingsFormLocators: locators/settings_form_locators.md # new
- TableLocators: locators/table_locators.md
- TextInputLocators: locators/text_input_locators.md
- TextLocators: locators/text_locators.md
- ToolbarLocators: locators/toolbar_locators.md
- UserCardLocators: locators/user_card_locators.md
- Страницы приложения:
- BasePage: pages/base_page.md
- LicenseTab: pages/license_tab.md
- LoginPage: pages/login_page.md
- MainPage: pages/main_page.md
- ServiceStatusTab: pages/service_status_tab.md
- CurrentSessionsTab: pages/current_session_tab.md # new
- SessionSettingsTab: pages/session_settings_tab.md # new
- TemplatesTab: pages/templates_tab.md
- UsersTab: pages/users_tab.md
- ZTPConfigTab: pages/ztp_config_tab.md
- ZTPTemplatesTab: pages/ztp_templates_tab.md
- Тесты:
- End-to-End:
- Sessions:
- TestCurrentSessionsTab: tests/e2e/sessions/test_current_sessions_tab.md # new
- TestCurrentSettingsTab: tests/e2e/sessions/test_session_settings_tab.md # new
- Users:
- TestUsersTabAddUser: tests/e2e/users/test_add_user.md
- TestUsersTabEditUser: tests/e2e/users/test_edit_user.md
- TestUserCard: tests/e2e/users/test_user_card.md
- TestUsersTab: tests/e2e/users/test_users_tab.md
- TestEventPanel: tests/e2e/test_event_panel.md
- TestNavigationPanel: tests/e2e/test_expand_navigation_panel.md
- TestLicenseTab: tests/e2e/test_license_tab.md
- TestLogin: tests/e2e/test_login.md
- TestServiceStatusTab: tests/e2e/test_service_status_tab.md
- TestSystemLogEventsContainer: tests/e2e/test_system_log_events_container.md
- TestTemplatesTab: tests/e2e/test_templates_tab.md
- TestZTPConfigTab: tests/e2e/test_ztp_config_tab.md
- TestZTPTemplatesTab: tests/e2e/test_ztp_templates_tab.md
- Компоненты:
- TestJsonContainer: tests/components/test_json_container.md
- TestNavigationPanel: tests/components/test_navigation_panel.md
- TestServiceStatusTable: tests/components/test_services_table.md
- TestUsersModalWindow: tests/components/test_user_modal_window.md
- Утилиты:
- Logging: tools/logger.md
- Python Project Fixer: tools/fix_python_project.md
- Инструкции:
- Документация проекта MkDocs: config/mkdocs_guide.md
- Требования при добавлении docstring: config/add_docstring.md
- Процесс разработки кода: config/code_development_process.md

View File

@ -1,195 +0,0 @@
"""Модуль вкладки настройки Push уведомлений.
Содержит класс PushNotificationsSettings для работы с вкладкой настройки Push уведомлений.
Позволяет проверять состояние и взаимодействовать с элементами вкладки.
"""
import re
from playwright.sync_api import Page
from locators.settings_form_locators import SettingsFormLocators
from elements.text_input_element import TextInput
from elements.text_element import Text
from components.toolbar_component import ToolbarComponent
from components.alert_component import AlertComponent
from components_derived.settings_form_component import SettingsFormComponent
from components_derived.interactive_dropdown_list import InteractiveDropdownList
from pages.base_page import BasePage
class PushNotificationsSettingsTab(BasePage):
"""Класс для работы с вкладкой настройки Push уведомлений.
Предоставляет методы для взаимодействия с вкладкой настройки Push уведомлений.
Args:
page: Экземпляр страницы Playwright.
"""
def __init__(self, page: Page) -> None:
"""Инициализирует компоненты вкладки настройки Push уведомлений."""
super().__init__(page)
self.toolbar = ToolbarComponent(page, "Push уведомления")
# Форма для отображения/редактирования полей настроек Push уведомлений
self.settings_form = SettingsFormComponent(page)
self.settings_form.add_toolbar_title("Общие")
message_setting_label = Text(page,
page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
get_by_text('Сообщение'),
"message_setting_label")
self.settings_form.add_content_item("message_setting_label", message_setting_label)
loc_message_input = page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
get_by_label('Сообщение').nth(1)
message_setting_input = TextInput(page, loc_message_input, "message_setting_input")
self.settings_form.add_content_item("message_setting_input", message_setting_input)
users_settings_locator = page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
get_by_label('Пользователи')
users_setting_label = Text(page, users_settings_locator, "users_setting_label")
self.settings_form.add_content_item("users_setting_label", users_setting_label)
users_setting_input = TextInput(page,
page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
get_by_role("combobox"),
"users_setting_input")
self.settings_form.add_content_item("users_setting_input", users_setting_input)
self.settings_form.add_content_item("users_list", InteractiveDropdownList(page))
self.settings_form.add_tooltip_button(page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
get_by_role("button", name='Отправить'),
"submit_button")
self.alert = AlertComponent(page)
# Действия:
def clear_users_setting_value(self) -> None:
"""Очищает текущее значение поля настроек 'Пользователи'."""
selected_users = self.get_users_setting_value()
if len(selected_users) > 0:
clear_selection_button = self.page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
get_by_role("combobox").locator(SettingsFormLocators.CLEAR_SELECTION_BUTTON)
clear_selection_button.click()
def click_submit_button(self) -> None:
"""Нажатие кнопки 'Отправить' в форме ввода настроек."""
self.settings_form.check_button_visibility("submit_button")
self.settings_form.get_button_by_name("submit_button").click()
def get_message_setting_value(self) -> str:
"""Возвращает текущее значение поля настроек 'Сообщение'.
Returns:
str : Текущее значение поля настроек 'Сообщение'.
"""
input_field = self.settings_form.get_content_item("message_setting_input")
return input_field.get_input_value().strip()
def get_users_setting_value(self) -> str:
"""Возвращает текущее значение поля настроек 'Пользователи'.
Returns:
str : Текущее значение поля настроек 'Пользователи'.
"""
users_setting_field_loc = self.page.locator(SettingsFormLocators.SETTTINGS_FORM_SCROLL_CONTAINER).\
get_by_role("combobox").locator(SettingsFormLocators.SELECTED_VALUES)
return users_setting_field_loc.text_content().strip()
def input_message(self, text: str) -> None:
"""Заполнение поля 'Сообщение'."""
message_input = self.settings_form.get_content_item("message_setting_input")
message_input.clear()
message_input.input_value(text)
def deselect_users(self, users: list[str]) -> None:
"""Изменение значения поля 'Пользователи' путем отмены выбора из выпадающего списка заданных имен."""
assert len(users) != 0, "Users list should not be empty"
self.settings_form.get_content_item("users_setting_input").click()
users_list = self.settings_form.get_content_item("users_list")
for user in users:
users_list.deselect_item_with_text(user)
# Закрываем выпадающий список (кликаем вне его)
self.page.mouse.click(10, 10)
def select_users(self, users: list[str]) -> None:
"""Заполнение поля 'Пользователи' путем выбора из выпадающего списка заданных имен."""
assert len(users) != 0, "Users list should not be empty"
self.settings_form.get_content_item("users_setting_input").click()
users_list = self.settings_form.get_content_item("users_list")
for user in users:
users_list.select_item_with_text(user)
# Закрываем выпадающий список (кликаем вне его)
self.page.mouse.click(10, 10)
# Проверки:
def check_content(self):
"""Проверяет наличие и корректность всех элементов страницы."""
self.should_be_toolbar()
self.should_be_form_toolbar()
for name in self.settings_form.content_items.keys():
if name == "users_list":
self.settings_form.get_content_item("users_setting_input").click()
users_list = self.settings_form.get_content_item(name)
selected_users = users_list.get_selected_items(SettingsFormLocators.DROPDOWN_LIST)
assert len(selected_users) == 0, "There should be no selected users"
else:
item = self.settings_form.get_content_item(name)
item.check_visibility(
f"Push notifications settings input form item with name '{name}' is missing"
)
self.settings_form.check_button_visibility("submit_button")
self.settings_form.check_button_tooltip("submit_button", "Отправить Push уведомление")
def should_be_toolbar(self) -> None:
"""Проверяет наличие тулбара страницы.
Raises:
AssertionError: Если тулбар или кнопка редактирования отсутствуют.
"""
loc = self.page.get_by_role("navigation").filter(
has_text=re.compile("Push уведомления")).locator("div").nth(1)
self.toolbar.check_toolbar_presence_by_locator(loc, "Toolbar with title 'Push уведомления' is missing")
def should_be_form_toolbar(self) -> None:
"""Проверяет наличие тулбара формы редактирования настроек.
Raises:
AssertionError: Если тулбар отсутствует.
"""
self.settings_form.should_be_toolbar()
def should_be_success_alert(self) -> None:
"""Проверяет наличие сообщения об успешной отправке push-уведомления.
Raises:
AssertionError: Если тулбар отсутствует.
"""
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('\nPush-уведомление\nуспешно отправлено\n')
self.alert.check_alert_absence('\nPush-уведомление\nуспешно отправлено\n')

View File

@ -9,8 +9,8 @@ from locators.settings_form_locators import SettingsFormLocators
from elements.text_input_element import TextInput
from elements.text_element import Text
from components.toolbar_component import ToolbarComponent
from components.settings_form_component import SettingsFormComponent
from components.alert_component import AlertComponent
from components_derived.settings_form_component import SettingsFormComponent
from pages.base_page import BasePage

View File

@ -1,124 +0,0 @@
"""Модуль тестов вкладки настройки Push уведомлений.
Содержит тесты для проверки корректности отображения
и функциональности элементов страницы настройки Push уведомлений.
"""
import pytest
from playwright.sync_api import Page
from pages.login_page import LoginPage
from pages.main_page import MainPage
from pages.push_notifications_settings_tab import PushNotificationsSettingsTab
# @pytest.mark.smoke
class TestPushNotificationsSettingsTab:
"""Набор тестов для вкладки настройки Push уведомлений.
Проверяет корректность отображения и функциональность элементов вкладки настройки Push уведомлений.
Тесты покрывают следующие сценарии:
1. test_session_settings_tab_content: Тест содержимого вкладки настройки Push уведомлений
"""
@pytest.fixture(scope="function", autouse=True)
def setup(self, browser: Page) -> None:
"""Фикстура для подготовки тестового окружения.
Выполняет:
1. Авторизацию в системе
2. Переход на вкладку настройки Push уведомлений через панель навигации
"""
# Авторизация в системе
login_page = LoginPage(browser)
login_page.do_login()
# Инициализация главной страницы
main_page = MainPage(browser)
# Проверка и взаимодействие с элементами навигации
main_page.should_be_navigation_panel()
main_page.click_main_navigation_panel_item("Настройки")
main_page.click_subpanel_item("Уведомления")
main_page.click_subpanel_item("Push уведомления")
# @pytest.mark.develop
def test_push_notifications_settings_tab_content(self, browser: Page) -> None:
"""Тест содержимого вкладки настройки Push уведомлений.
Проверяет:
Наличие и корректность элементов интерфейса
"""
expected_msg_value = "test"
# Инициализация вкладки
push_notification_settings_tab = PushNotificationsSettingsTab(browser)
# Проверка элементов интерфейса
push_notification_settings_tab.check_content()
msg_value = push_notification_settings_tab.get_message_setting_value()
assert msg_value == expected_msg_value, \
f"Actual message field value {msg_value} is not equal expected message field value {expected_msg_value}"
# @pytest.mark.develop
def test_send_push_notification(self, browser: Page) -> None:
"""Тест содержимого вкладки настройки Push уведомлений.
Проверяет:
Заполнение полей и отправку Push уведомления
"""
receivers = ["admin", "manager", "operator"]
# Инициализация вкладки
push_notification_settings_tab = PushNotificationsSettingsTab(browser)
expected_msg_value = "My test message"
push_notification_settings_tab.input_message(expected_msg_value)
msg_value = push_notification_settings_tab.get_message_setting_value()
assert msg_value == expected_msg_value, \
f"Actual message field value {msg_value} is not equal expected message field value {expected_msg_value}"
push_notification_settings_tab.select_users(receivers)
sep = ", "
expected_users = sep.join(receivers)
selected_users = push_notification_settings_tab.get_users_setting_value()
assert selected_users == expected_users, \
f"Actual users field value {selected_users} is not equal expected users field value {expected_users}"
push_notification_settings_tab.click_submit_button()
push_notification_settings_tab.should_be_success_alert()
# @pytest.mark.develop
def test_users_setting_input(self, browser: Page) -> None:
"""Тест содержимого вкладки настройки Push уведомлений.
Проверяет:
Заполнение и очистку поля 'Пользователи'
"""
receivers = ["manager", "operator", "collector"]
sep = ", "
# Инициализация вкладки
push_notification_settings_tab = PushNotificationsSettingsTab(browser)
push_notification_settings_tab.select_users(receivers)
expected_users = sep.join(receivers)
selected_users = push_notification_settings_tab.get_users_setting_value()
assert selected_users == expected_users, \
f"Actual users field value {selected_users} is not equal expected users field value {expected_users}"
receivers.remove("collector")
push_notification_settings_tab.deselect_users(["collector"])
expected_users = sep.join(receivers)
selected_users = push_notification_settings_tab.get_users_setting_value()
assert selected_users == expected_users, \
f"Actual users field value {selected_users} is not equal expected users field value {expected_users}"
push_notification_settings_tab.clear_users_setting_value()
selected_users = push_notification_settings_tab.get_users_setting_value()
assert len(selected_users) == 0, "There should be no selected users"

View File

@ -11,7 +11,6 @@ from pages.service_status_tab import ServiceStatusTab
from pages.main_page import MainPage
from pages.login_page import LoginPage
pytest.skip("пропуск всех тестов в этом файле в связи с переходом на новый виджет", allow_module_level=True)
# @pytest.mark.smoke
class TestServiceStatusTab: