Изменено в соответствии с code-review

radislav/element_rack
Radislav 2025-12-16 13:56:20 +03:00
parent e87b428f09
commit 00cf1ce14f
3 changed files with 103 additions and 84 deletions

View File

@ -27,6 +27,7 @@ class ToolbarComponent(BaseComponent):
def __init__(self, page: Page, title: str) -> None: def __init__(self, page: Page, title: str) -> None:
"""Инициализирует компонент тулбара с указанным заголовком.""" """Инициализирует компонент тулбара с указанным заголовком."""
super().__init__(page) super().__init__(page)
self.title = title self.title = title
self.buttons = [] self.buttons = []
@ -38,6 +39,7 @@ class ToolbarComponent(BaseComponent):
Args: Args:
title (str): Новый заголовок title (str): Новый заголовок
""" """
self.title = title self.title = title
def add_tooltip_button(self, locator: Locator, name: str) -> None: def add_tooltip_button(self, locator: Locator, name: str) -> None:
@ -47,6 +49,7 @@ class ToolbarComponent(BaseComponent):
locator (Locator): Локатор кнопки locator (Locator): Локатор кнопки
name (str): Уникальное имя кнопки name (str): Уникальное имя кнопки
""" """
self.buttons.append(TooltipButton(self.page, locator, name)) self.buttons.append(TooltipButton(self.page, locator, name))
def add_tab_button(self, locator: Locator, name: str) -> None: def add_tab_button(self, locator: Locator, name: str) -> None:
@ -56,6 +59,7 @@ class ToolbarComponent(BaseComponent):
locator (Locator): Локатор кнопки locator (Locator): Локатор кнопки
name (str): Уникальное имя кнопки name (str): Уникальное имя кнопки
""" """
self.buttons.append(TabButton(self.page, locator, name)) self.buttons.append(TabButton(self.page, locator, name))
def add_button(self, locator: Locator, name: str) -> None: def add_button(self, locator: Locator, name: str) -> None:
@ -65,6 +69,7 @@ class ToolbarComponent(BaseComponent):
locator (Locator): Локатор кнопки locator (Locator): Локатор кнопки
name (str): Уникальное имя кнопки name (str): Уникальное имя кнопки
""" """
self.buttons.append(Button(self.page, locator, name)) self.buttons.append(Button(self.page, locator, name))
def get_button_by_name(self, name: str def get_button_by_name(self, name: str
@ -77,6 +82,7 @@ class ToolbarComponent(BaseComponent):
Returns: Returns:
TooltipButton | TabButton | Button | None: Найденная кнопка или None TooltipButton | TabButton | Button | None: Найденная кнопка или None
""" """
for button in self.buttons: for button in self.buttons:
if button.name == name: if button.name == name:
return button return button
@ -91,6 +97,7 @@ class ToolbarComponent(BaseComponent):
Raises: Raises:
AssertionError: Если кнопка не найдена AssertionError: Если кнопка не найдена
""" """
button = self.get_button_by_name(name) button = self.get_button_by_name(name)
if button is None: if button is None:
raise AssertionError(f"Unsupported button name {name}") raise AssertionError(f"Unsupported button name {name}")
@ -112,6 +119,7 @@ class ToolbarComponent(BaseComponent):
Raises: Raises:
Exception: Если не удалось получить заголовок Exception: Если не удалось получить заголовок
""" """
# Получаем локатор заголовка # Получаем локатор заголовка
title_locator = self.get_locator(locator) title_locator = self.get_locator(locator)
@ -134,7 +142,6 @@ class ToolbarComponent(BaseComponent):
Args: Args:
locator: Локатор для заголовка тулбара locator: Локатор для заголовка тулбара
separator: Разделитель подзаголовков, по умолчанию галочка вправо (chevron_right)
timeout: Таймаут ожидания в миллисекундах timeout: Таймаут ожидания в миллисекундах
Returns: Returns:
@ -176,6 +183,7 @@ class ToolbarComponent(BaseComponent):
Raises: Raises:
AssertionError: Если имя кнопки не поддерживается AssertionError: Если имя кнопки не поддерживается
""" """
button = self.get_button_by_name(name) button = self.get_button_by_name(name)
if button is None: if button is None:
raise AssertionError(f"Unsupported button name {name}") raise AssertionError(f"Unsupported button name {name}")
@ -193,6 +201,7 @@ class ToolbarComponent(BaseComponent):
Raises: Raises:
AssertionError: Если имя кнопки не поддерживается AssertionError: Если имя кнопки не поддерживается
""" """
button = self.get_button_by_name(name) button = self.get_button_by_name(name)
if button is None: if button is None:
raise AssertionError(f"Unsupported button name {name}") raise AssertionError(f"Unsupported button name {name}")
@ -204,6 +213,7 @@ class ToolbarComponent(BaseComponent):
Args: Args:
message (str): Сообщение об ошибке если тулбар не виден message (str): Сообщение об ошибке если тулбар не виден
""" """
locator = self.get_locator(ToolbarLocators.TITLE).filter( locator = self.get_locator(ToolbarLocators.TITLE).filter(
has_text=self.title has_text=self.title
) )
@ -217,6 +227,7 @@ class ToolbarComponent(BaseComponent):
locator: Локатор тулбара locator: Локатор тулбара
message (str): Сообщение об ошибке если тулбар не виден message (str): Сообщение об ошибке если тулбар не виден
""" """
locator = self.get_locator(locator) locator = self.get_locator(locator)
expect(locator).to_be_visible(), message expect(locator).to_be_visible(), message
@ -228,6 +239,7 @@ class ToolbarComponent(BaseComponent):
locator: Локатор тулбара locator: Локатор тулбара
message (str): Сообщение об ошибке если тулбар не виден message (str): Сообщение об ошибке если тулбар не виден
""" """
locator = self.get_locator(locator).filter(has_text=self.title) locator = self.get_locator(locator).filter(has_text=self.title)
expect(locator).to_be_visible(), message expect(locator).to_be_visible(), message
@ -240,6 +252,7 @@ class ToolbarComponent(BaseComponent):
Raises: Raises:
AssertionError: Если кнопка не найдена или не видна AssertionError: Если кнопка не найдена или не видна
""" """
button = self.get_button_by_name(name) button = self.get_button_by_name(name)
if button is None: if button is None:
@ -258,6 +271,7 @@ class ToolbarComponent(BaseComponent):
Raises: Raises:
AssertionError: Если текст подсказки не совпадает AssertionError: Если текст подсказки не совпадает
""" """
button = self.get_button_by_name(name) button = self.get_button_by_name(name)
if button is None: if button is None:
raise AssertionError(f"Unsupported button name {name}") raise AssertionError(f"Unsupported button name {name}")

View File

@ -6,6 +6,7 @@
""" """
from playwright.sync_api import Page, expect from playwright.sync_api import Page, expect
from typing import Optional
from tools.logger import get_logger from tools.logger import get_logger
from locators.rack_locators import RackLocators from locators.rack_locators import RackLocators
from elements.tooltip_button_element import TooltipButton from elements.tooltip_button_element import TooltipButton
@ -15,6 +16,8 @@ from pages.base_page import BasePage
logger = get_logger("RACK_PAGE") logger = get_logger("RACK_PAGE")
logger.setLevel("INFO")
# Специфичные локаторы оставленые в основном коде # Специфичные локаторы оставленые в основном коде
PANEL_HEADER = "//span[text()='Объекты']/following-sibling::i" PANEL_HEADER = "//span[text()='Объекты']/following-sibling::i"
TOOLBAR_CONTENT = "//div[@class='v-toolbar__content']" TOOLBAR_CONTENT = "//div[@class='v-toolbar__content']"
@ -53,26 +56,6 @@ class RackPage(BasePage):
# Действия # Действия
def check_physical_devices_presence(self) -> None:
"""Проверяет наличие физических устройств на стойке."""
# Поиск устройств по классу parent-class
devices = self.page.locator(RackLocators.DEVICE_ELEMENTS)
device_count = devices.count()
if device_count > 0:
# Выводим информацию только о первом устройстве
first_device = devices.first
device_id = first_device.get_attribute("id") or "No id"
device_title = first_device.get_attribute("title") or "No title"
logger.info(
f"Devices found: {device_count} "
f"(first: ID={device_id}, Title={device_title})"
)
else:
logger.info("No devices detected")
def get_available_tabs(self) -> list[str]: def get_available_tabs(self) -> list[str]:
""" """
Возвращает список доступных вкладок. Возвращает список доступных вкладок.
@ -90,7 +73,7 @@ class RackPage(BasePage):
tab_elements.first.wait_for(state="visible", timeout=5000) tab_elements.first.wait_for(state="visible", timeout=5000)
total_count = tab_elements.count() total_count = tab_elements.count()
logger.info(f"Total top tab elements found: {total_count}") logger.debug(f"Total top tab elements found: {total_count}")
for i in range(total_count): for i in range(total_count):
element = tab_elements.nth(i) element = tab_elements.nth(i)
@ -102,15 +85,17 @@ class RackPage(BasePage):
tab_text = tab_text.strip() tab_text = tab_text.strip()
if tab_text and tab_text not in tabs: if tab_text and tab_text not in tabs:
tabs.append(tab_text) tabs.append(tab_text)
logger.info(f"Top tab found: '{tab_text}'") logger.debug(f"Top tab found: '{tab_text}'")
logger.info(f"Available top tabs found: {tabs}") logger.debug(f"Available top tabs found: {tabs}")
return tabs return tabs
def get_current_active_side(self) -> str: def get_current_active_side(self) -> Optional[str]:
""" """
Возвращает текущую активную сторону стойки. Возвращает текущую активную сторону стойки.
Проверяет конкретные кнопки стойки напрямую.
Returns:
Optional[str]: "Лицевая сторона", "Обратная сторона" или None если ни одна не активна
""" """
# Проверяем конкретно кнопку "Лицевая сторона" # Проверяем конкретно кнопку "Лицевая сторона"
@ -127,7 +112,7 @@ class RackPage(BasePage):
if "primary--text" in classes.split(): if "primary--text" in classes.split():
return "Обратная сторона" return "Обратная сторона"
return "" return None
def get_toolbar_title(self) -> list[str]: def get_toolbar_title(self) -> list[str]:
""" """
@ -180,7 +165,7 @@ class RackPage(BasePage):
AssertionError: Если вкладка не найдена или недоступна AssertionError: Если вкладка не найдена или недоступна
""" """
logger.info(f"Switching to tab '{tab_name}'...") logger.debug(f"Switching to tab '{tab_name}'...")
tab = self.page.locator(RackLocators.TAB_BY_NAME.format(tab_name)) tab = self.page.locator(RackLocators.TAB_BY_NAME.format(tab_name))
@ -188,7 +173,7 @@ class RackPage(BasePage):
# Проверяем активность ДО клика # Проверяем активность ДО клика
if self.is_tab_active(tab_name): if self.is_tab_active(tab_name):
logger.info(f"Tab '{tab_name}' is already active") logger.debug(f"Tab '{tab_name}' is already active")
return return
# Находим первую видимую вкладку с нужным именем # Находим первую видимую вкладку с нужным именем
@ -202,7 +187,7 @@ class RackPage(BasePage):
assert target_tab is not None, f"No visible/available tab '{tab_name}' found" assert target_tab is not None, f"No visible/available tab '{tab_name}' found"
# Кликаем на вкладку # Кликаем на вкладку
logger.info(f"Clicking on tab '{tab_name}'...") logger.debug(f"Clicking on tab '{tab_name}'...")
target_tab.click() target_tab.click()
# Ждем изменения активной вкладки # Ждем изменения активной вкладки
@ -214,7 +199,7 @@ class RackPage(BasePage):
def wait_for_rack_loading(self) -> None: def wait_for_rack_loading(self) -> None:
"""Ожидает загрузки интерфейса стойки.""" """Ожидает загрузки интерфейса стойки."""
logger.info("Waiting for rack interface to load...") logger.debug("Waiting for rack interface to load...")
# Проверяем наличие кнопок переключения сторон # Проверяем наличие кнопок переключения сторон
front_button = self.page.locator(RackLocators.FRONT_SIDE_BUTTON) front_button = self.page.locator(RackLocators.FRONT_SIDE_BUTTON)
@ -222,12 +207,12 @@ class RackPage(BasePage):
expect(front_button).to_be_visible(timeout=5000) expect(front_button).to_be_visible(timeout=5000)
expect(back_button).to_be_visible(timeout=5000) expect(back_button).to_be_visible(timeout=5000)
logger.info("Side toggle buttons loaded") logger.debug("Side toggle buttons loaded")
# Проверяем, что есть активная кнопка # Проверяем, что есть активная кнопка
active_button = self.page.locator(RackLocators.ACTIVE_SIDE_BUTTON) active_button = self.page.locator(RackLocators.ACTIVE_SIDE_BUTTON)
if active_button.count() > 0: if active_button.count() > 0:
logger.info("Active side button found") logger.debug("Active side button found")
else: else:
logger.warning("No active side button found") logger.warning("No active side button found")
@ -236,32 +221,52 @@ class RackPage(BasePage):
if main_container.count() == 0: if main_container.count() == 0:
logger.warning("Main rack container not found") logger.warning("Main rack container not found")
else: else:
logger.info(f"Main rack container found (count: {main_container.count()})") logger.debug(f"Main rack container found (count: {main_container.count()})")
expect(main_container.first).to_be_attached() expect(main_container.first).to_be_attached()
# Проверяем наличие позиций юнитов # Проверяем наличие позиций юнитов
unit_positions = self.page.locator(RackLocators.UNIT_POSITIONS) unit_positions = self.page.locator(RackLocators.UNIT_POSITIONS)
if unit_positions.count() > 0: if unit_positions.count() > 0:
logger.info(f"Unit positions found: {unit_positions.count()}") logger.debug(f"Unit positions found: {unit_positions.count()}")
if unit_positions.first.text_content(): if unit_positions.first.text_content():
content = unit_positions.first.text_content().strip() content = unit_positions.first.text_content().strip()
logger.info(f"First position: {content}") logger.debug(f"First position: {content}")
# Проверяем наличие кнопок добавления # Проверяем наличие кнопок добавления
open_buttons = self.page.locator(RackLocators.ADD_CIRCLE_BUTTON) open_buttons = self.page.locator(RackLocators.ADD_CIRCLE_BUTTON)
if open_buttons.count() > 0: if open_buttons.count() > 0:
logger.info(f"'add_circle' buttons found: {open_buttons.count()}") logger.debug(f"'add_circle' buttons found: {open_buttons.count()}")
logger.info("Rack interface loaded") logger.debug("Rack interface loaded")
# Проверки # Проверки
def check_physical_devices_presence(self) -> None:
"""Проверяет наличие физических устройств на стойке."""
# Поиск устройств по классу parent-class
devices = self.page.locator(RackLocators.DEVICE_ELEMENTS)
device_count = devices.count()
if device_count > 0:
# Выводим информацию только о первом устройстве
first_device = devices.first
device_id = first_device.get_attribute("id") or "No id"
device_title = first_device.get_attribute("title") or "No title"
logger.debug(
f"Devices found: {device_count} "
f"(first: ID={device_id}, Title={device_title})"
)
else:
logger.debug("No devices detected")
def check_tab_switching(self) -> None: def check_tab_switching(self) -> None:
""" """
Проверяет переключение между вкладками стойки. Проверяет переключение между вкладками стойки.
""" """
logger.info("Testing rack tab switching functionality...") logger.debug("Testing rack tab switching functionality...")
# Вкладки в правильном порядке # Вкладки в правильном порядке
defined_tabs = [ defined_tabs = [
@ -272,14 +277,14 @@ class RackPage(BasePage):
"Сервисы" "Сервисы"
] ]
logger.info(f"Defined tabs to test: {defined_tabs}") logger.debug(f"Defined tabs to test: {defined_tabs}")
successful_switches = 0 successful_switches = 0
failed_switches = [] failed_switches = []
# Тестируем переключение на каждую определенную вкладку # Тестируем переключение на каждую определенную вкладку
for tab_name in defined_tabs: for tab_name in defined_tabs:
logger.info(f"Testing switch to tab '{tab_name}'...") logger.debug(f"Testing switch to tab '{tab_name}'...")
try: try:
# Переключаемся на вкладку # Переключаемся на вкладку
@ -287,7 +292,7 @@ class RackPage(BasePage):
# Проверяем, что вкладка активна # Проверяем, что вкладка активна
if self.is_tab_active(tab_name): if self.is_tab_active(tab_name):
logger.info(f"Successfully switched to tab '{tab_name}'") logger.debug(f"Successfully switched to tab '{tab_name}'")
successful_switches += 1 successful_switches += 1
else: else:
logger.warning(f"Tab '{tab_name}' not active after switching") logger.warning(f"Tab '{tab_name}' not active after switching")
@ -301,13 +306,13 @@ class RackPage(BasePage):
self.wait_for_timeout(1000) self.wait_for_timeout(1000)
# Формируем итоговый отчет # Формируем итоговый отчет
logger.info("=== TAB SWITCHING RESULTS ===") logger.debug("=== TAB SWITCHING RESULTS ===")
logger.info(f"Successful switches: {successful_switches}/{len(defined_tabs)}") logger.debug(f"Successful switches: {successful_switches}/{len(defined_tabs)}")
if failed_switches: if failed_switches:
logger.info("Failed switches:") logger.debug("Failed switches:")
for failure in failed_switches: for failure in failed_switches:
logger.info(f" - {failure}") logger.debug(f" - {failure}")
# Требуем успешного переключения на все определенные вкладки # Требуем успешного переключения на все определенные вкладки
assert successful_switches == len(defined_tabs), ( assert successful_switches == len(defined_tabs), (
@ -317,7 +322,7 @@ class RackPage(BasePage):
f"Errors: {', '.join(failed_switches)}" f"Errors: {', '.join(failed_switches)}"
) )
logger.info(f"All {successful_switches} defined tabs successfully switched!") logger.debug(f"All {successful_switches} defined tabs successfully switched!")
def is_tab_active(self, tab_name: str) -> bool: def is_tab_active(self, tab_name: str) -> bool:
""" """
@ -336,13 +341,13 @@ class RackPage(BasePage):
if active_tab.count() > 0 and active_tab.first.is_visible(): if active_tab.count() > 0 and active_tab.first.is_visible():
active_text = active_tab.first.text_content() active_text = active_tab.first.text_content()
if active_text and active_text.strip() == tab_name: if active_text and active_text.strip() == tab_name:
logger.info(f"Tab '{tab_name}' is active (via active tab class)") logger.debug(f"Tab '{tab_name}' is active (via active tab class)")
return True return True
logger.info(f"Tab '{tab_name}' is not active") logger.debug(f"Tab '{tab_name}' is not active")
return False return False
def should_be_header_panel(self, expected_toolbar_title_items: list[str]) -> None: def should_be_panel_header(self, expected_toolbar_title_items: list[str]) -> None:
""" """
Проверяет наличие и корректность заголовка панели. Проверяет наличие и корректность заголовка панели.
@ -372,7 +377,7 @@ class RackPage(BasePage):
def should_be_rack_sides_displayed(self) -> None: def should_be_rack_sides_displayed(self) -> None:
"""Проверка отображения и структуры сторон стойки.""" """Проверка отображения и структуры сторон стойки."""
logger.info("Checking rack sides display and structure...") logger.debug("Checking rack sides display and structure...")
# Ожидаем загрузки # Ожидаем загрузки
self.wait_for_rack_loading() self.wait_for_rack_loading()
@ -388,11 +393,11 @@ class RackPage(BasePage):
expect(back_side_button).to_be_visible(timeout=5000), \ expect(back_side_button).to_be_visible(timeout=5000), \
"Back side button not found" "Back side button not found"
logger.info("Side toggle buttons found") logger.debug("Side toggle buttons found")
# Проверяем, какая сторона активна по умолчанию # Проверяем, какая сторона активна по умолчанию
current_active = self.get_current_active_side() current_active = self.get_current_active_side()
logger.info(f"Current active side: {current_active}") logger.debug(f"Current active side: {current_active}")
# Дополнительная проверка устройств # Дополнительная проверка устройств
self.check_physical_devices_presence() self.check_physical_devices_presence()
@ -405,7 +410,7 @@ class RackPage(BasePage):
# Возвращаемся на исходную активную сторону # Возвращаемся на исходную активную сторону
if current_active: if current_active:
logger.info(f"Returning to original active side: {current_active}") logger.debug(f"Returning to original active side: {current_active}")
if current_active == "Лицевая сторона": if current_active == "Лицевая сторона":
front_side_button.click() front_side_button.click()
else: else:
@ -413,9 +418,9 @@ class RackPage(BasePage):
self.wait_for_timeout(1000) self.wait_for_timeout(1000)
final_active = self.get_current_active_side() final_active = self.get_current_active_side()
logger.info(f"Final active side: {final_active}") logger.debug(f"Final active side: {final_active}")
logger.info("All rack sides checks passed successfully") logger.debug("All rack sides checks passed successfully")
def should_be_toolbar_buttons(self) -> None: def should_be_toolbar_buttons(self) -> None:
""" """
@ -425,7 +430,7 @@ class RackPage(BasePage):
AssertionError: Если кнопки недоступны или подсказки неверны. AssertionError: Если кнопки недоступны или подсказки неверны.
""" """
logger.info("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", "Изменить")
@ -436,7 +441,7 @@ class RackPage(BasePage):
Проверка кнопки "Скрыть стойку". Проверка кнопки "Скрыть стойку".
Проверяет видимость, тултип, кликабельность и эффект скрытия стойки. Проверяет видимость, тултип, кликабельность и эффект скрытия стойки.
""" """
logger.info("Checking 'Hide rack' button...") logger.debug("Checking 'Hide rack' button...")
# Проверяем видимость кнопки # Проверяем видимость кнопки
self.toolbar.check_button_visibility("hide_rack") self.toolbar.check_button_visibility("hide_rack")
@ -450,20 +455,20 @@ class RackPage(BasePage):
# Кликаем на кнопку "Скрыть стойку" # Кликаем на кнопку "Скрыть стойку"
self.toolbar.get_button_by_name("hide_rack").click() self.toolbar.get_button_by_name("hide_rack").click()
self.wait_for_timeout(2000) # Даем время для применения стилей self.wait_for_timeout(2000)
# Проверяем, что общий контейнер стойки теперь скрыт (имеет display: none) # Проверяем, что общий контейнер стойки теперь скрыт (имеет display: none)
expect(rack_container).to_have_css("display", "none", timeout=5000) expect(rack_container).to_have_css("display", "none", timeout=5000)
logger.info("Rack container successfully hidden (display: none)") logger.debug("Rack container successfully hidden (display: none)")
logger.info("'Hide rack' button test completed successfully") logger.debug("'Hide rack' button test completed successfully")
def should_have_show_rack_button(self) -> None: def should_have_show_rack_button(self) -> None:
""" """
Проверка кнопки "Показать стойку". Проверка кнопки "Показать стойку".
Проверяет наличие, тултип, кликабельность и эффект показа стойки. Проверяет наличие, тултип, кликабельность и эффект показа стойки.
""" """
logger.info("Checking 'Show rack' button...") logger.debug("Checking 'Show rack' button...")
# Проверяем видимость кнопки # Проверяем видимость кнопки
self.toolbar.check_button_visibility("show_rack") self.toolbar.check_button_visibility("show_rack")
@ -481,9 +486,9 @@ class RackPage(BasePage):
# Проверяем, что общий контейнер стойки теперь видим (display не равен "none") # Проверяем, что общий контейнер стойки теперь видим (display не равен "none")
expect(rack_container).not_to_have_css("display", "none", timeout=5000) expect(rack_container).not_to_have_css("display", "none", timeout=5000)
logger.info("Rack container successfully shown (display is not 'none')") logger.debug("Rack container successfully shown (display is not 'none')")
logger.info("'Show rack' button test completed successfully") logger.debug("'Show rack' button test completed successfully")
# Вспомогательные методы # Вспомогательные методы
@ -499,49 +504,49 @@ class RackPage(BasePage):
AssertionError: Если структура стороны некорректна AssertionError: Если структура стороны некорректна
""" """
logger.info(f"Checking {side_name}...") logger.debug(f"Checking {side_name}...")
# Логируем текущее состояние кнопки перед кликом # Логируем текущее состояние кнопки перед кликом
button_classes = side_button.get_attribute("class") or "" button_classes = side_button.get_attribute("class") or ""
logger.info(f"Button classes before click: {button_classes}") logger.debug(f"Button classes before click: {button_classes}")
# Проверяем, активна ли уже эта сторона # Проверяем, активна ли уже эта сторона
current_active = self.get_current_active_side() current_active = self.get_current_active_side()
logger.info(f"Current active side (before click): '{current_active}'") logger.debug(f"Current active side (before click): '{current_active}'")
if current_active == side_name: if current_active == side_name:
logger.info(f"{side_name} is already active") logger.debug(f"{side_name} is already active")
else: else:
# Если не активна, кликаем для переключения # Если не активна, кликаем для переключения
logger.info(f"Switching to {side_name}...") logger.debug(f"Switching to {side_name}...")
side_button.click() side_button.click()
# Даем время на перерисовку классов (увеличиваем время) # Даем время на перерисовку классов (увеличиваем время)
self.wait_for_timeout(2500) self.wait_for_timeout(2500)
# Проверяем классы после клика # Проверяем классы после клика
button_classes_after = side_button.get_attribute("class") or "" button_classes_after = side_button.get_attribute("class") or ""
logger.info(f"Button classes after click: {button_classes_after}") logger.debug(f"Button classes after click: {button_classes_after}")
# Проверяем, что нужная сторона стала активной # Проверяем, что нужная сторона стала активной
active_side = self.get_current_active_side() active_side = self.get_current_active_side()
logger.info(f"Active side after switching: '{active_side}'") logger.debug(f"Active side after switching: '{active_side}'")
assert active_side == side_name, \ assert active_side == side_name, \
f"Wrong side is active: '{active_side}', expected: '{side_name}'" f"Wrong side is active: '{active_side}', expected: '{side_name}'"
logger.info(f"{side_name} successfully activated") logger.debug(f"{side_name} successfully activated")
# Проверяем позиции юнитов # Проверяем позиции юнитов
unit_positions = self.page.locator(RackLocators.UNIT_POSITIONS) unit_positions = self.page.locator(RackLocators.UNIT_POSITIONS)
total_positions = unit_positions.count() total_positions = unit_positions.count()
logger.info(f"Total unit positions: {total_positions}") logger.debug(f"Total unit positions: {total_positions}")
assert total_positions > 0, f"No unit positions found on {side_name}" assert total_positions > 0, f"No unit positions found on {side_name}"
# Проверяем юниты # Проверяем юниты
all_units = self.page.locator(RackLocators.ALL_UNITS) all_units = self.page.locator(RackLocators.ALL_UNITS)
all_units_count = all_units.count() all_units_count = all_units.count()
units_per_side = all_units_count // 2 units_per_side = all_units_count // 2
logger.info(f"Units on {side_name}: {units_per_side}") logger.debug(f"Units on {side_name}: {units_per_side}")
# Проверяем устройства # Проверяем устройства
devices = self.page.locator(RackLocators.DEVICE_ELEMENTS) devices = self.page.locator(RackLocators.DEVICE_ELEMENTS)
@ -558,15 +563,15 @@ class RackPage(BasePage):
slots = first_device.locator(RackLocators.DEVICE_SLOTS) slots = first_device.locator(RackLocators.DEVICE_SLOTS)
slot_count = slots.count() slot_count = slots.count()
logger.info(f"Devices found: {device_count} (showing first)") logger.debug(f"Devices found: {device_count} (showing first)")
logger.info(f" Device: ID={device_id}") logger.debug(f" Device: ID={device_id}")
logger.info(f" Title: {device_title}") logger.debug(f" Title: {device_title}")
logger.info(f" Classes: {device_classes}") logger.debug(f" Classes: {device_classes}")
logger.info(f" Slots: {slot_count}") logger.debug(f" Slots: {slot_count}")
else: else:
logger.info("No devices detected") logger.debug("No devices detected")
logger.info(f"{side_name} check completed successfully") logger.debug(f"{side_name} check completed successfully")
def _wait_for_tab_activation(self, tab_name: str, timeout: int = 5000) -> None: def _wait_for_tab_activation(self, tab_name: str, timeout: int = 5000) -> None:
""" """
@ -580,12 +585,12 @@ class RackPage(BasePage):
AssertionError: Если вкладка не активирована в течение таймаута AssertionError: Если вкладка не активирована в течение таймаута
""" """
logger.info(f"Waiting for tab '{tab_name}' activation...") logger.debug(f"Waiting for tab '{tab_name}' activation...")
start_time = self.page.evaluate("Date.now()") start_time = self.page.evaluate("Date.now()")
while self.page.evaluate("Date.now()") - start_time < timeout: while self.page.evaluate("Date.now()") - start_time < timeout:
if self.is_tab_active(tab_name): if self.is_tab_active(tab_name):
logger.info(f"Tab '{tab_name}' successfully activated") logger.debug(f"Tab '{tab_name}' successfully activated")
return return
self.wait_for_timeout(100) self.wait_for_timeout(100)

View File

@ -78,7 +78,7 @@ class TestRackTab:
] ]
rt = RackPage(browser) rt = RackPage(browser)
rt.should_be_header_panel(expected_toolbar_subtitles) rt.should_be_panel_header(expected_toolbar_subtitles)
# Комплексная проверка отображения обеих сторон стойки с детальной информацией # Комплексная проверка отображения обеих сторон стойки с детальной информацией
rt.should_be_rack_sides_displayed() rt.should_be_rack_sides_displayed()