"""Модуль создания объекта 'Стойка'.""" 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_required_fields(rack_data) self._fill_optional_fields(rack_data) self._fill_combobox_fields(rack_data) logger.info("Rack data filled successfully") def _fill_required_fields(self, rack_data: RackData) -> None: """Заполняет обязательные поля.""" if rack_data.name: name_field = self.page.locator(RackLocators.RACK_NAME_FIELD).first name_field.fill(rack_data.name) logger.info(f"Filled 'Name' field: {rack_data.name}") def _fill_optional_fields(self, rack_data: RackData) -> None: """Заполняет опциональные поля.""" if rack_data.serial: serial_field = self.page.locator(RackLocators.RACK_SERIAL_FIELD).first serial_field.fill(rack_data.serial) logger.info(f"Filled serial number: {rack_data.serial}") if rack_data.inventory: inventory_field = self.page.locator(RackLocators.RACK_INVENTORY_FIELD).first inventory_field.fill(rack_data.inventory) logger.info(f"Filled inventory number: {rack_data.inventory}") if rack_data.comment: comment_field = self.page.locator(RackLocators.RACK_COMMENT_FIELD).first comment_field.fill(rack_data.comment) logger.info(f"Added comment: {rack_data.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 wait_for_timeout(self, timeout: int) -> None: """ Ожидает указанное количество миллисекунд. Args: timeout: Время ожидания в миллисекундах """ self.page.wait_for_timeout(timeout) # Проверки: 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")