import { UniDriver, waitFor } from '@wix/wix-ui-test-utils/unidriver'; import { baseUniDriverFactory, isSled2, isSled3 } from '../../unidriver'; import { EmptyStateUniDriver, FloatingNotificationUniDriver, SelectorListUniDriver, SelectorUniDriver, } from '@wix/design-system/dist/testkit/unidriver'; import { PickerTableListItemUniDriver } from '../PickerTableListItem/PickerTableListItem.uni.driver'; export function PickerUniDriver(base: UniDriver, body: UniDriver) { const selectorList = SelectorListUniDriver(base, body); const getEmptyState = async (factory: (element: E) => T) => factory(await base.getNative()); const getSelectors = () => base .$('[data-hook="selector-list-content"]') .$$('[data-hook="selector-list-selector"]'); const selectorDriverAt = (i: number) => SelectorUniDriver(getSelectors().get(i), body); const tableListItemDriverAt = (i: number) => PickerTableListItemUniDriver(getSelectors().get(i), body); const getSearchLoader = () => base.$('[data-hook="search-loader"]'); const getFloatingNotification = () => FloatingNotificationUniDriver( base.$('[data-hook="floating-notification"]'), body, ); const getPrimaryActionButtonAt = (i: number) => getSelectors().get(i).$('[data-hook="primary-action-button"]'); return { ...baseUniDriverFactory(base), wait: (timeout?: number) => base.wait(timeout), waitSearchLoader: (timeout?: number) => getSearchLoader().wait(timeout), searchLoaderExists: () => getSearchLoader().exists(), waitSearchLoaderRemoved: (timeout?: number) => waitFor(async () => !(await getSearchLoader().exists()), timeout), numberOfItemsInList: () => getSelectors().count(), primaryButtonExistsAt: (i: number) => getPrimaryActionButtonAt(i).exists(), getPrimaryActionButtonAt, scrollDown: async () => { const element = await base.getNative(); // puppeteer if (isSled2(element)) { const { page } = element as { page: { evaluate: (fn: () => void) => Promise } }; await page.evaluate(() => { const e = document.querySelector( '[data-hook="selector-list-content"]', )!; e.scrollBy({ behavior: 'smooth', top: e.scrollHeight }); }); } // playwright — run the same browser-side scroll via the locator's page else if (isSled3(element)) { const locator = element as { page: () => { evaluate: (fn: () => void) => Promise }; }; await locator.page().evaluate(() => { const e = document.querySelector( '[data-hook="selector-list-content"]', )!; e.scrollBy({ behavior: 'smooth', top: e.scrollHeight }); }); } // jsdom else { await selectorList.scrollDown(); } }, scrollTo: (i: number) => getSelectors().get(i).scrollIntoView?.(), toggleSelectorAt: selectorList.toggleSelectorAt, getTotalSelected: async () => { const checked = await Promise.all( await getSelectors().map((selector) => SelectorUniDriver(selector, body).isChecked(), ), ); return checked.filter(Boolean).length; }, isSelectorCheckedAt: selectorList.isSelectorCheckedAt, isListItemDisabledAt: (i: number) => selectorDriverAt(i).isDisabled(), waitListItemAt: async (i: number, timeout?: number) => waitFor(() => selectorDriverAt(i).exists(), timeout), getTableListItemAt: (i: number) => tableListItemDriverAt(i), waitRowEntered: (i: number, timeout?: number) => base .$('[data-hook="selector-list-content"]') .$$('[data-hook="picker-list-fade-item"].fade-entered') .get(i) .wait(timeout), hoverItemAt: (i: number) => getSelectors().get(i).hover(), getTitleTextAt: async (i: number) => selectorDriverAt(i).titleTextDriver().getText(), isIndeterminateAt: async (i: number) => selectorDriverAt(i).isIndeterminate(), getTitleTextContentAt: async (i: number) => getSelectors().get(i).$('[data-hook="selector-title"]').text(), getSubtitleTextAt: async (i: number) => selectorDriverAt(i).subtitleTextDriver().getText(), getSubtitleTextContentAt: async (i: number) => getSelectors().get(i).$('[data-hook="selector-subtitle"]').text(), getExtraNodeElementAt: (i: number) => selectorDriverAt(i).getExtraNode(), getImageElementAt: (i: number) => selectorDriverAt(i).getImage(), getToggleTooltipTextAt: (i: number) => selectorDriverAt(i).getTooltipText(), floatingNotificationExists: () => getFloatingNotification().exists(), getFloatingNotificationText: () => getFloatingNotification().getText(), getEmptyState, getEmptyStateByDataHook: (dataHook = 'picker-empty-state') => EmptyStateUniDriver(base.$(`[data-hook="${dataHook}"]`), body), getErrorStateByDataHook: (dataHook: string) => EmptyStateUniDriver(base.$(`[data-hook="${dataHook}"]`), body), }; }