UNPKG

wix-style-react

Version:
221 lines • 10.9 kB
import { baseUniDriverFactory, ReactBase, findByHook, getDataAttributeValue, isElementFocused, } from '../test-utils/utils/unidriver'; import { DATA_OPTION, DATA_HOOKS, DATA_DIRECTION, DATA_SHOWN, DROPDOWN_LAYOUT_DIRECTIONS, OPTION_DATA_HOOKS, DATA_SELECTED_OPTION_ID, } from './DataAttr'; export const dropdownLayoutDriverFactory = (base, body) => { const reactBase = ReactBase(base); const contentContainer = () => findByHook(base, DATA_HOOKS.CONTENT_CONTAINER); const infiniteScrollContainer = () => findByHook(base, DATA_HOOKS.INFINITE_SCROLL_CONTAINER); const optionsElement = () => findByHook(base, DATA_HOOKS.DROPDOWN_LAYOUT_OPTIONS); async function getOptionsContainerDataHook() { return (await infiniteScrollContainer().exists()) ? DATA_HOOKS.INFINITE_SCROLL_CONTAINER : DATA_HOOKS.DROPDOWN_LAYOUT_OPTIONS; } const optionElementAt = async (position) => await base.$(`[data-hook=${await getOptionsContainerDataHook()}] > *:nth-child(${position + 1})`); const optionElementContentAt = async (position) => await base.$(`[data-list-type="action"] [data-hook=${await getOptionsContainerDataHook()}] > *:nth-child(${position + 1}) > *`); const optionElementByDataHook = async (dataHook) => await base.$(`[data-hook=${await getOptionsContainerDataHook()}] [data-hook="${dataHook}"]`); const options = async () => base .$$(`[data-hook=${await getOptionsContainerDataHook()}] > *`) .map(i => i); const optionsLength = async () => (await options()).length; const doIfOptionExists = (position, onSuccess) => { if (optionsLength() <= position) { throw new Error(`index out of bounds, try to get option ${position} while only ${optionsLength()} options exists`); } return onSuccess(); }; const getOptionDriver = position => doIfOptionExists(position, async () => { const optionElementContent = await optionElementContentAt(position); return createOptionDriver((await optionElementContent.exists()) ? optionElementContent : await optionElementAt(position)); }); return { ...baseUniDriverFactory(base), /** @deprecated should be private */ classes: () => optionsElement()._prop('className'), /** Clicks on an option at a specific index * @param {number} option index * @return {Promise<void>} */ clickAtOption: async (index) => (await getOptionDriver(index)).click(), /** Clicks on an option with a specific dataHook * @param {string} dataHook * @return {Promise<void>} */ clickAtOptionByDataHook: async (dataHook) => (await optionElementByDataHook(dataHook)).click(), /** Clicks on an option with a specific value * @param {string} value * @return {Promise<void>} */ clickAtOptionWithValue: async (value) => { for (const _option of await options()) { const optionDriver = await createOptionDriver(_option); if ((await optionDriver.content()) === value) { return optionDriver.click(); } } }, /** @deprecated deprecated prop */ hasTopArrow: async () => await (await findByHook(base, DATA_HOOKS.TOP_ARROW)).exists(), /** @deprecated deprecated prop */ isDown: async () => (await (await contentContainer()).attr(DATA_DIRECTION)) === DROPDOWN_LAYOUT_DIRECTIONS.DOWN, /** @deprecated deprecated prop */ isUp: async () => (await (await contentContainer()).attr(DATA_DIRECTION)) === DROPDOWN_LAYOUT_DIRECTIONS.UP, isLinkOption: async (position) => doIfOptionExists(position, async () => { const optionDriver = await getOptionDriver(position); return optionDriver.isLink(); }), isOptionADivider: position => doIfOptionExists(position, async () => { const optionDriver = await getOptionDriver(position); return optionDriver.isDivider(); }), isOptionExists: async (optionText) => { for (const _option of await options()) { if ((await _option.text()) === optionText) { return true; } } return false; }, isOptionHovered: async (index) => doIfOptionExists(index, async () => { const optionDriver = await getOptionDriver(index); return optionDriver.isHovered(); }), isOptionSelected: async (index) => doIfOptionExists(index, async () => { const optionDriver = await getOptionDriver(index); return optionDriver.isSelected(); }), /** @deprecated */ isOptionHeightSmall: position => doIfOptionExists(position, async () => (await (await optionElementAt(position)).attr(DATA_OPTION.SIZE)) === 'small'), /** @deprecated */ isOptionHeightBig: position => doIfOptionExists(position, async () => (await (await optionElementAt(position)).attr(DATA_OPTION.SIZE)) === 'big'), isListItemFocused: async (position) => isElementFocused(await optionElementContentAt(position)), isShown: async () => !!(await (await contentContainer()).attr(DATA_SHOWN)), mouseEnter: () => base.hover(), mouseEnterAtOption: position => doIfOptionExists(position, async () => { const optionDriver = await getOptionDriver(position); return optionDriver.mouseEnter(); }), mouseLeave: async () => { switch (base.type) { case 'react': reactBase.mouseLeave(); return; case 'puppeteer': const { element } = await baseUniDriverFactory(base).element(); page.evaluate(element => { element.dispatchEvent(new MouseEvent('mouseout', { bubbles: true, view: window, cancelable: true, })); }, element); return; default: return; } }, /** @deprecated deprecated prop */ mouseClickOutside: () => ReactBase.clickBody(), mouseLeaveAtOption: position => doIfOptionExists(position, async () => { const optionDriver = await getOptionDriver(position); return optionDriver.mouseLeave(); }), /** @deprecated Use optionDriver*/ optionAt: () => { return optionElementAt.getNative(); // eslint-disable-line no-restricted-properties }, // This should be a private method since the hook include internal parts ('dropdown-divider-{id}, dropdown-item-{id})') */ /** @deprecated */ optionByHook: async (hook) => { const option = optionsElement().$(`[data-hook=${hook}]`); if (!(await option.exists())) { throw new Error(`an option with data-hook ${hook} was not found`); } return createOptionDriver(option); }, /** * Get Option by id * @returns {Promise<any>} */ optionById(optionId) { return this.optionByHook(`dropdown-item-${optionId}`); }, optionContentAt: position => doIfOptionExists(position, async () => { const optionDriver = await getOptionDriver(position); return optionDriver.content(); }), optionDriver: createOptionDriver, /** Get Options drivers */ options: async () => { const drivers = []; for (let position = 0; position < (await optionsLength()); position++) { drivers.push(await getOptionDriver(position)); } return drivers; }, optionsContent: async () => { const contentArray = []; for (const option of await options()) { const optionDriver = await createOptionDriver(option); contentArray.push(await optionDriver.content()); } return contentArray; }, markedOption: async () => { const allOptions = await options(); const optionsWithHovered = await Promise.all(allOptions.map(async (option) => ({ option, hovered: !!(await option.attr(DATA_OPTION.HOVERED)), }))); const hoveredOptions = optionsWithHovered .filter(option => option.hovered) .map(option => option.option); return ((hoveredOptions.length && createOptionDriver(hoveredOptions[0]).content()) || null); }, getSelectedOptionId: async () => await getDataAttributeValue(await contentContainer(), DATA_SELECTED_OPTION_ID), optionsLength, /** @deprecated should be private */ optionsScrollTop: () => optionsElement()._prop('scrollTop'), pressDownKey: () => base.pressKey('ArrowDown'), pressUpKey: () => base.pressKey('ArrowUp'), pressEnterKey: () => base.pressKey('Enter'), pressSpaceKey: () => base.pressKey(' '), pressTabKey: () => base.pressKey('Tab'), pressEscKey: () => base.pressKey('Escape'), keyDownListItem: async (position, key) => { const optionDriver = await getOptionDriver(position); return (await optionDriver.element()).pressKey(key); }, tabIndex: () => base._prop('tabIndex'), getListItemAttribute: async (position, attribute) => { const optionDriver = await getOptionDriver(position); return (await optionDriver.element()).attr(attribute); }, /** Returns the list type prop value */ getListType: dataHook => findByHook(body, dataHook).attr('data-list-type'), getOptionsContainerRole: () => optionsElement().attr('role'), }; }; const createOptionDriver = option => ({ element: () => option, mouseEnter: () => option.hover(), mouseLeave: () => ReactBase(option).mouseLeave(), isHovered: async () => !!(await option.attr(DATA_OPTION.HOVERED)), isSelected: async () => !!(await option.attr(DATA_OPTION.SELECTED)), content: () => option.text(), click: () => option.click(), isDivider: async () => { const divider = await findByHook(option, OPTION_DATA_HOOKS.DIVIDER); return divider.exists(); }, isDisabled: async () => !!(await option.attr(DATA_OPTION.DISABLED)), isLink: async () => (await option._prop('tagName')).toLowerCase() === 'a', }); //# sourceMappingURL=DropdownLayout.uni.driver.js.map