"""Модуль создания объекта 'Стойка'.""" 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") class RackObjectMaker(BaseComponent): """Компонент для создания и настройки стойки.""" def __init__(self, page: Page) -> None: """ Инициализирует компонент создания стойки. Args: page: Экземпляр страницы Playwright """ super().__init__(page) # Действия: def fill_rack_data(self, 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 = "") -> None: """ Заполняет данные для создания стойки. Args: name: Наименование стойки height: Высота в юнитах (по умолчанию 42) depth: Глубина в мм (по умолчанию 1000) serial: Серийный номер inventory: Инвентарный номер comment: Комментарий cable_entry: Ввод кабеля state: Состояние owner: Владелец service_org: Обслуживающая организация project: Проект/Титул """ logger.info(f"Filling rack data: {name}") # Заполняем обязательные поля с использованием first() if name: name_field = self.page.locator(RackLocators.RACK_NAME_FIELD).first name_field.fill(name) logger.info(f"Filled 'Name' field: {name}") if height: self._fill_combobox_field("Height in units", height, RackLocators.RACK_HEIGHT_FIELD) logger.info(f"Selected height: {height} units") if depth: self._fill_combobox_field("Depth (mm)", depth, RackLocators.RACK_DEPTH_FIELD) logger.info(f"Selected depth: {depth} mm") # Заполняем опциональные поля с использованием first() if serial: serial_field = self.page.locator(RackLocators.RACK_SERIAL_FIELD).first serial_field.fill(serial) logger.info(f"Filled serial number: {serial}") if inventory: inventory_field = self.page.locator(RackLocators.RACK_INVENTORY_FIELD).first inventory_field.fill(inventory) logger.info(f"Filled inventory number: {inventory}") if comment: comment_field = self.page.locator(RackLocators.RACK_COMMENT_FIELD).first comment_field.fill(comment) logger.info(f"Added comment: {comment}") # Заполняем дополнительные combobox поля if cable_entry: self._fill_combobox_field("Cable entry", cable_entry, RackLocators.RACK_CABLE_ENTRY_FIELD) logger.info(f"Selected cable entry: {cable_entry}") if state: self._fill_combobox_field("State", state, RackLocators.RACK_STATE_FIELD) logger.info(f"Selected state: {state}") if owner: self._fill_combobox_field("Owner", owner, RackLocators.RACK_OWNER_FIELD) logger.info(f"Selected owner: {owner}") if service_org: self._fill_combobox_field("Service organization", service_org, RackLocators.RACK_SERVICE_ORG_FIELD) logger.info(f"Selected service organization: {service_org}") if project: self._fill_combobox_field("Project/Title", project, RackLocators.RACK_PROJECT_FIELD) logger.info(f"Selected project/title: {project}") logger.info("Rack data filled successfully") 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") ] # Проверяем обязательные поля с использованием first() для избежания strict mode violation 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")