e-nms_qa_automation/tests/e2e/elements/test_edit_rack.py

548 lines
23 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.

"""Модуль тестов редактирования стойки в модуле Объекты.
Содержит тесты для проверки функциональности
редактирования стойки оборудования.
"""
import os
import pytest
from playwright.sync_api import Page
from tools.logger import get_logger
from locators.navigation_panel_locators import NavigationPanelLocators
from frames.create_element_frame import CreateElementFrame
from forms.create_rack_form import CreateRackForm, CreateRackData
from makers.edit_rack_maker import EditRackMaker, EditRackData
from pages.location_page import LocationPage
from pages.login_page import LoginPage
from pages.main_page import MainPage
from pages.rack_page import RackPage
from components.alert_component import AlertComponent
logger = get_logger("RACK_EDIT_TESTS")
logger.setLevel("INFO")
class TestRackEdit:
"""Набор тестов для редактирования стойки в модуле Объекты.
Проверяет функциональность редактирования различных вкладок стойки:
1. Общая информация
2. Изображение
3. Правила доступа
"""
# Имя тестовой стойки
RACK_NAME = "Test-Rack-Edit"
# Инициализируем атрибуты
main_page: MainPage = None
location_page: LocationPage = None
alert: AlertComponent = None
create_child_frame: CreateElementFrame = None
@pytest.fixture(scope="function", autouse=True)
def setup(self, browser: Page) -> None:
"""Фикстура для подготовки тестового окружения.
Выполняет:
1. Авторизацию в системе
2. Переход к локации test-zone
3. Инициализацию компонентов
4. Создание стойки если она не существует
5. Переход к стойке
Args:
browser: Экземпляр страницы Playwright для взаимодействия с UI
"""
# Авторизация в системе
login_page = LoginPage(browser)
login_page.do_login()
# Мы на главной странице
self.main_page = MainPage(browser)
self.main_page.should_be_navigation_panel()
# Переходим к Объектам
self.main_page.click_main_navigation_panel_item("Объекты")
self.main_page.wait_for_timeout(1000)
self.main_page.click_main_navigation_panel_item("test-zone")
# Создаем экземпляр страницы локации
self.location_page = LocationPage(browser)
# Инициализируем компонент алертов (вынесено в атрибуты класса)
self.alert = AlertComponent(browser)
# Инициализируем фрейм создания дочернего элемента (вынесено в атрибуты класса)
self.create_child_frame = CreateElementFrame(browser)
# Проверяем существование стойки
if not self._check_rack_existance(browser, self.RACK_NAME):
logger.info(f"Rack '{self.RACK_NAME}' does not exist. Creating...")
rack_data = CreateRackData(
name=self.RACK_NAME,
usize="42",
depth="1000"
)
self._create_rack(browser, rack_data)
self.main_page.wait_for_timeout(3000)
else:
logger.info(f"Rack '{self.RACK_NAME}' already exists")
# Переходим к стойке для тестирования
self.main_page.click_subpanel_item(self.RACK_NAME, parent="test-zone")
self.main_page.wait_for_timeout(3000)
@pytest.fixture(scope="class", autouse=True)
def cleanup_rack(self, browser: Page):
"""Фикстура для очистки созданной стойки после ВСЕХ тестов класса.
Выполняется один раз после завершения всех тестов класса TestRackEdit.
Удаляет созданную стойку.
Args:
browser: Экземпляр страницы Playwright
"""
# Тесты выполняются здесь
yield
logger.debug(f"Cleaning up rack: {self.RACK_NAME}")
# Переходим на главную страницу и в нужную зону
login_page = LoginPage(browser)
login_page.do_login()
self.main_page = MainPage(browser)
self.main_page.should_be_navigation_panel()
# Переходим к Объектам
self.main_page.click_main_navigation_panel_item("Объекты")
self.main_page.wait_for_timeout(1000)
self.main_page.click_main_navigation_panel_item("test-zone")
self.main_page.wait_for_timeout(1000)
# Инициализируем компонент алертов для cleanup
self.alert = AlertComponent(browser)
# Проверяем существование стойки
if self._check_rack_existance(browser, self.RACK_NAME):
# Переходим на страницу стойки
self.main_page.click_subpanel_item(self.RACK_NAME, parent="test-zone")
self.main_page.wait_for_timeout(2000)
# Удаляем стойку
self._delete_rack(browser, self.RACK_NAME)
# Дополнительная проверка
self.main_page.click_subpanel_item("test-zone")
self.main_page.wait_for_timeout(1000)
def _check_rack_existance(self, browser: Page, rack_name: str) -> bool:
"""Проверяет существование стойки.
Args:
browser: Страница Playwright
rack_name: Имя стойки для проверки
Returns:
bool: True если стойка существует, False в противном случае
"""
logger.debug(f"Checking existence of rack with name '{rack_name}'")
self.main_page.click_subpanel_item("test-zone")
nav_panel_locator = NavigationPanelLocators.TREEVIEW
element = browser.locator(nav_panel_locator).get_by_text(rack_name, exact=True).first
if element.is_visible():
logger.debug(f"Rack with name '{rack_name}' found")
return True
logger.debug(f"Rack with name '{rack_name}' not found")
return False
def _create_rack(self, browser: Page, rack_data: CreateRackData) -> None:
"""Создает стойку.
Args:
browser: Страница Playwright
rack_data: Данные стойки для создания
"""
logger.debug(f"Creating rack with name '{rack_data.name}'")
# Нажимаем кнопку "Создать" на тулбаре
self.location_page.click_create_button()
# Нажимаем на плашку "Класс объекта учета"
self.create_child_frame.open_object_class_combobox()
# Из выпадающего меню выбираем пункт "Стойка"
self.create_child_frame.select_object_class("Стойка")
# Создаем форму создания стойки
rack_form = CreateRackForm(browser)
# Заполняем данные стойки
fill_results = rack_form.fill_rack_data(rack_data)
logger.debug(f"Fill results: {fill_results}")
# Нажимаем кнопку создания
self.create_child_frame.click_add_button()
# Ждем появления alert с текстом
expected_alert_text = f"Успешно создано"
self.alert.check_alert_presence(expected_alert_text, timeout=7000)
self.alert.check_alert_absence(expected_alert_text, timeout=7000)
# Закрываем alert с текстом кнопкой 'Закрыть'
try:
self.alert.close_alert_by_text(expected_alert_text)
logger.debug("Alert forcibly closed")
except AssertionError:
# Если уже закрылся - игнорируем
logger.debug("Alert already closed by the time forcible close was attempted")
logger.info(f"Rack '{rack_data.name}' created successfully")
def _delete_rack(self, browser: Page, rack_name: str) -> None:
"""Удаляет стойку через контекстное меню.
Args:
browser: Страница Playwright
rack_name: Имя стойки для удаления
"""
# Находим элемент стойки в навигационной панели
rack_element = browser.locator(
NavigationPanelLocators.TREEVIEW
).get_by_text(rack_name, exact=True).first
# Прокручиваем до элемента если нужно
rack_element.scroll_into_view_if_needed()
self.main_page.wait_for_timeout(500)
# Проверяем и нажимаем кнопку "Изменить"
rack_page = RackPage(browser)
# Проверяем видимость и тултип кнопки
rack_page.should_be_toolbar_buttons()
# Кликаем на кнопку "Изменить"
rack_page.click_edit_button()
self.main_page.wait_for_timeout(1000)
# Создаем экземпляр EditRackMaker
rack_edit = EditRackMaker(browser, rack_name)
# Используем метод для удаления
rack_edit.click_remove_button()
# Проверяем уведомление об успешном удалении
expected_alert_text = "Успешно удалено"
self.alert.check_alert_presence(expected_alert_text, timeout=7000)
self.alert.check_alert_absence(expected_alert_text, timeout=7000)
# Закрываем alert с текстом кнопкой 'Закрыть'
try:
self.alert.close_alert_by_text(expected_alert_text)
logger.debug("Alert forcibly closed")
except AssertionError:
# Если уже закрылся - игнорируем
logger.debug("Alert already closed by the time forcible close was attempted")
logger.info(f"Rack '{rack_name}' deleted successfully")
def test_rack_general_info_tab_fields(self, browser: Page) -> None:
"""Тест заполнения полей вкладки 'Общая информация' стойки."""
logger.debug(f"Starting general info tab test for rack: {self.RACK_NAME}")
rack_page = RackPage(browser)
# Переходим в режим редактирования
rack_page.click_edit_button()
rack_page.wait_for_timeout(1000)
# Создаем экземпляр EditRackMaker
rack_edit = EditRackMaker(browser, self.RACK_NAME)
# Создаем тестовые данные для заполнения всех полей
rack_edit_data = EditRackData(
# Основные поля
name=self.RACK_NAME,
serial="SN123456789",
inventory="INV987654321",
comment="Тестовый комментарий для стойки (обновленный)",
allocated_power="5500",
# Combobox поля
cable_entry="сверху",
state="Введен в эксплуатацию",
owner="",
service_org="",
project="",
# Checkbox поля
ventilation_panel=True,
)
# Заполняем все поля формы
results = rack_edit.fill_rack_data(rack_edit_data)
logger.debug(f"Fill results: {results}")
# Сохраняем изменения
rack_edit.click_done_button()
# Проверяем уведомление об успешном обновлении
expected_alert_text = "Успешно обновлено"
self.alert.check_alert_presence(expected_alert_text, timeout=7000)
self.alert.check_alert_absence(expected_alert_text, timeout=7000)
# Закрываем alert с текстом кнопкой 'Закрыть'
try:
self.alert.close_alert_by_text(expected_alert_text)
logger.debug("Alert forcibly closed")
except AssertionError:
logger.debug("Alert already closed by the time forcible close was attempted")
# Вход в режим редактирования
rack_page.click_edit_button()
# Проверяем поля, пропуская недоступные
verification_results = rack_edit.verify_all_filled_fields(
rack_edit_data,
skip_fields=["Владелец", "Обслуживающая организация", "Проект/Титул"]
)
logger.debug(f"Verification results: {verification_results}")
# Проверяем результаты
assert verification_results["incorrectly_filled"] == 0, \
f"Available fields incorrectly filled: {verification_results['field_errors']}"
assert verification_results["not_filled"] == 0, \
f"Available fields not filled: {verification_results['field_errors']}"
rack_edit.click_close_button()
logger.debug("General info tab test completed successfully")
def test_required_field_name_validation(self, browser: Page) -> None:
"""Тест проверки обязательного поля ИМЯ при создании стойки."""
logger.debug(f"Starting required field name validation test for rack: {self.RACK_NAME}")
rack_page = RackPage(browser)
# Переходим в режим редактирования
rack_page.click_edit_button()
# Создаем экземпляр EditRackMaker
rack_edit = EditRackMaker(browser, self.RACK_NAME)
# ========== Тест 1: Обязательное поле имя пустое ==========
# Очищаем поле имя
rack_edit.clear_field("Имя")
# Создаем тестовые данные для заполнения поля
test_data_1 = EditRackData(
name=""
)
rack_edit.fill_rack_data(test_data_1)
rack_edit.click_done_button()
# Проверяем уведомление об ошибочном обновлении
expected_alert_text = "поле ИМЯ должно быть заполнено, и не должно превышать 35 знаков"
self.alert.check_alert_presence(expected_alert_text, timeout=7000)
self.alert.check_alert_absence(expected_alert_text, timeout=7000)
# ========== Тест 2: Обязательное поле имя не должно превышать 35 знаков ==========
# Создаем тестовые данные для заполнения поля
test_data_2 = EditRackData(
name="_123456789_123456789_123456789_12345"
)
rack_edit.fill_rack_data(test_data_2)
rack_edit.click_done_button()
# Проверяем уведомление об ошибочном обновлении
expected_alert_text = "поле ИМЯ должно быть заполнено, и не должно превышать 35 знаков"
self.alert.check_alert_presence(expected_alert_text, timeout=7000)
self.alert.check_alert_absence(expected_alert_text, timeout=7000)
rack_edit.click_close_button()
logger.debug("Required field name validation test completed successfully")
def test_rack_image_tab(self, browser: Page) -> None:
"""Тест вкладки 'Изображение' стойки."""
logger.debug(f"Starting image tab test for rack: {self.RACK_NAME}")
rack_page = RackPage(browser)
# Переходим в режим редактирования
rack_page.click_edit_button()
rack_page.wait_for_timeout(1000)
# Создаем экземпляр EditRackMaker
rack_edit = EditRackMaker(browser, self.RACK_NAME)
# Переключаемся на вкладку "Изображение"
rack_edit.switch_to_tab(EditRackMaker.TAB_IMAGE)
# Проверяем вкладку
assert rack_edit.is_tab_active(EditRackMaker.TAB_IMAGE), "Image tab should be active"
# Загружаем изображение если есть
test_image_path = os.path.join(os.path.dirname(__file__), "test_edit_rack_image.jpg")
if os.path.exists(test_image_path):
logger.debug(f"Found test image: {test_image_path}")
# Находим input и загружаем файл
file_input = browser.locator("input[type='file']")
if file_input.count() == 0:
file_input = browser.locator(".button-file-upload__input")
if file_input.count() > 0:
file_input.set_input_files(test_image_path)
rack_page.wait_for_timeout(2000)
logger.debug("Test image uploaded")
else:
logger.warning(f"Test image not found at: {test_image_path}")
# Сохраняем
rack_edit.click_done_button()
# Проверяем уведомление об успешном обновлении
expected_alert_text = "Успешно обновлено"
self.alert.check_alert_presence(expected_alert_text, timeout=7000)
self.alert.check_alert_absence(expected_alert_text, timeout=7000)
# Закрываем alert с текстом кнопкой 'Закрыть'
try:
self.alert.close_alert_by_text(expected_alert_text)
logger.debug("Alert forcibly closed")
except AssertionError:
logger.debug("Alert already closed by the time forcible close was attempted")
logger.debug("Image tab test completed successfully")
def test_rack_access_rules(self, browser: Page) -> None:
"""Тест заполнения полей правил доступа.
В каждое поле добавляются ВСЕ пользователи из списка custom_users.
"""
logger.debug(f"Starting access rules test for rack: {self.RACK_NAME}")
rack_page = RackPage(browser)
# Переходим в режим редактирования
rack_page.click_edit_button()
rack_page.wait_for_timeout(1000)
# Создаем экземпляр EditRackMaker
rack_edit = EditRackMaker(browser, self.RACK_NAME)
# Переключаемся на вкладку "Настройки"
rack_edit.switch_to_tab(EditRackMaker.TAB_SETTINGS)
# Проверяем, что вкладка активна
assert rack_edit.is_tab_active(EditRackMaker.TAB_SETTINGS), \
"Settings tab should be active after switching"
# Целевые поля для заполнения
target_fields = [
"read_access_rules",
"write_access_rules",
"sms_access_rules",
"email_access_rules",
"push_access_rules"
]
# Пользователи для добавления в каждое поле
custom_users = [
"admin",
"manager",
"operator",
"sec",
"collector"
]
# Заполняем поля
fill_results = rack_edit.fill_access_rules(
users_to_add=custom_users,
target_fields=target_fields
)
# Проверяем, что все пользователи были добавлены
expected_total = len(target_fields) * len(custom_users)
assert fill_results["access_rules_filled"] == expected_total, \
f"Added {fill_results['access_rules_filled']} users, expected {expected_total}"
assert len(fill_results["errors"]) == 0, \
f"Errors during filling: {fill_results['errors']}"
# Проверяем заполнение
verification_results = rack_edit.verify_access_rules(
expected_users=custom_users,
target_fields=target_fields
)
logger.debug(f"Verification results: {verification_results}")
# Проверяем результаты
assert verification_results["correctly_filled"] == expected_total, \
f"Correctly filled {verification_results['correctly_filled']} out of {expected_total}"
assert verification_results["incorrectly_filled"] == 0, \
f"Verification errors: {verification_results['field_errors']}"
# Дополнительная проверка
assert len(verification_results["fields_verified"]) == len(target_fields), \
f"Fields verified: {len(verification_results['fields_verified'])}, expected: {len(target_fields)}"
# Сохраняем изменения
rack_edit.click_done_button()
# Проверяем уведомление об успешном обновлении
expected_alert_text = "Успешно обновлено"
self.alert.check_alert_presence(expected_alert_text, timeout=7000)
self.alert.check_alert_absence(expected_alert_text, timeout=7000)
# Закрываем alert с текстом кнопкой 'Закрыть'
try:
self.alert.close_alert_by_text(expected_alert_text)
logger.debug("Alert forcibly closed")
except AssertionError:
logger.debug("Alert already closed by the time forcible close was attempted")
# Возвращаемся в режим редактирования и проверяем снова
rack_page.click_edit_button()
rack_page.wait_for_timeout(1000)
rack_edit = EditRackMaker(browser, self.RACK_NAME)
rack_edit.switch_to_tab(EditRackMaker.TAB_SETTINGS)
verification_results_after_save = rack_edit.verify_access_rules(
expected_users=custom_users,
target_fields=target_fields
)
logger.debug(f"Verification results after save: {verification_results_after_save}")
assert verification_results_after_save["correctly_filled"] == expected_total, \
f"After save - correctly filled {verification_results_after_save['correctly_filled']} out of {expected_total}"
rack_edit.click_close_button()
logger.debug("Access rules test completed successfully")