Разработка ттеста Стойка

ra2/create_element_rack
Radislav 2026-01-16 08:21:29 +03:00
parent 5f21e197f6
commit 8140769583
6 changed files with 400 additions and 65 deletions

View File

@ -114,6 +114,60 @@ class CreateChildElementFrame(BaseComponent):
""" """
return self.selection_bar.get_selection_bar_title() return self.selection_bar.get_selection_bar_title()
def is_field_filled(self, field_name: str, container_locator: Locator = None) -> bool:
"""
Проверяет, заполнено ли combobox или текстовое поле.
Args:
field_name: Название поля для проверки
container_locator: Локатор контейнера формы (опционально)
Returns:
bool: True если поле заполнено, False в противном случае
"""
logger.debug(f"Checking if field '{field_name}' is filled...")
# Если контейнер не передан, используем контейнер по умолчанию
if container_locator is None:
container_locator = self.page.locator(RackLocators.FORM_INPUT_CONTAINER).nth(1)
# Получаем словарь всех полей формы
fields_locators = self.get_input_fields_locators(container_locator)
if field_name not in fields_locators:
logger.debug(f"Field '{field_name}' not found in fields_locators")
return False
# Получаем контейнер поля
field_container = fields_locators[field_name]
if not field_container.is_visible():
logger.debug(f"Field '{field_name}' not visible")
return False
# Проверяем наличие выбранного значения через v-chip (чип выбранного значения в combobox)
selected_chip = field_container.locator(".v-chip").first
# Проверяем наличие текста в поле
field_text = field_container.text_content() or ""
has_text = bool(field_text.strip())
# Проверяем наличие чипа
has_chip = selected_chip.count() > 0 and selected_chip.is_visible()
# Для текстовых полей проверяем значение input
if not has_chip:
input_field = field_container.locator("input").first
if input_field.count() > 0:
input_value = input_field.input_value() or ""
has_input_value = bool(input_value.strip())
logger.debug(f"Field '{field_name}' - has input value: {has_input_value}")
has_text = has_text or has_input_value
logger.debug(f"Field '{field_name}' - has chip: {has_chip}, has text: {has_text}")
return has_chip or has_text
def open_object_class_combobox(self) -> None: def open_object_class_combobox(self) -> None:
"""Открывает выпадающий список combobox.""" """Открывает выпадающий список combobox."""

View File

@ -20,8 +20,8 @@ class Environment:
DEVELOP: str = 'develop' DEVELOP: str = 'develop'
URLS: Dict[str, str] = { URLS: Dict[str, str] = {
TEST: 'http://192.168.2.76/', TEST: 'https://192.168.2.76/',
DEVELOP: 'http://192.168.2.69/' DEVELOP: 'https://192.168.2.69/'
} }
def __init__(self) -> None: def __init__(self) -> None:

View File

@ -164,6 +164,7 @@ def get_context(browser: Browser, request: FixtureRequest, start: str) -> Browse
context = browser.new_context( context = browser.new_context(
# no_viewport=True, # no_viewport=True,
ignore_https_errors=True,
viewport= ast.literal_eval(request.config.getoption('--s')), viewport= ast.literal_eval(request.config.getoption('--s')),
locale=request.config.getoption('l') locale=request.config.getoption('l')
) )

View File

@ -113,3 +113,16 @@ class RackLocators:
# Кнопка "Показать стойку" # Кнопка "Показать стойку"
SHOW_RACK_BUTTON = ("//div[@data-testid='CABINET_SHOW__div__hideCabinet' and " SHOW_RACK_BUTTON = ("//div[@data-testid='CABINET_SHOW__div__hideCabinet' and "
"contains(@class, 'cabinet_hide_button_trigger_hide')]") "contains(@class, 'cabinet_hide_button_trigger_hide')]")
# Кнопки тулбара стойки
TOOLBAR_REPLACE_BUTTON = "[data-testid='cabinet-bar__toolbar__btn__replace']"
TOOLBAR_DONE_BUTTON = "[data-testid='cabinet-bar__toolbar__btn__done']"
TOOLBAR_CLOSE_BUTTON = "[data-testid='cabinet-bar__toolbar__btn__close']"
TOOLBAR_REMOVE_BUTTON = "[data-testid='cabinet-bar__toolbar__btn__remove']"
# Диалог удаления
REMOVE_DIALOG = "[data-testid='cabinet-bar__toolbar__dialog-remove']"
# Кнопки подтверждения удаления
CONFIRM_REMOVE_YES_BUTTON = "[data-testid='cabinet-bar__card_confirmation__btn__yes']"
CONFIRM_REMOVE_NO_BUTTON = "[data-testid='cabinet-bar__card_confirmation__btn__no']"

View File

@ -15,7 +15,7 @@ from pages.base_page import BasePage
logger = get_logger("RACK_PAGE") logger = get_logger("RACK_PAGE")
logger.setLevel("INFO") #logger.setLevel("INFO")
# Специфичные локаторы оставленые в основном коде # Специфичные локаторы оставленые в основном коде
PANEL_HEADER = "//span[text()='Объекты']/following-sibling::i" PANEL_HEADER = "//span[text()='Объекты']/following-sibling::i"
@ -48,13 +48,65 @@ class RackPage(BasePage):
show_button_locator = self.page.locator(RackLocators.SHOW_RACK_BUTTON) show_button_locator = self.page.locator(RackLocators.SHOW_RACK_BUTTON)
self.show_button = TooltipButton(page, show_button_locator, "show_rack") self.show_button = TooltipButton(page, show_button_locator, "show_rack")
# Кнопка "Переместить"
replace_button_locator = self.page.locator(RackLocators.TOOLBAR_REPLACE_BUTTON)
self.replace_button = TooltipButton(page, replace_button_locator, "replace")
# Кнопка "Сохранить"
done_button_locator = self.page.locator(RackLocators.TOOLBAR_DONE_BUTTON)
self.done_button = TooltipButton(page, done_button_locator, "done")
# Кнопка "Отменить"
close_button_locator = self.page.locator(RackLocators.TOOLBAR_CLOSE_BUTTON)
self.close_button = TooltipButton(page, close_button_locator, "close")
# Кнопка "Удалить"
remove_button_locator = self.page.locator(RackLocators.TOOLBAR_REMOVE_BUTTON)
self.remove_button = TooltipButton(page, remove_button_locator, "remove")
self.toolbar = ToolbarComponent(page, "") self.toolbar = ToolbarComponent(page, "")
self.toolbar.add_tooltip_button(locator_button, "edit") self.toolbar.add_tooltip_button(locator_button, "edit")
self.toolbar.add_tooltip_button(hide_button_locator, "hide_rack") self.toolbar.add_tooltip_button(hide_button_locator, "hide_rack")
self.toolbar.add_tooltip_button(show_button_locator, "show_rack") self.toolbar.add_tooltip_button(show_button_locator, "show_rack")
self.toolbar.add_tooltip_button(replace_button_locator, "replace")
self.toolbar.add_tooltip_button(done_button_locator, "done")
self.toolbar.add_tooltip_button(close_button_locator, "close")
self.toolbar.add_tooltip_button(remove_button_locator, "remove")
# Действия # Действия
def click_remove_button(self) -> None:
"""
Кликает на кнопку 'Удалить' и обрабатывает диалог подтверждения.
"""
logger.debug("Clicking on 'Remove' button...")
# Проверяем видимость кнопки
self.toolbar.check_button_visibility("remove")
# Проверяем тултип кнопки (может быть "Удалить" или "Remove")
try:
self.toolbar.check_button_tooltip("remove", "Удалить")
except:
try:
self.toolbar.check_button_tooltip("remove", "Remove")
except:
logger.debug("Could not verify tooltip text for remove button")
# Кликаем на кнопку удаления
self.toolbar.get_button_by_name("remove").click()
self.wait_for_timeout(1000)
# Ожидаем появления диалога подтверждения
self._handle_remove_confirmation_dialog()
def _handle_remove_confirmation_dialog(self) -> None:
"""
Обрабатывает диалог подтверждения удаления.
"""
logger.debug("Handling remove confirmation dialog...")
self.confirm_remove_dialog(confirm=True)
def get_available_tabs(self) -> list[str]: def get_available_tabs(self) -> list[str]:
""" """
Возвращает список доступных вкладок. Возвращает список доступных вкладок.
@ -431,10 +483,27 @@ class RackPage(BasePage):
logger.debug("Checking toolbar buttons...") logger.debug("Checking toolbar buttons...")
# Проверяем основные кнопки
self.toolbar.check_button_visibility("edit") self.toolbar.check_button_visibility("edit")
self.toolbar.check_button_tooltip("edit", "Изменить") self.toolbar.check_button_tooltip("edit", "Изменить")
# Кликаем на кнопку "Изменить" для проверки функциональности
self.toolbar.get_button_by_name("edit").click() self.toolbar.get_button_by_name("edit").click()
# Проверяем новые кнопки тулбара
self.toolbar.check_button_visibility("replace")
self.toolbar.check_button_tooltip("replace", "Переместить")
self.toolbar.check_button_visibility("done")
self.toolbar.check_button_tooltip("done", "Сохранить")
self.toolbar.check_button_visibility("close")
self.toolbar.check_button_tooltip("close", "Отменить")
self.toolbar.check_button_visibility("remove")
self.toolbar.check_button_tooltip("remove", "Удалить")
def should_have_hide_rack_button(self) -> None: def should_have_hide_rack_button(self) -> None:
""" """
Проверка кнопки "Скрыть стойку". Проверка кнопки "Скрыть стойку".
@ -594,3 +663,45 @@ class RackPage(BasePage):
self.wait_for_timeout(100) self.wait_for_timeout(100)
assert False, f"Tab '{tab_name}' not activated within {timeout}ms" assert False, f"Tab '{tab_name}' not activated within {timeout}ms"
def confirm_remove_dialog(self, confirm: bool = True) -> None:
"""
Подтверждает или отклоняет удаление в диалоговом окне.
"""
logger.debug(f"Confirming remove dialog with: {'Да' if confirm else 'Нет'}")
# Ждем немного перед поиском диалога
self.wait_for_timeout(1500)
# Ищем активный диалог
dialog = self.page.locator("div.v-dialog--active")
# Проверяем, что диалог найден и содержит нужный текст
assert dialog.count() > 0, "No active dialog found"
# Проверяем текст диалога
dialog_text = dialog.first.text_content()
logger.debug(f"Dialog text: {dialog_text}")
# Должен содержать "Запрос подтверждения" и "Удалить"
assert "Запрос подтверждения" in dialog_text, "Not a confirmation dialog"
# Ищем кнопку по data-testid
if confirm:
button = self.page.locator(RackLocators.CONFIRM_REMOVE_YES_BUTTON)
else:
button = self.page.locator(RackLocators.CONFIRM_REMOVE_NO_BUTTON)
# Проверяем, что кнопка найдена
assert button.count() > 0, f"Button not found with selector"
# Кликаем на кнопку
logger.debug(f"Clicking button with text: {button.first.text_content()}")
button.first.click()
self.wait_for_timeout(2000)
# Проверяем, что диалог закрылся
self.wait_for_timeout(1000)
logger.debug("Remove confirmation completed")

View File

@ -10,11 +10,12 @@ from components_derived.frames.create_child_element_frame import CreateChildElem
from pages.location_page import LocationPage from pages.location_page import LocationPage
from pages.login_page import LoginPage from pages.login_page import LoginPage
from pages.main_page import MainPage from pages.main_page import MainPage
from pages.rack_page import RackPage
logger = get_logger("CREATE_RACK_ELEMENT_TEST") logger = get_logger("CREATE_RACK_ELEMENT_TEST")
logger.setLevel("INFO") #logger.setLevel("INFO")
# @pytest.mark.smoke # @pytest.mark.smoke
class TestCreateRackElement: class TestCreateRackElement:
@ -25,6 +26,7 @@ class TestCreateRackElement:
2. test_create_rack_child_element: Проверяет создание дочернего элемента типа 'Стойка' 2. test_create_rack_child_element: Проверяет создание дочернего элемента типа 'Стойка'
3. test_create_rack_with_duplicate_name: Проверяет создание стойки с дублирующимся именем 3. test_create_rack_with_duplicate_name: Проверяет создание стойки с дублирующимся именем
4. test_required_fields_validation: Проверяет валидацию обязательных полей при создании стойки 4. test_required_fields_validation: Проверяет валидацию обязательных полей при создании стойки
5. test_delete_created_rack: Тест удаления созданной стойки
""" """
# Инициализируем атрибуты # Инициализируем атрибуты
@ -89,7 +91,7 @@ class TestCreateRackElement:
create_child_frame.should_be_toolbar_buttons() create_child_frame.should_be_toolbar_buttons()
#@pytest.mark.develop @pytest.mark.develop
def test_create_rack_child_element(self, browser: Page) -> None: def test_create_rack_child_element(self, browser: Page) -> None:
"""Тест создания дочернего элемента типа 'Стойка'.""" """Тест создания дочернего элемента типа 'Стойка'."""
@ -120,6 +122,9 @@ class TestCreateRackElement:
cable_entry="сверху" cable_entry="сверху"
) )
# Сохраняем имя стойки в переменную
rack_name = rack_data.name
# Заполняем данные стойки # Заполняем данные стойки
rack_maker.fill_rack_data(rack_data) rack_maker.fill_rack_data(rack_data)
@ -127,6 +132,50 @@ class TestCreateRackElement:
create_child_frame.click_add_button() create_child_frame.click_add_button()
create_child_frame.wait_for_timeout(2000) create_child_frame.wait_for_timeout(2000)
# 1. Проверяем уведомление об успешном создании стойки - требуется создать разработчику (заведена задача)
# Проверяем наличие alert-окна
# create_child_frame.alert.check_alert_presence("")
# Получаем текст alert
# alert_text = create_child_frame.alert.get_text()
# logger.debug(f"Alert text after creation: {alert_text}")
# Проверяем, что в тексте есть указание на успешное создание
# assert "создан" in alert_text.lower() or "успешно" in alert_text.lower()
# assert final_rack_name in alert_text
# Закрываем alert
# create_child_frame.alert.close_alert()
# 2. Проверяем, что стойка создана и отображается
logger.debug(f"Verifying that rack '{rack_name}' was created...")
# Обновляем навигационную панель
self.main_page.click_main_navigation_panel_item("test-zone")
self.main_page.wait_for_timeout(2000)
# Проверяем существование стойки в навигационной панели
rack_exists = self._check_rack_existance(browser, rack_name)
assert rack_exists, f"Rack '{rack_name}' should be visible in navigation panel after creation"
logger.debug(f"Rack '{rack_name}' is visible in navigation panel")
# 3. Очистка: Удаление созданной стойки
logger.debug(f"Cleaning up: deleting test rack '{rack_name}'...")
# Переходим на страницу стойки для удаления
self.main_page.click_subpanel_item(rack_name, parent="test-zone")
self.main_page.wait_for_timeout(1000)
# Удаляем стойку
self._delete_rack_from_context_menu(browser, rack_name)
# Проверяем, что стойка удалена
self.main_page.wait_for_timeout(2000)
rack_still_exists = self._check_rack_existance(browser, rack_name)
assert not rack_still_exists, f"Rack '{rack_name}' should be deleted"
logger.debug(f"Test rack '{rack_name}' successfully cleaned up")
logger.debug("Test for creating 'Rack' child element completed successfully") logger.debug("Test for creating 'Rack' child element completed successfully")
#@pytest.mark.develop #@pytest.mark.develop
@ -213,42 +262,12 @@ class TestCreateRackElement:
# Получаем контейнер формы # Получаем контейнер формы
container_locator = create_child_frame.page.locator(RackLocators.FORM_INPUT_CONTAINER).nth(1) container_locator = create_child_frame.page.locator(RackLocators.FORM_INPUT_CONTAINER).nth(1)
fields_locators = create_child_frame.get_input_fields_locators(container_locator)
logger.debug(f"Available fields: {list(fields_locators.keys())}") logger.debug(f"Available fields: {list(create_child_frame.get_input_fields_locators(container_locator).keys())}")
# Функция для проверки заполненности combobox поля
def is_field_filled(field_name: str) -> bool:
"""Проверяет, заполнено ли combobox поле."""
if field_name not in fields_locators:
logger.debug(f"Field '{field_name}' not found in fields_locators")
return False
# Получаем контейнер поля
field_container = fields_locators[field_name]
if not field_container.is_visible():
logger.debug(f"Field '{field_name}' not visible")
return False
# Проверяем наличие выбранного значения через v-chip (чип выбранного значения в combobox)
selected_chip = field_container.locator(".v-chip").first
# Проверяем наличие текста в поле
field_text = field_container.text_content() or ""
has_text = bool(field_text.strip())
# Проверяем наличие чипа
has_chip = selected_chip.count() > 0 and selected_chip.is_visible()
logger.debug(f"Field '{field_name}' - has chip: {has_chip}, has text: {has_text}")
return has_chip or has_text
# Проверяем и очищаем поле "Глубина (мм)" только если оно заполнено # Проверяем и очищаем поле "Глубина (мм)" только если оно заполнено
logger.debug("Checking field: Глубина (мм)") logger.debug("Checking field: Глубина (мм)")
if is_field_filled("Глубина (мм)"): if create_child_frame.is_field_filled("Глубина (мм)", container_locator):
logger.debug("Field 'Глубина (мм)' is filled, performing clearing") logger.debug("Field 'Глубина (мм)' is filled, performing clearing")
create_child_frame.clear_combobox_field("Глубина (мм)") create_child_frame.clear_combobox_field("Глубина (мм)")
logger.debug("Clearing completed for 'Глубина (мм)'") logger.debug("Clearing completed for 'Глубина (мм)'")
@ -257,7 +276,7 @@ class TestCreateRackElement:
# Проверяем и очищаем поле "Высота в юнитах" только если оно заполнено # Проверяем и очищаем поле "Высота в юнитах" только если оно заполнено
logger.debug("Checking field: Высота в юнитах") logger.debug("Checking field: Высота в юнитах")
if is_field_filled("Высота в юнитах"): if create_child_frame.is_field_filled("Высота в юнитах", container_locator):
logger.debug("Field 'Высота в юнитах' is filled, performing clearing") logger.debug("Field 'Высота в юнитах' is filled, performing clearing")
create_child_frame.clear_combobox_field("Высота в юнитах") create_child_frame.clear_combobox_field("Высота в юнитах")
logger.debug("Clearing completed for 'Высота в юнитах'") logger.debug("Clearing completed for 'Высота в юнитах'")
@ -315,7 +334,7 @@ class TestCreateRackElement:
create_child_frame.check_toolbar_title('Создать дочерний элемент в') create_child_frame.check_toolbar_title('Создать дочерний элемент в')
logger.debug("Test completed successfully") logger.debug("Test completed successfully")
@pytest.mark.develop #@pytest.mark.develop
def test_required_fields_validation(self, browser: Page) -> None: def test_required_fields_validation(self, browser: Page) -> None:
""" """
Тест проверки обязательных полей при создании стойки. Тест проверки обязательных полей при создании стойки.
@ -411,33 +430,26 @@ class TestCreateRackElement:
# Очищаем поле "Высота в юнитах" если оно заполнено # Очищаем поле "Высота в юнитах" если оно заполнено
if "Высота в юнитах" in fields_locators: if "Высота в юнитах" in fields_locators:
field_container = fields_locators["Высота в юнитах"] if create_child_frame.is_field_filled("Высота в юнитах", container_locator):
# Проверяем наличие текста в поле
field_text = field_container.inner_text() or ""
if field_text.strip():
logger.debug("Clearing 'Высота в юнитах' field...") logger.debug("Clearing 'Высота в юнитах' field...")
create_child_frame.clear_combobox_field("Высота в юнитах") create_child_frame.clear_combobox_field("Высота в юнитах")
create_child_frame.wait_for_timeout(500) create_child_frame.wait_for_timeout(500)
# Очищаем поле "Глубина (мм)" если оно заполнено # Очищаем поле "Глубина (мм)" если оно заполнено
if "Глубина (мм)" in fields_locators: if "Глубина (мм)" in fields_locators:
field_container = fields_locators["Глубина (мм)"] if create_child_frame.is_field_filled("Глубина (мм)", container_locator):
# Проверяем наличие текста в поле
field_text = field_container.inner_text() or ""
if field_text.strip():
logger.debug("Clearing 'Глубина (мм)' field...") logger.debug("Clearing 'Глубина (мм)' field...")
create_child_frame.clear_combobox_field("Глубина (мм)") create_child_frame.clear_combobox_field("Глубина (мм)")
create_child_frame.wait_for_timeout(500) create_child_frame.wait_for_timeout(500)
# Очищаем поле "Имя" если оно заполнено # Очищаем поле "Имя" если оно заполнено
if "Имя" in fields_locators: if "Имя" in fields_locators:
if create_child_frame.is_field_filled("Имя", container_locator):
logger.debug("Clearing 'Имя' field...")
# Специальная обработка для текстового поля
field_container = fields_locators["Имя"] field_container = fields_locators["Имя"]
# Находим input внутри контейнера
input_field = field_container.locator("input").first input_field = field_container.locator("input").first
if input_field.count() > 0: if input_field.count() > 0:
current_value = input_field.input_value()
if current_value.strip():
logger.debug("Clearing 'Имя' field...")
input_field.click() input_field.click()
input_field.press("Control+A") input_field.press("Control+A")
input_field.press("Backspace") input_field.press("Backspace")
@ -463,20 +475,163 @@ class TestCreateRackElement:
create_child_frame.click_add_button() create_child_frame.click_add_button()
create_child_frame.wait_for_timeout(1000) create_child_frame.wait_for_timeout(1000)
# Проверяем, что НЕТ alert-окон для всех обязательных полей # Проверяем уведомление об успешном создании стойки - требуется создать разработчику (заведена задача)
#create_child_frame.alert.check_alert_absence(expected_alert_text_height, 1000) # Проверяем наличие alert-окна
#create_child_frame.alert.check_alert_absence(expected_alert_text_depth, 1000) # create_child_frame.alert.check_alert_presence("")
#logger.debug("No alert windows for required fields appeared - all fields filled correctly")
# Проверяем, что ушли со страницы создания # Получаем текст alert
try: # alert_text = create_child_frame.alert.get_text()
create_child_frame.check_toolbar_title('Создать дочерний элемент в') # logger.debug(f"Alert text after creation: {alert_text}")
logger.warning("Rack creation may not have completed successfully")
except AssertionError: # Проверяем что в тексте есть указание на успешное создание
logger.debug("Creation page closed - rack successfully created") # assert "создан" in alert_text.lower() or "успешно" in alert_text.lower()
# assert final_rack_name in alert_text
# Закрываем alert
# create_child_frame.alert.close_alert()
# Удаляем стойку
self._delete_rack_from_context_menu(browser, final_rack_name)
# Проверяем, что стойка удалена
self.main_page.wait_for_timeout(2000)
rack_still_exists = self._check_rack_existance(browser, final_rack_name)
assert not rack_still_exists, f"Rack '{final_rack_name}' should be deleted"
logger.debug(f"Test rack '{final_rack_name}' successfully cleaned up")
logger.debug("Required fields validation test completed successfully") logger.debug("Required fields validation test completed successfully")
#@pytest.mark.develop
def test_delete_created_rack(self, browser: Page) -> None:
"""
Тест удаления созданной стойки.
Сценарий:
1. Создаем стойку с уникальным именем
2. Проверяем её существование
3. Переходим к стойке и удаляем её
4. Проверяем, что стойка больше не существует
"""
logger.debug("Starting test for deleting created rack")
# Генерируем уникальное имя для стойки
rack_name = f"Test-Rack-Delete"
logger.debug(f"Test rack name: {rack_name}")
# 1. Создаем стойку
logger.debug("Step 1: Creating rack...")
self._create_rack(browser, rack_name)
logger.debug(f"Rack '{rack_name}' created successfully")
# 2. Проверяем существование стойки
logger.debug("Step 2: Verifying rack existence...")
# Используем существующий метод _check_rack_existance
rack_exists = self._check_rack_existance(browser, rack_name)
assert rack_exists, f"Rack '{rack_name}' not found after creation"
logger.debug(f"Rack '{rack_name}' exists - verified with _check_rack_existance method")
# Кликаем на стойку для перехода
self.main_page.click_subpanel_item(rack_name, parent="test-zone")
self.main_page.wait_for_timeout(2000)
# 3. Проверяем, что мы на странице стойки
logger.debug("Step 3: Checking we're on rack page...")
expected_toolbar_subtitles = [
"test-zone",
'chevron_right',
rack_name
]
rack_page = RackPage(browser)
rack_page.should_be_panel_header(expected_toolbar_subtitles)
# 4. Открываем контекстное меню и удаляем стойку
logger.debug("Step 4: Deleting rack...")
self._delete_rack_from_context_menu(browser, rack_name)
# 5. Проверяем, что стойка удалена с использованием существующего метода
logger.debug("Step 5: Verifying rack deletion...")
self.main_page.wait_for_timeout(2000)
# Переходим обратно в test-zone для проверки
self.main_page.click_subpanel_item("test-zone")
self.main_page.wait_for_timeout(3000)
# Используем существующий метод для проверки отсутствия стойки
rack_still_exists = self._check_rack_existance(browser, rack_name)
assert not rack_still_exists, f"Rack '{rack_name}' still exists after deletion"
logger.debug(f"Rack '{rack_name}' successfully deleted - verified with _check_rack_existance method")
logger.debug("Rack deletion test completed successfully")
def _delete_rack_from_context_menu(self, browser: Page, rack_name: str) -> None:
"""
Удаляет стойку через контекстное меню.
Args:
browser: Страница Playwright
rack_name: Имя стойки для удаления
"""
logger.debug(f"Deleting rack '{rack_name}' from context menu...")
# 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. Проверяем и нажимаем кнопку "Изменить"
logger.debug("Step 1: Clicking 'Edit' button...")
rack_page = RackPage(browser)
# Проверяем видимость кнопки
rack_page.toolbar.check_button_visibility("edit")
# Проверяем тултип кнопки
rack_page.toolbar.check_button_tooltip("edit", "Изменить")
# Кликаем на кнопку "Изменить"
rack_page.toolbar.get_button_by_name("edit").click()
self.main_page.wait_for_timeout(1000)
logger.debug("Edit button clicked, waiting for edit form...")
# 3. Используем метод click_remove_button, который обрабатывает весь процесс удаления
# включая диалог подтверждения
logger.debug("Clicking remove button...")
rack_page.click_remove_button()
# Ждем завершения процесса удаления
self.main_page.wait_for_timeout(10000)
# 4. Проверяем уведомление об успешном удалении - требуется создать разработчику (заведена задача)
# Создаем экземпляр фрейма для доступа к alert компоненту
# create_child_frame = CreateChildElementFrame(browser)
# Проверяем наличие любого alert-окна (не обязательно точного текста)
# create_child_frame.alert.check_alert_presence("")
# Получаем текст alert, чтобы убедиться что удаление прошло успешно
# alert_text = create_child_frame.alert.get_text()
# logger.debug(f"Alert text after deletion: {alert_text}")
# Проверяем что в тексте есть указание на успешное удаление
# assert "удален" in alert_text.lower() or "успешно" in alert_text.lower()
# Закрываем alert
# create_child_frame.alert.close_alert()
logger.debug("Rack deletion completed")
def _check_rack_existance(self, browser: Page, rack_name: str) -> bool: def _check_rack_existance(self, browser: Page, rack_name: str) -> bool:
"""Проверяет существование стойки.""" """Проверяет существование стойки."""
@ -492,7 +647,7 @@ class TestCreateRackElement:
nav_panel_locator = NavigationPanelLocators.TREEVIEW nav_panel_locator = NavigationPanelLocators.TREEVIEW
# Проверяем видимость элемента # Проверяем видимость элемента
element = browser.locator(nav_panel_locator).get_by_text(rack_name).first element = browser.locator(nav_panel_locator).get_by_text(rack_name, exact=True).first
if element.is_visible(): if element.is_visible():
logger.debug(f"Rack with name '{rack_name}' found") logger.debug(f"Rack with name '{rack_name}' found")
@ -508,6 +663,7 @@ class TestCreateRackElement:
# Переходим обратно к созданию новой стойки # Переходим обратно к созданию новой стойки
self.main_page.click_main_navigation_panel_item("test-zone") self.main_page.click_main_navigation_panel_item("test-zone")
self.main_page.click_main_navigation_panel_item("test-zone")
self.main_page.wait_for_timeout(2000) self.main_page.wait_for_timeout(2000)
# Нажимаем кнопку "Создать" на тулбаре # Нажимаем кнопку "Создать" на тулбаре