refactor: реорганизация структуры проекта

- Изменены (test_edit_rack.py, test_management_rack.py)
ra6/create_rack
Radislav 2026-03-06 11:54:03 +03:00
parent ca7c69c423
commit 4fff4835f1
2 changed files with 401 additions and 317 deletions

View File

@ -1,157 +1,45 @@
"""Модуль тестов вкладки 'Стойка' в модуле Объекты.
"""Модуль тестов редактирования стойки в модуле Объекты.
Содержит тесты для проверки функциональности
работы со стойкой оборудования.
редактирования стойки оборудования.
"""
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.location_page import LocationPage
from pages.rack_page import RackPage
from components_derived.accounting_objects.rack_maker import RackObjectMaker, RackData
from components_derived.frames.create_child_element_frame import CreateChildElementFrame
from components_derived.modal_edit_rack import ModalEditRack, RackEditData
from components.alert_component import AlertComponent
from tools.logger import get_logger
# Константы
RACK_NAME = "Test-Rack-Functionality"
# Инициализация логгера для всего модуля
logger = get_logger("RACK_EDIT_TESTS")
logger.setLevel("INFO")
class TestRackTab:
"""Набор тестов для вкладки 'Стойка' в модуле Объекты.
Проверяет корректность отображения, функциональность элементов интерфейса
и переключение между вкладками стойки оборудования.
class TestRackEdit:
"""Набор тестов для редактирования стойки в модуле Объекты.
Тесты покрывают следующие функциональные области:
1. test_rack_general_info_tab_fields - Заполнение полей вкладки 'Общая информация'
2. test_rack_image_tab - Работа с вкладкой 'Изображение'
3. test_rack_access_rules - Заполнение полей правил доступа
Проверяет функциональность редактирования различных вкладок стойки:
1. Общая информация
2. Изображение
3. Правила доступа
"""
# Имя тестовой стойки
RACK_NAME = "Test-Rack-Edit"
# Инициализируем атрибуты
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: Имя стойки для создания
"""
logger.debug(f"Creating rack: {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()
# Проверяем уведомление об успешном создании
alert = AlertComponent(browser)
expected_alert_text = f"Элемент {rack_name} создан"
alert.check_alert_presence(expected_alert_text)
alert.close_alert_by_text(expected_alert_text)
logger.info(f"Rack '{rack_name}' created successfully")
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.should_be_toolbar_buttons()
# Кликаем на кнопку "Изменить"
rack_page.click_edit_button()
self.main_page.wait_for_timeout(1000)
# 3. Создаем экземпляр ModalRackEditRack
rack_edit = ModalEditRack(browser, rack_name)
# Используем метод для удаления
rack_edit.click_remove_button()
self.main_page.wait_for_timeout(1000)
# 4. Проверяем уведомление об успешном удалении
alert = AlertComponent(browser)
expected_alert_text = "Успешно удалено"
alert.check_alert_presence(expected_alert_text)
alert.close_alert_by_text(expected_alert_text)
logger.info(f"Rack '{rack_name}' deleted successfully")
alert: AlertComponent = None
create_child_frame: CreateElementFrame = None
@pytest.fixture(scope="function", autouse=True)
def setup(self, browser: Page) -> None:
@ -159,11 +47,13 @@ class TestRackTab:
Выполняет:
1. Авторизацию в системе
2. Создание стойки если она не существует
3. Переход к стойке
2. Переход к локации test-zone
3. Инициализацию компонентов
4. Создание стойки если она не существует
5. Переход к стойке
Args:
browser (Page): Экземпляр страницы Playwright для взаимодействия с UI
browser: Экземпляр страницы Playwright для взаимодействия с UI
"""
# Авторизация в системе
@ -182,22 +72,35 @@ class TestRackTab:
# Создаем экземпляр страницы локации
self.location_page = LocationPage(browser)
# Инициализируем компонент алертов (вынесено в атрибуты класса)
self.alert = AlertComponent(browser)
# Инициализируем фрейм создания дочернего элемента (вынесено в атрибуты класса)
self.create_child_frame = CreateElementFrame(browser)
# Проверяем существование стойки
if not self._check_rack_existance(browser, RACK_NAME):
self._create_rack(browser, RACK_NAME)
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 '{RACK_NAME}' already exists")
logger.info(f"Rack '{self.RACK_NAME}' already exists")
# Переходим к стойке для тестирования
self.main_page.click_subpanel_item(RACK_NAME, parent="test-zone")
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):
"""Фикстура для очистки созданной стойки после ВСЕХ тестов класса.
Выполняется один раз после завершения всех тестов класса TestRackTab.
Выполняется один раз после завершения всех тестов класса TestRackEdit.
Удаляет созданную стойку.
Args:
@ -207,6 +110,8 @@ class TestRackTab:
# Тесты выполняются здесь
yield
logger.debug(f"Cleaning up rack: {self.RACK_NAME}")
# Переходим на главную страницу и в нужную зону
login_page = LoginPage(browser)
login_page.do_login()
@ -220,37 +125,160 @@ class TestRackTab:
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, RACK_NAME):
if self._check_rack_existance(browser, self.RACK_NAME):
# Переходим на страницу стойки
self.main_page.click_subpanel_item(RACK_NAME, parent="test-zone")
self.main_page.click_subpanel_item(self.RACK_NAME, parent="test-zone")
self.main_page.wait_for_timeout(2000)
# Удаляем стойку
self._delete_rack_from_context_menu(browser, RACK_NAME)
self._delete_rack(browser, self.RACK_NAME)
# Дополнительная проверка
self.main_page.click_subpanel_item("test-zone")
self.main_page.wait_for_timeout(1000)
#@pytest.mark.develop
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"Элемент {rack_data.name} создан"
self.alert.check_alert_presence(expected_alert_text, timeout=5000)
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=5000)
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)
# Создаем экземпляр ModalEditRack
rack_edit = ModalEditRack(browser, RACK_NAME)
# Создаем экземпляр EditRackMaker
rack_edit = EditRackMaker(browser, self.RACK_NAME)
# Создаем тестовые данные для заполнения всех полей
rack_edit_data = RackEditData(
rack_edit_data = EditRackData(
# Основные поля
name=RACK_NAME,
name=self.RACK_NAME,
serial="SN123456789",
inventory="INV987654321",
comment="Тестовый комментарий для стойки (обновленный)",
@ -274,15 +302,19 @@ class TestRackTab:
# Сохраняем изменения
rack_edit.click_done_button()
rack_edit.wait_for_timeout(2000)
# Проверяем уведомление об успешном обновлении
alert = AlertComponent(browser)
expected_alert_text = "Элемент успешно обновлён"
alert.check_alert_presence(expected_alert_text)
alert.close_alert_by_text(expected_alert_text)
self.alert.check_alert_presence(expected_alert_text, timeout=5000)
browser.mouse.click(10, 10)
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()
@ -302,24 +334,27 @@ class TestRackTab:
rack_edit.click_close_button()
#@pytest.mark.develop
logger.debug("General info tab 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)
# Создаем экземпляр ModalEditRack
rack_edit = ModalEditRack(browser, RACK_NAME)
# Создаем экземпляр EditRackMaker
rack_edit = EditRackMaker(browser, self.RACK_NAME)
# Переключаемся на вкладку "Изображение"
rack_edit.switch_to_tab(ModalEditRack.TAB_IMAGE)
rack_edit.switch_to_tab(EditRackMaker.TAB_IMAGE)
# Проверяем вкладку
assert rack_edit.is_tab_active(ModalEditRack.TAB_IMAGE), "Image tab should be active"
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")
@ -339,35 +374,44 @@ class TestRackTab:
# Сохраняем
rack_edit.click_done_button()
rack_page.wait_for_timeout(2000)
# Проверяем уведомление об успешном обновлении
alert = AlertComponent(browser)
expected_alert_text = "Элемент успешно обновлён"
alert.check_alert_presence(expected_alert_text)
alert.close_alert_by_text(expected_alert_text)
self.alert.check_alert_presence(expected_alert_text, timeout=5000)
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")
@pytest.mark.develop
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)
# Создаем экземпляр ModalEditRack
rack_edit = ModalEditRack(browser, RACK_NAME)
# Создаем экземпляр EditRackMaker
rack_edit = EditRackMaker(browser, self.RACK_NAME)
# Переключаемся на вкладку "Настройки"
rack_edit.switch_to_tab(ModalEditRack.TAB_SETTINGS)
rack_edit.switch_to_tab(EditRackMaker.TAB_SETTINGS)
# Проверяем, что вкладка активна
assert rack_edit.is_tab_active(ModalEditRack.TAB_SETTINGS), \
assert rack_edit.is_tab_active(EditRackMaker.TAB_SETTINGS), \
"Settings tab should be active after switching"
# Целевые поля для заполнения
@ -420,20 +464,26 @@ class TestRackTab:
# Сохраняем изменения
rack_edit.click_done_button()
rack_page.wait_for_timeout(2000)
# Проверяем уведомление об успешном обновлении
alert = AlertComponent(browser)
expected_alert_text = "Элемент успешно обновлён"
alert.check_alert_presence(expected_alert_text)
alert.close_alert_by_text(expected_alert_text)
self.alert.check_alert_presence(expected_alert_text, timeout=5000)
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 = ModalEditRack(browser, RACK_NAME)
rack_edit.switch_to_tab(ModalEditRack.TAB_SETTINGS)
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,
@ -445,3 +495,5 @@ class TestRackTab:
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")

View File

@ -6,149 +6,37 @@
import pytest
from playwright.sync_api import Page
from tools.logger import get_logger
from locators.navigation_panel_locators import NavigationPanelLocators
from components_derived.accounting_objects.rack_maker import RackObjectMaker, RackData
from components_derived.frames.create_child_element_frame import CreateChildElementFrame
from components_derived.modal_edit_rack import ModalEditRack
from frames.create_element_frame import CreateElementFrame
from forms.create_rack_form import CreateRackForm, CreateRackData
from makers.edit_rack_maker import EditRackMaker
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
from tools.logger import get_logger
# Константы
RACK_NAME = "Test-Rack-Functionality"
# Инициализация логгера для всего модуля
logger = get_logger("RACK_MANAGEMENT_TESTS")
logger.setLevel("INFO")
class TestRackTab:
class TestRackManagement:
"""Набор тестов для вкладки 'Стойка' в модуле Объекты.
Проверяет корректность отображения, функциональность элементов интерфейса
и переключение между вкладками стойки оборудования.
Тесты покрывают следующие функциональные области:
1. test_rack_tab_content - Базовая структура и содержимое вкладки стойки
"""
# Имя тестовой стойки
RACK_NAME = "Test-Rack-Functionality"
# Инициализируем атрибуты
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: Имя стойки для создания
"""
logger.debug(f"Creating rack: {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()
# Проверяем уведомление об успешном создании
alert = AlertComponent(browser)
expected_alert_text = f"Элемент {rack_name} создан"
alert.check_alert_presence(expected_alert_text)
alert.close_alert_by_text(expected_alert_text)
logger.info(f"Rack '{rack_name}' created successfully")
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.should_be_toolbar_buttons()
# Кликаем на кнопку "Изменить"
rack_page.click_edit_button()
self.main_page.wait_for_timeout(1000)
# 3. Создаем экземпляр ModalRackEditRack
rack_edit = ModalEditRack(browser, rack_name)
# Используем метод для удаления
rack_edit.click_remove_button()
self.main_page.wait_for_timeout(1000)
# 4. Проверяем уведомление об успешном удалении
alert = AlertComponent(browser)
expected_alert_text = "Успешно удалено"
alert.check_alert_presence(expected_alert_text)
alert.close_alert_by_text(expected_alert_text)
logger.info(f"Rack '{rack_name}' deleted successfully")
alert: AlertComponent = None
create_child_frame: CreateElementFrame = None
@pytest.fixture(scope="function", autouse=True)
def setup(self, browser: Page) -> None:
@ -156,12 +44,15 @@ class TestRackTab:
Выполняет:
1. Авторизацию в системе
2. Создание стойки если она не существует
3. Переход к стойке
2. Переход к локации test-zone
3. Инициализацию компонентов
4. Создание стойки если она не существует
5. Переход к стойке
Args:
browser (Page): Экземпляр страницы Playwright для взаимодействия с UI
browser: Экземпляр страницы Playwright для взаимодействия с UI
"""
# Авторизация в системе
login_page = LoginPage(browser)
login_page.do_login()
@ -178,15 +69,28 @@ class TestRackTab:
# Создаем экземпляр страницы локации
self.location_page = LocationPage(browser)
# Инициализируем компонент алертов (вынесено в атрибуты класса)
self.alert = AlertComponent(browser)
# Инициализируем фрейм создания дочернего элемента (вынесено в атрибуты класса)
self.create_child_frame = CreateElementFrame(browser)
# Проверяем существование стойки
if not self._check_rack_existance(browser, RACK_NAME):
self._create_rack(browser, RACK_NAME)
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 '{RACK_NAME}' already exists")
logger.info(f"Rack '{self.RACK_NAME}' already exists")
# Переходим к стойке для тестирования
self.main_page.click_subpanel_item(RACK_NAME, parent="test-zone")
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)
@ -199,9 +103,12 @@ class TestRackTab:
Args:
browser: Экземпляр страницы Playwright
"""
# Тесты выполняются здесь
yield
logger.debug(f"Cleaning up rack: {self.RACK_NAME}")
# Переходим на главную страницу и в нужную зону
login_page = LoginPage(browser)
login_page.do_login()
@ -215,21 +122,142 @@ class TestRackTab:
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, RACK_NAME):
if self._check_rack_existance(browser, self.RACK_NAME):
# Переходим на страницу стойки
self.main_page.click_subpanel_item(RACK_NAME, parent="test-zone")
self.main_page.click_subpanel_item(self.RACK_NAME, parent="test-zone")
self.main_page.wait_for_timeout(2000)
# Удаляем стойку
self._delete_rack_from_context_menu(browser, RACK_NAME)
self._delete_rack(browser, self.RACK_NAME)
# Дополнительная проверка
self.main_page.click_subpanel_item("test-zone")
self.main_page.wait_for_timeout(1000)
#@pytest.mark.develop
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"Элемент {rack_data.name} создан"
self.alert.check_alert_presence(expected_alert_text, timeout=5000)
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=5000)
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_tab_content(self, browser: Page) -> None:
"""Тест содержимого вкладки 'Стойка'.
@ -240,30 +268,34 @@ class TestRackTab:
4. Корректность отображения юнитов и устройств на стойке
Args:
browser (Page): Экземпляр страницы Playwright для взаимодействия с UI
browser: Экземпляр страницы Playwright для взаимодействия с UI
"""
logger.debug(f"Starting test for rack tab content with rack: {self.RACK_NAME}")
expected_toolbar_subtitles = [
"test-zone",
'chevron_right',
RACK_NAME
]
self.RACK_NAME
]
rt = RackPage(browser)
rt.should_be_panel_header(expected_toolbar_subtitles)
rack_page = RackPage(browser)
rack_page.should_be_panel_header(expected_toolbar_subtitles)
# Комплексная проверка отображения обеих сторон стойки с детальной информацией
rt.should_be_rack_sides_displayed()
rack_page.should_be_rack_sides_displayed()
# Проверка кнопки "Скрыть стойку"
rt.should_have_hide_rack_button()
rack_page.should_have_hide_rack_button()
# Проверка кнопки "Показать стойку"
rt.should_have_show_rack_button()
rack_page.should_have_show_rack_button()
# Проверяем переключение между всеми вкладками стойки
rt.check_tab_switching()
rack_page.check_tab_switching()
# Переход в режим редактирования
rt.should_be_toolbar_buttons()
rt.wait_for_timeout(1000)
# Проверям наличие кнопки редактирования
rack_page.should_be_toolbar_buttons()
rack_page.wait_for_timeout(1000)
logger.debug("Test for rack tab content completed successfully")