379 lines
17 KiB
Python
379 lines
17 KiB
Python
"""Модуль тестов вкладки 'Стойка' в модуле Объекты.
|
||
|
||
Содержит тесты для проверки функциональности
|
||
работы со стойкой оборудования.
|
||
"""
|
||
|
||
import pytest
|
||
from playwright.sync_api import Page, expect
|
||
from locators.navigation_panel_locators import NavigationPanelLocators
|
||
from pages.location_page import LocationPage
|
||
from components_derived.accounting_objects.rack_maker import RackObjectMaker, RackData
|
||
from components_derived.frames.create_child_element_frame import CreateChildElementFrame
|
||
from pages.login_page import LoginPage
|
||
from pages.main_page import MainPage
|
||
from pages.rack_page import RackPage
|
||
from tools.logger import get_logger
|
||
from components_derived.modal_rack_edit import ModalRackEdit, RackEditData
|
||
|
||
# Константы
|
||
RACK_NAME = "Test-Rack-Functionality"
|
||
|
||
class TestRackTab:
|
||
"""Набор тестов для вкладки 'Стойка' в модуле Объекты.
|
||
|
||
Проверяет корректность отображения, функциональность элементов интерфейса
|
||
и переключение между вкладками стойки оборудования.
|
||
|
||
Тесты покрывают следующие функциональные области:
|
||
1. test_rack_tab_content - Базовая структура и содержимое вкладки стойки
|
||
2. test_rack_tab_switching - Функциональность переключения между вкладками стойки
|
||
"""
|
||
|
||
# Инициализируем атрибуты
|
||
main_page: MainPage = None
|
||
location_page: LocationPage = None
|
||
|
||
def _check_rack_existance(self, browser: Page, rack_name: str) -> bool:
|
||
"""Проверяет существование стойки.
|
||
|
||
Args:
|
||
browser: Страница Playwright
|
||
rack_name: Имя стойки для проверки
|
||
|
||
Returns:
|
||
bool: True если стойка существует, False в противном случае
|
||
"""
|
||
|
||
# Обновляем навигационную панель
|
||
self.main_page.wait_for_timeout(500)
|
||
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():
|
||
return True
|
||
return False
|
||
|
||
def _create_rack(self, browser: Page, rack_name: str) -> None:
|
||
"""Создает стойку.
|
||
|
||
Args:
|
||
browser: Страница Playwright
|
||
rack_name: Имя стойки для создания
|
||
"""
|
||
# Нажимаем кнопку "Создать" на тулбаре
|
||
self.location_page.click_create_button()
|
||
|
||
# Создаем фрейм создания дочернего элемента
|
||
create_child_frame = CreateChildElementFrame(browser)
|
||
|
||
# Нажимаем на плашку "Класс объекта учета"
|
||
create_child_frame.open_object_class_combobox()
|
||
|
||
# Из выпадающего меню выбираем пункт "Стойка"
|
||
create_child_frame.select_object_class("Стойка")
|
||
|
||
# Открывается набор плашек для задания параметров стойки
|
||
rack_maker = RackObjectMaker(browser)
|
||
|
||
# Создаем объект данных стойки
|
||
rack_data = RackData(
|
||
name=rack_name,
|
||
height="42",
|
||
depth="1000"
|
||
)
|
||
|
||
# Заполняем данные стойки
|
||
rack_maker.fill_rack_data(rack_data)
|
||
|
||
# Нажимаем кнопку создания
|
||
create_child_frame.click_add_button()
|
||
|
||
def _delete_rack_from_context_menu(self, browser: Page, rack_name: str) -> None:
|
||
"""Удаляет стойку через контекстное меню.
|
||
|
||
Args:
|
||
browser: Страница Playwright
|
||
rack_name: Имя стойки для удаления
|
||
"""
|
||
|
||
# 1. Находим элемент стойки в навигационной панели
|
||
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)
|
||
|
||
# 2. Проверяем и нажимаем кнопку "Изменить"
|
||
rack_page = RackPage(browser)
|
||
|
||
# Проверяем видимость кнопки
|
||
rack_page.toolbar.check_button_visibility("edit")
|
||
|
||
# Проверяем тултип кнопки
|
||
rack_page.toolbar.check_button_tooltip("edit", "Изменить")
|
||
|
||
# Кликаем на кнопку "Изменить"
|
||
rack_page.toolbar.get_button_by_name("edit").click()
|
||
|
||
# 3. Создаем экземпляр ModalRackEdit
|
||
rack_edit = ModalRackEdit(browser)
|
||
|
||
# Используем метод для удаления
|
||
rack_edit.click_remove_button()
|
||
|
||
# 4. Проверяем уведомление об успешном удалении - требуется создать разработчику (заведена задача)
|
||
# Создаем экземпляр фрейма для доступа к alert компоненту
|
||
# create_child_frame = CreateChildElementFrame(browser)
|
||
|
||
# Проверяем наличие любого alert-окна (не обязательно точного текста)
|
||
# create_child_frame.alert.check_alert_presence("")
|
||
|
||
# Получаем текст alert, чтобы убедиться что удаление прошло успешно
|
||
# alert_text = create_child_frame.alert.get_text()
|
||
# logger.debug(f"Alert text after deletion: {alert_text}")
|
||
|
||
# Проверяем что в тексте есть указание на успешное удаление
|
||
# assert "удален" in alert_text.lower() or "успешно" in alert_text.lower()
|
||
|
||
# Закрываем alert
|
||
# create_child_frame.alert.close_alert()
|
||
|
||
@pytest.fixture(scope="function", autouse=True)
|
||
def setup(self, browser: Page) -> None:
|
||
"""Фикстура для подготовки тестового окружения.
|
||
|
||
Выполняет:
|
||
1. Авторизацию в системе
|
||
2. Создание стойки если она не существует
|
||
3. Переход к стойке
|
||
|
||
Args:
|
||
browser (Page): Экземпляр страницы 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)
|
||
|
||
# Проверяем существование стойки
|
||
if not self._check_rack_existance(browser, RACK_NAME):
|
||
self._create_rack(browser, RACK_NAME)
|
||
self.main_page.wait_for_timeout(3000)
|
||
|
||
# Переходим к стойке для тестирования
|
||
self.main_page.click_subpanel_item(RACK_NAME, parent="test-zone")
|
||
self.main_page.wait_for_timeout(3000)
|
||
|
||
@pytest.fixture(scope="class", autouse=True)
|
||
def cleanup_rack(self, browser: Page):
|
||
"""Фикстура для очистки созданной стойки после ВСЕХ тестов класса.
|
||
|
||
Выполняется один раз после завершения всех тестов класса TestRackTab.
|
||
Удаляет созданную стойку.
|
||
|
||
Args:
|
||
browser: Экземпляр страницы Playwright
|
||
"""
|
||
# Тесты выполняются здесь
|
||
yield
|
||
|
||
# Переходим на главную страницу и в нужную зону
|
||
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)
|
||
|
||
# Проверяем существование стойки
|
||
if self._check_rack_existance(browser, RACK_NAME):
|
||
|
||
# Переходим на страницу стойки
|
||
self.main_page.click_subpanel_item(RACK_NAME, parent="test-zone")
|
||
self.main_page.wait_for_timeout(2000)
|
||
|
||
# Удаляем стойку
|
||
self._delete_rack_from_context_menu(browser, RACK_NAME)
|
||
|
||
# Дополнительная проверка
|
||
self.main_page.click_subpanel_item("test-zone")
|
||
self.main_page.wait_for_timeout(1000)
|
||
|
||
#@pytest.mark.develop
|
||
def test_rack_tab_content(self, browser: Page) -> None:
|
||
"""Тест содержимого вкладки 'Стойка'.
|
||
|
||
Проверяет:
|
||
1. Наличие и корректность заголовка панели с навигационной цепочкой
|
||
2. Отображение и структуру обеих сторон стойки (лицевой и обратной)
|
||
3. Наличие и функциональность кнопок панели инструментов
|
||
4. Корректность отображения юнитов и устройств на стойке
|
||
|
||
Args:
|
||
browser (Page): Экземпляр страницы Playwright для взаимодействия с UI
|
||
"""
|
||
|
||
expected_toolbar_subtitles = [
|
||
"test-zone",
|
||
'chevron_right',
|
||
RACK_NAME
|
||
]
|
||
|
||
rt = RackPage(browser)
|
||
rt.should_be_panel_header(expected_toolbar_subtitles)
|
||
|
||
# Комплексная проверка отображения обеих сторон стойки с детальной информацией
|
||
rt.should_be_rack_sides_displayed()
|
||
|
||
# Проверка кнопки "Скрыть стойку"
|
||
rt.should_have_hide_rack_button()
|
||
|
||
# Проверка кнопки "Показать стойку"
|
||
rt.should_have_show_rack_button()
|
||
|
||
rt.wait_for_timeout(1000)
|
||
|
||
def test_rack_tab_switching(self, browser: Page) -> None:
|
||
"""Тест переключения между вкладками стойки оборудования.
|
||
|
||
Тестирует переключение на все доступные вкладки: Общая информация,
|
||
Обслуживание, События, Сервисы.
|
||
|
||
Args:
|
||
browser (Page): Экземпляр страницы Playwright для взаимодействия с UI
|
||
"""
|
||
|
||
rt = RackPage(browser)
|
||
|
||
# Проверяем переключение между всеми вкладками стойки
|
||
rt.check_tab_switching()
|
||
|
||
# Переход в режим редактирования
|
||
rt.should_be_toolbar_buttons()
|
||
rt.wait_for_timeout(1000)
|
||
|
||
@pytest.mark.develop
|
||
def test_rack_general_info_tab_fields(self, browser: Page) -> None:
|
||
"""Тест заполнения полей вкладки 'Общая информация' стойки."""
|
||
logger = get_logger("RACK_GENERAL_INFO_TEST")
|
||
|
||
rt = RackPage(browser)
|
||
|
||
# Переходим в режим редактирования
|
||
logger.debug("Switching to edit mode...")
|
||
rt.toolbar.check_button_visibility("edit")
|
||
rt.toolbar.get_button_by_name("edit").click()
|
||
rt.wait_for_timeout(3000)
|
||
|
||
# Создаем экземпляр ModalRackEdit
|
||
rack_edit = ModalRackEdit(browser)
|
||
rack_edit.should_be_toolbar_buttons()
|
||
|
||
# Получаем список доступных полей (используем точные названия из этого списка)
|
||
available_fields = rack_edit.get_available_fields()
|
||
logger.info(f"Available fields in form: {available_fields}")
|
||
|
||
# Создаем маппинг: используем ТОЧНЫЕ названия полей из available_fields
|
||
field_mapping = {}
|
||
|
||
# Текстовые поля
|
||
for field_pattern, test_value in [
|
||
("Имя", "Test-Rack-Functionality"),
|
||
("Серийный номер", "SN123456789"),
|
||
("Инвентарный номер", "INV987654321"),
|
||
("Комментарий", "Тестовый комментарий для стойки"),
|
||
("Выделенная мощность (Вт/ВА)", "55"),
|
||
]:
|
||
# Ищем точное совпадение
|
||
if field_pattern in available_fields:
|
||
field_mapping[field_pattern] = ("text", test_value)
|
||
|
||
# Combobox поля
|
||
for field_pattern, test_value in [
|
||
("Ввод кабеля", "Сверху"),
|
||
("Состояние", "Введен в эксплуатацию"),
|
||
("Владелец", "Тестовый владелец"),
|
||
("Обслуживающая организация", "Тестовая сервисная организация"),
|
||
("Проект/Титул", "Тестовый проект"),
|
||
]:
|
||
if field_pattern in available_fields:
|
||
field_mapping[field_pattern] = ("combobox", test_value)
|
||
|
||
# Заполняем каждое поле вручную
|
||
results = {
|
||
"text_fields_filled": 0,
|
||
"combobox_fields_filled": 0,
|
||
"checkboxes_set": 0
|
||
}
|
||
|
||
logger.info("Filling fields individually...")
|
||
|
||
for field_name, (field_type, value) in field_mapping.items():
|
||
logger.info(f"Filling {field_type} field '{field_name}' with '{value}'...")
|
||
|
||
if field_type == "text":
|
||
success = rack_edit._fill_text_field(field_name, value)
|
||
if success:
|
||
results["text_fields_filled"] += 1
|
||
logger.info(f"✓ Text field '{field_name}' filled")
|
||
else:
|
||
logger.warning(f"✗ Failed to fill text field '{field_name}'")
|
||
|
||
elif field_type == "combobox":
|
||
success = rack_edit._fill_combobox_field(field_name, value)
|
||
if success:
|
||
results["combobox_fields_filled"] += 1
|
||
logger.info(f"✓ Combobox field '{field_name}' filled")
|
||
else:
|
||
logger.warning(f"✗ Failed to fill combobox field '{field_name}'")
|
||
|
||
# Устанавливаем checkbox
|
||
test_ventilation_panel = True
|
||
logger.info("Setting ventilation panel checkbox...")
|
||
success = rack_edit._set_checkbox_field("Вентиляционная панель", test_ventilation_panel)
|
||
if success:
|
||
results["checkboxes_set"] += 1
|
||
logger.info("✓ Checkbox set")
|
||
else:
|
||
logger.warning("✗ Failed to set checkbox")
|
||
|
||
# Проверяем результаты
|
||
logger.info(f"Fill results: {results}")
|
||
|
||
# Проверяем что хотя бы некоторые поля были заполнены
|
||
total_filled = results.get("text_fields_filled", 0) + results.get("combobox_fields_filled", 0)
|
||
assert total_filled > 0, f"No fields were filled successfully. Results: {results}"
|
||
|
||
# Сохраняем изменения
|
||
logger.info("Saving changes...")
|
||
# Используем метод из ModalRackEdit для кнопки "Сохранить"
|
||
rack_edit.click_done_button()
|
||
rack_edit.wait_for_timeout(3000)
|
||
|
||
# Проверяем выход из режима редактирования
|
||
rt.toolbar.check_button_visibility("edit")
|
||
logger.info("✓ Successfully exited edit mode")
|
||
|
||
logger.info("✓ General Info tab fields test completed")
|