"""Модуль тестов вкладки 'Сертификаты'. Содержит тесты для проверки корректности отображения и функциональности элементов вкладки 'Сертификаты'. """ import string import ssl import random import os import json from datetime import datetime import jsondiff import pytest from playwright.sync_api import Page from pages.login_page import LoginPage from pages.main_page import MainPage from pages.certificates_tab import CertificatesTab # @pytest.mark.smoke class TestCertificatesTab: """Набор тестов для вкладки 'Обслуживание и диагностика/Сертификаты'. Проверяет корректность отображения и функциональность элементов вкладки 'Сертификаты'. """ @pytest.fixture(scope="function", autouse=True) def setup(self, browser: Page) -> None: """Фикстура для подготовки тестового окружения. Выполняет: 1. Авторизацию в системе 2. Переход на вкладку 'Сертификаты' через панель навигации """ # Авторизация в системе login_page = LoginPage(browser) login_page.do_login() # Инициализация главной страницы main_page = MainPage(browser) # Проверка и взаимодействие с элементами навигации main_page.should_be_navigation_panel() main_page.click_main_navigation_panel_item("Настройки") main_page.click_subpanel_item("Обслуживание и диагностика") main_page.click_subpanel_item("Сертификаты") # @pytest.mark.develop def test_certificates_tab_content(self, browser: Page) -> None: """Тест содержимого вкладки 'Сертификаты'. Проверяет: Наличие и корректность элементов интерфейса """ # Инициализация страницы certificates_tab = CertificatesTab(browser) # Проверка элементов интерфейса certificates_tab.check_content() # @pytest.mark.develop def test_certificates_tab_check_viewed_certificate(self, browser: Page) -> None: """Проверка соответствия выводимого сертификата информации из базы данных.""" # Инициализация страницы certificates_tab = CertificatesTab(browser) certificates_tab.click_certificate_tab_button() viewed_certificate = certificates_tab.get_certificate() db_certificate_response = certificates_tab.send_get_api_request("api/certs/infoCert") if db_certificate_response.status == 200: response_body = certificates_tab.get_response_body(db_certificate_response) if response_body: response_body_json = json.dumps(response_body, ensure_ascii=False) viewed_certificate_json = json.dumps(viewed_certificate, ensure_ascii=False) diff = jsondiff.diff(response_body_json, viewed_certificate_json, syntax='symmetric') assert len(diff) == 0, "Viewed certificate does not match the one taken from DB. DIFF is {diff}" # @pytest.mark.develop def test_certificates_tab_check_exported_certificate(self, browser: Page) -> None: """Проверка соответствия выводимого сертификата и содержимого экспортированного сертификата.""" # Инициализация страницы certificates_tab = CertificatesTab(browser) certificates_tab.click_certificate_tab_button() viewed_certificate = certificates_tab.get_certificate() cert_file = certificates_tab.export_certificate() try: exported_certificate = ssl._ssl._test_decode_cert(cert_file) except Exception as e: assert False, f"Error decoding certificate {cert_file}: {e}" else: self._compare_certificates(exported_certificate, viewed_certificate) finally: # Удаление экспортированного файла if os.path.exists(cert_file): os.remove(cert_file) # @pytest.mark.develop def test_certificates_tab_check_import_certificate_input(self, browser: Page) -> None: """Частичная проверка действий при импорте сертификата.""" password = "12345" # Инициализация страницы certificates_tab = CertificatesTab(browser) certificates_tab.click_import_tab_button() assert certificates_tab.is_import_button_disabled(), "Import certificate button should be disabled" certificates_tab.input_password_field(password) assert not certificates_tab.is_import_button_disabled(), "Import certificate button should be enabled" actual_password = certificates_tab.get_password_field_value() assert actual_password == password, \ f"Actual password input field value {actual_password} is not equal expected value {password}" # @pytest.mark.develop def test_certificates_tab_check_reissue_certificate_input(self, browser: Page) -> None: """Проверка заполнения полей при перевыпуске сертификата.""" input_values = {"CN":"Entcor-e", "O":"Entcor-e", "OU":"Entcor-e", "C":"RU", "ST":"Moscow", "L":"Moscow"} # Инициализация страницы certificates_tab = CertificatesTab(browser) certificates_tab.click_reissue_tab_button() assert certificates_tab.is_reissue_button_disabled(), "Reissue certificate button should be disabled" certificates_tab.input_identification_cert_name_field(input_values["CN"]) certificates_tab.input_identification_organization_field(input_values["O"]) certificates_tab.input_identification_org_unit_field(input_values["OU"]) certificates_tab.input_location_country_field(input_values["C"]) certificates_tab.input_location_state_field(input_values["ST"]) certificates_tab.input_location_city_field(input_values["L"]) assert not certificates_tab.is_reissue_button_disabled(), "Reissue certificate button should be enabled" actual_identification_fields_values = certificates_tab.get_identification_fields_values() actual_location_fields_values = certificates_tab.get_location_fields_values() val = actual_identification_fields_values.get("CN") assert val == input_values["CN"], \ f"Actual value for field 'CN' {val} is not equal expected {input_values['CN']}" val = actual_identification_fields_values.get("O") assert val == input_values["O"], \ f"Actual value for field 'O' {val} is not equal expected {input_values['O']}" val = actual_identification_fields_values.get("OU") assert val == input_values["OU"], \ f"Actual value for field 'OU' {val} is not equal expected {input_values['OU']}" val = actual_location_fields_values.get("C") assert val == input_values["C"], \ f"Actual value for field 'C' {val} is not equal expected {input_values['C']}" val = actual_location_fields_values.get("ST") assert val == input_values["ST"], \ f"Actual value for field 'ST' {val} is not equal expected {input_values['ST']}" val = actual_location_fields_values.get("L") assert val == input_values["L"], \ f"Actual value for field 'L' {val} is not equal expected {input_values['L']}" # @pytest.mark.develop def test_certificates_tab_check_reissue_certificate_input_incorrect(self, browser: Page) -> None: """Проверка некорректного заполнения полей при перевыпуске сертификата.""" # Инициализация страницы certificates_tab = CertificatesTab(browser) certificates_tab.click_reissue_tab_button() assert certificates_tab.is_reissue_button_disabled(), "Reissue certificate button should be disabled" cert_name = self._generate_random_string(65) certificates_tab.input_identification_cert_name_field(cert_name) certificates_tab.check_alert('error', 'Поле не может содержать более 64 \n символов') certificates_tab.input_location_country_field("R") certificates_tab.input_location_state_field("") certificates_tab.check_alert('error', 'Поле должно содержать 2 \n символа') # заменить на после перехода на новую версию # certificates_tab.check_alert('error', # 'Поле СТРАНА (С) должно \n содержать 2 символа') certificates_tab.input_location_country_field("RUS") location_fields_values = certificates_tab.get_location_fields_values() val = location_fields_values.get("C") assert val == "RU", "Field 'Country' should be only 2 characters long" assert certificates_tab.is_reissue_button_disabled(), "Reissue certificate button should be disabled" # @pytest.mark.develop @pytest.mark.skip(reason="Временно пока работает неправильно") def test_certificates_tab_check_reissue_certificate_input_mandatory_fields(self, browser: Page) -> None: """Проверка некорректного заполнения полей при перевыпуске сертификата.""" # Инициализация страницы certificates_tab = CertificatesTab(browser) certificates_tab.click_reissue_tab_button() assert certificates_tab.is_reissue_button_disabled(), "Reissue certificate button should be disabled" # Кнопка перевыпуска сертификата становится активной только после заполнения обязательных полей cert_name = self._generate_random_string(15) certificates_tab.input_identification_cert_name_field(cert_name) assert certificates_tab.is_reissue_button_disabled(), "Reissue certificate button should be disabled" org_name = self._generate_random_string(5) certificates_tab.input_identification_organization_field(org_name) assert certificates_tab.is_reissue_button_disabled(), "Reissue certificate button should be disabled" certificates_tab.input_location_country_field("RU") assert not certificates_tab.is_reissue_button_disabled(), "Reissue certificate button should be enabled" certificates_tab.input_identification_organization_field("") assert certificates_tab.is_reissue_button_disabled(), "Reissue certificate button should be disabled" org_name = self._generate_random_string(5) certificates_tab.input_identification_organization_field(org_name) assert not certificates_tab.is_reissue_button_disabled(), "Reissue certificate button should be enabled" # Вспомогательные функции def _compare_certificates(self, exported: dict, viewed: dict) -> None: """ Сравнение содержимого отображаемого сертификата и экпортированного """ fields = {"countryName":"C", "stateOrProvinceName":"ST", "localityName":"L", "organizationName":"O", "commonName":"CN"} version = "v" + str(exported["version"]) viewed_version = viewed["baseInfo"]["version"] assert viewed_version == version, \ f"Viewed certificate version {viewed_version} is not equal exported certificate version {version}" serial_number = exported["serialNumber"] viewed_serial_number = viewed["baseInfo"]["serialNumber"].upper() assert viewed_serial_number == serial_number, \ f"Viewed certificate serial number {viewed_serial_number} is not equal exported \ certificate serial number {serial_number}" not_before = exported["notBefore"] time_string = viewed["validity"]["notBefore"] datetime_object = datetime.fromisoformat(time_string.replace('Z', '+00:00' if not time_string.endswith('+00:00') else '')) viewed_not_before = datetime_object.strftime("%B %d %H:%M:%S %Y") + " GMT" assert viewed_version == version, \ f"Viewed certificate validity not before {viewed_not_before} is not equal exported certificate {not_before}" not_after = exported["notAfter"] time_string = viewed["validity"]["notAfter"] datetime_object = datetime.fromisoformat(time_string.replace('Z', '+00:00' if not time_string.endswith('+00:00') else '')) viewed_not_after = datetime_object.strftime("%B %d %H:%M:%S %Y") + " GMT" assert viewed_version == version, \ f"Viewed certificate validity not after {viewed_not_after} is not equal exported certificate {not_after}" count = len(exported["subject"]) for i in range(count): name = exported["subject"][i][0][0] field = fields.get(name) if field: val = exported["subject"][i][0][1] viewed_val = viewed["subject"][field] assert viewed_val == val, \ f"Viewed certificate field {field} value {viewed_val} is not equal exported certificate {val}" def _generate_random_string(self, length): # Набор символов: ascii_letters + digits (буквы и цифры) characters = string.ascii_letters + string.digits # Выбираем случайные символы length раз random_string = ''.join(random.choices(characters, k=length)) return random_string