# Исходный код pages.license_tab

    """Модуль license_tab содержит класс для работы с вкладкой 'Лицензии'.

    Класс LicenseTab наследует BasePage и реализует методы для взаимодействия
    с элементами вкладки лицензий и проверки их состояния.
    """

    from playwright.sync_api import Page
    from locators.text_locators import TextLocators
    from locators.input_locators import InputLocators
    from locators.json_container_locators import JsonContainerLocators
    from locators.button_locators import ButtonLocators
    from elements.text_input_element import TextInput
    from elements.text_element import Text
    from elements.button_element import Button
    from components.toolbar_component import ToolbarComponent
    from components.json_container_component import JsonContainerComponent
    from components.alert_component import AlertComponent
    from pages.base_page import BasePage

    class LicenseTab(BasePage):
        """Класс для работы с вкладкой 'Лицензии'.

        Содержит методы для:
        - Взаимодействия с формой ввода лицензии
        - Проверки содержимого JSON-контейнера
        - Работы с элементами управления
        """

        def __init__(self, page: Page) -> None:
            """Инициализирует элементы вкладки 'Лицензии'.

            Args:
                page: Экземпляр страницы Playwright
            """

            super().__init__(page)

            self.toolbar = ToolbarComponent(page, "Лицензии")
            self.json_container = JsonContainerComponent(page)

            self.input_form_title = Text(page, TextLocators.TITLE_LICENSE_INPUT_FORM, "input form title")
            self.license_id = Text(page, TextLocators.LICENSE_ID, "license id")
            self.license_id_input = TextInput(page, InputLocators.LICENSE_ID_UPDATE, "license id input")
            self.update_button = Button(page, ButtonLocators.BUTTON_LICENSE_UPDATE, "update license button")

            self.alert = AlertComponent(page)

        # Действия:

        def fill_license_input_form(self, value: str) -> None:
            """Заполняет форму ввода лицензии указанным значением.

            Args:
                value: Значение для ввода
            """

            self.license_id_input.clear()
            self.license_id_input.input_value(value)
            self.update_button.click()

        def scroll_json_container_up(self) -> None:
            """Прокручивает JSON-контейнер вверх."""

            loc = self.page.locator(JsonContainerLocators.SCROLL_CONTAINER).first
            self.json_container.scroll_up(loc)

        def scroll_json_container_down(self) -> None:
            """Прокручивает JSON-контейнер вниз."""

            loc = self.page.locator(JsonContainerLocators.SCROLL_CONTAINER).first
            self.json_container.scroll_down(loc)

        # Проверки:

        def check_json_container_verticall_scrolling(self) -> bool:
            """Проверяет возможность вертикальной прокрутки контейнера.

            Returns:
                bool: Доступность прокрутки
            """

            loc = self.page.locator(JsonContainerLocators.SCROLL_CONTAINER).first
            return self.json_container.is_scrollable_vertically(loc)

        def check_content(self) -> None:
            """Проверяет наличие всех основных элементов вкладки."""

            self.should_be_toolbar()
            self.should_be_json_container()
            self.should_be_input_form_title()
            self.should_be_empty_input_form()
            self.should_be_update_button()

            self.verify_json_container_content()

        def should_be_error_alert_window_with_text(self, text: str) -> None:
            """Проверяет наличие/отсутствие алерта с указанным текстом.

            Args:
                text: Текст для проверки
            """

            alert_type = self.alert.get_alert_type()
            assert alert_type=="error", f"Expected error alert, but got {alert_type} alert"

            self.alert.check_alert_presence(text)
            self.alert.check_alert_absence(text)

        def should_be_toolbar(self) -> None:
            """Проверяет наличие панели инструментов."""

            self.toolbar.check_toolbar_presence("Toolbar is missing")

        def should_be_json_container(self) -> None:
            """Проверяет наличие JSON-контейнера."""

            self.json_container.check_visibility(
                JsonContainerLocators.CONTAINER,
                "Json container with license info is missing"
            )

        def should_be_input_form_title(self) -> None:
            """Проверяет заголовок формы и соответствие ID лицензии."""

            self.input_form_title.check_have_text(
                "Идентификатор:",
                "Input lisence id form title 'Идентификатор:' is missing"
            )

            actual_lisence_id = self.license_id.get_text(0).strip()

            # send request to backend to get license id
            response = self.send_get_api_request("e-cmdb/api/lic/deviceid")
            response_body = self.get_response_body(response)

            self.check_equals(
                actual_lisence_id,
                response_body['deviceId'],
                f"Expected ID value {response_body['deviceId']} is not equal actual value {actual_lisence_id}"
            )

        def should_be_empty_input_form(self) -> None:
            """Проверяет пустоту формы ввода лицензии."""

            self.license_id_input.check_empty_input("Input lisence id form is missing or not empty")

        def should_be_update_button(self) -> None:
            """Проверяет наличие кнопки обновления лицензии."""

            button_text = "Обновить лицензию"
            self.update_button.check_have_text(
                button_text,
                f"Update button with text '{button_text}' is missing"
            )

        def verify_json_container_content(self) -> None:
            """Проверяет соответствие данных контейнера данным из API."""

            actual_data = self.json_container.read_data(JsonContainerLocators.CONTAINER)

            # send request to backend to get license info
            response = self.send_get_api_request("api/service-manager/license")

            if response.status == 200:
                response_body = self.get_response_body(response)
                expected_data = response_body["data"]["config"]["config"]["e-nms"]

                for key_1, item in actual_data.items():
                    if not isinstance(item, dict):
                        assert actual_data[key_1] == expected_data[key_1],\
                            f"Expected json content is not equal actual: {actual_data[key_1]} {expected_data[key_1]}"
                        continue

                    for key_2 in item:
                        assert actual_data[key_1][key_2] == expected_data[key_1][key_2],\
                            f"Expected json content is not equal actual: {actual_data[key_1][key_2]} {expected_data[key_1][key_2]}"
            else:
                assert False, f"No response from 'api/service-manager/license' request: {response.status_text}"