Добавлены компоненты и тесты для панели отображения событий системного журнала

pull/1/head
nsubbot 2025-09-24 13:30:39 +03:00
parent 3cdc495fef
commit e505534a1e
9 changed files with 623 additions and 20 deletions

View File

@ -6,6 +6,7 @@ from locators.event_panel_locators import EventPanelLocators
from elements.tooltip_button_element import TooltipButton
from elements.tab_button_element import TabButton
from elements.button_element import Button
from components_derived.container_system_log_events import SystemLogEventsContainer
from components_derived.user_card import UserCard
from components.base_component import BaseComponent
@ -39,8 +40,6 @@ class EventPanelComponent(BaseComponent):
self.search_button = Button(page, buttons_service_locators[0], "search_button")
self.user_button = Button(page, buttons_service_locators[1], "user_button")
self.user_card = UserCard(page)
# Действия:
def click_expand_less_button(self) -> None:
"""Выполняет нажатие кнопки галочка вверх."""
@ -56,12 +55,23 @@ class EventPanelComponent(BaseComponent):
get_by_role("button").filter(has_text='expand_more')
button_locator.click()
def click_system_log_tab(self) -> SystemLogEventsContainer:
"""Выполняет нажатие tab-кнопки Системный журнал."""
self.system_log_tab.check_visibility("System log tab button is missing on event panel")
self.system_log_tab.click()
system_log_events = SystemLogEventsContainer(self.page, EventPanelLocators.CONTAINER_SYSTEM_LOG_EVENTS)
return system_log_events
def click_user_button(self) -> UserCard:
"""Выполняет нажатие кнопки пользователя."""
self.should_be_user_button()
self.user_button.click()
return self.user_card
user_card = UserCard(self.page)
return user_card
def do_logout(self) -> None:
"""Выполняет выход из системы."""
@ -129,11 +139,6 @@ class EventPanelComponent(BaseComponent):
return False
return True
def check_user_card_content(self):
"""Проверяет наличие и корректность элементов карточки пользователя."""
self.user_card.check_content()
def should_be_user_button(self) -> None:
"""Проверяет наличие кнопки пользователя."""

View File

@ -0,0 +1,272 @@
"""Модуль компонента контейнера с перечнем событий. Содержит класс для работы с контейнерами,
их элементами и проверками."""
from playwright.sync_api import Page, Locator
from tools.logger import get_logger
from locators.toolbar_locators import ToolbarLocators
# from locators.table_locators import TableLocators
from elements.tooltip_button_element import TooltipButton
from elements.tab_button_element import TabButton
from elements.button_element import Button
from components.toolbar_component import ToolbarComponent
from components.table_component import TableComponent
from components.base_component import BaseComponent
logger = get_logger("EVENTS_CONTANER")
class EventsContainerComponent(BaseComponent):
"""Компонент контейнера с перечнем событий. Предоставляет методы для взаимодействия с контейнером,
его содержимым и проверок."""
def __init__(self, page: Page, locator: str | Locator):
"""Инициализирует базовый контейнер.
Args:
page: Экземпляр страницы Playwright
locator: Локатор контейнера (строка или объект Locator)
"""
super().__init__(page)
self.container_locator = self.get_locator(locator)
# тулбар
self.toolbar = ToolbarComponent(page, "")
filter_button_locator = self.container_locator.locator(ToolbarLocators.TITLE).\
get_by_role("button")
self.toolbar.add_button(filter_button_locator, "filter_button")
export_buttons = self.container_locator.locator(ToolbarLocators.ITEMS).\
get_by_role("button").all()
self.toolbar.add_tooltip_button(export_buttons[1], "export_to_csv_button")
self.toolbar.add_tooltip_button(export_buttons[0], "export_to_pdf_button")
# Таблица событий
self.events_table = TableComponent(page)
self.table_locator = "//div[@class='scrolltable']/div/table"
# Кнопки пагинации в нижней части контейнера
self.chevron_left = Button(page,
self.container_locator.get_by_role("button").filter(has_text='chevron_left'),
"chevron_left")
self.chevron_right = Button(page,
self.container_locator.get_by_role("button").filter(has_text='chevron_right'),
"chevron_right")
loc = self.container_locator.get_by_role("button").filter(has_text='chevron_left').\
locator("xpath=..").get_by_role("button").nth(1)
self.data_set_number = Button(page, loc, "data_set_number")
# Действия:
def add_tab_to_toolbar(self, locator: str | Locator, name: str) -> None:
"""Добавление кнопки типа v-tabs к тулбару"""
tabs_locator = self.get_locator(locator)
self.toolbar.add_tab_button(self.container_locator.locator(tabs_locator), name)
def click_chevron_left(self) -> None:
"""Нажатие кнопки получения предыдущего набора данных"""
self.chevron_left.click()
def click_chevron_right(self) -> None:
"""Нажатие кнопки получения следующего набора данных"""
self.chevron_right.click()
def click_event_table_header_arrow(self, index) -> None:
""" Нажатие кнопки-стрелочки вверх/вниз в ячейке заголовка таблицы
Args:
index: Индекс ячейки в заголовке.
"""
loc = self.container_locator.locator(self.table_locator)
self.events_table.click_arrow_button(loc, index)
def get_current_data_set_number(self) -> int:
"""Получение номера текущего набора данных"""
try:
data_set_number = int(self.data_set_number.get_text(0))
except ValueError as e:
assert False, f"Value Error: {e}"
return data_set_number
def get_arrow_button_state(self, index: int) -> str:
""" Получение состояния кнопки-стрелочки вверх/вниз в ячейке заголовка таблицы
Args:
index: Индекс ячейки в заголовке.
Returns:
up, если это стрелочка вверх. down, если это стрелочка вниз.
"""
loc = self.container_locator.locator(self.table_locator)
return self.events_table.get_arrow_button_state(loc, index)
def get_events_table_content(self) -> list[list[str]]:
"""Возвращает содержимое таблицы, включая заголовки.
Args:
locator: Локатор таблицы.
Returns:
Двумерный список с содержимым таблицы.
"""
loc = self.container_locator.locator(self.table_locator)
return self.events_table.read(loc)
def get_events_table_rows_count(self) -> int:
"""Возвращает количество строк в таблице (без заголовка).
Returns:
int: Количество строк с данными.
Raises:
AssertionError: Если таблица пуста.
"""
loc = self.container_locator.locator(self.table_locator)
return self.events_table.get_rows_count(loc)
def get_toolbar_filter_button(self) -> Button:
"""Возвращает кнопку фильтрации."""
return self.toolbar.get_button_by_name("filter_button")
def get_toolbar_export_to_csv_button(self) -> TooltipButton:
"""Возвращает кнопку экспорта в csv."""
return self.toolbar.get_button_by_name("export_to_csv_button")
def get_toolbar_export_to_pdf_button(self) -> TooltipButton:
"""Возвращает кнопку экспорта в pdf."""
return self.toolbar.get_button_by_name("export_to_pdf_button")
def get_toolbar_tab_button(self, name: str) -> TabButton:
"""Возвращает кнопку типа v-tabs по имени."""
return self.toolbar.get_button_by_name(name)
def scroll_events_table_up(self) -> None:
"""Прокручивает таблицу событий вверх."""
loc = self.container_locator.locator("//div[@class='scrolltable']//table/tbody")
self.events_table.scroll_up(loc)
def scroll_events_table_down(self) -> None:
"""Прокручивает таблицу событий вниз."""
loc = self.container_locator.locator("//div[@class='scrolltable']//table/tbody")
self.events_table.scroll_down(loc)
# Проверки:
def check_events_table_headers(self, actual_headers, expected_headers) -> None:
""" Проверка соответствия заголовка таблицы ожидаемому"""
self.events_table.check_table_headers(actual_headers, expected_headers)
def check_events_table_column_descending_order(self,
index: int) -> bool:
"""Проверка, что заданный столбец таблицы упорядочен по убыванию.
Args:
index: Индекс столбца.
Returns:
True, если столбец таблицы упорядочен по убыванию. Иначе: False
"""
loc = self.container_locator.locator(self.table_locator)
return self.events_table.check_column_descending_order(loc, index)
def check_events_table_row_highlighting(self, row_index: int) -> None:
"""Проверяет выделение указанной строки таблицы.
Args:
row_index: Индекс проверяемой строки.
Raises:
AssertionError: Если строка не выделена.
"""
loc = self.container_locator.locator(self.table_locator)
self.events_table.check_row_highlighting(loc, row_index)
def check_events_table_first_row_visibility(self) -> None:
"""Проверяет видимость первой строки таблицы.
Raises:
AssertionError: Если строка не видна.
"""
loc = self.container_locator.locator(self.table_locator)
self.events_table.check_first_row_visibility(loc)
def check_events_table_last_row_visibility(self) -> None:
"""Проверяет видимость последней строки таблицы.
Raises:
AssertionError: Если строка не видна.
"""
loc = self.container_locator.locator(self.table_locator)
self.events_table.check_last_row_visibility(loc)
def check_events_table_verticall_scrolling(self) -> bool:
"""Проверяет возможность вертикальной прокрутки таблицы.
Returns:
bool: True если прокрутка возможна, иначе False.
"""
loc = self.container_locator.locator("//div[@class='scrolltable']//table/tbody")
return self.events_table.is_scrollable_vertically(loc)
def is_chevron_left_disabled(self) -> bool:
"""Проверка видимости кнопки получения предыдущего набора данных"""
return self.chevron_left.is_disabled()
def is_chevron_right_disabled(self) -> bool:
"""Проверка видимости кнопки получения следующего набора данных"""
return self.chevron_right.is_disabled()
def should_be_events_table(self) -> None:
"""Проверяет наличие таблицы событий.
Raises:
AssertionError: Если таблица отсутствует.
"""
loc = self.container_locator.locator(self.table_locator)
self.events_table.check_visibility(loc,
"Events table is missing"
)
def should_be_toolbar(self) -> None:
"""Проверка наличия тулбара"""
loc = self.container_locator.locator("//nav[contains(@class, 'v-toolbar')]").nth(0)
self.toolbar.check_toolbar_presence_by_locator(loc, "Toolbar is missing")
def should_be_base_toolbar_buttons(self) -> None:
"""Проверяет наличие и видимость базовых кнопок тулбара."""
self.toolbar.check_button_visibility("filter_button")
self.toolbar.check_button_visibility("export_to_pdf_button")
self.toolbar.check_button_tooltip("export_to_pdf_button", "Скачать в формате PDF")
self.toolbar.check_button_visibility("export_to_csv_button")
self.toolbar.check_button_tooltip("export_to_csv_button", "Скачать в формате CSV")
def should_be_pagination_buttons(self) -> None:
"""Проверяет наличие и видимость кнопок пагинации."""
self.chevron_left.check_visibility("Pagination button 'chevron left' is missing")
self.data_set_number.check_visibility("Pagination button 'data set number' is missing")
self.chevron_right.check_visibility("Pagination button 'chevron right' is missing")

View File

@ -21,6 +21,48 @@ class TableComponent(BaseComponent):
super().__init__(page)
# Действия:
def click_arrow_button(self, table_locator: str | Locator, index: int) -> None:
""" Нажатие кнопки-стрелочки вверх/вниз в ячейке заголовка таблицы
Args:
table_locator: Локатор таблицы.
index: Индекс ячейки в заголовке.
"""
table = self.get_locator(table_locator)
header_cells_count = table.locator("//thead/tr/th").count()
assert index in range(header_cells_count), "Header cell index is out of range"
arrow_button = table.locator("//thead/tr/th").nth(index).get_by_role("button")
assert arrow_button.is_enabled(), f"Arrow button is missing in {index} header cell"
arrow_button.click()
def get_arrow_button_state(self, table_locator: str | Locator, index: int) -> str:
""" Получение состояния кнопки-стрелочки вверх/вниз в ячейке заголовка таблицы
Args:
table_locator: Локатор таблицы.
index: Индекс ячейки в заголовке.
Returns:
up, если это стрелочка вверх. down, если это стрелочка вниз.
"""
table = self.get_locator(table_locator)
header_cells_count = table.locator("//thead/tr/th").count()
assert index in range(header_cells_count), "Header cell index is out of range"
arrow_button = table.locator("//thead/tr/th").nth(index).get_by_role("button")
assert arrow_button.is_enabled(), f"Arrow button is missing in {index} header cell"
state = arrow_button.inner_text()
if state == "keyboard_arrow_up":
return "up"
elif state == "keyboard_arrow_down":
return "down"
else:
assert False, f"Got unsupported arrow state: {state}"
def get_row_locator(self, table_locator: str | Locator, row_index: int) -> Locator | None:
"""Возвращает локатор строки по индексу.
@ -93,6 +135,25 @@ class TableComponent(BaseComponent):
return table_data
# Проверки:
def check_table_headers(self, actual_headers, expected_headers) -> None:
""" Проверка соответствия заголовка таблицы ожидаемому"""
is_equals = True
arrow_state = ["keyboard_arrow_down", "keyboard_arrow_up"]
for item in actual_headers:
item = item.strip()
if item in arrow_state:
continue
if item not in expected_headers:
is_equals = False
assert is_equals, \
f"Expected events table headers {expected_headers} are not equal {actual_headers}"
def check_content(self,
locator: str | Locator,
expected_headers: list[str]) -> None:
@ -109,14 +170,39 @@ class TableComponent(BaseComponent):
if len(table_content) == 0:
assert False, "The contents of the table are missing"
actual_headers = table_content[0]
assert actual_headers == expected_headers, \
f"Expected events table headers {expected_headers} are not equal {actual_headers}"
self.check_table_headers(table_content[0], expected_headers)
if len(table_content) == 1:
assert False, "Table body is missing"
def check_column_descending_order(self,
locator: str | Locator,
index: int) -> bool:
"""Проверка, что заданный столбец таблицы упорядочен по убыванию.
Args:
locator: Локатор таблицы.
index: Индекс столбца.
Returns:
True, если столбец таблицы упорядочен по убыванию. Иначе: False
"""
table_content = self.read(locator)
if len(table_content) == 0:
assert False, "The contents of the table are missing"
del table_content[0]
assert index in range(len(table_content[0])), \
"Column index is out of range"
column = []
for i in range(len(table_content)):
column.append(table_content[i][index])
return all([x > y for x, y in zip(column, column[1:])])
def check_first_row_visibility(self, locator: str | Locator) -> None:
"""Проверяет видимость первой строки таблицы.

View File

@ -71,14 +71,14 @@ class ToolbarComponent(BaseComponent):
self.buttons.append(Button(self.page, locator, name))
def get_button_by_name(self, name: str) -> TooltipButton | None:
def get_button_by_name(self, name: str) -> TooltipButton | TabButton| Button | None:
"""Возвращает кнопку по имени.
Args:
name (str): Имя кнопки
Returns:
TooltipButton | None: Найденная кнопка или None
TooltipButton | TabButton| Button | None: Найденная кнопка или None
"""
for button in self.buttons:
@ -147,6 +147,16 @@ class ToolbarComponent(BaseComponent):
locator = self.get_locator(ToolbarLocators.TITLE).filter(has_text=self.title)
expect(locator).to_be_visible(), message
def check_toolbar_presence_by_locator(self, locator: str|Locator, message: str) -> None:
"""Проверяет видимость тулбара.
Args:
message (str): Сообщение об ошибке если тулбар не виден
"""
locator = self.get_locator(locator)
expect(locator).to_be_visible(), message
def check_button_visibility(self, name: str) -> None:
"""Проверяет наличие и видимость кнопки с предварительной прокруткой к элементу.

View File

@ -0,0 +1,60 @@
"""Модуль контейнера для отображения событий системного журнала.
Содержит класс для работы с контейнером для отображения событий
системного журнала через Playwright.
"""
from playwright.sync_api import Page, Locator
from tools.logger import get_logger
from locators.toolbar_locators import ToolbarLocators
from components.events_container_component import EventsContainerComponent
logger = get_logger("USER_SETTINGS_DIALOG")
class SystemLogEventsContainer(EventsContainerComponent):
"""Компонент контейнера для отображения событий системного журнала.
Предоставляет методы для взаимодействия с элементами
контейнера для отображения событий системного журнала.
"""
def __init__(self, page: Page, locator: str | Locator):
"""Инициализирует компонент контейнера для отображения событий системного журнала.
Args:
page: Экземпляр страницы Playwright.
"""
super().__init__(page, locator)
self.add_tab_to_toolbar(ToolbarLocators.TABS, "events")
# Действия:
# Проверки:
def check_content(self) -> None:
"""Проверяет содержимое контейнера для отображения событий системного журнала."""
expected_headers = ['ТИП', 'ВРЕМЯ', 'СТРОГОСТЬ', 'ХОСТ', 'ОПИСАНИЕ']
self.should_be_toolbar()
self.should_be_base_toolbar_buttons()
events_tab = self.get_toolbar_tab_button("events")
events_tab_text = events_tab.get_text(0)
assert events_tab_text.find("chevron_right") != -1, "Should be icon 'chevron_right'"
assert events_tab_text.find("События") != -1, "Tab button with text События is missing on toolbar"
self.should_be_events_table()
events_table = self.get_events_table_content()
if len(events_table) == 0:
assert False, "The contents of the events table are missing"
self.check_events_table_headers(events_table[0], expected_headers)
if len(events_table) == 1:
assert False, "Table body is missing"
self.should_be_pagination_buttons()

View File

@ -15,6 +15,7 @@ class EventPanelLocators:
TAB_EVENTS (str): кнопки События.
TAB_MAINTENANCE (str): кнопки Обслуживания.
TAB_SYSTEM_LOG (str): кнопки Системный журнал.
CONTAINER_SYSTEM_LOG_EVENTS (str): контейнера с событиями Системного журнала.
BUTTONS_EVENT (str): блока кнопок-счетчиков событий.
BUTTONS_SERVICE (str): блока кнопок, содержащего кнопки Поиска и Текущего пользователя.
AREA_EVENTS (str): рабочей области страницы.
@ -28,8 +29,10 @@ class EventPanelLocators:
TAB_MAINTENANCE = f"{TABS_BLOCK}//div[@class='v-tabs']//div[@class='v-tabs__container']/div[5]"
TAB_SYSTEM_LOG = f"{TABS_BLOCK}//div[@class='v-tabs']//div[@class='v-tabs__container']/div[6]"
CONTAINER_SYSTEM_LOG_EVENTS = "#app > div.application--wrap > div > div:nth-child(3) > div:nth-child(5)"
BUTTONS_EVENT = "//nav/div[@class='v-toolbar__content']/div[@class='v-toolbar__items'][2]//span[contains(@class, 'v-tooltip')]"
BUTTONS_SERVICE = "//nav/div[@class='v-toolbar__content']/div[@class='v-toolbar__items'][2]"
AREA_EVENTS = "#app > div.application--wrap > div > div:nth-child(3)"

View File

@ -13,4 +13,6 @@ class ToolbarLocators:
"""
TITLE = "//nav//div[contains(@class, 'v-toolbar__title')]"
ITEMS = "//nav//div[@class='v-toolbar__items']"
TABS = "//nav//div[contains(@class, 'v-toolbar__title')]//a[contains(@class, 'v-tabs__item')]"
TOOLTIP = "//div[contains(@class,'v-tooltip__content menuable__content__active')]"

View File

@ -6,6 +6,7 @@
from playwright.sync_api import Page
from locators.navigation_panel_locators import NavigationPanelLocators
from components_derived.container_system_log_events import SystemLogEventsContainer
from components_derived.user_card import UserCard
from components.navbar_component import NavigationPanelComponent
from components.eventbar_component import EventPanelComponent
@ -62,6 +63,11 @@ class MainPage(BasePage):
self.event_panel.click_expand_more_button()
def click_events_panel_system_log_tab(self) -> SystemLogEventsContainer:
"""Выполняет нажатие tab-кнопки Системный журнал."""
return self.event_panel.click_system_log_tab()
def click_user_button(self) -> UserCard:
"""Выполняет нажатие кнопки пользователя."""
@ -164,8 +170,3 @@ class MainPage(BasePage):
NavigationPanelLocators.PANEL_MAIN,
item_name
)
# def check_user_card_content(self):
# """Проверяет наличие и корректность элементов карточки пользователя."""
# self.event_panel.check_user_card_content()

View File

@ -0,0 +1,164 @@
"""Модуль тестов контейнера для отображения событий системного журнала.
Содержит тесты для проверки функциональности
контейнера для отображения событий системного журнала.
"""
# import pytest
from playwright.sync_api import Page
from pages.main_page import MainPage
from pages.login_page import LoginPage
# @pytest.mark.smoke
class TestSystemLogEventsContainer:
"""Класс тестов для проверки контейнера для отображения событий системного журнала..
Тесты покрывают следующие сценарии:
1. test_system_log_events_content: Проверяет содержимое контейнера для отображения событий системного журнала.
Атрибуты:
browser: Фикстура для работы с браузером.
"""
def test_system_log_events_content(self, browser: Page) -> None:
"""Проверяет содержимое контейнера для отображения событий системного журнала.
Args:
browser: Экземпляр страницы Playwright.
"""
lp = LoginPage(browser)
lp.do_login()
mp = MainPage(browser)
mp.should_be_event_panel()
system_log_events_container = mp.click_events_panel_system_log_tab()
system_log_events_container.check_content()
def test_events_table_row_highlighting(self, browser: Page):
"""Проверяет выделение строк в таблице событий.
Args:
browser: Экземпляр страницы Playwright.
"""
lp = LoginPage(browser)
lp.do_login()
mp = MainPage(browser)
mp.should_be_event_panel()
system_log_events_container = mp.click_events_panel_system_log_tab()
# Получение количества строк в таблице
rows_count = system_log_events_container.get_events_table_rows_count()
# Проверка выделения строк
system_log_events_container.check_events_table_row_highlighting(0)
system_log_events_container.check_events_table_row_highlighting(rows_count - 1)
system_log_events_container.check_events_table_row_highlighting(int(rows_count / 2))
def test_events_table_scrolling(self, browser: Page):
"""Проверяет возможность скроллинга таблицы событий.
Args:
browser: Экземпляр страницы Playwright.
"""
lp = LoginPage(browser)
lp.do_login()
mp = MainPage(browser)
mp.should_be_event_panel()
system_log_events_container = mp.click_events_panel_system_log_tab()
events_panel_position = mp.get_events_panel_position()
# Проверка, что панель с таблицей открыта
assert events_panel_position != "bottom", "Panel with system log events should be opened"
is_scrollable = system_log_events_container.check_events_table_verticall_scrolling()
# Убеждаемся, что панель открыта наполовину и проверяем скроллинг
assert events_panel_position == "center",\
"Panel with system log events should be located on the main page center"
assert is_scrollable, "System log events table should be scrollable"
# Скроллинг вниз
system_log_events_container.scroll_events_table_down()
browser.wait_for_timeout(1000)
# Проверка видимости последней строки после прокрутки
system_log_events_container.check_events_table_last_row_visibility()
# Скроллинг вверх
system_log_events_container.scroll_events_table_up()
browser.wait_for_timeout(1000)
# Проверка видимости первой строки после прокрутки
system_log_events_container.check_events_table_first_row_visibility()
# Раскрываем панель полностью и проверяем скроллинг
assert mp.check_expand_less_button(), \
"Expand less button should be present"
mp.click_events_panel_expand_less_button()
mp.wait_for_timeout(500)
events_panel_position = mp.get_events_panel_position()
assert events_panel_position == "top",\
"Panel with system log events should be located on the main page top"
is_scrollable = system_log_events_container.check_events_table_verticall_scrolling()
assert is_scrollable, "System log events table should be scrollable in the full window"
# Скроллинг вниз
system_log_events_container.scroll_events_table_down()
browser.wait_for_timeout(1000)
# Проверка видимости последней строки после прокрутки
system_log_events_container.check_events_table_last_row_visibility()
# Скроллинг вверх
system_log_events_container.scroll_events_table_up()
browser.wait_for_timeout(1000)
# Проверка видимости первой строки после прокрутки
system_log_events_container.check_events_table_first_row_visibility()
# @pytest.mark.develop
def test_events_table_column_sorting(self, browser: Page):
"""Проверяет сортировку колонки 'Время' в таблице событий.
Args:
browser: Экземпляр страницы Playwright.
"""
lp = LoginPage(browser)
lp.do_login()
mp = MainPage(browser)
mp.should_be_event_panel()
system_log_events_container = mp.click_events_panel_system_log_tab()
index = 1
state = system_log_events_container.get_arrow_button_state(index)
assert state == "down", "Arrow button should be down"
system_log_events_container.click_event_table_header_arrow(index)
browser.wait_for_timeout(300)
state = system_log_events_container.get_arrow_button_state(index)
assert state == "up", "Arrow button should be up"
is_descending_order = system_log_events_container.check_events_table_column_descending_order(index)
assert not is_descending_order, "Column data should be in ascending order"
system_log_events_container.click_event_table_header_arrow(index)
browser.wait_for_timeout(300)
state = system_log_events_container.get_arrow_button_state(index)
assert state == "down", "Arrow button should be down"
is_descending_order = system_log_events_container.check_events_table_column_descending_order(index)
assert is_descending_order, "Column data should be in descending order"