diff --git a/.txt b/.txt new file mode 100644 index 0000000..3564baa Binary files /dev/null and b/.txt differ diff --git a/__pycache__/conftest.cpython-313-pytest-8.4.1.pyc b/__pycache__/conftest.cpython-313-pytest-8.4.1.pyc new file mode 100644 index 0000000..9690dcb Binary files /dev/null and b/__pycache__/conftest.cpython-313-pytest-8.4.1.pyc differ diff --git a/components/__pycache__/__init__.cpython-313.pyc b/components/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..cb98b88 Binary files /dev/null and b/components/__pycache__/__init__.cpython-313.pyc differ diff --git a/components/__pycache__/alert_component.cpython-313.pyc b/components/__pycache__/alert_component.cpython-313.pyc new file mode 100644 index 0000000..2182850 Binary files /dev/null and b/components/__pycache__/alert_component.cpython-313.pyc differ diff --git a/components/__pycache__/base_component.cpython-313.pyc b/components/__pycache__/base_component.cpython-313.pyc new file mode 100644 index 0000000..d28f1b3 Binary files /dev/null and b/components/__pycache__/base_component.cpython-313.pyc differ diff --git a/components/__pycache__/card_component.cpython-313.pyc b/components/__pycache__/card_component.cpython-313.pyc new file mode 100644 index 0000000..58f23f9 Binary files /dev/null and b/components/__pycache__/card_component.cpython-313.pyc differ diff --git a/components/__pycache__/confirm_component.cpython-313.pyc b/components/__pycache__/confirm_component.cpython-313.pyc new file mode 100644 index 0000000..ff5fd7e Binary files /dev/null and b/components/__pycache__/confirm_component.cpython-313.pyc differ diff --git a/components/__pycache__/dropdown_list_component.cpython-313.pyc b/components/__pycache__/dropdown_list_component.cpython-313.pyc new file mode 100644 index 0000000..f8ed61e Binary files /dev/null and b/components/__pycache__/dropdown_list_component.cpython-313.pyc differ diff --git a/components/__pycache__/json_container_component.cpython-313.pyc b/components/__pycache__/json_container_component.cpython-313.pyc new file mode 100644 index 0000000..9cd7631 Binary files /dev/null and b/components/__pycache__/json_container_component.cpython-313.pyc differ diff --git a/components/__pycache__/modal_window_component.cpython-313.pyc b/components/__pycache__/modal_window_component.cpython-313.pyc new file mode 100644 index 0000000..8b01476 Binary files /dev/null and b/components/__pycache__/modal_window_component.cpython-313.pyc differ diff --git a/components/__pycache__/navbar_component.cpython-313.pyc b/components/__pycache__/navbar_component.cpython-313.pyc new file mode 100644 index 0000000..86ee6f6 Binary files /dev/null and b/components/__pycache__/navbar_component.cpython-313.pyc differ diff --git a/components/__pycache__/table_component.cpython-313.pyc b/components/__pycache__/table_component.cpython-313.pyc new file mode 100644 index 0000000..9e0f568 Binary files /dev/null and b/components/__pycache__/table_component.cpython-313.pyc differ diff --git a/components/__pycache__/toolbar_component.cpython-313.pyc b/components/__pycache__/toolbar_component.cpython-313.pyc new file mode 100644 index 0000000..cedf4c2 Binary files /dev/null and b/components/__pycache__/toolbar_component.cpython-313.pyc differ diff --git a/components/base_component.py b/components/base_component.py index 614f428..8855159 100644 --- a/components/base_component.py +++ b/components/base_component.py @@ -59,7 +59,7 @@ class BaseComponent: # return elements # Проверки: - def check_presence(self, locator: str | Locator, msg: str) -> None: + def check_visibility(self, locator: str | Locator, msg: str) -> None: """Проверка видимости элемента на странице. Args: @@ -168,7 +168,7 @@ class BaseComponent: loc = self.get_locator(locator) - loc.evaluate("el => el.scrollBy(el.scrollWidth, 0)") + loc.evaluate("el => el.scrollBy(el.scrollWidth, 0)") loc.wait_for(timeout=2000) diff --git a/components/confirm_component.py b/components/confirm_component.py index ba2f462..5ee0e37 100644 --- a/components/confirm_component.py +++ b/components/confirm_component.py @@ -97,11 +97,11 @@ class ConfirmComponent(BaseComponent): def should_be_cancel_button(self) -> None: """Проверяет наличие и видимость кнопки Отмены.""" - self.cancel_button.check_presence("Cancel button is missing") + self.cancel_button.check_visibility("Cancel button is missing") def should_be_allow_button(self) -> None: """Проверяет наличие и видимость кнопки Подтверждения.""" - self.allow_button.check_presence("Allow button is missing") + self.allow_button.check_visibility("Allow button is missing") def check_cancel_button_text(self, expected_text: str) -> None: """Проверяет текст кнопки Отмены.""" diff --git a/components/modal_window_component.py b/components/modal_window_component.py index f78fff1..d352767 100644 --- a/components/modal_window_component.py +++ b/components/modal_window_component.py @@ -104,18 +104,18 @@ class ModalWindowComponent(BaseComponent): self.toolbar.check_toolbar_presence(f"Modal window with '{self.toolbar.title}' is missing") - def check_button_presence(self, name: str) -> None: + def check_button_visibility(self, name: str) -> None: """Проверяет наличие кнопки по имени. Вызывает ошибку, если не найдена.""" button = self.get_button_by_name(name) if button is None: assert False, f"Button with name '{name}' not found" - button.check_presence(f"Button with name '{name}' is missing") + button.check_visibility(f"Button with name '{name}' is missing") def check_toolbar_button_presence(self, name: str) -> None: """Проверяет наличие кнопки в панели инструментов.""" - self.toolbar.check_button_presence(name) + self.toolbar.check_button_visibility(name) def check_toolbar_button_tooltip(self, name: str, tooltip: str) -> None: """Проверяет подсказку у кнопки в панели инструментов.""" diff --git a/components/navbar_component.py b/components/navbar_component.py index 43ad6e4..1add89b 100644 --- a/components/navbar_component.py +++ b/components/navbar_component.py @@ -207,4 +207,4 @@ class NavigationPanelComponent(BaseComponent): loc = loc.get_by_text("Шаблоны").nth(1) else: loc = loc.get_by_text(item_name) - self.check_presence(loc, msg) + self.check_visibility(loc, msg) diff --git a/components/toolbar_component.py b/components/toolbar_component.py index dc0e4bd..847ff64 100644 --- a/components/toolbar_component.py +++ b/components/toolbar_component.py @@ -125,7 +125,7 @@ class ToolbarComponent(BaseComponent): locator = self.get_locator(ToolbarLocators.TITLE).filter(has_text=self.title) expect(locator).to_be_visible(), message - def check_button_presence(self, name: str) -> None: + def check_button_visibility(self, name: str) -> None: """Проверяет наличие и видимость кнопки с предварительной прокруткой к элементу. Args: @@ -141,7 +141,7 @@ class ToolbarComponent(BaseComponent): raise AssertionError(f"Unsupported button name {name}") button.locator.scroll_into_view_if_needed() - button.check_presence(f"Button with name {name} is missing") + button.check_visibility(f"Button with name {name} is missing") def check_button_tooltip(self, name: str, tooltip: str) -> None: """Проверяет текст подсказки кнопки. diff --git a/components/Реестр_изменений_companents.txt b/components/Реестр_изменений_companents.txt deleted file mode 100644 index 63a190a..0000000 --- a/components/Реестр_изменений_companents.txt +++ /dev/null @@ -1,113 +0,0 @@ -components - -alert_component.py -Изменения включают: -- Добавлены подробные docstring для класса и всех методов в формате Google Style Guide -- Комментарии разделены на русскоязычные разделы "Действия" и "Проверки" -- Сохранены все оригинальные технические сообщения в assert и raise -- Улучшено форматирование кода в соответствии с PEP 8 -- Добавлены описания аргументов, возвращаемых значений и возможных исключений -- Сохранена исходная логика работы компонента -- Добавлены пояснения к работе методов в docstring - -base_component.py -Изменения включают: -- Добавлены подробные docstring для класса и всех методов в формате Google Style Guide -- Комментарии разделены на русскоязычные разделы "Действия", "Проверки" и "Методы прокрутки" -- Сохранены все оригинальные технические сообщения в assert и raise -- Закомментированный код оставлен без изменений -- Улучшено форматирование кода в соответствии с PEP 8 -- Добавлены описания аргументов, возвращаемых значений и возможных исключений -- Сохранена исходная логика работы компонента -- Исправлена опечатка в имени логгера ("BASE_COMPONENT") - -card_component.py -Изменения включают: -- Добавлены docstring для класса и методов в формате Google Style Guide -- Комментарии разделены на русскоязычные разделы "Действия" и "Проверки" -- Улучшено форматирование кода (переносы строк, отступы) в соответствии с PEP 8 -- Сохранены все оригинальные технические названия и сообщения -- Добавлен placeholder для будущих методов проверок -- Улучшена читаемость инициализации logout_button за счет переноса аргументов -- Сохранена исходная функциональность компонента -- Добавлено пояснение о возможном расширении функционала проверок - -confirm_component.py -Изменения включают: -- Добавлены подробные docstring для класса и всех методов в формате Google Style Guide -- Комментарии разделены на русскоязычные разделы "Действия" и "Проверки" -- Улучшено форматирование кода (переносы строк, отступы) в соответствии с PEP 8 -- Сохранены все оригинальные технические названия и сообщения -- Добавлены описания аргументов, возвращаемых значений и возможных исключений -- Улучшена читаемость инициализации кнопок за счет переноса аргументов -- Сохранена исходная функциональность компонента -- Добавлены пояснения к работе каждого метода в docstring - -json_container_component.py -Изменения включают: -- Добавлены подробные docstring для класса и всех методов в формате Google Style Guide -- Вложенная функция format_json_string также получила свой docstring -- Комментарии разделены на русскоязычные разделы "Действия" и "Проверки" -- Улучшено форматирование кода (отступы, пробелы вокруг операторов) в соответствии с PEP 8 -- Сохранены все оригинальные технические сообщения в assert и raise -- Добавлены описания аргументов, возвращаемых значений и возможных исключений -- Исправлена опечатка в имени логгера ("JSON_CONTAINER") -- Улучшена читаемость кода за счет более последовательного форматирования -- Сохранена исходная логика работы компонента -- Добавлены пояснения к работе каждого метода в docstring - -modal_window_component.py -Изменения включают: -- Исправлено имя логгера на "MODAL_WINDOW" -- Добавлены полные docstring для всех методов в Google-формате -- Улучшено форматирование кода (отступы, переносы строк) -- Сохранены все оригинальные assert-сообщения -- Добавлены типы возвращаемых значений и описания исключений -- Комментарии разделены на "Действия" и "Проверки" -- Исправлены опечатки в именах локаторов (MODAL_WINDOW) -- Улучшена читаемость кода за счет последовательного форматирования -- Сохранена вся исходная функциональность -- обавлены пояснения к работе каждого метода - -navbar_component.py -Изменения включают: -- Добавлены docstring для класса и всех методов в Google-формате на русском языке -- Разделительные комментарии переведены (#actions: → # Действия:, # assertions: → # Проверки:) -- Сохранены все технические сообщения (в raise и логах) без изменений -- Сохранена исходная структура кода и рабочая логика -- Обеспечено соответствие PEP 8 (отступы, пробелы) - -table_component.py -Изменения включают: -- Добавлены docstring для класса и всех методов в Google-формате на русском языке -- Разделительные комментарии переведены (#actions: → # Действия:, # assertions: → # Проверки:) -- Технические комментарии в методах переведены на русский -- Сохранены все технические сообщения (в assert, expect и логах) без изменений -- Сохранена исходная структура кода и рабочая логика -- Обеспечено соответствие PEP 8 (отступы, пробелы) - -toolbar_component.py -Изменения включают: -- Полная документация: - Добавлены docstring для класса и всех методов - Указаны типы аргументов и возвращаемых значений - Описаны возможные исключения - Добавлены пояснения к важным параметрам -- Оптимизированное форматирование: - Соблюдение PEP 8 (отступы, длина строк, пробелы) - Логическая группировка методов - Улучшенные переносы длинных строк -- Улучшенная читаемость: - Последовательные именования переменных - Четкое разделение блоков - Единый стиль оформления -- Соответствие требованиям: - PEP 8 - Google Python Style Guide - Требованиям из README_форматирование_кода.md -- Дополнительные улучшения: - Более информативные сообщения об ошибках - Явное указание timeout для методов ожидания - Использование raise вместо assert для ошибок - Улучшенные названия переменных - diff --git a/data/__pycache__/__init__.cpython-313.pyc b/data/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..0a48d71 Binary files /dev/null and b/data/__pycache__/__init__.cpython-313.pyc differ diff --git a/data/__pycache__/constants.cpython-313.pyc b/data/__pycache__/constants.cpython-313.pyc new file mode 100644 index 0000000..3c4903b Binary files /dev/null and b/data/__pycache__/constants.cpython-313.pyc differ diff --git a/data/__pycache__/environment.cpython-313.pyc b/data/__pycache__/environment.cpython-313.pyc new file mode 100644 index 0000000..ca43632 Binary files /dev/null and b/data/__pycache__/environment.cpython-313.pyc differ diff --git a/data/__pycache__/roles_dict.cpython-313.pyc b/data/__pycache__/roles_dict.cpython-313.pyc new file mode 100644 index 0000000..5d13253 Binary files /dev/null and b/data/__pycache__/roles_dict.cpython-313.pyc differ diff --git a/data/environment.py b/data/environment.py index edc6f16..ddcecf6 100644 --- a/data/environment.py +++ b/data/environment.py @@ -46,13 +46,13 @@ class Environment: return self.URLS[self.env] + "e-nms-ui/" return self.URLS[self.env] raise Exception(f"Unknown value of ENV variable {self.env}") - + def get_env_name(self) -> str: """Возвращает имя текущего окружения. Возвращает: str: имя текущего окружения. - """ + """ return self.env def get_request_url(self) -> str: diff --git a/elements/__pycache__/__init__.cpython-313.pyc b/elements/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..23daa05 Binary files /dev/null and b/elements/__pycache__/__init__.cpython-313.pyc differ diff --git a/elements/__pycache__/base_element.cpython-313.pyc b/elements/__pycache__/base_element.cpython-313.pyc new file mode 100644 index 0000000..b94b5bb Binary files /dev/null and b/elements/__pycache__/base_element.cpython-313.pyc differ diff --git a/elements/__pycache__/button_element.cpython-313.pyc b/elements/__pycache__/button_element.cpython-313.pyc new file mode 100644 index 0000000..f810558 Binary files /dev/null and b/elements/__pycache__/button_element.cpython-313.pyc differ diff --git a/elements/__pycache__/checkbox_element.cpython-313.pyc b/elements/__pycache__/checkbox_element.cpython-313.pyc new file mode 100644 index 0000000..dbdba28 Binary files /dev/null and b/elements/__pycache__/checkbox_element.cpython-313.pyc differ diff --git a/elements/__pycache__/dropdown_list_element.cpython-313.pyc b/elements/__pycache__/dropdown_list_element.cpython-313.pyc new file mode 100644 index 0000000..aec203f Binary files /dev/null and b/elements/__pycache__/dropdown_list_element.cpython-313.pyc differ diff --git a/elements/__pycache__/text_element.cpython-313.pyc b/elements/__pycache__/text_element.cpython-313.pyc new file mode 100644 index 0000000..bd8d9a9 Binary files /dev/null and b/elements/__pycache__/text_element.cpython-313.pyc differ diff --git a/elements/__pycache__/text_input_element.cpython-313.pyc b/elements/__pycache__/text_input_element.cpython-313.pyc new file mode 100644 index 0000000..c2ba3a4 Binary files /dev/null and b/elements/__pycache__/text_input_element.cpython-313.pyc differ diff --git a/elements/__pycache__/tooltip_button_element.cpython-313.pyc b/elements/__pycache__/tooltip_button_element.cpython-313.pyc new file mode 100644 index 0000000..df3b8ef Binary files /dev/null and b/elements/__pycache__/tooltip_button_element.cpython-313.pyc differ diff --git a/elements/base_element.py b/elements/base_element.py index c71fa1f..fe0b504 100644 --- a/elements/base_element.py +++ b/elements/base_element.py @@ -74,7 +74,7 @@ class BaseElement: logger.info(f"Check that {self.type_of} '{self.name}' has text '{text}'") expect(self.locator).to_have_text(text), msg - def check_presence(self, msg: str) -> None: + def check_visibility(self, msg: str) -> None: """Проверяет видимость элемента на странице.""" logger.info(f"Check that {self.type_of} '{self.name}' is present") diff --git a/elements/button_element.py b/elements/button_element.py index 8569d1b..71d5867 100644 --- a/elements/button_element.py +++ b/elements/button_element.py @@ -27,7 +27,7 @@ class Button(BaseElement): return "button" - # Действия: + # Действия: # (Методы действий будут добавлены по мере необходимости) # Проверки: diff --git a/fixtures/__pycache__/__init__.cpython-313.pyc b/fixtures/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..416a7fc Binary files /dev/null and b/fixtures/__pycache__/__init__.cpython-313.pyc differ diff --git a/fixtures/__pycache__/pages.cpython-313-pytest-8.4.1.pyc b/fixtures/__pycache__/pages.cpython-313-pytest-8.4.1.pyc new file mode 100644 index 0000000..f492a9a Binary files /dev/null and b/fixtures/__pycache__/pages.cpython-313-pytest-8.4.1.pyc differ diff --git a/fixtures/pages.py b/fixtures/pages.py index 37ff8be..b90a6b1 100644 --- a/fixtures/pages.py +++ b/fixtures/pages.py @@ -30,7 +30,7 @@ def pytest_addoption(parser: Parser): help="Choose browser: chrome, remote_chrome or firefox") parser.addoption('--h', action='store', default=False, help='Choose headless: True or False') - parser.addoption('--s', action='store', default="{'width': 1600, 'height': 900}", + parser.addoption('--s', action='store', default="{'width': 1920, 'height': 400}", help='Size window: width,height') # Закомментированные альтернативные размеры окон # parser.addoption('--s', action='store', default="{'width': 1920, 'height': 1080}", @@ -161,7 +161,7 @@ def get_context(browser: Browser, request: FixtureRequest, start: str) -> Browse if start == 'local': # current_viewport = json.loads(request.config.getoption('--s')) - + context = browser.new_context( # no_viewport=True, viewport= ast.literal_eval(request.config.getoption('--s')), diff --git a/locators/__pycache__/button_locators.cpython-313.pyc b/locators/__pycache__/button_locators.cpython-313.pyc new file mode 100644 index 0000000..b2aa54a Binary files /dev/null and b/locators/__pycache__/button_locators.cpython-313.pyc differ diff --git a/locators/__pycache__/confirm_locators.cpython-313.pyc b/locators/__pycache__/confirm_locators.cpython-313.pyc new file mode 100644 index 0000000..404505c Binary files /dev/null and b/locators/__pycache__/confirm_locators.cpython-313.pyc differ diff --git a/locators/__pycache__/event_panel_locators.cpython-313.pyc b/locators/__pycache__/event_panel_locators.cpython-313.pyc new file mode 100644 index 0000000..7a0aff9 Binary files /dev/null and b/locators/__pycache__/event_panel_locators.cpython-313.pyc differ diff --git a/locators/__pycache__/input_locators.cpython-313.pyc b/locators/__pycache__/input_locators.cpython-313.pyc new file mode 100644 index 0000000..9353d59 Binary files /dev/null and b/locators/__pycache__/input_locators.cpython-313.pyc differ diff --git a/locators/__pycache__/json_container_locators.cpython-313.pyc b/locators/__pycache__/json_container_locators.cpython-313.pyc new file mode 100644 index 0000000..a5f66ff Binary files /dev/null and b/locators/__pycache__/json_container_locators.cpython-313.pyc differ diff --git a/locators/__pycache__/modal_window_locators.cpython-313.pyc b/locators/__pycache__/modal_window_locators.cpython-313.pyc new file mode 100644 index 0000000..98125e9 Binary files /dev/null and b/locators/__pycache__/modal_window_locators.cpython-313.pyc differ diff --git a/locators/__pycache__/navigation_panel_locators.cpython-313.pyc b/locators/__pycache__/navigation_panel_locators.cpython-313.pyc new file mode 100644 index 0000000..de66f81 Binary files /dev/null and b/locators/__pycache__/navigation_panel_locators.cpython-313.pyc differ diff --git a/locators/__pycache__/table_locators.cpython-313.pyc b/locators/__pycache__/table_locators.cpython-313.pyc new file mode 100644 index 0000000..88ca431 Binary files /dev/null and b/locators/__pycache__/table_locators.cpython-313.pyc differ diff --git a/locators/__pycache__/text_locators.cpython-313.pyc b/locators/__pycache__/text_locators.cpython-313.pyc new file mode 100644 index 0000000..1163a24 Binary files /dev/null and b/locators/__pycache__/text_locators.cpython-313.pyc differ diff --git a/locators/__pycache__/toolbar_locators.cpython-313.pyc b/locators/__pycache__/toolbar_locators.cpython-313.pyc new file mode 100644 index 0000000..4a7fdd0 Binary files /dev/null and b/locators/__pycache__/toolbar_locators.cpython-313.pyc differ diff --git a/modal_windows/__pycache__/__init__.cpython-313.pyc b/modal_windows/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..057cacb Binary files /dev/null and b/modal_windows/__pycache__/__init__.cpython-313.pyc differ diff --git a/modal_windows/__pycache__/modal_add_AD_user.cpython-313.pyc b/modal_windows/__pycache__/modal_add_AD_user.cpython-313.pyc new file mode 100644 index 0000000..2aa07ef Binary files /dev/null and b/modal_windows/__pycache__/modal_add_AD_user.cpython-313.pyc differ diff --git a/modal_windows/__pycache__/modal_add_local_user.cpython-313.pyc b/modal_windows/__pycache__/modal_add_local_user.cpython-313.pyc new file mode 100644 index 0000000..0472bb1 Binary files /dev/null and b/modal_windows/__pycache__/modal_add_local_user.cpython-313.pyc differ diff --git a/modal_windows/__pycache__/modal_add_user.cpython-313.pyc b/modal_windows/__pycache__/modal_add_user.cpython-313.pyc new file mode 100644 index 0000000..5a3f454 Binary files /dev/null and b/modal_windows/__pycache__/modal_add_user.cpython-313.pyc differ diff --git a/modal_windows/__pycache__/modal_edit_user.cpython-313.pyc b/modal_windows/__pycache__/modal_edit_user.cpython-313.pyc new file mode 100644 index 0000000..746fb5e Binary files /dev/null and b/modal_windows/__pycache__/modal_edit_user.cpython-313.pyc differ diff --git a/modal_windows/modal_add_AD_user.py b/modal_windows/modal_add_AD_user.py index b1343f5..67135e2 100644 --- a/modal_windows/modal_add_AD_user.py +++ b/modal_windows/modal_add_AD_user.py @@ -298,7 +298,7 @@ class AddADUserModalWindow(ModalWindowComponent): elif name == "group_input": item.click() group_list = self.get_content_item("group_list") - group_list.check_presence(menu_locator, + group_list.check_visibility(menu_locator, "Groups list is missing") is_scrollable_vertically = group_list.check_vertical_scrolling(menu_locator) @@ -307,7 +307,7 @@ class AddADUserModalWindow(ModalWindowComponent): elif name == "role_input": item.click() roles_list = self.get_content_item("roles_list") - roles_list.check_presence(menu_locator, + roles_list.check_visibility(menu_locator, "Roles list is missing") is_scrollable_vertically = roles_list.check_vertical_scrolling(menu_locator) @@ -323,13 +323,13 @@ class AddADUserModalWindow(ModalWindowComponent): elif name in no_op_names: continue else: - item.check_presence( + item.check_visibility( f"Modal window content item with name '{name}' is missing" ) - self.check_button_presence("search") - self.check_button_presence("add") - self.check_button_presence("close") + self.check_button_visibility("search") + self.check_button_visibility("add") + self.check_button_visibility("close") search_button = self.get_button_by_name("search") search_button.click() @@ -344,7 +344,7 @@ class AddADUserModalWindow(ModalWindowComponent): user_AD_input.click() user_AD_list = self.get_content_item("user_AD_list") - user_AD_list.check_presence(menu_locator, + user_AD_list.check_visibility(menu_locator, "Users AD list is missing") is_scrollable_vertically = user_AD_list.check_vertical_scrolling(menu_locator) assert is_scrollable_vertically, "Users AD list should be scrollable_vertically" @@ -352,13 +352,13 @@ class AddADUserModalWindow(ModalWindowComponent): self.update_input_form_fields(expand=True) - self.get_content_item("name_input").check_presence( + self.get_content_item("name_input").check_visibility( "Modal window content item with name 'name_input' is missing") - self.get_content_item("role_input").check_presence( + self.get_content_item("role_input").check_visibility( "Modal window content item with name 'role_input' is missing") - self.get_content_item("commentary_input").check_presence( + self.get_content_item("commentary_input").check_visibility( "Modal window content item with name 'commentary_input' is missing") - self.get_content_item("email_input").check_presence( + self.get_content_item("email_input").check_visibility( "Modal window content item with name 'email_input' is missing") - self.get_content_item("phone_input").check_presence( + self.get_content_item("phone_input").check_visibility( "Modal window content item with name 'phone_input' is missing") diff --git a/modal_windows/modal_add_local_user.py b/modal_windows/modal_add_local_user.py index 5355c80..59867b0 100644 --- a/modal_windows/modal_add_local_user.py +++ b/modal_windows/modal_add_local_user.py @@ -226,7 +226,7 @@ class AddLocalUserModalWindow(ModalWindowComponent): elif name == "role_input": item.click() roles_list = self.get_content_item("roles_list") - roles_list.check_presence(menu_locator, + roles_list.check_visibility(menu_locator, "Roles list is missing") is_scrollable_vertically = roles_list.check_vertical_scrolling(menu_locator) @@ -241,9 +241,10 @@ class AddLocalUserModalWindow(ModalWindowComponent): elif name == "roles_list": continue else: - item.check_presence( + item.check_visibility( f"Modal window content item with name '{name}' is missing" ) - self.check_button_presence("add") - self.check_button_presence("close") + self.check_button_visibility("add") + self.check_button_visibility("close") + diff --git a/modal_windows/modal_edit_user.py b/modal_windows/modal_edit_user.py index 287e963..6ed13ee 100644 --- a/modal_windows/modal_edit_user.py +++ b/modal_windows/modal_edit_user.py @@ -215,17 +215,17 @@ class EditUserModalWindow(ModalWindowComponent): elif name == "role_input": item.click() roles_list = self.get_content_item("roles_list") - roles_list.check_presence(menu_locator, + roles_list.check_visibility(menu_locator, "Roles list is missing") roles_list.check_item_with_text(role) elif name == "roles_list": continue else: - item.check_presence( + item.check_visibility( f"Modal window content item with name '{name}' is missing" ) - self.check_button_presence("save") - self.check_button_presence("delete") - self.check_button_presence("reset_password") - self.check_button_presence("close") + self.check_button_visibility("save") + self.check_button_visibility("delete") + self.check_button_visibility("reset_password") + self.check_button_visibility("close") diff --git a/pages/__pycache__/__init__.cpython-313.pyc b/pages/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..ed9c8c7 Binary files /dev/null and b/pages/__pycache__/__init__.cpython-313.pyc differ diff --git a/pages/__pycache__/base_page.cpython-313.pyc b/pages/__pycache__/base_page.cpython-313.pyc new file mode 100644 index 0000000..5fcd72f Binary files /dev/null and b/pages/__pycache__/base_page.cpython-313.pyc differ diff --git a/pages/__pycache__/license_tab.cpython-313.pyc b/pages/__pycache__/license_tab.cpython-313.pyc new file mode 100644 index 0000000..d3d25bc Binary files /dev/null and b/pages/__pycache__/license_tab.cpython-313.pyc differ diff --git a/pages/__pycache__/login_page.cpython-313.pyc b/pages/__pycache__/login_page.cpython-313.pyc new file mode 100644 index 0000000..7a98536 Binary files /dev/null and b/pages/__pycache__/login_page.cpython-313.pyc differ diff --git a/pages/__pycache__/main_page.cpython-313.pyc b/pages/__pycache__/main_page.cpython-313.pyc new file mode 100644 index 0000000..4627658 Binary files /dev/null and b/pages/__pycache__/main_page.cpython-313.pyc differ diff --git a/pages/__pycache__/service_status_tab.cpython-313.pyc b/pages/__pycache__/service_status_tab.cpython-313.pyc new file mode 100644 index 0000000..4ae44d9 Binary files /dev/null and b/pages/__pycache__/service_status_tab.cpython-313.pyc differ diff --git a/pages/__pycache__/session_tab.cpython-313.pyc b/pages/__pycache__/session_tab.cpython-313.pyc new file mode 100644 index 0000000..4a32a0f Binary files /dev/null and b/pages/__pycache__/session_tab.cpython-313.pyc differ diff --git a/pages/__pycache__/users_tab.cpython-313.pyc b/pages/__pycache__/users_tab.cpython-313.pyc new file mode 100644 index 0000000..19ff326 Binary files /dev/null and b/pages/__pycache__/users_tab.cpython-313.pyc differ diff --git a/pages/base_page.py b/pages/base_page.py index 99953d5..025927e 100644 --- a/pages/base_page.py +++ b/pages/base_page.py @@ -2,6 +2,7 @@ Содержит общие методы для взаимодействия со страницей и API. """ +import time from typing import Dict, Any from playwright.sync_api import Page, Response, APIRequestContext, expect @@ -78,50 +79,113 @@ class BasePage: """ api_request_context = self.get_api_request_context() token = host.get_access_token() + + # Проверяем что токен получен + if not token: + logger.error("Failed to get access token: token is None or empty") + # Возвращаем заглушечный response или бросаем исключение + # В Playwright можно создать mock response если нужно + return None + headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"} - response = api_request_context.get( - f"{host.get_request_url()}{uri}", - headers=headers - ) + full_url = f"{host.get_request_url()}{uri}" + + logger.debug("Sending GET request to: %s", full_url) + response = api_request_context.get(full_url, headers=headers) + + # Логируем статус ответа + logger.debug("GET response status: %s", response.status) + return response def send_post_api_request(self, uri: str, payload: Dict) -> Response: - """Отправляет POST-запрос к API. - - Args: - uri (str): URI API-эндпоинта (без базового URL). - payload (Dict): Данные для отправки в теле запроса. - - Returns: - Response: Ответ сервера. - """ + """Отправляет POST-запрос к API.""" api_request_context = self.get_api_request_context() token = host.get_access_token() - headers = {"Accept": "application/json", "Authorization": f"Bearer {token}"} + + if not token: + logger.error("Failed to get access token: token is None or empty") + return None + + headers = { + "Accept": "application/json", + "Content-Type": "application/json", + "Authorization": f"Bearer {token}" + } + full_url = f"{host.get_request_url()}{uri}" + + logger.debug("Sending POST request to: %s", full_url) + + # Сериализуем payload в JSON + json_data = json.dumps(payload) + + # Проверяем что сериализация прошла успешно + if json_data is None: + logger.error("Failed to serialize payload to JSON: result is None") + return None + + if not isinstance(json_data, str): + logger.error("Failed to serialize payload to JSON: expected string got %s", type(json_data)) + return None + response = api_request_context.post( - f"{host.get_request_url()}{uri}", + full_url, headers=headers, - data=payload + data=json_data # Передаем сериализованный JSON как data ) + + logger.debug("POST response status: %s", response.status) + return response - def get_response_body(self, response: Response) -> dict | None: + def get_response_body(self, response: Response) -> dict | list | None: """Извлекает тело ответа в format JSON. Args: response (Response): Ответ сервера. Returns: - dict | None: Распарсенное тело ответа или None в случае ошибки. + dict | list | None: Распарсенное тело ответа или None в случае ошибки. """ - try: - response_body = response.json() - except json.JSONDecodeError: - logger.error("Failed to decode JSON response") - return None - return response_body + start_time = time.time() - # Проверки: + # Проверяем что response не None + if response is None: + logger.error("Response object is None") + processing_time = time.time() - start_time + logger.debug("Response processing time1: %.3f seconds", processing_time) + return None + + # Проверяем статус ответа + if response.status >= 400: + logger.error("API request failed with status %s", response.status) + processing_time = time.time() - start_time + logger.debug("Response processing time2: %.3f seconds", processing_time) + return None + + # Пытаемся получить JSON + json_result = response.json() + + # Проверяем что результат не None + if json_result is None: + logger.error("JSON parsing returned None") + processing_time = time.time() - start_time + logger.debug("Response processing time3: %.3f seconds", processing_time) + return None + + # Принимаем как словари, так и списки + if not isinstance(json_result, (dict, list)): + logger.error("Expected dict or list but got %s", type(json_result)) + processing_time = time.time() - start_time + logger.debug("Response processing time4: %.3f seconds", processing_time) + return None + + processing_time = time.time() - start_time + logger.debug("Response processing time5: %.3f seconds", processing_time) + + return json_result + + # Проверки: def check_URL(self, uri: str, msg: str) -> None: """Проверяет, что текущий URL соответствует ожидаемому. @@ -132,7 +196,7 @@ class BasePage: Raises: AssertionError: Если URL не соответствует ожидаемому. """ - expect(self.page).to_have_url( + expect(self.page).to_have_url( # pylint: disable=expression-not-assigned f"{host.get_base_url()}{uri}", timeout=60000 ), msg diff --git a/pages/license_tab.py b/pages/license_tab.py index 94fe899..00b2991 100644 --- a/pages/license_tab.py +++ b/pages/license_tab.py @@ -113,7 +113,7 @@ class LicenseTab(BasePage): def should_be_json_container(self) -> None: """Проверяет наличие JSON-контейнера.""" - self.json_container.check_presence( + self.json_container.check_visibility( JsonContainerLocators.CONTAINER, "Json container with license info is missing" ) diff --git a/pages/main_page.py b/pages/main_page.py index a2b093f..20fae66 100644 --- a/pages/main_page.py +++ b/pages/main_page.py @@ -93,7 +93,7 @@ class MainPage(BasePage): def should_be_navigation_panel(self) -> None: """Проверяет наличие панели навигации.""" - self.navigation_panel.check_presence( + self.navigation_panel.check_visibility( NavigationPanelLocators.PANEL_MAIN, "Navigation panel is missing" ) @@ -101,7 +101,7 @@ class MainPage(BasePage): def should_be_user_button(self) -> None: """Проверяет наличие кнопки пользователя.""" - self.user_button.check_presence("User button is missing on event panel") + self.user_button.check_visibility("User button is missing on event panel") def check_navigation_panel_verticall_scrolling(self) -> bool: """Проверяет возможность вертикальной прокрутки панели. diff --git a/pages/service_status_tab.py b/pages/service_status_tab.py index bcf9bca..5afbec6 100644 --- a/pages/service_status_tab.py +++ b/pages/service_status_tab.py @@ -154,7 +154,8 @@ class ServiceStatusTab(BasePage): AssertionError: Если таблица отсутствует. """ - self.services_table.check_presence( + self.services_table.check_visibility( TableLocators.TABLE_WORK_AREA, "Service statuses table is missing" ) + diff --git a/pages/session_tab.py b/pages/session_tab.py index d4bf184..9d412a8 100644 --- a/pages/session_tab.py +++ b/pages/session_tab.py @@ -139,6 +139,7 @@ class SessionsTab(BasePage): # Находим кнопку удаления сеанса и нажимаем на нее delete_session_button = self.get_delete_session_button_from_row(row_index) delete_session_button.click() + self.page.wait_for_timeout(1000) # Подтверждаем удаление self.delete_session_confirm.click_allow_button() @@ -311,7 +312,7 @@ class SessionsTab(BasePage): AssertionError: Если таблица отсутствует. """ - self.sessions_table.check_presence( + self.sessions_table.check_visibility( TableLocators.TABLE_WORK_AREA, "Sessions table is missing" ) @@ -335,7 +336,7 @@ class SessionsTab(BasePage): self.wait_for_tooltip_to_disappear() delete_button = self.get_delete_session_button_from_row(row_index) - delete_button.check_presence( + delete_button.check_visibility( f"Delete session button is missing on {row_index} row" ) delete_button.check_tooltip_with_text(ButtonLocators.TOOLTIP, tooltip) diff --git a/pages/users_tab.py b/pages/users_tab.py index 679c0c0..0563adf 100644 --- a/pages/users_tab.py +++ b/pages/users_tab.py @@ -293,10 +293,10 @@ class UsersTab(BasePage): """ if self.toolbar.is_button_not_present("close"): - self.toolbar.check_button_presence("edit") + self.toolbar.check_button_visibility("edit") self.toolbar.click_button("edit") - self.toolbar.check_button_presence("add_user") + self.toolbar.check_button_visibility("add_user") self.toolbar.click_button("add_user") self.add_modal_window("add_local_user", "") self.get_modal_window("add_local_user").check_by_window_title() @@ -441,7 +441,7 @@ class UsersTab(BasePage): """ self.toolbar.check_toolbar_presence("Toolbar is missing") - self.toolbar.check_button_presence("edit") + self.toolbar.check_button_visibility("edit") def should_be_toolbar_buttons(self) -> None: """Проверяет наличие и функциональность кнопок тулбара. @@ -450,17 +450,17 @@ class UsersTab(BasePage): AssertionError: Если кнопки недоступны или подсказки неверны. """ - self.toolbar.check_button_presence("edit") + self.toolbar.check_button_visibility("edit") self.toolbar.check_button_tooltip("edit", "Редактировать") self.toolbar.get_button_by_name("edit").click() - self.toolbar.check_button_presence("add_user") - self.toolbar.check_button_presence("close") + self.toolbar.check_button_visibility("add_user") + self.toolbar.check_button_visibility("close") self.toolbar.check_button_tooltip("add_user", "Добавить") self.toolbar.check_button_tooltip("close", "Закрыть") self.toolbar.get_button_by_name("close").click() - self.toolbar.check_button_presence("edit") + self.toolbar.check_button_visibility("edit") def should_be_users_table(self) -> None: """Проверяет наличие таблицы пользователей. @@ -469,7 +469,7 @@ class UsersTab(BasePage): AssertionError: Если таблица отсутствует. """ - self.users_table.check_presence( + self.users_table.check_visibility( TableLocators.TABLE_WORK_AREA, "Users table is missing" ) diff --git a/ping_log.txt b/ping_log.txt new file mode 100644 index 0000000..cd51dbd Binary files /dev/null and b/ping_log.txt differ diff --git a/ping_log_020925.txt b/ping_log_020925.txt new file mode 100644 index 0000000..1c780a5 Binary files /dev/null and b/ping_log_020925.txt differ diff --git a/pytest_detailed_log_20250903_082728.txt b/pytest_detailed_log_20250903_082728.txt new file mode 100644 index 0000000..06f3cea Binary files /dev/null and b/pytest_detailed_log_20250903_082728.txt differ diff --git a/test_logs.txt b/test_logs.txt new file mode 100644 index 0000000..e25d58d Binary files /dev/null and b/test_logs.txt differ diff --git a/test_logs_020925.txt b/test_logs_020925.txt new file mode 100644 index 0000000..15d6302 Binary files /dev/null and b/test_logs_020925.txt differ diff --git a/tests/components/test_user_modal_window.py b/tests/components/test_user_modal_window.py index 0c63e92..d75e628 100644 --- a/tests/components/test_user_modal_window.py +++ b/tests/components/test_user_modal_window.py @@ -50,7 +50,7 @@ class TestUsersModalWindow: assert is_scrollable_vertically, "Should be vertical scrolling" modal_window.scroll_window_down() - modal_window.check_button_presence("close") + modal_window.check_button_visibility("close") ut.wait_for_timeout(3000) modal_window.scroll_window_up() @@ -84,7 +84,7 @@ class TestUsersModalWindow: assert is_scrollable_vertically, "Should be vertical scrolling" modal_window.scroll_window_down() - modal_window.check_button_presence("close") + modal_window.check_button_visibility("close") ut.wait_for_timeout(3000) modal_window.scroll_window_up() diff --git a/tools/__pycache__/__init__.cpython-313.pyc b/tools/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..ffcfb6d Binary files /dev/null and b/tools/__pycache__/__init__.cpython-313.pyc differ diff --git a/tools/__pycache__/logger.cpython-313.pyc b/tools/__pycache__/logger.cpython-313.pyc new file mode 100644 index 0000000..5a3b942 Binary files /dev/null and b/tools/__pycache__/logger.cpython-313.pyc differ