Добавлены тесты работы с сеансами пользователей, их создание, удаление и автоматическую очистку.
parent
a19e125ef2
commit
13d821b43f
|
|
@ -95,3 +95,18 @@ class ConfirmComponent(BaseComponent):
|
||||||
|
|
||||||
return self.is_scrollable_horizontally(ConfirmLocators.CONFIRM)
|
return self.is_scrollable_horizontally(ConfirmLocators.CONFIRM)
|
||||||
|
|
||||||
|
def should_be_cancel_button(self) -> None:
|
||||||
|
"""Проверяет наличие и видимость кнопки Отмены."""
|
||||||
|
self.cancel_button.check_presence("Cancel button is missing")
|
||||||
|
|
||||||
|
def should_be_allow_button(self) -> None:
|
||||||
|
"""Проверяет наличие и видимость кнопки Подтверждения."""
|
||||||
|
self.allow_button.check_presence("Allow button is missing")
|
||||||
|
|
||||||
|
def check_cancel_button_text(self, expected_text: str) -> None:
|
||||||
|
"""Проверяет текст кнопки Отмены."""
|
||||||
|
self.cancel_button.check_have_text(expected_text, "Cancel button text doesn't match expected")
|
||||||
|
|
||||||
|
def check_allow_button_text(self, expected_text: str) -> None:
|
||||||
|
"""Проверяет текст кнопки Подтверждения."""
|
||||||
|
self.allow_button.check_have_text(expected_text, "Allow button text doesn't match expected")
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"""Модуль вкладки 'Сессия'.
|
"""Модуль вкладки 'Сеанс'.
|
||||||
|
|
||||||
Содержит класс SessionsTab для работы с таблицей сессий.
|
Содержит класс SessionsTab для работы с таблицей сеансов.
|
||||||
Позволяет проверять состояние и взаимодействовать с элементами вкладки.
|
Позволяет проверять состояние и взаимодействовать с элементами вкладки.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -16,9 +16,9 @@ from components.confirm_component import ConfirmComponent
|
||||||
from pages.base_page import BasePage
|
from pages.base_page import BasePage
|
||||||
|
|
||||||
class SessionsTab(BasePage):
|
class SessionsTab(BasePage):
|
||||||
"""Класс для работы с вкладкой 'Сессия'.
|
"""Класс для работы с вкладкой 'Сеанс'.
|
||||||
|
|
||||||
Предоставляет методы для взаимодействия с таблицей сессий и проверки
|
Предоставляет методы для взаимодействия с таблицей сеансов и проверки
|
||||||
её состояния.
|
её состояния.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
@ -26,7 +26,7 @@ class SessionsTab(BasePage):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, page: Page) -> None:
|
def __init__(self, page: Page) -> None:
|
||||||
"""Инициализирует компоненты вкладки 'Сессия'."""
|
"""Инициализирует компоненты вкладки 'Сеанс'."""
|
||||||
|
|
||||||
super().__init__(page)
|
super().__init__(page)
|
||||||
|
|
||||||
|
|
@ -55,7 +55,7 @@ class SessionsTab(BasePage):
|
||||||
return rows_count - 1
|
return rows_count - 1
|
||||||
|
|
||||||
def get_delete_session_button_from_row(self, row_index: int) -> TooltipButton:
|
def get_delete_session_button_from_row(self, row_index: int) -> TooltipButton:
|
||||||
"""Возвращает кнопку удаления сессии для указанной строки.
|
"""Возвращает кнопку удаления сеанса для указанной строки.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
row_index: Индекс строки в таблице.
|
row_index: Индекс строки в таблице.
|
||||||
|
|
@ -89,7 +89,7 @@ class SessionsTab(BasePage):
|
||||||
return host.get_access_token()
|
return host.get_access_token()
|
||||||
|
|
||||||
def find_session_in_table(self, token: str) -> int:
|
def find_session_in_table(self, token: str) -> int:
|
||||||
"""Ищет сессию пользователя в таблице по выданному ему токену.
|
"""Ищет сеанс пользователя в таблице по выданному ему токену.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
token (str): Токен пользователя
|
token (str): Токен пользователя
|
||||||
|
|
@ -111,28 +111,66 @@ class SessionsTab(BasePage):
|
||||||
return row_index
|
return row_index
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
def delete_session_by_token(self, token: str) -> None:
|
||||||
|
"""Удаляет сеанс по токену.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
token (str): Токен сеанс для удаления
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
AssertionError: Если сеанс не найден или удаление не удалось.
|
||||||
|
"""
|
||||||
|
row_index = self.find_session_in_table(token)
|
||||||
|
if row_index == -1:
|
||||||
|
raise AssertionError(f"Session with token {token} not found")
|
||||||
|
|
||||||
|
self.delete_session_by_index(row_index)
|
||||||
|
|
||||||
|
def delete_session_by_index(self, row_index: int) -> None:
|
||||||
|
"""Удаляет сеанс по индексу строки.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
row_index (int): Индекс строки в таблице
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
AssertionError: Если удаление не удалось.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Находим кнопку удаления сеанса и нажимаем на нее
|
||||||
|
delete_session_button = self.get_delete_session_button_from_row(row_index)
|
||||||
|
delete_session_button.click()
|
||||||
|
|
||||||
|
# Подтверждаем удаление
|
||||||
|
self.delete_session_confirm.click_allow_button()
|
||||||
|
|
||||||
|
# Ждем обновления таблицы
|
||||||
|
self.page.wait_for_timeout(1000)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise AssertionError(f"Failed to delete session at index {row_index}: {e}")
|
||||||
|
|
||||||
|
|
||||||
def scroll_sessions_table_up(self) -> None:
|
def scroll_sessions_table_up(self) -> None:
|
||||||
"""Прокручивает таблицу сессий вверх."""
|
"""Прокручивает таблицу сеансов вверх."""
|
||||||
|
|
||||||
self.sessions_table.scroll_up(TableLocators.TABLE_SCROLL_CONTAINER)
|
self.sessions_table.scroll_up(TableLocators.TABLE_SCROLL_CONTAINER)
|
||||||
|
|
||||||
def scroll_sessions_table_down(self) -> None:
|
def scroll_sessions_table_down(self) -> None:
|
||||||
"""Прокручивает таблицу сессий вниз."""
|
"""Прокручивает таблицу сеансов вниз."""
|
||||||
|
|
||||||
self.sessions_table.scroll_down(TableLocators.TABLE_SCROLL_CONTAINER)
|
self.sessions_table.scroll_down(TableLocators.TABLE_SCROLL_CONTAINER)
|
||||||
|
|
||||||
# Проверки:
|
# Проверки:
|
||||||
def check_delete_session_confirm_window(self):
|
def check_delete_session_confirm_window(self):
|
||||||
""" Проверяет контент и возможность горизонтального скроллинга окна подтверждения удаления сессии. """
|
""" Проверяет контент и возможность горизонтального скроллинга окна подтверждения удаления сеанс. """
|
||||||
|
|
||||||
# Поиск в таблице сессий сроки для текущего пользователя
|
# Поиск в таблице сеанс сроки для текущего пользователя
|
||||||
session_token = self.get_session_token()
|
session_token = self.get_session_token()
|
||||||
row_index = self.find_session_in_table(session_token)
|
row_index = self.find_session_in_table(session_token)
|
||||||
if row_index == -1:
|
if row_index == -1:
|
||||||
assert False, "Session for this token has not been found"
|
assert False, "Session for this token has not been found"
|
||||||
|
|
||||||
# Найти кнопку удаления сессии и нажать на нее
|
# Найти кнопку удаления сеанса и нажать на нее
|
||||||
delete_session_button = self.get_delete_session_button_from_row(row_index)
|
delete_session_button = self.get_delete_session_button_from_row(row_index)
|
||||||
delete_session_button.click()
|
delete_session_button.click()
|
||||||
|
|
||||||
|
|
@ -150,6 +188,16 @@ class SessionsTab(BasePage):
|
||||||
"Confirmation dialog window text does not match what is expected"
|
"Confirmation dialog window text does not match what is expected"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Проверка наличия и видимости кнопки "Отмена"
|
||||||
|
self.delete_session_confirm.should_be_cancel_button()
|
||||||
|
|
||||||
|
# Проверка наличия и видимости кнопки "Удалить"
|
||||||
|
self.delete_session_confirm.should_be_allow_button()
|
||||||
|
|
||||||
|
# Проверка текста на кнопках
|
||||||
|
self.delete_session_confirm.check_cancel_button_text(" Отмена ")
|
||||||
|
self.delete_session_confirm.check_allow_button_text(" Удалить ")
|
||||||
|
|
||||||
# Проверка горизонтального скроллинга
|
# Проверка горизонтального скроллинга
|
||||||
is_scrollable_horizontally = self.delete_session_confirm.check_window_horizontal_scrolling()
|
is_scrollable_horizontally = self.delete_session_confirm.check_window_horizontal_scrolling()
|
||||||
assert is_scrollable_horizontally, "Should be horizontal scrolling"
|
assert is_scrollable_horizontally, "Should be horizontal scrolling"
|
||||||
|
|
@ -163,7 +211,7 @@ class SessionsTab(BasePage):
|
||||||
self.delete_session_confirm.click_cancel_button()
|
self.delete_session_confirm.click_cancel_button()
|
||||||
|
|
||||||
def check_sessions_table_content(self, verify: bool = False) -> None:
|
def check_sessions_table_content(self, verify: bool = False) -> None:
|
||||||
"""Проверяет содержимое таблицы сессий.
|
"""Проверяет содержимое таблицы сеансов.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
verify: Проверять соответствие данных из БД. По умолчанию False.
|
verify: Проверять соответствие данных из БД. По умолчанию False.
|
||||||
|
|
@ -257,7 +305,7 @@ class SessionsTab(BasePage):
|
||||||
self.toolbar.check_toolbar_presence("Toolbar is missing")
|
self.toolbar.check_toolbar_presence("Toolbar is missing")
|
||||||
|
|
||||||
def should_be_sessions_table(self) -> None:
|
def should_be_sessions_table(self) -> None:
|
||||||
"""Проверяет наличие таблицы сессий.
|
"""Проверяет наличие таблицы сеансов.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
AssertionError: Если таблица отсутствует.
|
AssertionError: Если таблица отсутствует.
|
||||||
|
|
@ -297,26 +345,26 @@ class SessionsTab(BasePage):
|
||||||
|
|
||||||
|
|
||||||
def should_be_session_in_table(self, token: str) -> None:
|
def should_be_session_in_table(self, token: str) -> None:
|
||||||
"""Проверяет наличие сессии пользователя в таблице.
|
"""Проверяет наличие сеанса пользователя в таблице.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
token (str): Токен пользователя
|
token (str): Токен пользователя
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
AssertionError: Если сессия не найдена.
|
AssertionError: Если сеанс не найден.
|
||||||
"""
|
"""
|
||||||
found = self.find_session_in_table(token)
|
found = self.find_session_in_table(token)
|
||||||
if found == -1:
|
if found == -1:
|
||||||
assert False, "Session for this token has not been found"
|
assert False, "Session for this token has not been found"
|
||||||
|
|
||||||
def should_not_be_session_in_table(self, token: str) -> None:
|
def should_not_be_session_in_table(self, token: str) -> None:
|
||||||
"""Проверяет отсутствие сессии пользователя в таблице.
|
"""Проверяет отсутствие сеанса пользователя в таблице.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
token (str): Токен пользователя
|
token (str): Токен пользователя
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
AssertionError: Если сессия найдена.
|
AssertionError: Если сеанс найден.
|
||||||
"""
|
"""
|
||||||
found = self.find_session_in_table(token)
|
found = self.find_session_in_table(token)
|
||||||
if found != -1:
|
if found != -1:
|
||||||
|
|
@ -335,7 +383,7 @@ class SessionsTab(BasePage):
|
||||||
|
|
||||||
expected_sessions_list = []
|
expected_sessions_list = []
|
||||||
|
|
||||||
# Отправка запроса к бэкенду для получения информации о сессиях
|
# Отправка запроса к бэкенду для получения информации о сеансах
|
||||||
response = self.send_get_api_request("e-nms/auth/sessions")
|
response = self.send_get_api_request("e-nms/auth/sessions")
|
||||||
response_body = self.get_response_body(response)
|
response_body = self.get_response_body(response)
|
||||||
|
|
||||||
|
|
@ -344,7 +392,7 @@ class SessionsTab(BasePage):
|
||||||
session_info.append(item["id"])
|
session_info.append(item["id"])
|
||||||
session_info.append(item["userId"])
|
session_info.append(item["userId"])
|
||||||
|
|
||||||
# Временно неподдерживаемое поле: время жизни сессии
|
# Временно неподдерживаемое поле: время жизни сеанса
|
||||||
session_info.append("")
|
session_info.append("")
|
||||||
|
|
||||||
roles = []
|
roles = []
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"""Модуль тестов вкладки 'Сеансы'.
|
"""Модуль тестов вкладки 'Сеансы'.
|
||||||
|
|
||||||
Содержит тесты для проверки функциональности
|
Содержит тесты для проверки функциональности
|
||||||
работы с пользовательтскими сессиями.
|
работы с пользовательтскими сеансами.
|
||||||
"""
|
"""
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from playwright.sync_api import Page
|
from playwright.sync_api import Page
|
||||||
|
|
@ -12,15 +12,25 @@ from pages.users_tab import UsersTab
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
class TestSessionsTab:
|
class TestSessionsTab:
|
||||||
"""Набор тестов для вкладки 'Сеансы'.
|
"""Набор тестов для вкладки 'Сеансы'.
|
||||||
|
|
||||||
Проверяет корректность отображения и функциональность элементов вкладки сеансов.
|
Проверяет корректность отображения и функциональность элементов вкладки сеансов,
|
||||||
|
включая работу с сеансами пользователей, их создание, удаление и автоматическую очистку.
|
||||||
|
|
||||||
|
Тесты покрывают следующие сценарии:
|
||||||
|
1. Тест содержимого вкладки 'Сеансы'
|
||||||
|
2. Тест подсветки строк таблицы сеансов
|
||||||
|
3. Тест окна подтверждения удаления сеанса
|
||||||
|
4. Тест автоматического удаления сеанса после выхода пользователя из системы (отложено)
|
||||||
|
5. Тест создания нескольких пользователей и их сеансов
|
||||||
|
6. Тест удаления сеанса при удалении пользователя (отложено)
|
||||||
|
7. Тест автоматического удаления сеанса через 15 минут после выхода пользователя (отложено)
|
||||||
|
8. Тест проверки невозможности пользователя удалить свой собственный сеанс (отложено)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@pytest.fixture(scope="function", autouse=True)
|
@pytest.fixture(scope="function", autouse=True)
|
||||||
def setup(self, browser):
|
def setup(self, browser: Page) -> None:
|
||||||
"""Фикстура для подготовки тестового окружения.
|
"""Фикстура для подготовки тестового окружения.
|
||||||
|
|
||||||
Выполняет:
|
Выполняет:
|
||||||
|
|
@ -41,24 +51,41 @@ class TestSessionsTab:
|
||||||
main_page.click_subpanel_item("Сеансы")
|
main_page.click_subpanel_item("Сеансы")
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function")
|
||||||
def cleanup_user(self, browser: Page) -> None:
|
def cleanup_users(self, browser: Page) -> None:
|
||||||
"""Фикстура для очистки пользователя NewUser после теста."""
|
"""Фикстура для очистки тестовых пользователей и их сеансов после теста."""
|
||||||
|
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
# Выход из системы текущего пользователя
|
||||||
mp = MainPage(browser)
|
mp = MainPage(browser)
|
||||||
|
mp.do_logout()
|
||||||
|
|
||||||
|
# Авторизация администратором для очистки
|
||||||
|
login_page = LoginPage(browser)
|
||||||
|
login_page.do_login()
|
||||||
|
|
||||||
|
# Удаляем тестовых пользователей
|
||||||
|
self._cleanup_test_users(browser)
|
||||||
|
|
||||||
|
def _cleanup_test_users(self, browser: Page) -> None:
|
||||||
|
"""Удаляет тестовых пользователей."""
|
||||||
|
mp = MainPage(browser)
|
||||||
|
mp.click_main_navigation_panel_item("Настройки")
|
||||||
mp.click_subpanel_item("Пользователи")
|
mp.click_subpanel_item("Пользователи")
|
||||||
ut = UsersTab(browser)
|
ut = UsersTab(browser)
|
||||||
|
|
||||||
# Удаляем тестового пользователя после выполнения теста
|
# Удаляем тестовых пользователей
|
||||||
user_data: Dict[str, str] = {"name": "NewUser", "role": "Администратор"}
|
test_users = ["TestUser1", "TestUser2", "TestUser3", "TestUserForSessionDeletion",
|
||||||
|
"TestUserForManualDeletion", "UserForAutoSessionDeletion",
|
||||||
|
"TestUserFor15MinDeletion", "TestUserForSelfDeletion"]
|
||||||
|
|
||||||
|
for user_name in test_users:
|
||||||
# Проверяем существует ли пользователь и удаляем его
|
# Проверяем существует ли пользователь и удаляем его
|
||||||
if ut.find_user_in_table(user_data["name"], user_data["role"]) != -1:
|
user_index = ut.find_user_in_table(user_name, "Администратор")
|
||||||
ut.open_edit_user_page_by_user(user_data["name"], user_data["role"])
|
if user_index != -1:
|
||||||
ut.delete_user(user_data["name"])
|
ut.open_edit_user_page_by_user(user_name, "Администратор")
|
||||||
|
ut.delete_user(user_name)
|
||||||
|
|
||||||
def test_sessions_tab_content(self, browser):
|
def test_sessions_tab_content(self, browser: Page) -> None:
|
||||||
"""Тест содержимого вкладки 'Сеансы'.
|
"""Тест содержимого вкладки 'Сеансы'.
|
||||||
|
|
||||||
Проверяет:
|
Проверяет:
|
||||||
|
|
@ -84,20 +111,22 @@ class TestSessionsTab:
|
||||||
else:
|
else:
|
||||||
sessions_tab.check_sessions_table_content(verify=True)
|
sessions_tab.check_sessions_table_content(verify=True)
|
||||||
|
|
||||||
# Проверка содержимого таблицы с верификацией данных из БД
|
# Проверка содержимого таблица с верификацией данных из БД
|
||||||
# sessions_tab.check_sessions_table_content(verify=True)
|
sessions_tab.check_sessions_table_content(verify=True)
|
||||||
|
|
||||||
def test_sessions_table_row_highlighting(self, browser):
|
def test_sessions_table_row_highlighting(self, browser: Page) -> None:
|
||||||
"""Тест содержимого вкладки 'Сеансы'.
|
"""Тест подсветки строк таблицы сеансов.
|
||||||
|
|
||||||
Проверяет:
|
Проверяет:
|
||||||
1. Наличие таблицы сеансов
|
1. Наличие таблицы сеансов
|
||||||
2. Проверка подсветки строки при наведении на нее курсором
|
2. Подсветку строки при наведении курсора на первую строку
|
||||||
|
3. Подсветку строки при наведении курсора на последнюю строку (если строк больше одной)
|
||||||
|
4. Корректность визуального отображения подсветки строк
|
||||||
"""
|
"""
|
||||||
# Инициализация страницы сеансов
|
# Инициализация страницы сеансов
|
||||||
sessions_tab = SessionsTab(browser)
|
sessions_tab = SessionsTab(browser)
|
||||||
|
|
||||||
# Проверка элементов интерфейса
|
# Проверка наличия таблицы сеансов
|
||||||
sessions_tab.should_be_sessions_table()
|
sessions_tab.should_be_sessions_table()
|
||||||
|
|
||||||
# Получение количества строк в таблице без учета заголовка
|
# Получение количества строк в таблице без учета заголовка
|
||||||
|
|
@ -113,37 +142,39 @@ class TestSessionsTab:
|
||||||
browser.wait_for_timeout(1000)
|
browser.wait_for_timeout(1000)
|
||||||
sessions_tab.check_sessions_table_row_highlighting(rows_count - 1)
|
sessions_tab.check_sessions_table_row_highlighting(rows_count - 1)
|
||||||
|
|
||||||
def test_delete_session_confirm_window(self, browser):
|
def test_delete_session_confirm_window(self, browser: Page) -> None:
|
||||||
"""Тест содержимого вкладки 'Сеансы'.
|
"""Тест окна подтверждения удаления сеанса.
|
||||||
|
|
||||||
Проверяет:
|
Проверяет:
|
||||||
1. Наличие таблицы сеансов
|
1. Наличие таблицы сеансов
|
||||||
2. Проверка контента и возможности горизонтального скроллинга окна подтверждения удаления сессии
|
2. Содержимое окна подтверждения удаления сеанса
|
||||||
|
3. Возможность горизонтального скроллинга в окне подтверждения
|
||||||
|
4. Корректность отображения элементов интерфейса в окне подтверждения
|
||||||
|
5. Функциональность кнопок в окне подтверждения удаления
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Инициализация страницы сеансов
|
# Инициализация страницы сеансов
|
||||||
sessions_tab = SessionsTab(browser)
|
sessions_tab = SessionsTab(browser)
|
||||||
|
|
||||||
# Проверка элементов интерфейса
|
# Проверка наличия таблицы сеансов
|
||||||
sessions_tab.should_be_sessions_table()
|
sessions_tab.should_be_sessions_table()
|
||||||
|
|
||||||
# Проверка контента и скроллинга окна подтверждения удаления сессии
|
# Проверка контента и скроллинга окна подтверждения удаления сеанса
|
||||||
sessions_tab.check_delete_session_confirm_window()
|
sessions_tab.check_delete_session_confirm_window()
|
||||||
|
|
||||||
# @pytest.mark.develop
|
@pytest.mark.skip(reason="Не реализовано разработчиком, заведен тикет")
|
||||||
def test_session_for_new_user(self, browser, cleanup_user):
|
def test_delete_session_after_logout(self, browser: Page, cleanup_users: None) -> None:
|
||||||
"""Тест содержимого вкладки 'Сеансы'.
|
"""Тест автоматического удаления сеанса после выхода пользователя из системы.
|
||||||
|
|
||||||
Проверяет:
|
Проверяет:
|
||||||
1. Создание нового пользователя
|
1. Создание нового пользователя
|
||||||
2. Вход нового пользователя в систему
|
2. Вход нового пользователя в систему
|
||||||
3. Проверка наличия сессии нового пользователя
|
3. Проверка наличия сеанса нового пользователя
|
||||||
4. Выход нового пользователя из системы (logout)
|
4. Выход нового пользователя из системы (logout)
|
||||||
5. Вход в систему первоначального пользователя
|
5. Вход в систему пользователя admin
|
||||||
6. Проверка отсутствия сессии нового пользователя
|
6. Проверка отсутствия сеанса нового пользователя
|
||||||
7. Удаление нового пользователя
|
7. Удаление пользователя выполняется автоматически фикстурой cleanup_users
|
||||||
"""
|
"""
|
||||||
user_data = {"name": "NewUser", "role": "Администратор", "password": "qwerty"}
|
user_data = {"name": "TestUserForSessionDeletion", "role": "Администратор", "password": "qwerty"}
|
||||||
|
|
||||||
mp = MainPage(browser)
|
mp = MainPage(browser)
|
||||||
ut = UsersTab(browser)
|
ut = UsersTab(browser)
|
||||||
|
|
@ -176,10 +207,10 @@ class TestSessionsTab:
|
||||||
# Инициализация страницы сеансов
|
# Инициализация страницы сеансов
|
||||||
st = SessionsTab(browser)
|
st = SessionsTab(browser)
|
||||||
|
|
||||||
# Проверка элементов интерфейса
|
# # Проверка наличия таблицы сеансов
|
||||||
st.should_be_sessions_table()
|
st.should_be_sessions_table()
|
||||||
|
|
||||||
# Проверка наличия записи о сессии текущего пользователя
|
# Проверка наличия записи о сеансе текущего пользователя
|
||||||
session_token = st.get_session_token()
|
session_token = st.get_session_token()
|
||||||
st.should_be_session_in_table(session_token)
|
st.should_be_session_in_table(session_token)
|
||||||
|
|
||||||
|
|
@ -187,25 +218,419 @@ class TestSessionsTab:
|
||||||
new_mp.do_logout()
|
new_mp.do_logout()
|
||||||
|
|
||||||
# Авторизация в системе предыдущего пользователя
|
# Авторизация в системе предыдущего пользователя
|
||||||
prev_lp = LoginPage(browser)
|
admin_lp = LoginPage(browser)
|
||||||
prev_lp.do_login()
|
admin_lp.do_login()
|
||||||
|
|
||||||
# Инициализация главной страницы
|
# Инициализация главной страницы
|
||||||
prev_mp = MainPage(browser)
|
admin_mp = MainPage(browser)
|
||||||
|
|
||||||
# Открыть вкладку Сессии
|
# Открыть вкладку Сеансы
|
||||||
prev_mp.should_be_navigation_panel()
|
admin_mp.should_be_navigation_panel()
|
||||||
prev_mp.click_main_navigation_panel_item("Настройки")
|
admin_mp.click_main_navigation_panel_item("Настройки")
|
||||||
prev_mp.click_subpanel_item("Обслуживание и диагностика")
|
admin_mp.click_subpanel_item("Обслуживание и диагностика")
|
||||||
prev_mp.click_subpanel_item("Сеансы")
|
admin_mp.click_subpanel_item("Сеансы")
|
||||||
|
|
||||||
# Проверка элементов интерфейса
|
# Проверка наличия таблица сеансов
|
||||||
# st.should_be_sessions_table()
|
st.should_be_sessions_table()
|
||||||
|
|
||||||
# Проверка отсутствия записи о сессии созданного пользователя после выхода из системы
|
# Проверка отсутствия записи о сессии созданного пользователя после выхода из системы
|
||||||
# st.should_not_be_session_in_table(session_token)
|
st.should_not_be_session_in_table(session_token)
|
||||||
|
|
||||||
# Удаление созданного пользователя
|
# Удаление пользователя выполняется автоматически фикстурой cleanup_users после теста
|
||||||
#prev_ut = UsersTab(browser)
|
|
||||||
#prev_ut.open_edit_user_page_by_user(user_data["name"], user_data["role"])
|
def test_delete_existed_session(self, browser: Page, cleanup_users: None) -> None:
|
||||||
#prev_ut.delete_user(user_data["name"])
|
"""Тест удаления созданного сеанса.
|
||||||
|
|
||||||
|
Проверяет:
|
||||||
|
1. Создание нового пользователя
|
||||||
|
2. Вход нового пользователя в систему
|
||||||
|
3. Проверка наличия сеанса нового пользователя
|
||||||
|
4. Выход нового пользователя из системы (logout)
|
||||||
|
5. Вход в систему пользователя admin
|
||||||
|
6. Удаление сеанса нового пользователя
|
||||||
|
7. Проверка отсутствия сеанса нового пользователя
|
||||||
|
8. Удаление пользователя выполняется автоматически фикстурой cleanup_users
|
||||||
|
"""
|
||||||
|
user_data = {"name": "TestUserForManualDeletion", "role": "Администратор", "password": "qwerty123"}
|
||||||
|
|
||||||
|
mp = MainPage(browser)
|
||||||
|
ut = UsersTab(browser)
|
||||||
|
|
||||||
|
# Создание нового пользователя NewUser
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
ut.open_add_user_window()
|
||||||
|
ut.add_new_user(user_data)
|
||||||
|
|
||||||
|
# Обновление списка пользователей (двойной клик - возможно баг?)
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
|
||||||
|
# Проверка наличия пользователя в таблице
|
||||||
|
ut.should_be_user_in_table(user_data["name"], user_data["role"])
|
||||||
|
|
||||||
|
# Вход в систему для нового пользователя NewUser
|
||||||
|
new_lp = LoginPage(browser)
|
||||||
|
new_lp.do_login(username=user_data["name"], password=user_data["password"])
|
||||||
|
|
||||||
|
# Инициализация главной страницы
|
||||||
|
new_mp = MainPage(browser)
|
||||||
|
|
||||||
|
# Открыть вкладку Сеанса
|
||||||
|
new_mp.should_be_navigation_panel()
|
||||||
|
new_mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
new_mp.click_subpanel_item("Обслуживание и диагностика")
|
||||||
|
new_mp.click_subpanel_item("Сеансы")
|
||||||
|
|
||||||
|
# Инициализация страницы сеансов
|
||||||
|
st = SessionsTab(browser)
|
||||||
|
|
||||||
|
# Проверка наличия таблицы сеансов
|
||||||
|
st.should_be_sessions_table()
|
||||||
|
|
||||||
|
# Проверка наличия записи о сеансе текущего пользователя
|
||||||
|
new_user_token = st.get_session_token()
|
||||||
|
st.should_be_session_in_table(new_user_token)
|
||||||
|
|
||||||
|
# logout
|
||||||
|
new_mp.do_logout()
|
||||||
|
|
||||||
|
# Авторизация в системе пользователя admin
|
||||||
|
admin_lp = LoginPage(browser)
|
||||||
|
admin_lp.do_login()
|
||||||
|
|
||||||
|
# Переход на вкладку Сеансы
|
||||||
|
admin_mp = MainPage(browser)
|
||||||
|
admin_mp.should_be_navigation_panel()
|
||||||
|
admin_mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
admin_mp.click_subpanel_item("Обслуживание и диагностика")
|
||||||
|
admin_mp.click_subpanel_item("Сеансы")
|
||||||
|
|
||||||
|
# Удаление сеанса созданного пользователя по токену
|
||||||
|
admin_sessions_tab = SessionsTab(browser)
|
||||||
|
admin_sessions_tab.should_be_sessions_table()
|
||||||
|
admin_sessions_tab.delete_session_by_token(new_user_token)
|
||||||
|
|
||||||
|
# Проверка отсутствия записи о сеансе созданного пользователя после удаления
|
||||||
|
admin_sessions_tab.should_not_be_session_in_table(new_user_token)
|
||||||
|
|
||||||
|
# Удаление пользователя выполняется автоматически фикстурой cleanup_users после теста
|
||||||
|
|
||||||
|
def test_multiple_users_sessions(self, browser: Page, cleanup_users: None) -> None:
|
||||||
|
"""Тест создания нескольких пользователей и их сеансов.
|
||||||
|
|
||||||
|
Проверяет:
|
||||||
|
1. Создание нескольких пользователей User1..User3
|
||||||
|
2. Вход каждого пользователя в систему и создание сеансов
|
||||||
|
3. Проверка наличия сеанса в таблице
|
||||||
|
4. Проверка скроллинга таблицы с множеством сеансов
|
||||||
|
5. Удаление пользователей выполняется автоматически фикстурой cleanup_users
|
||||||
|
"""
|
||||||
|
users_data = [
|
||||||
|
{"name": "TestUser1", "role": "Администратор", "password": "password1"},
|
||||||
|
{"name": "TestUser2", "role": "Администратор", "password": "password2"},
|
||||||
|
{"name": "TestUser3", "role": "Администратор", "password": "password3"}
|
||||||
|
]
|
||||||
|
|
||||||
|
session_tokens = []
|
||||||
|
|
||||||
|
mp = MainPage(browser)
|
||||||
|
ut = UsersTab(browser)
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
|
||||||
|
# Создание нескольких пользователей
|
||||||
|
for user_data in users_data:
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
ut.open_add_user_window()
|
||||||
|
ut.add_new_user(user_data)
|
||||||
|
|
||||||
|
# Проверка наличия пользователя в таблице
|
||||||
|
ut.should_be_user_in_table(user_data["name"], user_data["role"])
|
||||||
|
|
||||||
|
# Вход каждого пользователя и получение токенов сеансов
|
||||||
|
for user_data in users_data:
|
||||||
|
# Вход новым пользователем
|
||||||
|
login_page = LoginPage(browser)
|
||||||
|
login_page.do_login(username=user_data["name"], password=user_data["password"])
|
||||||
|
|
||||||
|
# Получение токена сеансов
|
||||||
|
sessions_tab = SessionsTab(browser)
|
||||||
|
#sessions_tab.should_be_sessions_table()
|
||||||
|
session_token = sessions_tab.get_session_token()
|
||||||
|
session_tokens.append(session_token)
|
||||||
|
|
||||||
|
# Возврат администратора для проверки сеансов
|
||||||
|
login_page = LoginPage(browser)
|
||||||
|
login_page.do_login()
|
||||||
|
|
||||||
|
mp = MainPage(browser)
|
||||||
|
mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
mp.click_subpanel_item("Обслуживание и диагностика")
|
||||||
|
mp.click_subpanel_item("Сеансы")
|
||||||
|
|
||||||
|
sessions_tab = SessionsTab(browser)
|
||||||
|
sessions_tab.should_be_sessions_table()
|
||||||
|
|
||||||
|
# Проверка наличия сеансов всех пользователей
|
||||||
|
for session_token in session_tokens:
|
||||||
|
sessions_tab.should_be_session_in_table(session_token)
|
||||||
|
|
||||||
|
# Проверка скроллинга таблицы с множеством сеансов
|
||||||
|
self._test_sessions_table_scrolling(sessions_tab)
|
||||||
|
|
||||||
|
def _test_sessions_table_scrolling(self, sessions_tab: SessionsTab) -> None:
|
||||||
|
"""Вспомогательный метод для проверки скроллинга таблицы сеансов.
|
||||||
|
|
||||||
|
Проверяет:
|
||||||
|
1. Возможность вертикального скроллинга таблицы
|
||||||
|
2. Видимость первой и последней строк после скроллинга
|
||||||
|
"""
|
||||||
|
# Проверка возможности вертикального скроллинга
|
||||||
|
is_scrollable = sessions_tab.check_sessions_table_verticall_scrolling()
|
||||||
|
|
||||||
|
if is_scrollable:
|
||||||
|
print("Таблица поддерживает вертикальный скроллинг")
|
||||||
|
|
||||||
|
# Прокрутка вниз
|
||||||
|
sessions_tab.scroll_sessions_table_down()
|
||||||
|
|
||||||
|
# Проверка видимости последней строки после прокрутки
|
||||||
|
sessions_tab.check_sessions_table_last_row_visibility()
|
||||||
|
|
||||||
|
# Прокрутка вверх
|
||||||
|
sessions_tab.scroll_sessions_table_up()
|
||||||
|
|
||||||
|
# Проверка видимости первой строки после прокрутки
|
||||||
|
sessions_tab.check_sessions_table_first_row_visibility()
|
||||||
|
else:
|
||||||
|
print("Таблица не поддерживает вертикальный скроллинг - проверяем базовую функциональность")
|
||||||
|
|
||||||
|
# Проверка видимости первой строки
|
||||||
|
sessions_tab.check_sessions_table_first_row_visibility()
|
||||||
|
|
||||||
|
@pytest.mark.skip(reason="Не реализовано разработчиком")
|
||||||
|
def test_session_removed_when_user_deleted(self, browser: Page, cleanup_users: None) -> None:
|
||||||
|
"""Тест удаления сеанса при удалении пользователя.
|
||||||
|
|
||||||
|
Проверяет:
|
||||||
|
1. Создание нового пользователя
|
||||||
|
2. Вход пользователя и создание сеанса
|
||||||
|
3. Удаление пользователя администратором
|
||||||
|
4. Проверка автоматического удаления сеанса пользователя
|
||||||
|
"""
|
||||||
|
user_data = {"name": "UserForAutoSessionDeletion", "role": "Администратор", "password": "qwerty123"}
|
||||||
|
|
||||||
|
mp = MainPage(browser)
|
||||||
|
ut = UsersTab(browser)
|
||||||
|
|
||||||
|
# Создание нового пользователя
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
ut.open_add_user_window()
|
||||||
|
ut.add_new_user(user_data)
|
||||||
|
|
||||||
|
# Обновление списка пользователей
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
|
||||||
|
# Проверка наличия пользователя в таблице
|
||||||
|
ut.should_be_user_in_table(user_data["name"], user_data["role"])
|
||||||
|
|
||||||
|
# Вход в систему для нового пользователя
|
||||||
|
new_lp = LoginPage(browser)
|
||||||
|
new_lp.do_login(username=user_data["name"], password=user_data["password"])
|
||||||
|
|
||||||
|
# Получение токена сессии нового пользователя
|
||||||
|
new_mp = MainPage(browser)
|
||||||
|
|
||||||
|
# Открыть вкладку Сессии
|
||||||
|
new_mp.should_be_navigation_panel()
|
||||||
|
new_mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
new_mp.click_subpanel_item("Обслуживание и диагностика")
|
||||||
|
new_mp.click_subpanel_item("Сеансы")
|
||||||
|
|
||||||
|
# Получаем токен сессии
|
||||||
|
sessions_tab = SessionsTab(browser)
|
||||||
|
new_user_token = sessions_tab.get_session_token()
|
||||||
|
|
||||||
|
# Проверка наличия сессии в таблице
|
||||||
|
sessions_tab.should_be_session_in_table(new_user_token)
|
||||||
|
|
||||||
|
# Выход из системы нового пользователя
|
||||||
|
new_mp.do_logout()
|
||||||
|
|
||||||
|
# Авторизация администратором
|
||||||
|
admin_lp = LoginPage(browser)
|
||||||
|
admin_lp.do_login()
|
||||||
|
|
||||||
|
# Переход на вкладку Пользователи
|
||||||
|
admin_mp = MainPage(browser)
|
||||||
|
admin_mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
admin_mp.click_subpanel_item("Пользователи")
|
||||||
|
|
||||||
|
# Удаление пользователя
|
||||||
|
admin_ut = UsersTab(browser)
|
||||||
|
admin_ut.open_edit_user_page_by_user(user_data["name"], user_data["role"])
|
||||||
|
admin_ut.delete_user(user_data["name"])
|
||||||
|
|
||||||
|
# Переход на вкладку Сеансы
|
||||||
|
admin_mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
admin_mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
admin_mp.click_subpanel_item("Обслуживание и диагностика")
|
||||||
|
admin_mp.click_subpanel_item("Сеансы")
|
||||||
|
|
||||||
|
# Проверка отсутствия сессии после удаления пользователя
|
||||||
|
admin_sessions_tab = SessionsTab(browser)
|
||||||
|
admin_sessions_tab.should_be_sessions_table()
|
||||||
|
|
||||||
|
# Сессия должна автоматически удалиться при удалении пользователя
|
||||||
|
admin_sessions_tab.should_not_be_session_in_table(new_user_token)
|
||||||
|
|
||||||
|
@pytest.mark.skip(reason="Требует настройки таймера очистки сеансов")
|
||||||
|
def test_session_auto_deletion_after_15_minutes(self, browser: Page, cleanup_users: None) -> None:
|
||||||
|
"""Тест автоматического удаления сеанса через 15 минут после выхода пользователя.
|
||||||
|
|
||||||
|
Проверяет:
|
||||||
|
1. Создание нового пользователя
|
||||||
|
2. Вход пользователя и создание сеанса
|
||||||
|
3. Выход пользователя из системы
|
||||||
|
4. Ожидание 15 минут
|
||||||
|
5. Проверка автоматического удаления сеанса по истечении времени
|
||||||
|
6. Удаление пользователя выполняется автоматически фикстурой cleanup_users
|
||||||
|
"""
|
||||||
|
user_data = {"name": "TestUserFor15MinDeletion", "role": "Администратор", "password": "qwerty123"}
|
||||||
|
|
||||||
|
mp = MainPage(browser)
|
||||||
|
ut = UsersTab(browser)
|
||||||
|
|
||||||
|
# Создание нового пользователя
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
ut.open_add_user_window()
|
||||||
|
ut.add_new_user(user_data)
|
||||||
|
|
||||||
|
# Обновление списка пользователей
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
|
||||||
|
# Проверка наличия пользователя в таблице
|
||||||
|
ut.should_be_user_in_table(user_data["name"], user_data["role"])
|
||||||
|
|
||||||
|
# Вход в систему для нового пользователя
|
||||||
|
new_lp = LoginPage(browser)
|
||||||
|
new_lp.do_login(username=user_data["name"], password=user_data["password"])
|
||||||
|
|
||||||
|
# Получение токена сессии нового пользователя
|
||||||
|
new_mp = MainPage(browser)
|
||||||
|
|
||||||
|
# Открыть вкладку Сессии
|
||||||
|
new_mp.should_be_navigation_panel()
|
||||||
|
new_mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
new_mp.click_subpanel_item("Обслуживание и диагностика")
|
||||||
|
new_mp.click_subpanel_item("Сеансы")
|
||||||
|
|
||||||
|
# Получаем токен сессии
|
||||||
|
sessions_tab = SessionsTab(browser)
|
||||||
|
session_token = sessions_tab.get_session_token()
|
||||||
|
|
||||||
|
# Проверка наличия сессии в таблице
|
||||||
|
sessions_tab.should_be_session_in_table(session_token)
|
||||||
|
|
||||||
|
# Выход из системы нового пользователя
|
||||||
|
new_mp.do_logout()
|
||||||
|
|
||||||
|
# Авторизация администратором
|
||||||
|
admin_lp = LoginPage(browser)
|
||||||
|
admin_lp.do_login()
|
||||||
|
|
||||||
|
# Переход на вкладку Сеансы
|
||||||
|
admin_mp = MainPage(browser)
|
||||||
|
admin_mp.should_be_navigation_panel()
|
||||||
|
admin_mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
admin_mp.click_subpanel_item("Обслуживание и диагностика")
|
||||||
|
admin_mp.click_subpanel_item("Сеансы")
|
||||||
|
|
||||||
|
# Проверка наличия сессии сразу после выхода
|
||||||
|
admin_sessions_tab = SessionsTab(browser)
|
||||||
|
admin_sessions_tab.should_be_session_in_table(session_token)
|
||||||
|
|
||||||
|
admin_mp.do_logout()
|
||||||
|
|
||||||
|
# Ожидание 15 минут 1 секунда (901 секунд)
|
||||||
|
print("Ожидание 15 минут для автоматического удаления сеанса...")
|
||||||
|
browser.wait_for_timeout(901000) # 15 минут 1 секунда в миллисекундах
|
||||||
|
|
||||||
|
# Авторизация администратором
|
||||||
|
admin_lp = LoginPage(browser)
|
||||||
|
admin_lp.do_login()
|
||||||
|
|
||||||
|
# Повторный переход на вкладку Сеансы после обновления
|
||||||
|
admin_mp = MainPage(browser)
|
||||||
|
admin_mp.should_be_navigation_panel()
|
||||||
|
admin_mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
admin_mp.click_subpanel_item("Обслуживание и диагностика")
|
||||||
|
admin_mp.click_subpanel_item("Сеансы")
|
||||||
|
|
||||||
|
# Проверка отсутствия сессии после 15 минут
|
||||||
|
admin_sessions_tab = SessionsTab(browser)
|
||||||
|
admin_sessions_tab.should_be_sessions_table()
|
||||||
|
admin_sessions_tab.should_not_be_session_in_table(session_token)
|
||||||
|
|
||||||
|
# Удаление пользователя выполняется автоматически фикстурой cleanup_users после теста
|
||||||
|
|
||||||
|
@pytest.mark.skip(reason="Не реализован разработчиком, требует проверки бизнес-логики")
|
||||||
|
def test_user_cannot_delete_own_session(self, browser: Page, cleanup_users: None) -> None:
|
||||||
|
"""Тест проверки невозможности пользователя удалить свой собственный сеанс.
|
||||||
|
Проверяет:
|
||||||
|
1. Создание нового пользователя
|
||||||
|
2. Вход пользователя и создание сеанса
|
||||||
|
3. Попытку удаления своего собственного сеанса
|
||||||
|
4. Проверку, что кнопка удаления недоступна или скрыта
|
||||||
|
5. Удаление пользователя выполняется автоматически фикстурой cleanup_users
|
||||||
|
"""
|
||||||
|
user_data = {"name": "TestUserForSelfDeletion", "role": "Администратор", "password": "qwerty123"}
|
||||||
|
|
||||||
|
mp = MainPage(browser)
|
||||||
|
ut = UsersTab(browser)
|
||||||
|
|
||||||
|
# Создание нового пользователя
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
ut.open_add_user_window()
|
||||||
|
ut.add_new_user(user_data)
|
||||||
|
|
||||||
|
# Обновление списка пользователей
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
mp.click_subpanel_item("Пользователи")
|
||||||
|
|
||||||
|
# Проверка наличия пользователя в таблице
|
||||||
|
ut.should_be_user_in_table(user_data["name"], user_data["role"])
|
||||||
|
|
||||||
|
# Вход в систему для нового пользователя
|
||||||
|
new_lp = LoginPage(browser)
|
||||||
|
new_lp.do_login(username=user_data["name"], password=user_data["password"])
|
||||||
|
|
||||||
|
# Переход на вкладку Сеансы
|
||||||
|
new_mp = MainPage(browser)
|
||||||
|
new_mp.should_be_navigation_panel()
|
||||||
|
new_mp.click_main_navigation_panel_item("Настройки")
|
||||||
|
new_mp.click_subpanel_item("Обслуживание и диагностика")
|
||||||
|
new_mp.click_subpanel_item("Сеансы")
|
||||||
|
|
||||||
|
# Получаем токен сессии
|
||||||
|
sessions_tab = SessionsTab(browser)
|
||||||
|
session_token = sessions_tab.get_session_token()
|
||||||
|
|
||||||
|
# Проверка наличия сессии в таблице
|
||||||
|
sessions_tab.should_be_session_in_table(session_token)
|
||||||
|
|
||||||
|
# Попытка найти кнопку удаления для своего сеанса
|
||||||
|
row_index = sessions_tab.find_session_in_table(session_token)
|
||||||
|
|
||||||
|
# Проверяем, что кнопка удаления либо отсутствует, либо неактивна
|
||||||
|
delete_button = sessions_tab.get_delete_session_button_from_row(row_index)
|
||||||
|
|
||||||
|
# Проверяем, что кнопка либо не видима, либо отключена
|
||||||
|
expect(delete_button).not_to_be_visible()
|
||||||
|
|
||||||
|
# Выход из системы
|
||||||
|
new_mp.do_logout()
|
||||||
|
|
||||||
|
# Удаление пользователя выполняется автоматически фикстурой cleanup_users после теста
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue