Compare commits
2 Commits
e3fd08999c
...
5f21e197f6
| Author | SHA1 | Date |
|---|---|---|
|
|
5f21e197f6 | |
|
|
5bbd4e2d46 |
|
|
@ -30,59 +30,51 @@ class BaseComponent:
|
|||
|
||||
# Действия:
|
||||
|
||||
def get_input_fields_locators_(self, container_locator: Locator, search_class: str = "layout") -> dict:
|
||||
"""Получение объекта словаря имя поля ввода : Locator.
|
||||
def get_input_fields_locators(self, container_locator: Locator) -> dict:
|
||||
"""Находит пары "метка-поле ввода" в контейнере с layout структурой.
|
||||
|
||||
Метод ищет элементы в структуре div.layout > div.flex, где:
|
||||
- Первый div.flex содержит метку (текст в input элементе)
|
||||
- Второй div.flex содержит соответствующее поле ввода
|
||||
|
||||
Поддерживает различные структуры:
|
||||
- xs4 (метка) -> xs8 (поле ввода)
|
||||
- xs4 (метка) -> xs1 (поле ввода)
|
||||
- Любые другие парные flex контейнеры
|
||||
|
||||
Args:
|
||||
container_locator: объект Locator.
|
||||
search_class: css класс для поиска (по умолчанию layout)
|
||||
container_locator: Контейнер, в котором искать поля ввода.
|
||||
|
||||
Returns:
|
||||
dict: словарь имя поля ввода : Locator xs8 контейнера
|
||||
Словарь, где ключ - текст метки, значение - Locator контейнера с полем ввода.
|
||||
"""
|
||||
|
||||
fields_locators = {}
|
||||
|
||||
if search_class == "layout":
|
||||
# Поиск по структуре layout -> xs4 (label) + xs8 (input контейнер)
|
||||
layout_containers = container_locator.locator("div.layout")
|
||||
layouts = container_locator.locator("div.layout")
|
||||
|
||||
for i in range(layout_containers.count()):
|
||||
layout_container = layout_containers.nth(i)
|
||||
for i in range(layouts.count()):
|
||||
layout = layouts.nth(i)
|
||||
flex_containers = layout.locator("div.flex")
|
||||
|
||||
xs4_div = layout_container.locator("div.flex.xs4").first
|
||||
xs8_div = layout_container.locator("div.flex.xs8").first
|
||||
|
||||
if xs4_div.count() > 0 and xs8_div.count() > 0:
|
||||
# Ищем input в label_container
|
||||
label_input = xs4_div.locator("div.v-text-field__slot > input").first
|
||||
if label_input.count() > 0:
|
||||
label_text = label_input.input_value().strip()
|
||||
# Обрабатываем пары контейнеров
|
||||
for j in range(0, flex_containers.count() - 1):
|
||||
label_container = flex_containers.nth(j)
|
||||
input_container = flex_containers.nth(j + 1)
|
||||
|
||||
# Извлекаем текст метки
|
||||
inputs = label_container.locator("input")
|
||||
if inputs.count() > 0:
|
||||
label_text = inputs.first.input_value().strip()
|
||||
if label_text:
|
||||
# Возвращаем xs8 контейнер
|
||||
fields_locators[label_text] = xs8_div
|
||||
# Проверяем поле ввода
|
||||
has_input = input_container.locator(
|
||||
"input, textarea, select"
|
||||
).count() > 0
|
||||
|
||||
return fields_locators
|
||||
if has_input:
|
||||
fields_locators[label_text] = input_container
|
||||
|
||||
def get_input_fields_locators(self, container_locator: Locator, css_class: str) -> dict:
|
||||
"""Получение объекта словаря имя поля ввода : Locator.
|
||||
|
||||
Args:
|
||||
locator: объект Locator.
|
||||
css_class: css класс для уточнения положения искомого объекта в DOM.
|
||||
Returns:
|
||||
dict: словарь имя поля ввода : Locator.
|
||||
"""
|
||||
|
||||
fields_locators = {}
|
||||
|
||||
elements = container_locator.locator(f"div.flex.{css_class} div.v-text-field__slot > input").all()
|
||||
|
||||
for el in elements:
|
||||
val = el.input_value().strip()
|
||||
if val:
|
||||
fields_locators[val] = el.locator("../ancestor::div[6]")
|
||||
return fields_locators
|
||||
|
||||
def get_locator(self, locator: str | Locator) -> Locator:
|
||||
|
|
|
|||
|
|
@ -57,10 +57,13 @@ class RackObjectMaker(BaseComponent):
|
|||
|
||||
logger.debug("Rack data filled successfully")
|
||||
|
||||
def _fill_text_fields(self, rack_data: RackData) -> None:
|
||||
"""Заполняет текстовые поля."""
|
||||
def _get_form_fields(self) -> dict:
|
||||
"""
|
||||
Получает все поля формы стойки.
|
||||
|
||||
logger.debug("Filling text fields...")
|
||||
Returns:
|
||||
dict: Словарь {название поля: Locator контейнера поля}
|
||||
"""
|
||||
|
||||
# Получаем контейнер формы (второй элемент)
|
||||
container_locator = self.page.locator(RackLocators.FORM_INPUT_CONTAINER).nth(1)
|
||||
|
|
@ -69,8 +72,15 @@ class RackObjectMaker(BaseComponent):
|
|||
logger.error("Form container not found")
|
||||
raise ValueError("Form container not found")
|
||||
|
||||
# Используем метод из базового класса для получения всех полей
|
||||
fields_locators = self.get_input_fields_locators_(container_locator, "layout")
|
||||
return self.get_input_fields_locators(container_locator)
|
||||
|
||||
def _fill_text_fields(self, rack_data: RackData) -> None:
|
||||
"""Заполняет текстовые поля."""
|
||||
|
||||
logger.debug("Filling text fields...")
|
||||
|
||||
# Получаем все поля формы
|
||||
fields_locators = self._get_form_fields()
|
||||
|
||||
logger.debug(f"Available text fields: {list(fields_locators.keys())}")
|
||||
|
||||
|
|
@ -81,7 +91,7 @@ class RackObjectMaker(BaseComponent):
|
|||
logger.debug(f"Skipping empty value for field '{field_name}'")
|
||||
return
|
||||
|
||||
# Получаем xs8 контейнер поля
|
||||
# Получаем контейнер поля
|
||||
field_container = fields_locators.get(field_name)
|
||||
|
||||
if not field_container:
|
||||
|
|
@ -137,51 +147,49 @@ class RackObjectMaker(BaseComponent):
|
|||
def _fill_combobox_fields(self, rack_data: RackData) -> None:
|
||||
"""Заполняет combobox поля."""
|
||||
|
||||
# Получаем все поля формы
|
||||
fields_locators = self._get_form_fields()
|
||||
|
||||
# Обязательные поля.
|
||||
if rack_data.height:
|
||||
self._fill_combobox_field("Высота в юнитах", rack_data.height)
|
||||
self._fill_combobox_field("Высота в юнитах", rack_data.height, fields_locators)
|
||||
logger.debug(f"Selected height: {rack_data.height} units")
|
||||
|
||||
if rack_data.depth:
|
||||
self._fill_combobox_field("Глубина (мм)", rack_data.depth)
|
||||
self._fill_combobox_field("Глубина (мм)", rack_data.depth, fields_locators)
|
||||
logger.debug(f"Selected depth: {rack_data.depth} mm")
|
||||
|
||||
# Опциональные поля.
|
||||
if rack_data.cable_entry:
|
||||
self._fill_combobox_field("Ввод кабеля", rack_data.cable_entry)
|
||||
self._fill_combobox_field("Ввод кабеля", rack_data.cable_entry, fields_locators)
|
||||
logger.debug(f"Selected cable entry: {rack_data.cable_entry}")
|
||||
|
||||
if rack_data.state:
|
||||
self._fill_combobox_field("Состояние", rack_data.state)
|
||||
self._fill_combobox_field("Состояние", rack_data.state, fields_locators)
|
||||
logger.debug(f"Selected state: {rack_data.state}")
|
||||
|
||||
if rack_data.owner:
|
||||
self._fill_combobox_field("Владелец", rack_data.owner)
|
||||
self._fill_combobox_field("Владелец", rack_data.owner, fields_locators)
|
||||
logger.debug(f"Selected owner: {rack_data.owner}")
|
||||
|
||||
if rack_data.service_org:
|
||||
self._fill_combobox_field("Обслуживающая организация", rack_data.service_org)
|
||||
self._fill_combobox_field("Обслуживающая организация", rack_data.service_org, fields_locators)
|
||||
logger.debug(f"Selected service organization: {rack_data.service_org}")
|
||||
|
||||
if rack_data.project:
|
||||
self._fill_combobox_field("Проект/Титул", rack_data.project)
|
||||
self._fill_combobox_field("Проект/Титул", rack_data.project, fields_locators)
|
||||
logger.debug(f"Selected project/title: {rack_data.project}")
|
||||
|
||||
def _fill_combobox_field(self, field_name: str, value: str) -> None:
|
||||
def _fill_combobox_field(self, field_name: str, value: str, fields_locators: dict) -> None:
|
||||
"""
|
||||
Заполняет combobox поле.
|
||||
|
||||
Args:
|
||||
field_name: Название поля
|
||||
value: Значение для установки
|
||||
fields_locators: Словарь с найденными полями формы
|
||||
"""
|
||||
|
||||
# Получаем контейнер формы (второй элемент)
|
||||
container_locator = self.page.locator(RackLocators.FORM_INPUT_CONTAINER).nth(1)
|
||||
|
||||
# Используем метод из базового класса BaseComponent
|
||||
fields_locators = self.get_input_fields_locators_(container_locator, "layout")
|
||||
|
||||
# Получаем контейнер поля по его названию
|
||||
field_container = fields_locators.get(field_name)
|
||||
|
||||
|
|
@ -270,14 +278,8 @@ class RackObjectMaker(BaseComponent):
|
|||
|
||||
logger.debug("Checking rack fields presence...")
|
||||
|
||||
# Получаем контейнер формы (второй элемент)
|
||||
container_locator = self.page.locator(RackLocators.FORM_INPUT_CONTAINER).nth(1)
|
||||
|
||||
# Проверяем наличие контейнера
|
||||
assert container_locator.count() > 0, "Form container not found"
|
||||
|
||||
# Используем метод из базового класса BaseComponent для получения всех полей
|
||||
fields_locators = self.get_input_fields_locators_(container_locator, "layout")
|
||||
# Получаем все поля формы
|
||||
fields_locators = self._get_form_fields()
|
||||
|
||||
logger.debug(f"Found fields in form: {list(fields_locators.keys())}")
|
||||
|
||||
|
|
|
|||
|
|
@ -61,15 +61,13 @@ class CreateChildElementFrame(BaseComponent):
|
|||
|
||||
# Получаем контейнер формы
|
||||
container_locator = self.page.locator(RackLocators.FORM_INPUT_CONTAINER).nth(1)
|
||||
|
||||
# Используем метод get_input_fields_locators для получения всех полей
|
||||
fields_locators = self.get_input_fields_locators_(container_locator, "layout")
|
||||
fields_locators = self.get_input_fields_locators(container_locator)
|
||||
|
||||
if field_name not in fields_locators:
|
||||
logger.warning(f"Field '{field_name}' not found in form")
|
||||
return
|
||||
|
||||
# Получаем xs8 контейнер поля
|
||||
# Получаем контейнер поля
|
||||
field_container = fields_locators[field_name]
|
||||
|
||||
# Прокручиваем до поля
|
||||
|
|
@ -121,9 +119,7 @@ class CreateChildElementFrame(BaseComponent):
|
|||
"""Открывает выпадающий список combobox."""
|
||||
|
||||
container_locator = self.page.locator(RackLocators.FORM_INPUT_CONTAINER)
|
||||
|
||||
# Используем метод из базового класса BaseComponent
|
||||
fields_locators = self.get_input_fields_locators_(container_locator, "layout")
|
||||
fields_locators = self.get_input_fields_locators(container_locator)
|
||||
combobox_container = fields_locators.get("Класс объекта учета")
|
||||
|
||||
if not combobox_container:
|
||||
|
|
@ -149,7 +145,7 @@ class CreateChildElementFrame(BaseComponent):
|
|||
# Открываем combobox
|
||||
self.open_object_class_combobox()
|
||||
|
||||
# Выбираем значение из списка
|
||||
# Выбирает значение из списка
|
||||
self.selection_bar.select_value(class_name)
|
||||
|
||||
# Даем время на применение выбора
|
||||
|
|
@ -171,7 +167,7 @@ class CreateChildElementFrame(BaseComponent):
|
|||
|
||||
# Получаем контейнеры всех полей
|
||||
container_locator = self.page.locator(RackLocators.FORM_INPUT_CONTAINER)
|
||||
fields_locators = self.get_input_fields_locators_(container_locator, "layout")
|
||||
fields_locators = self.get_input_fields_locators(container_locator)
|
||||
|
||||
# Получаем контейнер конкретного поля
|
||||
field_container = fields_locators.get(field_name)
|
||||
|
|
@ -204,7 +200,7 @@ class CreateChildElementFrame(BaseComponent):
|
|||
|
||||
# Получаем контейнеры всех полей
|
||||
container_locator = self.page.locator(RackLocators.FORM_INPUT_CONTAINER)
|
||||
fields_locators = self.get_input_fields_locators_(container_locator, "layout")
|
||||
fields_locators = self.get_input_fields_locators(container_locator)
|
||||
|
||||
# Получаем контейнер конкретного поля
|
||||
field_container = fields_locators.get(field_name)
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@ class SettingsFormLocators:
|
|||
SETTTINGS_FORM_TITLE = f"{SETTTINGS_FORM_SCROLL_CONTAINER}//div[contains(@class, 'v-toolbar__title')]"
|
||||
|
||||
SETTINGS_FORM_INPUT_FORM_CONTAINER = "//nav[contains(@class, 'active v-toolbar')]/following-sibling::div"
|
||||
SETTINGS_FORM_INPUT_FIELD = "div:nth-child(2) div.v-text-field__slot > input"
|
||||
SETTINGS_FORM_INPUT_VALUE_SUFFIX = "div:nth-child(2) div.v-text-field__slot div.v-text-field__suffix"
|
||||
|
||||
SETTINGS_FORM_INPUT_FIELD = "div.v-text-field__slot > input"
|
||||
SETTINGS_FORM_INPUT_VALUE_SUFFIX = ".v-text-field__suffix"
|
||||
|
||||
DROPDOWN_LIST = "//div[contains(@class, 'menuable__content__active')]"
|
||||
SELECTED_VALUES = "//div[@class='v-select__selections']"
|
||||
|
|
|
|||
|
|
@ -36,9 +36,8 @@ class PushNotificationsSettingsTab(BasePage):
|
|||
self.settings_form = SettingsFormComponent(page)
|
||||
self.settings_form.add_toolbar_title("Общие")
|
||||
|
||||
css_class = "xs6"
|
||||
container_locator = self.page.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FORM_CONTAINER)
|
||||
self.input_fields_locators = self.settings_form.get_input_fields_locators(container_locator, css_class)
|
||||
self.input_fields_locators = self.settings_form.get_input_fields_locators(container_locator)
|
||||
|
||||
loc = self.input_fields_locators.get("Сообщение")
|
||||
loc_message_input = loc.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FIELD).first
|
||||
|
|
|
|||
|
|
@ -44,32 +44,32 @@ class SessionSettingsTab(BasePage):
|
|||
|
||||
self.settings_form.add_toolbar_title("Время жизни сеанса")
|
||||
|
||||
css_class = "xs4"
|
||||
container_locator = self.page.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FORM_CONTAINER)
|
||||
self.input_fields_locators = self.settings_form.get_input_fields_locators(container_locator, css_class)
|
||||
self.input_fields_locators = self.settings_form.get_input_fields_locators(container_locator)
|
||||
|
||||
# Используем локаторы для числовых полей
|
||||
loc = self.input_fields_locators.get("Администратор")
|
||||
loc_admin = loc.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FIELD)
|
||||
loc_admin = loc.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FIELD).first
|
||||
admin_setting = TextInput(page, loc_admin, "admin_setting")
|
||||
self.settings_form.add_content_item("admin_setting", admin_setting)
|
||||
|
||||
loc = self.input_fields_locators.get("Оператор")
|
||||
loc_oper = loc.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FIELD)
|
||||
loc_oper = loc.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FIELD).first
|
||||
operator_setting = TextInput(page, loc_oper, "operator_setting")
|
||||
self.settings_form.add_content_item("operator_setting", operator_setting)
|
||||
|
||||
loc = self.input_fields_locators.get("Контактное лицо")
|
||||
loc_manager = loc.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FIELD)
|
||||
loc_manager = loc.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FIELD).first
|
||||
manager_setting = TextInput(page, loc_manager, "manager_setting")
|
||||
self.settings_form.add_content_item("manager_setting", manager_setting)
|
||||
|
||||
loc = self.input_fields_locators.get("Специалист информационной безопасности")
|
||||
loc_inform_secur_user = loc.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FIELD)
|
||||
loc_inform_secur_user = loc.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FIELD).first
|
||||
inform_secur_user_setting = TextInput(page, loc_inform_secur_user, "inform_secur_user_setting")
|
||||
self.settings_form.add_content_item("inform_secur_user_setting", inform_secur_user_setting)
|
||||
|
||||
loc = self.input_fields_locators.get('$collector')
|
||||
loc_collector = loc.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FIELD)
|
||||
loc_collector = loc.locator(SettingsFormLocators.SETTINGS_FORM_INPUT_FIELD).first
|
||||
collector_setting = TextInput(page, loc_collector, "collector_setting")
|
||||
self.settings_form.add_content_item("collector_setting", collector_setting)
|
||||
|
||||
|
|
@ -220,8 +220,8 @@ class SessionSettingsTab(BasePage):
|
|||
)
|
||||
|
||||
for name in actual_input_field_names:
|
||||
value_suffix_loc = self.input_fields_locators.get(name).\
|
||||
locator(SettingsFormLocators.SETTINGS_FORM_INPUT_VALUE_SUFFIX)
|
||||
# Для суффикса "минут"
|
||||
value_suffix_loc = self.input_fields_locators.get(name).locator(SettingsFormLocators.SETTINGS_FORM_INPUT_VALUE_SUFFIX)
|
||||
value_suffix = value_suffix_loc.text_content().strip()
|
||||
assert value_suffix == "минут", f"Incorrect value suffix for field {name}"
|
||||
|
||||
|
|
|
|||
|
|
@ -213,9 +213,7 @@ class TestCreateRackElement:
|
|||
|
||||
# Получаем контейнер формы
|
||||
container_locator = create_child_frame.page.locator(RackLocators.FORM_INPUT_CONTAINER).nth(1)
|
||||
|
||||
# Используем метод get_input_fields_locators для получения всех полей
|
||||
fields_locators = create_child_frame.get_input_fields_locators_(container_locator, "layout")
|
||||
fields_locators = create_child_frame.get_input_fields_locators(container_locator)
|
||||
|
||||
logger.debug(f"Available fields: {list(fields_locators.keys())}")
|
||||
|
||||
|
|
@ -227,7 +225,7 @@ class TestCreateRackElement:
|
|||
logger.debug(f"Field '{field_name}' not found in fields_locators")
|
||||
return False
|
||||
|
||||
# Получаем xs8 контейнер поля
|
||||
# Получаем контейнер поля
|
||||
field_container = fields_locators[field_name]
|
||||
|
||||
if not field_container.is_visible():
|
||||
|
|
@ -409,9 +407,7 @@ class TestCreateRackElement:
|
|||
|
||||
# Получаем контейнер формы
|
||||
container_locator = create_child_frame.page.locator(RackLocators.FORM_INPUT_CONTAINER).nth(1)
|
||||
|
||||
# Используем метод get_input_fields_locators для получения всех полей
|
||||
fields_locators = create_child_frame.get_input_fields_locators_(container_locator, "layout")
|
||||
fields_locators = create_child_frame.get_input_fields_locators(container_locator)
|
||||
|
||||
# Очищаем поле "Высота в юнитах" если оно заполнено
|
||||
if "Высота в юнитах" in fields_locators:
|
||||
|
|
|
|||
Loading…
Reference in New Issue