229 lines
8.3 KiB
Python
229 lines
8.3 KiB
Python
"""Модуль создания объекта 'Стойка'."""
|
||
|
||
from dataclasses import dataclass
|
||
from playwright.sync_api import Page
|
||
from tools.logger import get_logger
|
||
from locators.rack_locators import RackLocators
|
||
from components.base_component import BaseComponent
|
||
|
||
logger = get_logger("RACK_MAKER")
|
||
|
||
|
||
@dataclass
|
||
class RackData:
|
||
"""Класс для хранения данных стойки."""
|
||
|
||
name: str
|
||
height: str = "42"
|
||
depth: str = "1000"
|
||
serial: str = ""
|
||
inventory: str = ""
|
||
comment: str = ""
|
||
cable_entry: str = ""
|
||
state: str = ""
|
||
owner: str = ""
|
||
service_org: str = ""
|
||
project: str = ""
|
||
|
||
|
||
class RackObjectMaker(BaseComponent):
|
||
"""Компонент для создания и настройки стойки."""
|
||
|
||
def __init__(self, page: Page) -> None:
|
||
"""
|
||
Инициализирует компонент создания стойки.
|
||
|
||
Args:
|
||
page: Экземпляр страницы Playwright
|
||
"""
|
||
|
||
super().__init__(page)
|
||
|
||
# Действия:
|
||
|
||
def fill_rack_data(self, rack_data: RackData) -> None:
|
||
"""
|
||
Заполняет данные для создания стойки.
|
||
|
||
Args:
|
||
rack_data: Данные стойки
|
||
"""
|
||
|
||
logger.info(f"Filling rack data: {rack_data.name}")
|
||
|
||
self._fill_text_fields(rack_data)
|
||
self._fill_combobox_fields(rack_data)
|
||
|
||
logger.info("Rack data filled successfully")
|
||
|
||
def _fill_text_fields(self, rack_data: RackData) -> None:
|
||
"""Заполняет текстовые поля."""
|
||
|
||
def clear_and_fill(locator, value: str, field_name: str):
|
||
"""Очищает поле и заполняет его значением."""
|
||
|
||
field = self.page.locator(locator).first
|
||
# Очищаем поле
|
||
field.click()
|
||
field.press("Control+A")
|
||
field.press("Backspace")
|
||
# Заполняем значение
|
||
field.fill(value)
|
||
logger.info(f"Filled '{field_name}': {value}")
|
||
|
||
# Обязательные поля.
|
||
if rack_data.name:
|
||
clear_and_fill(RackLocators.RACK_NAME_FIELD, rack_data.name, "Name")
|
||
|
||
# Опциональные поля.
|
||
if rack_data.serial:
|
||
clear_and_fill(RackLocators.RACK_SERIAL_FIELD, rack_data.serial, "Serial number")
|
||
|
||
if rack_data.inventory:
|
||
clear_and_fill(RackLocators.RACK_INVENTORY_FIELD, rack_data.inventory, "Inventory number")
|
||
|
||
if rack_data.comment:
|
||
clear_and_fill(RackLocators.RACK_COMMENT_FIELD, rack_data.comment, "Comment")
|
||
|
||
def _fill_combobox_fields(self, rack_data: RackData) -> None:
|
||
"""Заполняет combobox поля."""
|
||
|
||
# Обязательные поля.
|
||
if rack_data.height:
|
||
self._fill_combobox_field("Height in units", rack_data.height,
|
||
RackLocators.RACK_HEIGHT_FIELD)
|
||
logger.info(f"Selected height: {rack_data.height} units")
|
||
|
||
if rack_data.depth:
|
||
self._fill_combobox_field("Depth (mm)", rack_data.depth,
|
||
RackLocators.RACK_DEPTH_FIELD)
|
||
logger.info(f"Selected depth: {rack_data.depth} mm")
|
||
|
||
# Опциональные поля.
|
||
if rack_data.cable_entry:
|
||
self._fill_combobox_field("Cable entry", rack_data.cable_entry,
|
||
RackLocators.RACK_CABLE_ENTRY_FIELD)
|
||
logger.info(f"Selected cable entry: {rack_data.cable_entry}")
|
||
|
||
if rack_data.state:
|
||
self._fill_combobox_field("State", rack_data.state,
|
||
RackLocators.RACK_STATE_FIELD)
|
||
logger.info(f"Selected state: {rack_data.state}")
|
||
|
||
if rack_data.owner:
|
||
self._fill_combobox_field("Owner", rack_data.owner,
|
||
RackLocators.RACK_OWNER_FIELD)
|
||
logger.info(f"Selected owner: {rack_data.owner}")
|
||
|
||
if rack_data.service_org:
|
||
self._fill_combobox_field("Service organization", rack_data.service_org,
|
||
RackLocators.RACK_SERVICE_ORG_FIELD)
|
||
logger.info(f"Selected service organization: {rack_data.service_org}")
|
||
|
||
if rack_data.project:
|
||
self._fill_combobox_field("Project/Title", rack_data.project,
|
||
RackLocators.RACK_PROJECT_FIELD)
|
||
logger.info(f"Selected project/title: {rack_data.project}")
|
||
|
||
def _fill_combobox_field(self, field_name: str, value: str, field_locator: str) -> None:
|
||
"""
|
||
Заполняет combobox поле.
|
||
|
||
Args:
|
||
field_name: Название поля
|
||
value: Значение для установки
|
||
field_locator: Локатор поля
|
||
"""
|
||
|
||
logger.info(f"Filling field '{field_name}' with value '{value}'...")
|
||
|
||
# Используем first() для избежания strict mode violation
|
||
field_container = self.page.locator(field_locator).first
|
||
|
||
# Прокручиваем до поля
|
||
field_container.scroll_into_view_if_needed()
|
||
self.wait_for_timeout(500)
|
||
|
||
# Проверяем видимость поля
|
||
self.check_visibility(field_container, f"Field '{field_name}' not found")
|
||
|
||
# Кликаем и вводим значение
|
||
field_container.click(force=True)
|
||
self.wait_for_timeout(1000)
|
||
|
||
# Вводим значение
|
||
self.page.keyboard.type(value)
|
||
self.wait_for_timeout(500)
|
||
self.page.keyboard.press("Enter")
|
||
|
||
logger.info(f"Field '{field_name}' filled successfully")
|
||
|
||
def _get_field_locator(self, field_name: str) -> str:
|
||
"""
|
||
Возвращает локатор поля по его названию.
|
||
|
||
Args:
|
||
field_name: Название поля
|
||
|
||
Returns:
|
||
str: Локатор поля
|
||
"""
|
||
|
||
field_map = {
|
||
"Имя": RackLocators.RACK_NAME_FIELD,
|
||
"Высота в юнитах": RackLocators.RACK_HEIGHT_FIELD,
|
||
"Глубина (мм)": RackLocators.RACK_DEPTH_FIELD
|
||
}
|
||
|
||
if field_name not in field_map:
|
||
raise ValueError(f"Field '{field_name}' is not supported")
|
||
|
||
return field_map[field_name]
|
||
|
||
# Проверки:
|
||
|
||
def check_rack_fields_presence(self) -> None:
|
||
"""
|
||
Проверяет наличие полей специфичных для стойки.
|
||
|
||
Raises:
|
||
AssertionError: Если какое-либо поле не найдено
|
||
"""
|
||
|
||
logger.info("Checking rack fields presence...")
|
||
|
||
# Основные обязательные поля
|
||
required_fields = [
|
||
(RackLocators.RACK_NAME_FIELD, "Name"),
|
||
(RackLocators.RACK_HEIGHT_FIELD, "Height in units"),
|
||
(RackLocators.RACK_DEPTH_FIELD, "Depth (mm)")
|
||
]
|
||
|
||
# Дополнительные поля
|
||
optional_fields = [
|
||
(RackLocators.RACK_SERIAL_FIELD, "Serial number"),
|
||
(RackLocators.RACK_INVENTORY_FIELD, "Inventory number"),
|
||
(RackLocators.RACK_COMMENT_FIELD, "Comment"),
|
||
(RackLocators.RACK_CABLE_ENTRY_FIELD, "Cable entry"),
|
||
(RackLocators.RACK_STATE_FIELD, "State"),
|
||
(RackLocators.RACK_OWNER_FIELD, "Owner"),
|
||
(RackLocators.RACK_SERVICE_ORG_FIELD, "Service organization"),
|
||
(RackLocators.RACK_PROJECT_FIELD, "Project/Title")
|
||
]
|
||
|
||
# Проверяем обязательные поля
|
||
for field_locator, field_name in required_fields:
|
||
field = self.page.locator(field_locator).first
|
||
self.check_visibility(field, f"Required field '{field_name}' not found")
|
||
logger.info(f"Required field '{field_name}' found")
|
||
|
||
# Проверяем дополнительные поля
|
||
for field_locator, field_name in optional_fields:
|
||
field = self.page.locator(field_locator).first
|
||
if field.count() > 0 and field.is_visible():
|
||
logger.info(f"Optional field '{field_name}' found")
|
||
else:
|
||
logger.info(f"Optional field '{field_name}' not found or not visible")
|
||
|
||
logger.info("All main rack fields are present")
|