"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FormFieldFillers = void 0;
const test_1 = require("@playwright/test");
const timeouts_1 = require("../../../../timeouts");
const logger_1 = require("../../../../utils/logger");
const test_errors_1 = require("../../../../utils/test-errors");
const path_1 = __importDefault(require("path"));
const FormFieldLocatorResolver_1 = require("./FormFieldLocatorResolver");
const FormFieldValueUtils_1 = require("./FormFieldValueUtils");
const FormFieldAssertionUtils_1 = require("./FormFieldAssertionUtils");
const findSearchInput = (page) => page.getByRole('textbox', { name: 'Поиск' });
/**
 * Низкоуровневое заполнение полей формы
 */
class FormFieldFillers {
    /**
     * @param page — страница Playwright
     */
    constructor(page) {
        this.page = page;
    }
    // ==================== ПУБЛИЧНЫЕ МЕТОДЫ ====================
    /**
     * Заполняет текстовое поле по его ключу
     *
     * @param fieldKey - Ключ поля из FormFieldsLocators.textFieldsLocators
     * @param value - Текст для заполнения
     * @param locators - Реестр локаторов всех полей формы
     * @param context - Контекст для логирования (название формы, экрана и т.д.)
     *
     * @example
     * ```typescript
     * await formHelper.fillTextField('email', 'user@example.com', locators, 'форма регистрации');
     * ```
     *
     * @throws {Error} Если поле не найдено или не удалось заполнить
     */
    async fillTextField(fieldKey, value, locators, context = 'формы') {
        const textField = (0, FormFieldLocatorResolver_1.findFieldLocator)(locators.textFieldsLocators, fieldKey, 'text', context);
        if (!textField) {
            logger_1.logger.warn(`Текстовое поле "${fieldKey}" не найдено в ${context}`);
            return;
        }
        await textField.focus();
        await this.fillTextFieldInternal(textField, value, fieldKey);
    }
    /**
     * Выбирает значение в выпадающем списке (combobox) по ключу поля
     *
     * @param fieldKey - Ключ поля из FormFieldsLocators.comboboxFieldsLocators
     * @param value - Значение для выбора. Может быть строкой или объектом с valueForSearch
     * @param locators - Реестр локаторов всех полей формы
     * @param context - Контекст для логирования (название формы, экрана и т.д.)
     *
     * @example
     * ```typescript
     * // Простой выбор
     * await formHelper.selectComboboxValue('city', 'Москва', locators);
     *
     * // Выбор с поиском
     * await formHelper.selectComboboxValue('city', {
     *   selectValue: 'Москва',
     *   valueForSearch: 'Мос'
     * }, locators);
     *
     * // Точное совпадение (с префиксом "=")
     * await formHelper.selectComboboxValue('city', '=Москва (город)', locators);
     * ```
     *
     * @throws {Error} Если поле не найдено, недоступно или значение не найдено в списке
     */
    async selectComboboxValue(fieldKey, value, locators, context = 'формы') {
        const comboboxField = (0, FormFieldLocatorResolver_1.findFieldLocator)(locators.comboboxFieldsLocators, fieldKey, 'combobox', context);
        if (!comboboxField) {
            logger_1.logger.warn(`Combobox "${fieldKey}" не найден в ${context}`);
            return;
        }
        const option = typeof value === 'string' ? { selectValue: value } : value;
        await this.selectOptionInCombobox(comboboxField, option, fieldKey);
    }
    /**
     * Выбирает одно или несколько значений в мульти-выпадающем списке (multi-combobox)
     *
     * @param fieldKey - Ключ поля из FormFieldsLocators.multiComboboxFieldsLocators
     * @param options - Массив опций для выбора. Каждая опция может содержать valueForSearch
     * @param locators - Реестр локаторов всех полей формы
     * @param context - Контекст для логирования (название формы, экрана и т.д.)
     *
     * @example
     * ```typescript
     * // Выбор одного значения
     * await formHelper.selectMultiComboboxValues('tags', [
     *   { selectValue: 'Важный' }
     * ], locators);
     *
     * // Выбор нескольких значений
     * await formHelper.selectMultiComboboxValues('tags', [
     *   { selectValue: 'Важный' },
     *   { selectValue: 'Срочный' },
     *   { selectValue: 'Архив', valueForSearch: 'арх' }
     * ], locators);
     * ```
     *
     * @throws {Error} Если поле не найдено, недоступно или какая-либо опция не найдена
     */
    async selectMultiComboboxValues(fieldKey, options, locators, context = 'формы') {
        const multiComboboxField = (0, FormFieldLocatorResolver_1.findFieldLocator)(locators.multiComboboxFieldsLocators, fieldKey, 'multi-combobox', context);
        if (!multiComboboxField) {
            logger_1.logger.warn(`Multi-combobox "${fieldKey}" не найден в ${context}`);
            return;
        }
        await this.selectOptionsInMultiCombobox(multiComboboxField, options, fieldKey);
    }
    /**
     * Заполняет поле с подсказками DaData
     *
     * Ввод через `pressSequentially` для срабатывания debounce DaData API.
     * Выбор подсказки — клик по `.autocomplele-item` в панели подсказок
     * (CDK overlay для `core-dadata-search` либо inline `.autocomplete-items` у поля).
     *
     * @param fieldKey - Ключ поля из FormFieldsLocators.daDataFieldsLocators
     * @param inputValue - Значение для ввода в поле (триггер для поиска подсказок)
     * @param selectValue - Текст подсказки для выбора; префикс `=` — exact-совпадение
     * @param expectedValue - Ожидаемое значение в input после выбора (по умолчанию = selectValue без `=`)
     * @param locators - Реестр локаторов всех полей формы
     * @param context - Контекст для логирования (название формы, экрана и т.д.)
     *
     * @example
     * ```typescript
     * // Заполнение адреса
     * await formHelper.fillDaDataField(
     *   'Adress',
     *   'г Москва, ул Тверская',
     *   '=г Москва, ул Тверская, д 15',
     *   undefined,
     *   locators
     * );
     *
     * // Организация: inputValue — поиск, selectValue — полный текст подсказки
     * await formHelper.fillDaDataField(
     *   'InnOrNameCompany',
     *   'ООО "НАЙЗА"',
     *   'ООО "НАЙЗА" ИНН: 5050151540',
     *   'ООО "НАЙЗА"',
     *   locators
     * );
     * ```
     *
     * @throws {Error} Если поле не найдено, недоступно или не удалось выбрать подсказку
     */
    async fillDaDataField(fieldKey, inputValue, selectValue, expectedValue, locators, context = 'формы') {
        const daDataField = (0, FormFieldLocatorResolver_1.findFieldLocator)(locators.daDataFieldsLocators, fieldKey, 'DaData', context);
        if (!daDataField) {
            logger_1.logger.warn(`DaData поле "${fieldKey}" не найдено в ${context}`);
            return;
        }
        await this.fillDaDataFieldInternal(daDataField, inputValue, selectValue, expectedValue, fieldKey);
    }
    /**
     * Устанавливает переключатель (toggle/switch) в заданное состояние
     *
     * @param fieldKey - Ключ поля из FormFieldsLocators.toggleButtonsLocators
     * @param desiredState - Желаемое состояние: true/false или 'Yes'/'No'
     * @param locators - Реестр локаторов всех полей формы
     * @param context - Контекст для логирования (название формы, экрана и т.д.)
     *
     * @example
     * ```typescript
     * // Включить toggle
     * await formHelper.setToggle('notifications', true, locators);
     *
     * // Выключить toggle
     * await formHelper.setToggle('darkMode', false, locators);
     *
     * // С использованием строковых значений
     * await formHelper.setToggle('newsletter', 'Yes', locators);
     * ```
     *
     * @throws {Error} Если поле не найдено или не удалось изменить состояние
     */
    async setToggle(fieldKey, desiredState, locators, context = 'формы') {
        const toggleButton = (0, FormFieldLocatorResolver_1.findFieldLocator)(locators.toggleButtonsLocators, fieldKey, 'toggle', context);
        if (!toggleButton) {
            logger_1.logger.warn(`Toggle "${fieldKey}" не найдено в ${context}`);
            return;
        }
        await this.setToggleButtonInternal(toggleButton, desiredState, fieldKey);
    }
    /**
     * Устанавливает чекбокс в заданное состояние
     *
     * @param checkboxKey - Ключ чекбокса из FormFieldsLocators.checkboxesLocators
     * @param checked - Желаемое состояние: true (отмечен) или false (не отмечен)
     * @param checkboxes - Объект с локаторами всех чекбоксов формы
     *
     * @example
     * ```typescript
     * // Отметить чекбокс
     * await formHelper.setCheckbox('agreement', true, locators.checkboxesLocators);
     *
     * // Снять отметку
     * await formHelper.setCheckbox('newsletter', false, locators.checkboxesLocators);
     * ```
     *
     * @throws {Error} Если чекбокс не найден
     */
    async setCheckbox(checkboxKey, checked, checkboxes) {
        const checkbox = checkboxes[checkboxKey];
        if (!checkbox) {
            logger_1.logger.warn(`Чекбокс "${checkboxKey}" не найден`);
            return;
        }
        if (checked) {
            await checkbox.check({ timeout: (0, timeouts_1.getTimeouts)().EXPECT });
        }
        else {
            await checkbox.uncheck({ timeout: (0, timeouts_1.getTimeouts)().EXPECT });
        }
        logger_1.logger.debug(`Чекбокс "${checkboxKey}" установлен в ${checked}`);
    }
    /**
     * Выбирает радиокнопку по её ключу
     *
     * @param radioKey - Ключ радиокнопки из FormFieldsLocators.radioButtonsLocators
     * @param radioButtons - Объект с локаторами всех радиокнопок формы
     *
     * @example
     * ```typescript
     * // Выбрать радиокнопку "Мужской"
     * await formHelper.selectRadioButton('male', locators.radioButtonsLocators);
     *
     * // Выбрать радиокнопку "Доставка курьером"
     * await formHelper.selectRadioButton('courier', locators.radioButtonsLocators);
     * ```
     *
     * @throws {Error} Если радиокнопка не найдена или не удалось выбрать
     */
    async selectRadioButton(radioKey, radioButtons) {
        const radioButton = radioButtons[radioKey];
        if (!radioButton) {
            logger_1.logger.warn(`Радиокнопка "${radioKey}" не найдена`);
            return;
        }
        try {
            await radioButton.check({ timeout: (0, timeouts_1.getTimeouts)().EXPECT });
            logger_1.logger.debug(`Радиокнопка "${radioKey}" выбрана`);
        }
        catch (error) {
            throw test_errors_1.ErrorFactory.data('selectRadioButton', `Ошибка при выборе radiobutton "${radioKey}"`, undefined, 'radioButtonKey', radioKey, { radioButtonKey: radioKey });
        }
    }
    /**
     * Загружает файл в поле загрузки файлов
     *
     * @param fieldKey - Ключ поля из FormFieldsLocators.fileFieldsLocators
     * @param filePath - Путь к файлу (абсолютный или относительный от resources/files)
     * @param locators - Реестр локаторов всех полей формы
     * @param context - Контекст для логирования (название формы, экрана и т.д.)
     *
     * @example
     * ```typescript
     * // Загрузка файла из стандартной директории
     * await formHelper.uploadFileByFieldKey('passport', 'passport.pdf', locators);
     *
     * // Загрузка файла по абсолютному пути
     * await formHelper.uploadFileByFieldKey('photo', '/Users/user/photo.jpg', locators);
     *
     * // Загрузка файла из поддиректории
     * await formHelper.uploadFileByFieldKey('document', 'docs/contract.pdf', locators);
     * ```
     *
     * @throws {Error} Если поле не найдено или загрузка не удалась (статус ответа не 200)
     */
    async uploadFileByFieldKey(fieldKey, filePath, locators, context = 'формы') {
        const fileField = (0, FormFieldLocatorResolver_1.findFieldLocator)(locators.fileFieldsLocators, fieldKey, 'file', context);
        if (!fileField) {
            logger_1.logger.warn(`Поле для загрузки файлов "${fieldKey}" не найдено в ${context}`);
            return;
        }
        await this.uploadFileInternal(fileField, filePath, fieldKey);
    }
    /**
     * Универсальный метод для массового заполнения всех типов полей формы
     *
     * @param data - Объект с данными для заполнения всех полей формы
     * @param locators - Реестр локаторов всех полей формы
     * @param context - Контекст для логирования (название формы, экрана и т.д.)
     *
     * @example
     * ```typescript
     * const formData = {
     *   textFieldsData: {
     *     email: 'user@example.com',
     *     name: 'Иван Петров'
     *   },
     *   comboboxFieldsData: {
     *     city: { selectValue: 'Москва' },
     *     country: { selectValue: 'Россия', valueForSearch: 'Рос' }
     *   },
     *   checkboxesData: {
     *     agreement: true,
     *     newsletter: false
     *   },
     *   fileFieldsData: {
     *     passport: ['passport.pdf'],
     *     photo: ['avatar.jpg']
     *   }
     * };
     *
     * await formHelper.fillFormFields(formData, locators, 'форма регистрации');
     * ```
     *
     * @remarks
     * Метод автоматически определяет какие поля нужно заполнить по наличию данных
     * Порядок заполнения: radiobutton → toggle → combobox → multi-combobox → text → DaData → checkbox → file
     *
     * @throws {Error} При ошибке заполнения любого из полей
     */
    async fillFormFields(data, locators, context = 'формы') {
        logger_1.logger.info(`Начало заполнения ${context}`);
        const fillSteps = [
            {
                name: 'radiobutton', condition: data.radioButtonsData && locators.radioButtonsLocators,
                action: () => this.fillRadioButtonsGroup(locators.radioButtonsLocators, data.radioButtonsData)
            },
            {
                name: 'toggle', condition: data.toggleButtonsData && locators.toggleButtonsLocators,
                action: () => this.fillTogglesGroup(data.toggleButtonsData, locators, context)
            },
            {
                name: 'combobox', condition: data.comboboxFieldsData && locators.comboboxFieldsLocators,
                action: () => this.fillComboboxesGroup(data.comboboxFieldsData, locators, context)
            },
            {
                name: 'multi-combobox', condition: data.multiComboboxFieldsData && locators.multiComboboxFieldsLocators,
                action: () => this.fillMultiComboboxesGroup(data.multiComboboxFieldsData, locators, context)
            },
            {
                name: 'text', condition: data.textFieldsData && locators.textFieldsLocators,
                action: () => this.fillTextFieldsGroup(data.textFieldsData, locators, context)
            },
            {
                name: 'DaData', condition: data.daDataFieldsData && locators.daDataFieldsLocators,
                action: () => this.fillDaDataFieldsGroup(data.daDataFieldsData, locators, context)
            },
            {
                name: 'checkbox', condition: data.checkboxesData && locators.checkboxesLocators,
                action: () => this.fillCheckboxesGroup(locators.checkboxesLocators, data.checkboxesData)
            },
            {
                name: 'file', condition: data.fileFieldsData && locators.fileFieldsLocators,
                action: () => this.fillFilesGroup(data.fileFieldsData, locators, context)
            }
        ];
        for (const step of fillSteps) {
            if (step.condition) {
                await test_1.test.step(`Заполнение ${step.name} полей`, step.action);
            }
        }
        logger_1.logger.info(`Заполнение ${context} завершено`);
    }
    // ==================== ПРИВАТНЫЕ МЕТОДЫ ====================
    /**
     * Внутренний метод заполнения текстового поля
     * @private
     */
    async fillTextFieldInternal(textField, value, fieldKey) {
        await textField.fill(value);
        logger_1.logger.debug(`Текстовое поле "${fieldKey}" заполнено: "${value}"`);
    }
    /**
     * Внутренний метод выбора опции в combobox
     * @private
     */
    async selectOptionInCombobox(comboboxField, option, fieldKey) {
        const { selectValue, valueForSearch } = option;
        await comboboxField.waitFor({
            state: 'visible',
            timeout: (0, timeouts_1.getTimeouts)().ELEMENT_STABLE_WAIT
        });
        await comboboxField.click();
        await this.selectDropdownOption({ selectValue, valueForSearch }, { clearAfterSelection: false });
        const { value: actualSelectValue } = (0, FormFieldValueUtils_1.parseSelectValue)(selectValue);
        try {
            await (0, FormFieldAssertionUtils_1.expectComboboxValue)(comboboxField, actualSelectValue);
            logger_1.logger.debug(`Combobox "${fieldKey}" выбрано значение: "${actualSelectValue}"`);
        }
        catch (error) {
            logger_1.logger.warn(`Не удалось проверить выбор в combobox "${fieldKey}"`);
        }
    }
    /**
     * Внутренний метод выбора опций в multi-combobox
     * @private
     */
    async selectOptionsInMultiCombobox(multiComboboxField, options, fieldKey) {
        await multiComboboxField.click();
        await this.selectDropdownOption(options, { clearAfterSelection: true });
        logger_1.logger.debug(`Multi-combobox "${fieldKey}" выбрано ${options.length} значений`);
    }
    /**
     * Внутренний метод заполнения DaData поля
     * @private
     */
    async fillDaDataFieldInternal(daDataField, inputValue, selectValue, expectedValue, fieldKey) {
        await daDataField.click();
        await daDataField.clear();
        await daDataField.pressSequentially(inputValue, { delay: (0, timeouts_1.getTimeouts)().AUTOCOMPLETE_KEY_DELAY });
        await this.selectAutocompleteSuggestion(daDataField, selectValue);
        const { value: actualSelectValue } = (0, FormFieldValueUtils_1.parseSelectValue)(selectValue);
        const expected = expectedValue || actualSelectValue;
        try {
            await test_1.expect.soft(daDataField).toHaveValue(expected);
            logger_1.logger.debug(`DaData поле "${fieldKey}" заполнено: "${inputValue}" -> "${expected}"`);
        }
        catch (error) {
            logger_1.logger.error(`DaData поле "${fieldKey}" заполнено некорректно`);
            throw error;
        }
    }
    /**
     * Возвращает панель подсказок DaData для активного поля.
     * - `core-dadata-search` → CDK overlay (`.core-dadata-suggestions-overlay .autocomplete-items`);
     * - иначе → `.autocomplete-items` внутри ближайшего предка `div.autocomplete` у input
     * Резолв всегда от поля, без привязки к имени конкретного Angular-компонента.
     * @param field — локатор input DaData-поля
     * @returns локатор панели `.autocomplete-items`
     * @throws {Error} Если не удалось определить контейнер подсказок относительно поля
     * @private
     */
    async resolveAutocompleteSuggestionsPanel(field) {
        const isCdkSearch = await field.locator('xpath=ancestor::core-dadata-search[1]').count() > 0;
        if (isCdkSearch) {
            return this.page.locator('.core-dadata-suggestions-overlay .autocomplete-items');
        }
        const inlineAutocompleteRoot = field.locator('xpath=ancestor::div[contains(concat(" ", normalize-space(@class), " "), " autocomplete ")][1]');
        if (await inlineAutocompleteRoot.count() > 0) {
            return inlineAutocompleteRoot.locator('.autocomplete-items');
        }
        throw new Error('Панель подсказок DaData: не найден CDK overlay (core-dadata-search) и нет предка div.autocomplete у поля');
    }
    /**
     * Выбирает подсказку в DaData autocomplete (`.autocomplele-item`).
     * @param field — локатор input DaData-поля
     * @param selectValue — текст подсказки (substring в `.autocomplele-item`); префикс `=` влияет только на проверку значения поля
     * @private
     */
    async selectAutocompleteSuggestion(field, selectValue) {
        const { value: actualSelectValue } = (0, FormFieldValueUtils_1.parseSelectValue)(selectValue);
        const suggestionsPanel = await this.resolveAutocompleteSuggestionsPanel(field);
        await (0, test_1.expect)(suggestionsPanel).toBeVisible({ timeout: (0, timeouts_1.getTimeouts)().OPTION_VISIBLE_WAIT });
        const suggestion = suggestionsPanel.locator('.autocomplele-item').filter({
            hasText: actualSelectValue,
        });
        await suggestion.first().click();
    }
    /**
     * Внутренний метод установки toggle
     * @private
     */
    async setToggleButtonInternal(toggleButton, desiredState, fieldKey) {
        const targetBooleanState = typeof desiredState === 'boolean'
            ? desiredState
            : desiredState === 'Yes';
        const currentAriaChecked = await toggleButton.getAttribute('aria-checked');
        const isCurrentlyChecked = currentAriaChecked === 'true';
        if (isCurrentlyChecked === targetBooleanState) {
            logger_1.logger.debug(`Toggle "${fieldKey}" уже в состоянии ${targetBooleanState}`);
            return;
        }
        try {
            await toggleButton.click();
            await (0, test_1.expect)(toggleButton).toHaveAttribute('aria-checked', String(targetBooleanState), { timeout: (0, timeouts_1.getTimeouts)().EXPECT });
            logger_1.logger.debug(`Toggle "${fieldKey}" установлен в ${targetBooleanState}`);
        }
        catch (error) {
            logger_1.logger.error(`Ошибка при изменении toggle "${fieldKey}"`);
            throw new Error(`Не удалось установить toggle "${fieldKey}" в состояние ${targetBooleanState}`);
        }
    }
    /**
     * Внутренний метод загрузки файла
     * @private
     */
    async uploadFileInternal(fileField, filePath, fieldKey) {
        const resolvedPath = this.resolveFilePath(filePath);
        const uploadResponsePromise = this.page.waitForResponse(response => response.url().includes('/files'), { timeout: (0, timeouts_1.getTimeouts)().ACTION });
        const [fileChooser] = await Promise.all([
            this.page.waitForEvent('filechooser', { timeout: (0, timeouts_1.getTimeouts)().ACTION }),
            fileField.click()
        ]);
        const [response] = await Promise.all([
            uploadResponsePromise,
            fileChooser.setFiles(resolvedPath),
        ]);
        if (response.status() !== 200) {
            const responseBody = await response.text();
            throw new Error(`Ошибка загрузки файла в поле "${fieldKey}": ${response.status()} - ${responseBody}`);
        }
        logger_1.logger.debug(`Файл "${path_1.default.basename(resolvedPath)}" загружен в поле "${fieldKey}"`);
    }
    // Групповые методы для fillFormFields
    /**
     * Заполнение группы радиокнопок
     * @private
     */
    async fillRadioButtonsGroup(radioButtons, radioButtonKeys) {
        for (const key of radioButtonKeys) {
            await this.selectRadioButton(key, radioButtons);
        }
    }
    /**
     * Заполнение группы toggle кнопок
     * @private
     */
    async fillTogglesGroup(toggleButtonsData, locators, context) {
        for (const [toggleKey, state] of Object.entries(toggleButtonsData)) {
            await this.setToggle(toggleKey, state, locators, context);
        }
    }
    /**
     * Заполнение группы combobox полей
     * @private
     */
    async fillComboboxesGroup(comboboxFieldsData, locators, context) {
        for (const [key, value] of Object.entries(comboboxFieldsData)) {
            await this.selectComboboxValue(key, value, locators, context);
        }
    }
    /**
     * Заполнение группы multi-combobox полей
     * @private
     */
    async fillMultiComboboxesGroup(multiComboboxFieldsData, locators, context) {
        for (const [key, options] of Object.entries(multiComboboxFieldsData)) {
            await this.selectMultiComboboxValues(key, options, locators, context);
        }
    }
    /**
     * Заполнение группы текстовых полей
     * @private
     */
    async fillTextFieldsGroup(textFieldsData, locators, context) {
        for (const [key, value] of Object.entries(textFieldsData)) {
            await this.fillTextField(key, value, locators, context);
        }
    }
    /**
     * Заполнение группы DaData полей
     * @private
     */
    async fillDaDataFieldsGroup(daDataFieldsData, locators, context) {
        for (const [key, daDataValue] of Object.entries(daDataFieldsData)) {
            await this.fillDaDataField(key, daDataValue.inputValue, daDataValue.selectValue, daDataValue.expectedValue, locators, context);
        }
    }
    /**
     * Заполнение группы чекбоксов
     * @private
     */
    async fillCheckboxesGroup(checkboxes, checkboxesData) {
        for (const [key, checked] of Object.entries(checkboxesData)) {
            await this.setCheckbox(key, checked, checkboxes);
        }
    }
    /**
     * Заполнение группы полей загрузки файлов (последовательно, по одному файлу на клик).
     * @private
     */
    async fillFilesGroup(fileFieldsData, locators, context) {
        for (const [key, filePaths] of Object.entries(fileFieldsData)) {
            for (const filePath of filePaths) {
                await this.uploadFileByFieldKey(key, filePath, locators, context);
            }
        }
    }
    // Вспомогательные приватные методы
    /**
     * Универсальный метод выбора опций в выпадающих списках
     * @private
     */
    async selectDropdownOption(options, optionsForSearch) {
        const optionsArray = Array.isArray(options) ? options : [options];
        const { clearAfterSelection = true } = optionsForSearch || {};
        for (let i = 0; i < optionsArray.length; i++) {
            const option = optionsArray[i];
            const { selectValue, valueForSearch } = option;
            const { exact, value: actualSelectValue } = (0, FormFieldValueUtils_1.parseSelectValue)(selectValue);
            if (valueForSearch) {
                await this.fillSearchInput(valueForSearch);
            }
            const optionLocator = this.page.getByRole('listbox').getByRole('option', { name: actualSelectValue, exact });
            await this.waitForAndSelectOption(optionLocator, actualSelectValue, exact);
        }
        if (clearAfterSelection && Array.isArray(options)) {
            await this.page.keyboard.press('Escape');
        }
    }
    /**
     * Заполнение поля поиска в выпадающем списке
     * @private
     */
    async fillSearchInput(value) {
        try {
            const searchInput = findSearchInput(this.page);
            await searchInput.fill(value);
            logger_1.logger.debug(`Поиск: "${value}"`);
        }
        catch (error) {
            throw error;
        }
    }
    /**
     * Ожидание появления опции и клик по ней
     * @private
     */
    async waitForAndSelectOption(optionLocator, actualSelectValue, exact) {
        try {
            await optionLocator.waitFor({ state: 'visible', timeout: (0, timeouts_1.getTimeouts)().ACTION });
        }
        catch (error) {
            const textLocator = this.page.getByText(actualSelectValue, { exact });
            await textLocator.waitFor({ state: 'visible', timeout: (0, timeouts_1.getTimeouts)().ACTION });
        }
        try {
            await optionLocator.click();
        }
        catch (error) {
            const textLocator = this.page.getByText(actualSelectValue, { exact });
            await textLocator.click();
        }
    }
    /**
     * Разрешение полного пути к файлу
     * @private
     */
    resolveFilePath(filePath) {
        if (filePath.startsWith('/') || (process.platform === 'win32' && /^[A-Za-z]:/.test(filePath))) {
            return filePath;
        }
        if (filePath.includes('resources/files') || filePath.includes('resources\\files')) {
            return path_1.default.resolve(process.cwd(), filePath);
        }
        return path_1.default.resolve(process.cwd(), 'resources/files', filePath);
    }
}
exports.FormFieldFillers = FormFieldFillers;
