import { UniDriver, waitFor } from '@wix/wix-ui-test-utils/unidriver'; import { ButtonUniDriver, CounterBadgeUniDriver, InputWithOptionsUniDriver, SearchUniDriver, TextButtonUniDriver, } from '@wix/design-system/dist/testkit/unidriver'; import { CollectionDropdownFilterUniDriver } from '../DropdownFilter/CollectionDropdownFilter.uni.driver'; import { FiltersPanelUniDriver } from '../FiltersPanel/FiltersPanel.uni.driver'; import { CollectionViewsDropdownUniDriver } from '../CollectionViewsDropdown/CollectionViewsDropdown.uni.driver'; import TabsFilterUniDriver from '../TabsFilter/TabsFilter.uni.driver'; import { TableGridSwitchButtonUniDriver } from '../TableGridSwitchButton/TableGridSwitchButton.uni.driver'; import { CustomColumnsPanelUniDriver } from '../CustomColumnsPanel/CustomColumnsPanel.uni.driver'; import { MultiLevelSortingPanelUniDriver } from '../MultiLevelSortingPanel/MultiLevelSortingPanel.uni.driver'; import { baseUniDriverFactory } from '../../unidriver'; import { MultiLevelSortingCTAButtonUniDriver } from '../MultiLevelSorting/MultiLevelSortingCTAButton.uni.driver'; import { ToolbarSecondaryActionsUniDriver } from './ToolbarSecondaryActions.uni.driver'; import { MoreActionsUniDriver } from '../MoreActions/MoreActions.uni.driver'; export const CollectionToolbarUniDriver = ( base: UniDriver, body: UniDriver, ) => { const toolbar = baseUniDriverFactory(base); /** Returns more actions button driver */ const getMoreActions = (dataHook: string = 'toolbar-more-actions') => MoreActionsUniDriver(base, body).getMoreActions(dataHook); const getSecondaryActions = (index: number, dataHook?: string) => ToolbarSecondaryActionsUniDriver(base, body).getSecondaryActions( dataHook, index, ); const searchDriver = { ...SearchUniDriver(base.$('[data-hook="collection-search"]'), body), click: () => base.$('[data-hook="collection-search"]').click(), }; const filtersPanel = FiltersPanelUniDriver(body, body); const getSwitchButton = () => TableGridSwitchButtonUniDriver( base.$('[data-hook="layout-switch-toggle-button"]'), body, ); const getSwitchButtonDivider = () => base.$('[data-hook="collection-table--grid-switch--divider"]'); const getPrimaryActionButton = () => ButtonUniDriver( base.$('[data-hook="toolbar-primary-action-button"]'), body, ); const getInputWithOptionsDriver = (filterName: string) => { const dataHook = `collection-filter-${filterName}`; const inputWithOptionsBase = base.$(`[data-hook="${dataHook}"]`); const inputWithOptionsDriver = InputWithOptionsUniDriver( inputWithOptionsBase, body, ); return CollectionDropdownFilterUniDriver( inputWithOptionsDriver, dataHook, inputWithOptionsBase, body, ); }; const isFiltersPanelOpen = () => filtersPanel.isOpen(); const getMoreFiltersPanelButton = () => ButtonUniDriver(base.$('[data-hook="more-filters-button"]'), body); const clickMoreFiltersButton = () => getMoreFiltersPanelButton().click(); const closeFiltersPanel = () => filtersPanel.clickCloseButton(); const getViewsDropdown = () => CollectionViewsDropdownUniDriver(base, body); const isToolbarWithFilters = async () => base.$(`[data-hook="toolbar-item-filter-0"]`).exists(); const getToolbarFiltersItemsCount = async () => { return base.$$(`[data-hook^="toolbar-item-filter-"]`).count(); }; const getToolbarFilterTitleAt = async (index: number) => { return base .$( `[data-hook="toolbar-item-filter-${index}"] [data-hook="table-toolbar-label"]`, ) .text(); }; const getMultiLevelSortingButton = () => MultiLevelSortingCTAButtonUniDriver(base, body, { dataHook: 'multi-level-sorting-button', }); const slidingModalBase = () => body.$('[data-hook="cairo-side-panel-modal"]'); const customColumnsPopover = () => CustomColumnsPanelUniDriver(body, body); const getMultiLevelSortingPanel = () => MultiLevelSortingPanelUniDriver(body, body); const getSearchCancelButton = () => TextButtonUniDriver(base.$('[data-hook="collection-search-cancel"]'), body); return { ...toolbar, getSearch: () => searchDriver, getToolbarFiltersItemsCount, getMoreActions, getSecondaryActions, wait: (timeout?: number) => base.wait(timeout), /** Get the text of the search input */ getSearchText: searchDriver.inputDriver.getText, /** Enter text into the search input */ enterSearchText: searchDriver.inputDriver.enterText, /** Get the max length of the search input */ getSearchMaxLength: searchDriver.inputDriver.getMaxLength, /** Clear the text of the search input */ clearSearchText: searchDriver.inputDriver.clearText, /** Indicates search input exists */ searchInputExists: searchDriver.inputDriver.exists, /** Clicks clear button of the search input */ clickClearSearchText: searchDriver.inputDriver.clickClear, /** Indicates whether the search cancel button exists */ searchCancelButtonExists: () => getSearchCancelButton().exists(), /** Clicks the cancel button of the search */ clickSearchCancelButton: () => getSearchCancelButton().click(), isToolbarWithFilters: () => isToolbarWithFilters(), skeletonExists: () => base.$('[data-hook="toolbar-skeleton"]').exists(), viewsSkeletonExists: () => base.$('[data-hook="toolbar-views-skeleton"]').exists(), getViewsDropdown: () => getViewsDropdown(), openViewsDropdown: () => getViewsDropdown().open(), getViewListItemAt: (index: number) => getViewsDropdown().getViewListItemAt(index), getViewListItemById: (id: string) => getViewsDropdown().getViewListItemById(id), getSaveViewModal: () => getViewsDropdown().getSaveViewModal(), getRenameViewModal: () => getViewsDropdown().getRenameViewModal(), /** Click on a FiltersPanel's "clear" button */ clickClearAllFilters: filtersPanel.clickClearAllFilters, /** Get text from FiltersPanel's "applied filter" section **/ getFilterAppliedText: filtersPanel.getFilterAppliedText, /** get FiltersPanel's "clear" button */ getClearAllFiltersButton: filtersPanel.getClearAllFiltersButton, /** * Select specific items of a dropdown filter that placed in the table toolbar * @param filterName - the key of the filter in the filters object passed to `useCollection` * @param ids - keys of the items to select * @param options * @param options.closeDropdown - close the dropdown after selection - default=true */ selectFilterOptions: ( filterName: string, ids: string[], options?: { closeDropdown?: boolean }, ) => { return getInputWithOptionsDriver(filterName).selectOptions(ids, options); }, /** * Select specific items of a dropdown filter that placed in the table toolbar * @param filterName - the key of the filter in the filters object passed to `useCollection` * @param id - keys of the item to select * @param options */ selectFilterOption: (filterName: string, id: string) => { return getInputWithOptionsDriver(filterName).selectOption(id); }, /** * Select random options of a dropdown filter that placed in the table toolbar * @param filterName - the key of the filter in the filters object passed to `useCollection` * @param count - number of items to select * @param options * @param options.closeDropdown - close the dropdown after selection - default=true */ selectFilterRandomOptions: ( filterName: string, count: number, options?: { closeDropdown?: boolean }, ) => { return getInputWithOptionsDriver(filterName).selectRandomOptions( count, options, ); }, /** * Returns the amount of available filters options in the dropdown * @param filterName - the key of the filter in the filters object passed to `useCollection` */ getFilterDropdownOptionsCount: (filterName: string) => { return getInputWithOptionsDriver(filterName).getOptionsCount(); }, /** * Returns all available filter's options ids * @param filterName - the key of the filter in the filters object passed to `useCollection` */ getFilterDropdownAvailableOptionsIds: (filterName: string) => { return getInputWithOptionsDriver(filterName).getAvailableOptionsIds(); }, /** * Indicates if a specific dropdown option is disabled * @param filterName - the key of the filter in the filters object passed to `useCollection` * @param id - the key of the option */ isFilterDropdownOptionDisabled: (filterName: string, id: string) => { return getInputWithOptionsDriver(filterName).isOptionDisabled(id); }, /** * Indicates if a specific dropdown option exposes a disabled tooltip * @param filterName - the key of the filter in the filters object passed to `useCollection` * @param id - the key of the option */ hasFilterDropdownOptionDisabledTooltip: ( filterName: string, id: string, ) => { return getInputWithOptionsDriver(filterName).hasOptionDisabledTooltip(id); }, /** * Returns filter's placeholder text * @param filterName - the key of the filter in the filters object passed to `useCollection` */ getFilterInputPlaceholder: (filterName: string) => { return getInputWithOptionsDriver(filterName).getInputPlaceholder(); }, /** * Indicates if the filter is in the empty state * @param filterName - the key of the filter in the filters object passed to `useCollection` */ isFilterInNoSearchResultsState: (filterName: string) => { return getInputWithOptionsDriver(filterName).isNoSearchResults(); }, /** * Gets the empty state text * @param filterName - the key of the filter in the filters object passed to `useCollection` */ getFilterEmptyStateText: (filterName: string) => { return getInputWithOptionsDriver(filterName).getEmptyStateText(); }, /** * Indicates if the filter is in the empty state * @param filterName - the key of the filter in the filters object passed to `useCollection` */ isFilterInErrorState: (filterName: string) => { return getInputWithOptionsDriver(filterName).isErrorStateExists(); }, /** * Indicates if the filter has this element. Can be used to check fixedFooter, for example * @param filterName - the key of the filter in the filters object passed to `useCollection` * @param dataHook - the dataHook of the element */ existsInFilter: async (filterName: string, dataHook: string) => { await getInputWithOptionsDriver(filterName).inputDriver.click(); return getInputWithOptionsDriver(filterName).existInFilter(dataHook); }, /** * Enters a text to the filter's Input * @param filterName - the key of the filter in the filters object passed to `useCollection` * @param value */ enterFilterText: async (filterName: string, value: string) => { await getInputWithOptionsDriver(filterName).inputDriver.click(); return getInputWithOptionsDriver(filterName).inputDriver.enterText(value); }, /** * Select specific items of a dropdown filter that placed in the filter panel * @param filterName - the key of the filter in the filters object passed to `useCollection` * @param ids - keys of the items to select * @param options * @param options.closePanel - close the filters panel after selection - default=true * @param options.closeAccordionItem - close the accordion item after selection - default=true * @param options.closeDropdown - close the dropdown after selection - default=true */ selectPanelFilterOptions: async ( filterName: string, ids: string[], options?: { closePanel?: boolean; closeAccordionItem?: boolean; closeDropdown?: boolean; }, ) => { if (!(await isFiltersPanelOpen())) { await clickMoreFiltersButton(); } return filtersPanel.selectFilterOptions(filterName, ids, options); }, /** * Select random items of a dropdown filter that placed in the table toolbar * @param filterName - the key of the filter in the filters object passed to `useCollection` * @param count - number of items to select * @param options * @param options.closePanel - close the filters panel after selection - default=true * @param options.closeAccordionItem - close the accordion item after selection - default=true * @param options.closeDropdown - close the dropdown after selection - default=true */ selectPanelFilterRandomOptions: async ( filterName: string, count: number, options?: { closePanel?: boolean; closeAccordionItem?: boolean; closeDropdown?: boolean; }, ) => { if (!(await isFiltersPanelOpen())) { await clickMoreFiltersButton(); } return filtersPanel.selectFilterRandomOptions(filterName, count, options); }, /** * Select specific items of a inline checkboxes filter that placed in the filter panel * @param filterName - the key of the filter in the filters object passed to `useCollection` * @param ids - keys of the items to select * @param options * @param options.closePanel - close the filters panel after selection - default=true * @param options.closeAccordionItem - close the accordion item after selection - default=true */ checkPanelFilterInlineCheckboxes: async ( filterName: string, ids: string[], options: { closePanel?: boolean; closeAccordionItem?: boolean } = {}, ) => { if (!(await isFiltersPanelOpen())) { await clickMoreFiltersButton(); } return filtersPanel.checkFilterInlineCheckboxes(filterName, ids, options); }, /** * Select specific/random dates in date range filter that placed in the filter panel * @param filterName - the key of the filter in the filters object passed to `useCollection` * @param options.dates - specific dates to choose * @param options.closePanel - close the filters panel after selection - default=true * @param options.closeAccordionItem - close the accordion item after selection - default=true */ choosePanelFilterDateRange: async ( filterName: string, options: { closePanel?: boolean; closeAccordionItem?: boolean; dates?: Date[]; } = {}, ) => { if (!(await isFiltersPanelOpen())) { await clickMoreFiltersButton(); } return filtersPanel.chooseDatesFilterDateRange(filterName, options); }, /** * Open filter panel and click a filter with 'filterName' * @param filterName - the key of the filter in the filters object passed to `useCollection` */ clickFilterInPanel: async (filterName: string) => { if (!(await isFiltersPanelOpen())) { await clickMoreFiltersButton(); } return filtersPanel.clickFilterTitle(filterName); }, /** Indicates whether the filters panel is open */ isFiltersPanelOpen: () => filtersPanel.isOpen(), /** Get layout switch button */ getSwitchButton, /** get layout switch button divider */ getSwitchButtonDivider, /** Get the title of the filters panel */ getFiltersPanelTitleText: () => filtersPanel.getTitleText(), /** Opens the filters panel */ clickMoreFiltersButton: () => clickMoreFiltersButton(), /** Returns the number of applied filters in the Filters badge */ getMoreFiltersButtonCounterValue: () => CounterBadgeUniDriver( base.$('[data-hook="more-filters-button-counter"]'), body, ).getContentText(), /** Closes the filters panel */ closeFiltersPanel: () => closeFiltersPanel(), /** Closes custom columns panel */ closeCustomColumnsPanel: () => customColumnsPopover().clickCloseButton(), getCustomColumnsPanelTitle: () => customColumnsPopover().getTitle(), getCustomColumnsPanelSubtitle: () => customColumnsPopover().getSubtitle(), customColumnsPanelCloseButtonExists: () => customColumnsPopover().closeButtonExists(), getCustomColumnInfoIconAt: (index: number) => customColumnsPopover().getCustomColumnInfoIconAt(index), /** * Gets the title of the accordion item of a filter placed in the filters panel * @param filterName - the key of the filter in the filters object passed to `useCollection` */ getPanelFilterTitleText: (filterName: string) => filtersPanel.getFilterTitleText(filterName), /** * Click on a title of the accordion item of a filter placed in the filters panel * @param filterName - the key of the filter in the filters object passed to `useCollection` */ clickPanelFilterTitle: (filterName: string) => filtersPanel.clickFilterTitle(filterName), /** * Indicates whether the accordion item of filter placed in the filters panel is open * @param filterName - the key of the filter in the filters object passed to `useCollection` */ isPanelFilterExpanded: (filterName: string) => filtersPanel.isFilterExpanded(filterName), /** * Get a testkit for a custom filter that places in the filters panel * @param filterName - the key of the filter in the filters object passed to `useCollection` * @param fn - a callback function that accepts the filters panel base element and should return a testkit that matches the custom filter */ getPanelCustomFilter: async ( filterName: string, fn: (element: E) => T, ) => filtersPanel.getCustomFilter(filterName, fn), /** * Get a testkit for a custom filter that places in the filters panel * @param fn - a callback function that accepts the toolbar base element and should return a testkit that matches the custom filter */ getCustomFilter: async (fn: (element: E) => T) => fn(await toolbar.element()), /** Indicates whether the button that open the filters panel exists */ moreFilterButtonExists: () => getMoreFiltersPanelButton().exists(), /** Gets the title of the button that open the filters panel exists */ getMoreFiltersButtonText: () => getMoreFiltersPanelButton().getButtonTextContent(), /** Clicks the button that opens the custom columns dropdown */ clickCustomColumnsButton: () => base.$('[data-hook="custom-columns-button"]').click(), customColumnsButtonExists: () => base.$('[data-hook="custom-columns-button"]').exists(), /** Indicates whether the custom columns dropdown is open */ isCustomColumnsOpen: () => customColumnsPopover().isOpen(), isCustomColumnsAddNewExist: () => customColumnsPopover().addNewExists(), clickCustomColumnsAddNew: () => customColumnsPopover().clickAddNew(), waitSidePanelFullyOpened: () => { return waitFor( async () => (await slidingModalBase().attr('data-transition-status')) === 'entered', ); }, waitSidePanelFullyClosed: () => { return waitFor( async () => (await slidingModalBase().attr('data-transition-status')) === 'exited', ); }, /** * Click checkboxes that hide / show columns from the table * @param ids - IDs of the columns to click on */ clickCustomColumnsCheckboxes: (ids: string[]) => customColumnsPopover().checkOptions(ids), /** * Get a column checkbox within the custom columns dropdown * @param index - index of the column checkbox */ getCustomColumnCheckboxAt: (index: number) => customColumnsPopover().getCheckboxAt(index), /** * Get full custom columns driver */ getCustomColumnsDriver: () => customColumnsPopover(), /** * Get a column checkboxes count within the custom columns dropdown */ getCustomColumnCheckboxesCount: () => customColumnsPopover().getCheckboxesCount(), /** * Get a column checkbox within the custom columns dropdown * @param id - column id */ getCustomColumnCheckboxById: (id: string) => customColumnsPopover().getCheckboxById(id), /** * Get all custom columns items text */ getCustomColumnsTitles: () => customColumnsPopover().getTitles(), /** Returns the amount of hidden columns rendered in the CustomColumns CTA badge */ getCustomColumnsButtonCounterValue: () => CounterBadgeUniDriver( base.$('[data-hook="custom-columns-button-counter"]'), body, ).getContentText(), /** * Get a InputWithOptions testkit for a filter that placed in the table toolbar * @param filterName - the key of the filter in the filters object passed to `useCollection` */ getInputWithOptions: (filterName: string) => getInputWithOptionsDriver(filterName), /** * Get a InputWithOptions testkit for a filter that placed in the filters panel * @param filterName - the key of the filter in the filters object passed to `useCollection` */ getFiltersPanelInputWithOptions: (filterName: string) => filtersPanel.getInputWithOptionsDriver(filterName), getFiltersPanelMultiSelect: (filterName: string) => filtersPanel.getFiltersPanelMultiSelect(filterName), /** * Scrolls down a dropdown filter placed in the table toolbar * @param filterName */ scrollDownFilter: (filterName: string) => getInputWithOptionsDriver(filterName).scrollDown(), /** * Scrolls down a dropdown filter placed in the filters panel * @param filterName */ scrollDownPanelFilter: (filterName: string) => filtersPanel.getInputWithOptionsDriver(filterName).scrollDown(), clickFilterClearButton: (filterName: string) => { return getInputWithOptionsDriver(filterName).clickInputClear(); }, /** * Returns an amount of filters currently rendered in the Panel. */ getPanelFiltersCount: filtersPanel.getPanelFiltersCount, /** Whether the filters-panel search box is rendered (only when >7 filters). */ isFilterSearchVisible: filtersPanel.isFilterSearchVisible, /** Type into the filters-panel search box. */ enterFilterSearch: filtersPanel.enterFilterSearch, /** Clear the filters-panel search input (×). */ clearFilterSearchInput: filtersPanel.clearFilterSearchInput, /** Current value of the filters-panel search input. */ getFilterSearchValue: filtersPanel.getFilterSearchValue, /** Whether the "No filters match" empty state is visible. */ isNoFiltersMatchVisible: filtersPanel.isNoFiltersMatchVisible, /** Title text of the "No filters match" empty state. */ getNoFiltersMatchText: filtersPanel.getNoFiltersMatchText, /** Click the "Clear search" button in the empty state. */ clickClearSearchButton: filtersPanel.clickClearSearchButton, /** * Returns filter's title at in at index. */ /** * Get a filter's title * @param index - index of the filter */ getToolbarFilterTitleAt, /** * Get tabs driver */ getTabs: () => TabsFilterUniDriver(base.$('[data-hook="collection-tabs-filter"]'), body), /** * Get date range filter by filter name */ getDateRangeFilter: filtersPanel.getDateRangeFilter, /** * Get number range filter driver by filter name */ getNumberRangeFilterDriver: (filterName: string) => filtersPanel.getNumberRangeDriver(filterName), /** * Get operator picker filter driver by filter name */ getOperatorPickerDriver: (filterName: string) => filtersPanel.getOperatorPickerDriver(filterName), /** * Get radio group filter by filter name */ getRadioGroupFilter: filtersPanel.getRadioGroupFilter, getMultiLevelSortingButton, /** * Checks if the MultiLevelSorting button exists in the toolbar */ multiLevelSortingButtonExists: () => getMultiLevelSortingButton().getIconButton().exists(), /** * Clicks the MultiLevelSorting button */ clickMultiLevelSortingButton: () => getMultiLevelSortingButton().getIconButton().click(), getMultiLevelSortingButtonCounterValue: () => CounterBadgeUniDriver( base.$('[data-hook="multi-level-sorting-button-counter"]'), body, ).getContentText(), /** * MultiLevelSorting panel driver */ getMultiLevelSortingPanel, /** * Button driver for primary action button */ getPrimaryActionButton, getMainToolbar: () => base.$('[data-hook="collection-table-toolbar"]'), /** * Indicates whether the collection table toolbr total items counter exists */ isShowTotal: () => base.$('[data-hook="toolbar-counter"]').exists(), /** * Gets collection table toolbr total items counter */ getShowTotal: () => CounterBadgeUniDriver( base.$('[data-hook="toolbar-counter"]'), body, ).getContentText(), /** * Indicates whether the collection table title exists */ isTitleExists: () => base.$('[data-hook="toolbar-title"]').exists(), /** * Get collection table toolbar title */ getTitleText: () => base.$('[data-hook="toolbar-title"]').text(), /** * Get collection table toolbar subtitle */ getSubtitleText: () => base.$('[data-hook="toolbar-subtitle"]').text(), /** * Get collection table toolbar learn more button */ getSubtitleLearnMoreButton: () => TextButtonUniDriver( base.$('[data-hook="toolbar-subtitle-learn-more-cta"]'), body, ), applyButton: () => filtersPanel.applyButton(), discardChangesModal: () => filtersPanel.discardChangesModal(), getFiltersPanelItemTextAt: filtersPanel.getItemTextAt, getFiltersPanelItemsCount: filtersPanel.getItemsCount, getCustomFieldOptionsAt: (index: number) => customColumnsPopover().getCustomFieldOptionsAt(index), _filtersPanel: () => filtersPanel, }; };