Добавлены тесты для вкладки 'Сертификаты'
parent
384ee4e15e
commit
085d8c4ec7
|
|
@ -0,0 +1,39 @@
|
||||||
|
"""Модуль компонента тулбара (class=toolbar_castom).
|
||||||
|
|
||||||
|
Содержит класс ToolbarComponent для работы с элементами тулбара
|
||||||
|
- Проверка видимости элементов
|
||||||
|
"""
|
||||||
|
|
||||||
|
from playwright.sync_api import Page, expect
|
||||||
|
from tools.logger import get_logger
|
||||||
|
from locators.certificate_locators import CertificateLocators
|
||||||
|
from components.base_component import BaseComponent
|
||||||
|
|
||||||
|
logger = get_logger("TOOLBAR_CUSTOM")
|
||||||
|
|
||||||
|
class CustomToolbar(BaseComponent):
|
||||||
|
"""Класс для работы с информационным тулбаром на странице.
|
||||||
|
|
||||||
|
Наследует функциональность BaseComponent и добавляет специфичные
|
||||||
|
методы и проверки.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, page: Page) -> None:
|
||||||
|
"""Инициализирует компонент тулбара."""
|
||||||
|
|
||||||
|
super().__init__(page)
|
||||||
|
|
||||||
|
# Действия:
|
||||||
|
# (Методы действий будут добавлены по мере необходимости)
|
||||||
|
|
||||||
|
# Проверки:
|
||||||
|
def check_toolbar_presence(self, titles: list[str]) -> None:
|
||||||
|
"""Проверяет видимость тулбара.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
titles: Набор заголовков тулбара
|
||||||
|
"""
|
||||||
|
|
||||||
|
for title in titles:
|
||||||
|
locator = self.page.locator(f"{CertificateLocators.TOOLBAR_CASTOM}//span[contains(text(),'{title}')]")
|
||||||
|
expect(locator).to_be_visible(), f"Toolbar with title {title} is not visible"
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
"""Модуль контейнера для импорта сертификата во вкладке 'Сертификаты'.
|
||||||
|
|
||||||
|
Содержит класс для работы с формой для импорта
|
||||||
|
сертификата во вкладке 'Сертификаты' через Playwright.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from playwright.sync_api import Page, expect
|
||||||
|
from tools.logger import get_logger
|
||||||
|
from locators.certificate_locators import CertificateLocators
|
||||||
|
from elements.text_input_element import TextInput
|
||||||
|
from elements.text_element import Text
|
||||||
|
from elements.tooltip_button_element import TooltipButton
|
||||||
|
from components.toolbar_custom_component import CustomToolbar
|
||||||
|
from components.base_component import BaseComponent
|
||||||
|
|
||||||
|
logger = get_logger("IMPORT_CRTIFICATE_FORM")
|
||||||
|
|
||||||
|
|
||||||
|
class ImportCertificateForm(BaseComponent):
|
||||||
|
"""Компонент формы для импорта сертификата во вкладке 'Сертификаты'.
|
||||||
|
|
||||||
|
Предоставляет методы для взаимодействия с элементами
|
||||||
|
формы для импорта сертификата во вкладке 'Сертификаты'.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, page: Page):
|
||||||
|
"""Инициализирует компонент формы для импорта сертификата во вкладке 'Сертификаты'.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
page: Экземпляр страницы Playwright.
|
||||||
|
"""
|
||||||
|
|
||||||
|
super().__init__(page)
|
||||||
|
|
||||||
|
import_title_locator = page.locator(CertificateLocators.BLOCK_HEADER_TEXT). \
|
||||||
|
filter(has_text='Импорт CA (P12)')
|
||||||
|
self.import_title = Text(page, import_title_locator, "import_title")
|
||||||
|
|
||||||
|
button_locator = page.locator(CertificateLocators.BUTTON_IMPORT)
|
||||||
|
self.button_import = TooltipButton(page, button_locator, "button_import")
|
||||||
|
|
||||||
|
self.toolbar_info = CustomToolbar(page)
|
||||||
|
|
||||||
|
self.password_input = TextInput(page, CertificateLocators.FIELD_INPUT_PASSWORD,
|
||||||
|
"password_input_field")
|
||||||
|
|
||||||
|
# Действия:
|
||||||
|
def get_password_field_value(self) -> str:
|
||||||
|
"""Возвращает текущее значение поля 'Пароль'.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str : Текущее значение поля 'Пароль.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.password_input.get_input_value().strip()
|
||||||
|
|
||||||
|
def input_password_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Пароль'"""
|
||||||
|
|
||||||
|
self.password_input.clear()
|
||||||
|
self.password_input.input_value(value)
|
||||||
|
|
||||||
|
def _get_label_for_input_field(self, field_locator: str) -> str:
|
||||||
|
div_loc = f"//div[contains(@class, 'flex')][.{field_locator}]"
|
||||||
|
label = self.page.locator(div_loc).locator("//preceding-sibling::div[1]").locator("//input")
|
||||||
|
return label.input_value()
|
||||||
|
|
||||||
|
# Проверки:
|
||||||
|
def check_content(self):
|
||||||
|
"""Проверяет наличие и корректность всех элементов формы."""
|
||||||
|
|
||||||
|
self.import_title.check_visibility("Title 'Импорт CA (P12)' is missing")
|
||||||
|
|
||||||
|
self.button_import.check_visibility("Import certificate button is missing")
|
||||||
|
assert self.button_import.is_disabled(), "Import certificate button should be disabled"
|
||||||
|
self.button_import.check_tooltip_with_text("Импорт сертификата (CA)")
|
||||||
|
|
||||||
|
# Проверка информационного тулбара
|
||||||
|
self.toolbar_info.check_toolbar_presence(['Создание нового сертификата',
|
||||||
|
'Приведет к замене корневого сертификата системы'])
|
||||||
|
# проверка наличия всех полей формы
|
||||||
|
password_label = self._get_label_for_input_field(CertificateLocators.FIELD_INPUT_PASSWORD).strip()
|
||||||
|
assert password_label == 'Пароль', f"Unexpected field name {password_label} has got"
|
||||||
|
self.password_input.check_visibility("Field password input is missing")
|
||||||
|
|
||||||
|
info_loc = self.page.get_by_text("Пароль используется для расшифровки закрытого ключа в файле P12")
|
||||||
|
expect(info_loc).to_be_visible()
|
||||||
|
|
||||||
|
def is_import_button_disabled(self) -> bool:
|
||||||
|
"""Проверяет наличие и доступность кнопки перевыпуска сертификата."""
|
||||||
|
|
||||||
|
self.button_import.check_visibility("Import certificate button is missing")
|
||||||
|
return self.button_import.is_disabled()
|
||||||
|
|
@ -0,0 +1,172 @@
|
||||||
|
"""Модуль контейнера для пересоздания сертификата во вкладке 'Сертификаты'.
|
||||||
|
|
||||||
|
Содержит класс для работы с формой для пересоздания
|
||||||
|
сертификата во вкладке 'Сертификаты' через Playwright.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from playwright.sync_api import Page
|
||||||
|
from tools.logger import get_logger
|
||||||
|
from locators.certificate_locators import CertificateLocators
|
||||||
|
from elements.text_input_element import TextInput
|
||||||
|
from elements.text_element import Text
|
||||||
|
from elements.tooltip_button_element import TooltipButton
|
||||||
|
from components.toolbar_custom_component import CustomToolbar
|
||||||
|
from components.base_component import BaseComponent
|
||||||
|
|
||||||
|
logger = get_logger("REISSUE_CRTIFICATE_FORM")
|
||||||
|
|
||||||
|
|
||||||
|
class ReissueCertificateForm(BaseComponent):
|
||||||
|
"""Компонент формы для пересоздания сертификата во вкладке 'Сертификаты'.
|
||||||
|
|
||||||
|
Предоставляет методы для взаимодействия с элементами
|
||||||
|
формы для пересоздания сертификата во вкладке 'Сертификаты'.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, page: Page):
|
||||||
|
"""Инициализирует компонент формы для пересоздания сертификата во вкладке 'Сертификаты'.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
page: Экземпляр страницы Playwright.
|
||||||
|
"""
|
||||||
|
|
||||||
|
super().__init__(page)
|
||||||
|
|
||||||
|
button_locator = page.locator(CertificateLocators.FORM_CONTAINER).get_by_role("button")
|
||||||
|
self.button_reissue = TooltipButton(page, button_locator, "button_reissue")
|
||||||
|
|
||||||
|
self.toolbar_info = CustomToolbar(page)
|
||||||
|
|
||||||
|
# поля блока 'Идентификация CA'
|
||||||
|
identification_title_locator = page.locator(CertificateLocators.BLOCK_HEADER_TEXT). \
|
||||||
|
filter(has_text='Идентификация CA')
|
||||||
|
self.identification_title = Text(page, identification_title_locator, "identification_title")
|
||||||
|
self.identification_cert_name = TextInput(page, CertificateLocators.FIELD_INPUT_CERT_NAME,
|
||||||
|
"identification_cert_name_field")
|
||||||
|
self.identification_organization = TextInput(page, CertificateLocators.FIELD_INPUT_ORGANIZATION,
|
||||||
|
"identification_organization_field")
|
||||||
|
self.identification_org_unit = TextInput(page, CertificateLocators.FIELD_INPUT_ORG_UNIT,
|
||||||
|
"identification_org_unit_field")
|
||||||
|
|
||||||
|
# поля блока 'Адрес / Местонахождение'
|
||||||
|
location_title_locator = page.locator(CertificateLocators.BLOCK_HEADER_TEXT). \
|
||||||
|
filter(has_text='Адрес / Местонахождение')
|
||||||
|
self.location_title = Text(page, location_title_locator, "location_title")
|
||||||
|
self.location_country = TextInput(page, CertificateLocators.FIELD_INPUT_COUNTRY, "location_country_field")
|
||||||
|
self.location_state = TextInput(page, CertificateLocators.FIELD_INPUT_STATE, "location_state_field")
|
||||||
|
self.location_city = TextInput(page, CertificateLocators.FIELD_INPUT_LOC, "location_city_field")
|
||||||
|
|
||||||
|
# Действия:
|
||||||
|
def get_identification_fields_values(self) -> dict:
|
||||||
|
"""Возвращает текущее значение полей блока 'Идентификация CA'.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict : Текущее значение полей блока 'Идентификация CA'.
|
||||||
|
"""
|
||||||
|
|
||||||
|
values = {}
|
||||||
|
values.update({"CN": self.identification_cert_name.get_input_value().strip()})
|
||||||
|
values.update({"O": self.identification_organization.get_input_value().strip()})
|
||||||
|
values.update({"OU": self.identification_org_unit.get_input_value().strip()})
|
||||||
|
|
||||||
|
return values
|
||||||
|
|
||||||
|
def get_location_fields_values(self) -> dict:
|
||||||
|
"""Возвращает текущее значение полей блока 'Адрес / Местонахождение'.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict : Текущее значение полей блока блока 'Адрес / Местонахождение'.
|
||||||
|
"""
|
||||||
|
|
||||||
|
values = {}
|
||||||
|
values.update({"C": self.location_country.get_input_value().strip()})
|
||||||
|
values.update({"ST": self.location_state.get_input_value().strip()})
|
||||||
|
values.update({"L": self.location_city.get_input_value().strip()})
|
||||||
|
|
||||||
|
return values
|
||||||
|
|
||||||
|
def input_identification_cert_name_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Имя Сертификата' блока 'Идентификация CA'"""
|
||||||
|
|
||||||
|
self.identification_cert_name.clear()
|
||||||
|
self.identification_cert_name.input_value(value)
|
||||||
|
|
||||||
|
def input_identification_organization_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Организация' блока 'Идентификация CA'"""
|
||||||
|
|
||||||
|
self.identification_organization.clear()
|
||||||
|
self.identification_organization.input_value(value)
|
||||||
|
|
||||||
|
def input_identification_org_unit_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Подразделение' блока 'Идентификация CA'"""
|
||||||
|
|
||||||
|
self.identification_org_unit.clear()
|
||||||
|
self.identification_org_unit.input_value(value)
|
||||||
|
|
||||||
|
def input_location_country_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Страна' блока 'Адрес / Местонахождение'"""
|
||||||
|
|
||||||
|
self.location_country.clear()
|
||||||
|
self.location_country.input_value(value)
|
||||||
|
|
||||||
|
def input_location_state_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Регион / Область' блока 'Адрес / Местонахождение'"""
|
||||||
|
|
||||||
|
self.location_state.clear()
|
||||||
|
self.location_state.input_value(value)
|
||||||
|
|
||||||
|
def input_location_city_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Город' блока 'Адрес / Местонахождение'"""
|
||||||
|
|
||||||
|
self.location_city.clear()
|
||||||
|
self.location_city.input_value(value)
|
||||||
|
|
||||||
|
def _get_label_for_input_field(self, field_locator: str) -> str:
|
||||||
|
div_loc = f"//div[contains(@class, 'flex')][.{field_locator}]"
|
||||||
|
label = self.page.locator(div_loc).locator("//preceding-sibling::div[1]").locator("//input")
|
||||||
|
return label.input_value()
|
||||||
|
|
||||||
|
# Проверки:
|
||||||
|
def check_content(self):
|
||||||
|
"""Проверяет наличие и корректность всех элементов формы."""
|
||||||
|
|
||||||
|
self.button_reissue.check_visibility("Reissue certificate button is missing")
|
||||||
|
assert self.button_reissue.is_disabled(), "Reissue certificate button should be disabled"
|
||||||
|
self.button_reissue.check_tooltip_with_text("Пересоздание сертификата (CA)")
|
||||||
|
|
||||||
|
# Проверка информационного тулбара
|
||||||
|
self.toolbar_info.check_toolbar_presence(['Создание нового сертификата',
|
||||||
|
'Приведет к замене корневого сертификата системы'])
|
||||||
|
# проверка наличия всех полей формы
|
||||||
|
self.identification_title.check_visibility("Title 'Идентификация CA' is missing")
|
||||||
|
|
||||||
|
cert_name_label = self._get_label_for_input_field(CertificateLocators.FIELD_INPUT_CERT_NAME).strip()
|
||||||
|
assert cert_name_label == 'ИМЯ СЕРТИФИКАТА (CN)', f"Unexpected field name {cert_name_label} has got"
|
||||||
|
self.identification_cert_name.check_visibility("Field certificate name input is missing")
|
||||||
|
|
||||||
|
organization_label = self._get_label_for_input_field(CertificateLocators.FIELD_INPUT_ORGANIZATION).strip()
|
||||||
|
assert organization_label == 'ОРГАНИЗАЦИЯ (О)', f"Unexpected field name {organization_label} has got"
|
||||||
|
self.identification_organization.check_visibility("Field organization input is missing")
|
||||||
|
|
||||||
|
org_unit_label = self._get_label_for_input_field(CertificateLocators.FIELD_INPUT_ORG_UNIT).strip()
|
||||||
|
assert org_unit_label == 'ПОДРАЗДЕЛЕНИЕ (OU)', f"Unexpected field name {org_unit_label} has got"
|
||||||
|
self.identification_org_unit.check_visibility("Field organization unit input is missing")
|
||||||
|
|
||||||
|
self.location_title.check_visibility("Title 'Адрес / Местонахождение' is missing")
|
||||||
|
|
||||||
|
country_label = self._get_label_for_input_field(CertificateLocators.FIELD_INPUT_COUNTRY).strip()
|
||||||
|
assert country_label == 'СТРАНА (С)', f"Unexpected field name {country_label} has got"
|
||||||
|
self.location_country.check_visibility("Field country input is missing")
|
||||||
|
|
||||||
|
state_label = self._get_label_for_input_field(CertificateLocators.FIELD_INPUT_STATE).strip()
|
||||||
|
assert state_label == 'РЕГИОН / ОБЛАСТЬ (ST)', f"Unexpected field name {state_label} has got"
|
||||||
|
self.location_state.check_visibility("Field state input is missing")
|
||||||
|
|
||||||
|
city_label = self._get_label_for_input_field(CertificateLocators.FIELD_INPUT_LOC).strip()
|
||||||
|
assert city_label == 'ГОРОД (l)', f"Unexpected field name {city_label} has got"
|
||||||
|
self.location_city.check_visibility("Field city input is missing")
|
||||||
|
|
||||||
|
def is_reissue_button_disabled(self) -> bool:
|
||||||
|
"""Проверяет доступность кнопки перевыпуска сертификата."""
|
||||||
|
|
||||||
|
return self.button_reissue.is_disabled()
|
||||||
|
|
@ -0,0 +1,267 @@
|
||||||
|
"""Модуль контейнера для отображения сертификата во вкладке 'Сертификаты'.
|
||||||
|
|
||||||
|
Содержит класс для работы с формой для отображения данных
|
||||||
|
сертификата во вкладке 'Сертификаты' через Playwright.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
from playwright.sync_api import Page
|
||||||
|
from tools.logger import get_logger
|
||||||
|
from locators.certificate_locators import CertificateLocators
|
||||||
|
from elements.text_input_element import TextInput
|
||||||
|
from elements.text_element import Text
|
||||||
|
from elements.tooltip_button_element import TooltipButton
|
||||||
|
from components.base_component import BaseComponent
|
||||||
|
|
||||||
|
logger = get_logger("VIEW_CRTIFICATE_FORM")
|
||||||
|
|
||||||
|
|
||||||
|
class ViewCertificateForm(BaseComponent):
|
||||||
|
"""Компонент формы для отображения данных сертификата во вкладке 'Сертификаты'.
|
||||||
|
|
||||||
|
Предоставляет методы для взаимодействия с элементами
|
||||||
|
формы для отображения данных сертификата во вкладке 'Сертификаты'.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, page: Page):
|
||||||
|
"""Инициализирует компонент формы для отображения данных сертификата во вкладке 'Сертификаты'.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
page: Экземпляр страницы Playwright.
|
||||||
|
"""
|
||||||
|
|
||||||
|
super().__init__(page)
|
||||||
|
|
||||||
|
button_locator = page.locator(CertificateLocators.FORM_CONTAINER).get_by_role("button")
|
||||||
|
self.button_export = TooltipButton(page, button_locator, "button_export")
|
||||||
|
|
||||||
|
# поля блока 'Основная информация'
|
||||||
|
base_info_title_locator = page.locator(CertificateLocators.BLOCK_HEADER_TEXT). \
|
||||||
|
filter(has_text='Основная информация')
|
||||||
|
self.base_info_title = Text(page, base_info_title_locator, "base_info_title")
|
||||||
|
|
||||||
|
self.base_info_version = TextInput(page, CertificateLocators.FIELD_VERSION, "base_info_version_field")
|
||||||
|
self.base_info_serial_number = TextInput(page, CertificateLocators.FIELD_SERIAL_NUMBER,
|
||||||
|
"base_info_serial_number_field")
|
||||||
|
self.base_info_signature_algorithm = TextInput(page, CertificateLocators.FIELD_SIGNATURE_ALGORITHM,
|
||||||
|
"base_info_signature_algorithm_field")
|
||||||
|
|
||||||
|
# поля блока 'Срок действия'
|
||||||
|
validity_title_locator = page.locator(CertificateLocators.BLOCK_HEADER_TEXT). \
|
||||||
|
filter(has_text='Срок действия')
|
||||||
|
self.validity_title = Text(page, validity_title_locator, "validity_title")
|
||||||
|
self.validity = TextInput(page, CertificateLocators.FIELD_VALIDITY, "validity_validity_field")
|
||||||
|
self.validity_not_before = TextInput(page, CertificateLocators.FIELD_NOT_BEFORE, "validity_not_before_field")
|
||||||
|
self.validity_not_after = TextInput(page, CertificateLocators.FIELD_NOT_AFTER, "validity_not_after_field")
|
||||||
|
|
||||||
|
# поля блока 'Издатель / Субъект'
|
||||||
|
subject_title_locator = page.locator(CertificateLocators.BLOCK_HEADER_TEXT). \
|
||||||
|
filter(has_text='Издатель / Субъект')
|
||||||
|
self.subject_title = Text(page, subject_title_locator, "subject_title")
|
||||||
|
self.subject_cert_name = TextInput(page, CertificateLocators.FIELD_CERT_NAME, "subject_cert_name_field")
|
||||||
|
self.subject_organization = TextInput(page, CertificateLocators.FIELD_ORGANIZATION,
|
||||||
|
"subject_organization_field")
|
||||||
|
self.subject_org_unit = TextInput(page, CertificateLocators.FIELD_ORG_UNIT, "subject_org_unit_field")
|
||||||
|
self.subject_country = TextInput(page, CertificateLocators.FIELD_COUNTRY, "subject_country_field")
|
||||||
|
self.subject_state = TextInput(page, CertificateLocators.FIELD_STATE, "subject_state_field")
|
||||||
|
self.subject_location = TextInput(page, CertificateLocators.FIELD_LOC, "subject_location_field")
|
||||||
|
|
||||||
|
# поля блока 'Ключ и отпечаток'
|
||||||
|
fingerprint_title_locator = page.locator(CertificateLocators.BLOCK_HEADER_TEXT). \
|
||||||
|
filter(has_text='Ключ и отпечаток')
|
||||||
|
self.fingerprint_title = Text(page, fingerprint_title_locator, "fingerprint_title")
|
||||||
|
self.fingerprint_public_key = TextInput(page, CertificateLocators.FIELD_PUBLIC_KEY_FINGERPRINT,
|
||||||
|
"fingerprint_public_key_field")
|
||||||
|
self.fingerprint_algorithm = TextInput(page, CertificateLocators.FIELD_ALGORITHM,
|
||||||
|
"fingerprint_algorithm_field")
|
||||||
|
self.fingerprint_key_size = TextInput(page, CertificateLocators.FIELD_KEY_SIZE,
|
||||||
|
"fingerprint_key_size_field")
|
||||||
|
|
||||||
|
# Действия:
|
||||||
|
def get_certificate(self) -> dict:
|
||||||
|
""" Возвращает значания полей отображаемого сертификата"""
|
||||||
|
|
||||||
|
certificate = {}
|
||||||
|
|
||||||
|
base_info_dict = {}
|
||||||
|
val = self.base_info_version.get_input_value().strip()
|
||||||
|
base_info_dict.update({"version": val})
|
||||||
|
val = self.base_info_serial_number.get_input_value().strip()
|
||||||
|
base_info_dict.update({"serialNumber": val})
|
||||||
|
val = self.base_info_signature_algorithm.get_input_value().strip()
|
||||||
|
base_info_dict.update({"signatureAlgorithm": val})
|
||||||
|
|
||||||
|
validity_dict = {}
|
||||||
|
val = self.validity.get_input_value().strip()
|
||||||
|
validity_dict.update({"status": val})
|
||||||
|
val = self.validity_not_before.get_input_value().strip()
|
||||||
|
validity_dict.update({"notBefore": val})
|
||||||
|
val = self.validity_not_after.get_input_value().strip()
|
||||||
|
validity_dict.update({"notAfter": val})
|
||||||
|
|
||||||
|
fingerprint_dict = {}
|
||||||
|
val = self.fingerprint_public_key.get_input_value().strip()
|
||||||
|
fingerprint_dict.update({"publicKeyFingerprint": val})
|
||||||
|
val = self.fingerprint_algorithm.get_input_value().strip()
|
||||||
|
fingerprint_dict.update({"algorithm": val})
|
||||||
|
val = self.fingerprint_key_size.get_input_value().strip()
|
||||||
|
fingerprint_dict.update({"keySize": int(val)})
|
||||||
|
|
||||||
|
subject_dict = {}
|
||||||
|
if self.subject_country.get_locator().count() != 0:
|
||||||
|
val = self.subject_country.get_input_value().strip()
|
||||||
|
subject_dict.update({"C": val})
|
||||||
|
if self.subject_state.get_locator().count() != 0:
|
||||||
|
val = self.subject_state.get_input_value().strip()
|
||||||
|
subject_dict.update({"ST": val})
|
||||||
|
if self.subject_location.get_locator().count() != 0:
|
||||||
|
val = self.subject_location.get_input_value().strip()
|
||||||
|
subject_dict.update({"L": val})
|
||||||
|
if self.subject_organization.get_locator().count() != 0:
|
||||||
|
val = self.subject_organization.get_input_value().strip()
|
||||||
|
subject_dict.update({"O": val})
|
||||||
|
if self.subject_org_unit.get_locator().count() != 0:
|
||||||
|
val = self.subject_org_unit.get_input_value().strip()
|
||||||
|
subject_dict.update({"OU": val})
|
||||||
|
if self.subject_cert_name.get_locator().count() != 0:
|
||||||
|
val = self.subject_cert_name.get_input_value().strip()
|
||||||
|
subject_dict.update({"CN": val})
|
||||||
|
|
||||||
|
certificate["baseInfo"] = base_info_dict
|
||||||
|
certificate["validity"] = validity_dict
|
||||||
|
certificate["fingerprint"] = fingerprint_dict
|
||||||
|
certificate["subject"] = subject_dict
|
||||||
|
|
||||||
|
return certificate
|
||||||
|
|
||||||
|
|
||||||
|
def export_certificate(self) -> str:
|
||||||
|
"""Нажатие кнопки 'Экспорт сертификата (CA)' в форме отображения сертификата и
|
||||||
|
скачивание текущего корневого сертификата.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str : Полный путь к скачанному файлу.
|
||||||
|
"""
|
||||||
|
|
||||||
|
path_to_download = Path.home() / "Downloads"
|
||||||
|
|
||||||
|
self.button_export.check_visibility("Export certificate button is missing")
|
||||||
|
|
||||||
|
with self.page.expect_download() as download_info:
|
||||||
|
self.button_export.click()
|
||||||
|
download = download_info.value
|
||||||
|
|
||||||
|
download_error = download.failure()
|
||||||
|
assert not download_error, f"Download certificate error: {download_error}"
|
||||||
|
|
||||||
|
file_to_download = os.path.join(path_to_download, download.suggested_filename)
|
||||||
|
download.save_as(file_to_download)
|
||||||
|
|
||||||
|
assert os.path.exists(file_to_download), f"The certificate file '{file_to_download}' not found"
|
||||||
|
assert os.path.getsize(file_to_download) > 0, f"The certificate file '{file_to_download}' is empty"
|
||||||
|
|
||||||
|
return file_to_download
|
||||||
|
|
||||||
|
|
||||||
|
def _get_label_for_input_field(self, field_locator: str) -> str:
|
||||||
|
div_loc = f"//div[contains(@class, 'flex')][.{field_locator}]"
|
||||||
|
label = self.page.locator(div_loc).locator("//preceding-sibling::div[1]").locator("//input")
|
||||||
|
return label.input_value()
|
||||||
|
|
||||||
|
# Проверки:
|
||||||
|
def check_content(self):
|
||||||
|
"""Проверяет наличие и корректность всех элементов формы."""
|
||||||
|
|
||||||
|
self.button_export.check_visibility("Export certificate button is missing")
|
||||||
|
self.button_export.check_tooltip_with_text("Экспорт сертификата CA")
|
||||||
|
|
||||||
|
# проверка наличия всех полей формы
|
||||||
|
self.base_info_title.check_visibility("Title 'Основная информация' is missing")
|
||||||
|
|
||||||
|
version_label = self._get_label_for_input_field(CertificateLocators.FIELD_VERSION).strip()
|
||||||
|
assert version_label == 'ВЕРСИЯ (Version)', f"Unexpected field name {version_label} has got"
|
||||||
|
self.base_info_version.check_visibility("Field version value is missing")
|
||||||
|
|
||||||
|
serial_number_label = self._get_label_for_input_field(CertificateLocators.FIELD_SERIAL_NUMBER).strip()
|
||||||
|
assert serial_number_label == 'СЕРИЙНЫЙ НОМЕР (Serial Number)',\
|
||||||
|
f"Unexpected field name {serial_number_label} has got"
|
||||||
|
self.base_info_serial_number.check_visibility("Field serial number value is missing")
|
||||||
|
|
||||||
|
signature_algorithm_label = self._get_label_for_input_field(CertificateLocators.FIELD_SIGNATURE_ALGORITHM). \
|
||||||
|
strip()
|
||||||
|
assert signature_algorithm_label == 'АЛГОРИТМ ПОДПИСИ (Signature Algorithm)',\
|
||||||
|
f"Unexpected field name {signature_algorithm_label} has got"
|
||||||
|
self.base_info_signature_algorithm.check_visibility("Field signature algorithm value is missing")
|
||||||
|
|
||||||
|
self.validity_title.check_visibility("Title 'Срок действия' is missing")
|
||||||
|
|
||||||
|
validity_label = self._get_label_for_input_field(CertificateLocators.FIELD_VALIDITY).strip()
|
||||||
|
assert validity_label == 'СТАТУС (Validity)',\
|
||||||
|
f"Unexpected field name {validity_label} has got"
|
||||||
|
self.validity.check_visibility("Field validity value is missing")
|
||||||
|
|
||||||
|
validity_not_before_label = self._get_label_for_input_field(CertificateLocators.FIELD_NOT_BEFORE).strip()
|
||||||
|
assert validity_not_before_label == 'ДЕЙСТВИТЕЛЕН С (Not Before)',\
|
||||||
|
f"Unexpected field name {validity_not_before_label} has got"
|
||||||
|
self.validity_not_before.check_visibility("Field validity not before value is missing")
|
||||||
|
|
||||||
|
validity_not_after_label = self._get_label_for_input_field(CertificateLocators.FIELD_NOT_AFTER).strip()
|
||||||
|
assert validity_not_after_label == 'ДЕЙСТВИТЕЛЕН ДО (Not After)',\
|
||||||
|
f"Unexpected field name {validity_not_after_label} has got"
|
||||||
|
self.validity_not_after.check_visibility("Field validity not after value is missing")
|
||||||
|
|
||||||
|
self.subject_title.check_visibility("Title 'Издатель / Субъект' is missing")
|
||||||
|
|
||||||
|
if self.page.locator(CertificateLocators.FIELD_CERT_NAME).count() != 0:
|
||||||
|
cert_name_label = self._get_label_for_input_field(CertificateLocators.FIELD_CERT_NAME).strip()
|
||||||
|
assert cert_name_label == 'ИМЯ СЕРТИФИКАТА (CN)',\
|
||||||
|
f"Unexpected field name {cert_name_label} has got"
|
||||||
|
self.subject_cert_name.check_visibility("Field certificate name value is missing")
|
||||||
|
|
||||||
|
if self.page.locator(CertificateLocators.FIELD_ORGANIZATION).count() != 0:
|
||||||
|
organization_label = self._get_label_for_input_field(CertificateLocators.FIELD_ORGANIZATION).strip()
|
||||||
|
assert organization_label == 'ОРГАНИЗАЦИЯ (О)',\
|
||||||
|
f"Unexpected field name {organization_label} has got"
|
||||||
|
self.subject_organization.check_visibility("Field organization value is missing")
|
||||||
|
|
||||||
|
if self.page.locator(CertificateLocators.FIELD_ORG_UNIT).count() != 0:
|
||||||
|
org_unit_label = self._get_label_for_input_field(CertificateLocators.FIELD_ORG_UNIT).strip()
|
||||||
|
assert org_unit_label == 'ПОДРАЗДЕЛЕНИЕ (OU)',\
|
||||||
|
f"Unexpected field name {org_unit_label} has got"
|
||||||
|
self.subject_org_unit.check_visibility("Field organization unit value is missing")
|
||||||
|
|
||||||
|
if self.page.locator(CertificateLocators.FIELD_COUNTRY).count() != 0:
|
||||||
|
country_label = self._get_label_for_input_field(CertificateLocators.FIELD_COUNTRY).strip()
|
||||||
|
assert country_label == 'СТРАНА (С)',\
|
||||||
|
f"Unexpected field name {country_label} has got"
|
||||||
|
self.subject_country.check_visibility("Field country value is missing")
|
||||||
|
|
||||||
|
if self.page.locator(CertificateLocators.FIELD_STATE).count() != 0:
|
||||||
|
state_label = self._get_label_for_input_field(CertificateLocators.FIELD_STATE).strip()
|
||||||
|
assert state_label == 'РЕГИОН / ОБЛАСТЬ (ST)',\
|
||||||
|
f"Unexpected field name {state_label} has got"
|
||||||
|
self.subject_state.check_visibility("Field state value is missing")
|
||||||
|
|
||||||
|
if self.page.locator(CertificateLocators.FIELD_LOC).count() != 0:
|
||||||
|
location_label = self._get_label_for_input_field(CertificateLocators.FIELD_LOC).strip()
|
||||||
|
assert location_label == 'ГОРОД (l)',\
|
||||||
|
f"Unexpected field name {location_label} has got"
|
||||||
|
self.subject_location.check_visibility("Field location value is missing")
|
||||||
|
|
||||||
|
self.fingerprint_title.check_visibility("Title 'Ключ и отпечаток' is missing")
|
||||||
|
|
||||||
|
public_key_label = self._get_label_for_input_field(CertificateLocators.FIELD_PUBLIC_KEY_FINGERPRINT).strip()
|
||||||
|
assert public_key_label == 'ПУБЛИЧНЫЙ ОТПЕЧАТОК (PublicKeyFingerprint)',\
|
||||||
|
f"Unexpected field name {public_key_label} has got"
|
||||||
|
self.fingerprint_public_key.check_visibility("Field public key value is missing")
|
||||||
|
|
||||||
|
algorithm_label = self._get_label_for_input_field(CertificateLocators.FIELD_ALGORITHM).strip()
|
||||||
|
assert algorithm_label == 'АЛГОРИТМ (Algorithm)',\
|
||||||
|
f"Unexpected field name {algorithm_label} has got"
|
||||||
|
self.fingerprint_algorithm.check_visibility("Field algorithm value is missing")
|
||||||
|
|
||||||
|
key_size_label = self._get_label_for_input_field(CertificateLocators.FIELD_KEY_SIZE).strip()
|
||||||
|
assert key_size_label == 'ДЛИНА КЛЮЧА (Key Size)',\
|
||||||
|
f"Unexpected field name {key_size_label} has got"
|
||||||
|
self.fingerprint_key_size.check_visibility("Field key size value is missing")
|
||||||
|
|
@ -31,4 +31,13 @@ class TabButton(BaseElement):
|
||||||
# (Методы действий будут добавлены по мере необходимости)
|
# (Методы действий будут добавлены по мере необходимости)
|
||||||
|
|
||||||
# Проверки:
|
# Проверки:
|
||||||
# (Методы проверок будут добавлены по мере необходимости)
|
def is_active(self) -> bool:
|
||||||
|
""" Проверяет является ли кнопка-tab активной """
|
||||||
|
|
||||||
|
tab_locator = self.get_locator()
|
||||||
|
attributes = tab_locator.get_attribute("class")
|
||||||
|
|
||||||
|
is_active_tab = False
|
||||||
|
if "v-tabs__item--active" in attributes:
|
||||||
|
is_active_tab = True
|
||||||
|
return is_active_tab
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
"""Модуль certificate_locators содержит локаторы элементов вкладки 'Сертификаты'.
|
||||||
|
|
||||||
|
Класс ToolbarLocators предоставляет XPath локаторы для взаимодействия
|
||||||
|
с элементами тулбара и всплывающими подсказками.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class CertificateLocators:
|
||||||
|
"""Локаторы элементов вкладки 'Сертификаты'.
|
||||||
|
|
||||||
|
Содержит XPath локаторы для поиска элементов.
|
||||||
|
"""
|
||||||
|
|
||||||
|
TOOLBAR_CASTOM = "//div[contains(@class, 'scrollarea__container')]//div[contains(@class,'toolbar_castom')]"
|
||||||
|
|
||||||
|
MAIN_CONTAINER = f"{TOOLBAR_CASTOM}/ancestor::div[4]"
|
||||||
|
MAIN_CONTAINER_HEADER = f"{MAIN_CONTAINER}//div[contains(@class, 'scrollarea__header')]"
|
||||||
|
MAIN_CONTAINER_BODY = f"{MAIN_CONTAINER}//div[contains(@class, 'scrollarea__body')]"
|
||||||
|
|
||||||
|
TAB_CERTIFICATE_CA = f"{MAIN_CONTAINER_HEADER}//a[contains(@class, 'v-tabs__item') and contains(.,'Сертификат CA')]"
|
||||||
|
TAB_REISSUE_CA = f"{MAIN_CONTAINER_HEADER}//a[contains(@class, 'v-tabs__item') and contains(., 'Пересоздание CA')]"
|
||||||
|
TAB_IMPORT_CA = f"{MAIN_CONTAINER_HEADER}//a[contains(@class, 'v-tabs__item') and contains(., 'import ca (p12)')]"
|
||||||
|
|
||||||
|
FORM_CONTAINER = f"{MAIN_CONTAINER_BODY}//div[contains(@class, 'scrollarea__body')]"
|
||||||
|
|
||||||
|
BLOCK_HEADER_TEXT = f"{FORM_CONTAINER}//span[@class='body-2']"
|
||||||
|
|
||||||
|
# поля блока 'Сертификат CA/Основная информация'
|
||||||
|
FIELD_VERSION = "//input[@data-testid='SERTIFICATES-CA__text-field__baseInfo.version']"
|
||||||
|
FIELD_SERIAL_NUMBER = "//input[@data-testid='SERTIFICATES-CA__text-field__baseInfo.serialNumber']"
|
||||||
|
FIELD_SIGNATURE_ALGORITHM = "//input[@data-testid='SERTIFICATES-CA__text-field__baseInfo.signatureAlgorithm']"
|
||||||
|
|
||||||
|
# поля блока 'Сертификат CA/Срок действия'
|
||||||
|
FIELD_VALIDITY = "//input[@data-testid='SERTIFICATES-CA__text-field__validity.status']"
|
||||||
|
FIELD_NOT_BEFORE = "//input[@data-testid='SERTIFICATES-CA__text-field__validity.notBefore']"
|
||||||
|
FIELD_NOT_AFTER = "//input[@data-testid='SERTIFICATES-CA__text-field__validity.notAfter']"
|
||||||
|
|
||||||
|
# поля блока 'Сертификат CA/Издатель / Субъект'
|
||||||
|
FIELD_CERT_NAME = "//input[@data-testid='SERTIFICATES-CA__text-field__subject.CN']"
|
||||||
|
FIELD_ORGANIZATION = "//input[@data-testid='SERTIFICATES-CA__text-field__subject.O']"
|
||||||
|
FIELD_ORG_UNIT = "//input[@data-testid='SERTIFICATES-CA__text-field__subject.OU']"
|
||||||
|
FIELD_COUNTRY = "//input[@data-testid='SERTIFICATES-CA__text-field__subject.C']"
|
||||||
|
FIELD_STATE = "//input[@data-testid='SERTIFICATES-CA__text-field__subject.ST']"
|
||||||
|
FIELD_LOC = "//input[@data-testid='SERTIFICATES-CA__text-field__subject.L']"
|
||||||
|
|
||||||
|
# поля блока 'Сертификат CA/Ключ и отпечаток'
|
||||||
|
FIELD_PUBLIC_KEY_FINGERPRINT = "//input[@data-testid='SERTIFICATES-CA__text-field__fingerprint.publicKeyFingerprint']"
|
||||||
|
FIELD_ALGORITHM = "//input[@data-testid='SERTIFICATES-CA__text-field__fingerprint.algorithm']"
|
||||||
|
FIELD_KEY_SIZE = "//input[@data-testid='SERTIFICATES-CA__text-field__fingerprint.keySize']"
|
||||||
|
|
||||||
|
# поля блока 'Пересоздание CA/Идентификация CA'
|
||||||
|
FIELD_INPUT_CERT_NAME = "//input[@data-testid='SERTIFICATES-REISSUE__text-field__publisher.cn']"
|
||||||
|
FIELD_INPUT_ORGANIZATION = "//input[@data-testid='SERTIFICATES-REISSUE__text-field__publisher.o']"
|
||||||
|
FIELD_INPUT_ORG_UNIT = "//input[@data-testid='SERTIFICATES-REISSUE__text-field__publisher.ou']"
|
||||||
|
|
||||||
|
# поля блока 'Пересоздание CA/Адрес / Местонахождение'
|
||||||
|
FIELD_INPUT_COUNTRY = "//input[@data-testid='SERTIFICATES-REISSUE__text-field__publisher.c']"
|
||||||
|
FIELD_INPUT_STATE = "//input[@data-testid='SERTIFICATES-REISSUE__text-field__publisher.st']"
|
||||||
|
FIELD_INPUT_LOC = "//input[@data-testid='SERTIFICATES-REISSUE__text-field__publisher.l']"
|
||||||
|
|
||||||
|
# поля блока 'Импорт CA'
|
||||||
|
FIELD_INPUT_PASSWORD = "//input[@data-testid='SERTIFICATES-IMPORT__text-field__pass']"
|
||||||
|
BUTTON_IMPORT = "//button[@data-testid='SERTIFICATES-IMPORT__btn__upload_p12']"
|
||||||
|
|
||||||
|
|
@ -0,0 +1,178 @@
|
||||||
|
"""Модуль вкладки 'Сертификаты'.
|
||||||
|
|
||||||
|
Содержит класс CertificatesTab для работы с вкладкой 'Сертификаты'.
|
||||||
|
Позволяет проверять состояние и взаимодействовать с элементами вкладки.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from playwright.sync_api import Page
|
||||||
|
from locators.certificate_locators import CertificateLocators
|
||||||
|
from elements.tab_button_element import TabButton
|
||||||
|
from components.toolbar_custom_component import CustomToolbar
|
||||||
|
from components.alert_component import AlertComponent
|
||||||
|
from components_derived.view_certificate_form import ViewCertificateForm
|
||||||
|
from components_derived.reissue_certificate_form import ReissueCertificateForm
|
||||||
|
from components_derived.import_certificate_form import ImportCertificateForm
|
||||||
|
from pages.base_page import BasePage
|
||||||
|
|
||||||
|
|
||||||
|
class CertificatesTab(BasePage):
|
||||||
|
"""Класс для работы с вкладкой 'Сертификаты'.
|
||||||
|
|
||||||
|
Предоставляет методы для взаимодействия с вкладкой 'Сертификаты'.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
page: Экземпляр страницы Playwright.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, page: Page) -> None:
|
||||||
|
"""Инициализирует компоненты вкладки настройки резервного копирования."""
|
||||||
|
|
||||||
|
super().__init__(page)
|
||||||
|
|
||||||
|
self.toolbar_main = CustomToolbar(page)
|
||||||
|
self.toolbar_secondary = CustomToolbar(page)
|
||||||
|
|
||||||
|
self.tab_button_certificate = TabButton(page, CertificateLocators.TAB_CERTIFICATE_CA, "tab_button_certificate")
|
||||||
|
self.tab_button_reissue = TabButton(page, CertificateLocators.TAB_REISSUE_CA, "tab_button_reissue")
|
||||||
|
self.tab_button_import = TabButton(page, CertificateLocators.TAB_IMPORT_CA, "tab_button_import")
|
||||||
|
|
||||||
|
self.view_certificate_form = ViewCertificateForm(page)
|
||||||
|
self.reissue_certificate_form = ReissueCertificateForm(page)
|
||||||
|
self.import_certificate_form = ImportCertificateForm(page)
|
||||||
|
|
||||||
|
self.alert = AlertComponent(page)
|
||||||
|
|
||||||
|
# Действия:
|
||||||
|
def click_certificate_tab_button(self) -> None:
|
||||||
|
"""Выполняет нажатие tab-кнопки 'Сертификат CA'."""
|
||||||
|
|
||||||
|
self.tab_button_certificate.check_visibility("'Сертификат CA' tab button is missing")
|
||||||
|
self.tab_button_certificate.click()
|
||||||
|
assert self.tab_button_certificate.is_active(), "'Сертификат CA' tab button should be active"
|
||||||
|
|
||||||
|
def click_reissue_tab_button(self) -> None:
|
||||||
|
"""Выполняет нажатие tab-кнопки 'Пересоздание CA'."""
|
||||||
|
|
||||||
|
self.tab_button_reissue.check_visibility("'Пересоздание CA' tab button is missing")
|
||||||
|
self.tab_button_reissue.click()
|
||||||
|
assert self.tab_button_reissue.is_active(), "'Пересоздание CA' tab button should be active"
|
||||||
|
|
||||||
|
def click_import_tab_button(self) -> None:
|
||||||
|
"""Выполняет нажатие tab-кнопки 'Import ca (p12)'."""
|
||||||
|
|
||||||
|
self.tab_button_import.check_visibility("'Import ca (p12)' tab button is missing")
|
||||||
|
self.tab_button_import.click()
|
||||||
|
assert self.tab_button_import.is_active(), "'Import ca (p12)' tab button should be active"
|
||||||
|
|
||||||
|
def get_certificate(self) -> dict:
|
||||||
|
""" Возвращает значания полей отображаемого сертификата"""
|
||||||
|
|
||||||
|
return self.view_certificate_form.get_certificate()
|
||||||
|
|
||||||
|
def get_identification_fields_values(self) -> dict:
|
||||||
|
"""Возвращает текущее значение полей блока 'Идентификация CA' формы для пересоздания сертификата.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict : Текущее значение полей блока 'Идентификация CA' формы для пересоздания сертификата.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.reissue_certificate_form.get_identification_fields_values()
|
||||||
|
|
||||||
|
def get_location_fields_values(self) -> dict:
|
||||||
|
"""Возвращает текущее значение полей блока 'Адрес / Местонахождение' формы для пересоздания сертификата.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict : Текущее значение полей блока блока 'Адрес / Местонахождение' формы для пересоздания сертификата.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.reissue_certificate_form.get_location_fields_values()
|
||||||
|
|
||||||
|
def get_password_field_value(self) -> str:
|
||||||
|
"""Возвращает текущее значение поля 'Пароль' формы импорта сертификата.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str : Текущее значение поля 'Пароль' формы импорта сертификата.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.import_certificate_form.get_password_field_value()
|
||||||
|
|
||||||
|
def export_certificate(self) -> str:
|
||||||
|
"""Нажатие кнопки 'Экспорт сертификата (CA)' в форме отображения сертификата и
|
||||||
|
скачивание текущего корневого сертификата.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str : Полный путь к скачанному файлу.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.view_certificate_form.export_certificate()
|
||||||
|
|
||||||
|
def input_identification_cert_name_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Имя Сертификата' блока 'Идентификация CA' формы для пересоздания сертификата"""
|
||||||
|
|
||||||
|
self.reissue_certificate_form.input_identification_cert_name_field(value)
|
||||||
|
|
||||||
|
def input_identification_organization_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Организация' блока 'Идентификация CA' формы для пересоздания сертификата"""
|
||||||
|
|
||||||
|
self.reissue_certificate_form.input_identification_organization_field(value)
|
||||||
|
|
||||||
|
def input_identification_org_unit_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Подразделение' блока 'Идентификация CA' формы для пересоздания сертификата"""
|
||||||
|
|
||||||
|
self.reissue_certificate_form.input_identification_org_unit_field(value)
|
||||||
|
|
||||||
|
def input_location_country_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Страна' блока 'Адрес / Местонахождение' формы для пересоздания сертификата"""
|
||||||
|
|
||||||
|
self.reissue_certificate_form.input_location_country_field(value)
|
||||||
|
|
||||||
|
def input_location_state_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Регион / Область' блока 'Адрес / Местонахождение' формы для пересоздания сертификата"""
|
||||||
|
|
||||||
|
self.reissue_certificate_form.input_location_state_field(value)
|
||||||
|
|
||||||
|
def input_location_city_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Город' блока 'Адрес / Местонахождение' формы для пересоздания сертификата"""
|
||||||
|
|
||||||
|
self.reissue_certificate_form.input_location_city_field(value)
|
||||||
|
|
||||||
|
def input_password_field(self, value: str) -> None:
|
||||||
|
"""Заполнение поля 'Пароль' формы импорта сертификата"""
|
||||||
|
|
||||||
|
self.import_certificate_form.input_password_field(value)
|
||||||
|
|
||||||
|
# Проверки:
|
||||||
|
def check_content(self):
|
||||||
|
"""Проверяет наличие и корректность всех элементов страницы."""
|
||||||
|
|
||||||
|
self.toolbar_main.check_toolbar_presence(['Сертификаты'])
|
||||||
|
self.toolbar_secondary.check_toolbar_presence(['Центр сертификации (CA)',
|
||||||
|
'Управление корневым сертификатом системы'])
|
||||||
|
|
||||||
|
self.click_certificate_tab_button()
|
||||||
|
self.view_certificate_form.check_content()
|
||||||
|
|
||||||
|
self.click_reissue_tab_button()
|
||||||
|
self.reissue_certificate_form.check_content()
|
||||||
|
|
||||||
|
self.click_import_tab_button()
|
||||||
|
self.import_certificate_form.check_content()
|
||||||
|
|
||||||
|
def check_alert(self, alert_type: str, alert_text: str) -> None:
|
||||||
|
"""Проверяет наличие alert заданного типа и текста."""
|
||||||
|
|
||||||
|
actual_alert_type = self.alert.get_alert_type()
|
||||||
|
assert actual_alert_type == alert_type, f"Got unexpected alert type {actual_alert_type}"
|
||||||
|
|
||||||
|
self.alert.check_alert_presence(alert_text)
|
||||||
|
self.alert.check_alert_absence(alert_text)
|
||||||
|
|
||||||
|
def is_import_button_disabled(self) -> bool:
|
||||||
|
"""Проверяет доступность кнопки импорта сертификата."""
|
||||||
|
|
||||||
|
return self.import_certificate_form.is_import_button_disabled()
|
||||||
|
|
||||||
|
def is_reissue_button_disabled(self) -> bool:
|
||||||
|
"""Проверяет доступность кнопки перевыпуска сертификата."""
|
||||||
|
|
||||||
|
return self.reissue_certificate_form.is_reissue_button_disabled()
|
||||||
|
|
@ -0,0 +1,273 @@
|
||||||
|
"""Модуль тестов вкладки 'Сертификаты'.
|
||||||
|
|
||||||
|
Содержит тесты для проверки корректности отображения
|
||||||
|
и функциональности элементов вкладки 'Сертификаты'.
|
||||||
|
"""
|
||||||
|
|
||||||
|
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.check_alert('error',
|
||||||
|
# 'Поле должно содержать 2 \n символа')
|
||||||
|
# certificates_tab.input_location_country_field("RUS")
|
||||||
|
# certificates_tab.check_alert('error',
|
||||||
|
# 'Поле должно содержать 2 \n символа')
|
||||||
|
|
||||||
|
assert certificates_tab.is_reissue_button_disabled(), "Reissue certificate button should be disabled"
|
||||||
|
|
||||||
|
@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"
|
||||||
|
|
||||||
|
# Вспомогательные функции
|
||||||
|
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
|
||||||
Loading…
Reference in New Issue