import { baseUniDriverFactory, isElementFocused, ReactBase, } from '../utils/test-utils/unidriver';
import { statusIndicatorDriverFactory } from '../StatusIndicator/StatusIndicator.uni.driver';
import { dataHooks, DATA_ATTR } from './Input.constants';
import { tooltipDriverFactory } from '../Tooltip/Tooltip.uni.driver';
import { isPlaywrightUniDriver } from '../utils/test-utils/unidriver/isPlaywrightUniDriver';
import { isDomUniDriver } from '../utils/test-utils/unidriver/isDomUniDriver';
import { isPuppeteerUniDriver } from '../utils/test-utils/unidriver/isPuppeteerUniDriver';
export const testkit = (base, body) => {
    // single $ throws an exception for more than 1 match, so we use the first matching result with $$
    // to support cases of multiple inputs, e.g cases where this driver is used inside other drivers with popovers
    // which includes an input
    const input = base.$$('input').get(0);
    const reactBase = ReactBase(base);
    const reactBaseInput = ReactBase(input);
    const clearButtonNode = base.$(`[data-hook=input-clear-button]`);
    const menuArrowNode = base.$(`[data-hook="${dataHooks.menuArrow}"]`);
    const getStatusIndicatorDriver = () => statusIndicatorDriverFactory(base.$(`[data-hook="${dataHooks.status}"]`), body);
    const getTooltipDriver = () => tooltipDriverFactory(base.$(`[data-hook="${dataHooks.tooltip}"]`), body);
    const trigger = async (eventType, event) => {
        if (eventType === 'focus') {
            return await driver.focus();
        }
        if (eventType === 'blur') {
            return await driver.blur();
        }
        if (eventType === 'keyUp') {
            return await driver.keyUp();
        }
        if (eventType === 'keyDown') {
            return await driver.keyDown(event);
        }
        if (eventType === 'paste') {
            return await driver.paste();
        }
        if (eventType === 'copy') {
            return await driver.copy();
        }
        if (eventType === 'change') {
            const castedEvent = event;
            return await driver.enterText(castedEvent.target.value);
        }
        if (eventType === 'wheel') {
            return await driver.wheel();
        }
    };
    const driver = {
        ...baseUniDriverFactory(base),
        click: () => input.click(),
        getInputAttribute: async (name) => await input.attr(name),
        getInputElementClasses: async () => await reactBaseInput._DEPRECATED_getClassList(),
        suffixComponentExists: async (className) => await base.$(`[data-hook="${dataHooks.suffixes}"] ${className}`).exists(),
        getRootElementClasses: async () => await reactBase._DEPRECATED_getClassList(),
        getAriaDescribedby: async () => await input.attr('aria-describedby'),
        getAriaLabel: async () => await input.attr('aria-label'),
        getName: async () => await input.attr('name'),
        getMaxLength: async () => await input.attr('maxLength'),
        getType: async () => await input.attr('type'),
        getAriaControls: async () => await input.attr('aria-controls'),
        clickIconAffix: async () => await base.$(`[data-hook="icon-affix"]`).click(),
        clickCustomAffix: async () => await base.$(`[data-hook="custom-affix"]`).click(),
        getCustomAffixText: async () => {
            const customAffix = await base.get(`[data-hook="custom-affix"]`);
            return customAffix.text();
        },
        hasSuffix: async () => await base.$(`[data-hook="${dataHooks.suffixes}"]`).exists(),
        getClearButtonTooltipContent: async () => (await getTooltipDriver().getTooltipText()),
        prefixComponentExists: async (style) => !!(await base.attr(DATA_ATTR.PREFIX)) && (await base.$(style).exists()),
        hasPrefix: async () => (await base.attr(DATA_ATTR.PREFIX)) === 'true',
        hasClearButton: async () => await clearButtonNode.exists(),
        clickClear: async () => await clearButtonNode.click(),
        getValue: async () => await input.value(),
        getText: async () => await input.value(),
        getPattern: async () => await input.attr('pattern'),
        getPlaceholder: async () => await input.attr('placeholder'),
        isOfSize: async (size) => (await base.attr(DATA_ATTR.SIZE)) === size,
        getSize: async () => (await base.attr(DATA_ATTR.SIZE)),
        isDisabled: async () => (await base.attr(DATA_ATTR.DISABLED)) === 'true',
        isHoveredStyle: async () => (await base.attr(DATA_ATTR.HOVER)) === 'true',
        isFocusedStyle: async () => (await base.attr(DATA_ATTR.FOCUS)) === 'true',
        getRequired: async () => await input.prop('required'),
        enterText: async (value) => await input.enterValue(value),
        getAutocomplete: async () => await input.attr('autocomplete'),
        getDefaultValue: async () => await input.prop('defaultValue'),
        getTabIndex: async () => await input.prop('tabIndex'),
        isCustomInput: async () => (await input.attr('data-hook')) === 'wsr-custom-input',
        getReadOnly: async () => await input.prop('readOnly'),
        getDisabled: async () => await input.prop('disabled'),
        getTextOverflow: async () => (await input.prop('style'))['text-overflow'],
        focus: async () => await reactBaseInput.focus(),
        blur: async () => await reactBaseInput.blur(),
        keyUp: async () => await reactBaseInput.keyUp(),
        keyDown: async (eventData) => await reactBaseInput.keyDown(eventData),
        pressKey: async (key) => await input.pressKey(key),
        paste: async () => await reactBaseInput.paste(),
        copy: async () => await reactBaseInput.copy(),
        wheel: async () => await reactBaseInput.wheel(),
        trigger,
        isFocus: async () => isElementFocused(input),
        clickMenuArrow: async () => await menuArrowNode.click(),
        hasMenuArrow: async () => await menuArrowNode.exists(),
        isRTL: async () => (await base.attr('dir')) === 'rtl',
        getCursorLocation: () => input.prop('selectionStart'),
        clearText: () => driver.enterText(''),
        clickOutside: async () => {
            if (isPlaywrightUniDriver(base) || isPuppeteerUniDriver(base)) {
                const LocatorOrHandle = await base.unwrap();
                return LocatorOrHandle.evaluate(node => {
                    return node.ownerDocument.body.click();
                });
            }
            if (isDomUniDriver(base)) {
                return document.body.click();
            }
            return ReactBase.clickDocument();
        },
        isMasked: async () => (await input.attr('data-mask')) === 'true',
        isSelected: async () => {
            const selectionStart = await input.prop('selectionStart');
            const selectionEnd = await input.prop('selectionEnd');
            return selectionStart !== selectionEnd;
        },
        // Status
        /** Return true if there's a status */
        hasStatus: async (status) => (await base.attr(DATA_ATTR.STATUS)) === status,
        /** If there's a status message, returns its text value */
        getStatusMessage: async () => {
            const statusIndicatorDriver = getStatusIndicatorDriver();
            return await statusIndicatorDriver.getMessage();
        },
    };
    return driver;
};
export default testkit;
//# sourceMappingURL=Input.uni.driver.js.map