import { BulkActionToolbarUniDriver } from '../BulkActionToolbar/BulkActionToolbar.uni.driver'; import { CollectionItemActionsUniDriver } from '../CollectionItemActions/CollectionItemActions.uni.driver'; import { CollectionToolbarUniDriver } from '../CollectionToolbar/CollectionToolbar.uni.driver'; import { UniDriver, waitFor } from '@wix/wix-ui-test-utils/unidriver'; import { LoaderUniDriver, MessageModalLayoutUniDriver, TableUniDriver, LiveRegionUniDriver, PopoverUniDriver, } from '@wix/design-system/dist/testkit/unidriver'; import { AppliedFiltersTagListUniDriver } from '../AppliedFiltersTagList/AppliedFiltersTagList.uni.driver'; import { TableTopNotificationUniDriver } from '../TableTopNotification/TableTopNotification.uni.driver'; import TabsFilterUniDriver from '../TabsFilter/TabsFilter.uni.driver'; import { MultiBulkActionToolbarUniDriver } from '../MultiBulkActionToolbar/MultiBulkActionToolbar.uni.driver'; import ExportButtonUniDriver from '../ExportButton/ExportButton.uni.driver'; import ExportModalUniDriver from '../ExportButton/ExportModal.uni.driver'; import ImportButtonUniDriver from '../ImportButton/ImportButton.uni.driver'; import ImportModalUniDriver from '../ImportButton/ImportModal.uni.driver'; import { DragAndDropUniDriver } from '../DragAndDrop/DragAndDrop.uni.driver'; import { ReorderModeToolbarUniDriver } from '../CollectionToolbar/ReorderModeToolbar.uni.driver'; import { SummaryBarUniDriver } from '../SummaryBar/SummaryBar.uni.driver'; import { CustomFieldPanelUniDriver } from '../CustomFieldsPanel/CustomFieldPanel.uni.driver'; export const CollectionTableUniDriver = (base: UniDriver, body: UniDriver) => { const table = TableUniDriver(base, body); const toolbar = CollectionToolbarUniDriver( base.$('[data-hook="collection-toolbar"]'), body, ); const getLiveRegion = () => LiveRegionUniDriver(body.$('[data-hook="collection-live-region"]'), body); const tableContentBase = () => base.$('[data-hook="table-content"]'); const refreshLoaderBase = () => base.$(`[data-hook="placeholder-states-loading-state"]`); const refreshLoader = () => LoaderUniDriver(refreshLoaderBase(), body); const getActionCell = (rowIndex: number) => { return CollectionItemActionsUniDriver(table.getRow(rowIndex), body); }; const bulkActionToolbar = BulkActionToolbarUniDriver( base.$('[data-hook="bulk-action-toolbar"]'), body, ); const multiBulkActionToolbar = MultiBulkActionToolbarUniDriver( base.$('[data-hook="bulk-action-toolbar"]'), body, ); const tagList = AppliedFiltersTagListUniDriver( base.$('[data-hook="collection-table-sub-toolbar"]'), body, ); const getExportModal = () => ExportModalUniDriver(base, body); const getExportButton = () => ExportButtonUniDriver(base.$('[data-hook="export-button"]'), body); const getImportModal = () => ImportModalUniDriver(base, body); const getImportButton = () => ImportButtonUniDriver(base.$('[data-hook="import-button"]'), body); const getRowDragHandleCell = (index: number) => { return table.getRow(index).$('[data-hook="drag-handle"]'); }; const getRowDragHandle = (index: number) => { return getRowDragHandleCell(index).$('[role="button"]'); }; const getDragAndDrop = () => DragAndDropUniDriver(base); const openManageViewPopover = () => toolbar.getViewsDropdown().openManageViewPopover(); const saveNewViewActionClick = () => toolbar.getViewsDropdown().saveNewViewActionClick(); const deleteViewActionClick = () => toolbar.getViewsDropdown().deleteViewActionClick(); const saveViewChangesActionClick = () => toolbar.getViewsDropdown().saveViewChangesActionClick(); const renameViewActionClick = () => toolbar.getViewsDropdown().renameViewActionClick(); const setAsDefaultViewActionClick = () => toolbar.getViewsDropdown().setAsDefaultViewActionClick(); const getReorderModeToolbar = () => ReorderModeToolbarUniDriver( base.$('[data-hook="reorder-mode-toolbar"]'), body, ); const getSummaryBar = () => SummaryBarUniDriver(base, body); const loadingRowExists = async () => { return base.$('[data-hook="table-loading-row"]').exists(); }; const _loadingRowWithAnimationExists = async () => { return base.$('[data-hook="loading-row-lottie"]').exists(); }; return { ...toolbar, ...table, getToolbar: () => toolbar, isHeaderHiddenAccessible: async () => (await base.$('[data-hook="titlebar-a11y-wrapper"]')._prop('style')) .display === 'none', /** @private */ _getTableElement: () => base.$('[data-hook="table-content"] table'), /** Wait for the table refresh loader to be shown */ waitRefreshLoader: (timeout?: number) => refreshLoaderBase().wait(timeout), /** Wait for the table refresh loader to be removed */ waitRefreshLoaderRemoved: (timeout?: number) => waitFor(async () => !(await refreshLoaderBase().exists()), timeout), /** Indicates whether table refresh loader is in loading status */ isRefreshLoaderLoading: () => refreshLoader().isLoading(), /** Indicates whether table refresh loader exists */ refreshLoaderExists: () => refreshLoader().exists(), /** Indicates whether table refresh loader exists and no rows are rendered */ refreshLoaderExistsAndNoRows: async () => { const [refreshLoaderExists, tableContentExists] = await Promise.all([ refreshLoader().exists(), tableContentBase().exists(), ]); return refreshLoaderExists && !tableContentExists; }, /** indicates whether the table content exists */ tableContentExists: () => tableContentBase().exists(), getAppliedFiltersTagListDriver: () => AppliedFiltersTagListUniDriver( base.$('[data-hook="collection-table-sub-toolbar"]'), body, ), /** Indicates whether applied filters tag list exists in the table sub-toolbar */ appliedFiltersTagListExists: tagList.exists, /** Get the text of a tag inside the applied filters tag list */ getAppliedFilterTagText: tagList.getAppliedFilterTagText, /** Indicates a tag inside the applied filters tag list exists */ appliedFilterTagExists: tagList.appliedFilterTagExists, /** Get a tag driver of a tag inside the applied filters tag list */ getAppliedFilterTag: tagList.getAppliedFilterTag, /** Remove a tag inside the applied filters tag list */ removeAppliedFilterTag: tagList.removeAppliedFilterTag, /** Indicates whether table sub-toolbar exists */ subToolbarExists: tagList.exists, /** Indicates whether the Manage View popover exists */ manageViewPopoverExists: () => toolbar.getViewsDropdown().manageViewPopoverExists(), /** Indicates whether the Manage View popover opened */ isManageViewPopoverOpen: () => toolbar.getViewsDropdown().isManageViewPopoverOpen(), /** Opens the Manage View popover */ openManageViewPopover, /** Clicks the Save Changes action in the Manage View popover */ saveViewChangesActionClick, /** Clicks the Save as New View action in the Manage View popover */ saveNewViewActionClick, /** Clicks the Rename action in the Manage View popover */ renameViewActionClick, /** Clicks the Set as Default View action in the Manage View popover */ setAsDefaultViewActionClick, /** Clicks the Delete action in the Manage View popover */ deleteViewActionClick, /** Get DropdownLayoutOptionUniDriver of a Save Changes option */ getSaveViewChangesBtn: () => toolbar.getViewsDropdown().getSaveViewChangesBtn(), /** Get DropdownLayoutOptionUniDriver of a Save as New View option */ getSaveNewViewBtn: () => toolbar.getViewsDropdown().getSaveNewViewBtn(), /** Get DropdownLayoutOptionUniDriver of a Delete View option */ getDeleteViewBtn: () => toolbar.getViewsDropdown().getDeleteViewBtn(), /** Get DropdownLayoutOptionUniDriver of a Rename option */ getRenameViewBtn: () => toolbar.getViewsDropdown().getRenameViewBtn(), /** Get DropdownLayoutOptionUniDriver of a Set as Default View option */ getSetAsDefaultViewBtn: () => toolbar.getViewsDropdown().getSetAsDefaultViewBtn(), /** Saves new view with a defined name and current filters / sort / columns */ saveNewView: async (name: string) => toolbar.getViewsDropdown().saveNewView(name), /** Deletes the view with a given index */ deleteView: async (ind: number) => toolbar.getViewsDropdown().deleteView(ind), /** Saves changes to the current view */ saveViewChanges: async () => toolbar.getViewsDropdown().saveViewChanges(), /** Renames the current view with a given name */ renameView: async (name: string) => toolbar.getViewsDropdown().renameView(name), /** Sets a default view with a given index */ setAsDefaultView: async (ind: number) => toolbar.getViewsDropdown().setAsDefaultView(ind), clickAppliedFiltersClearButton: tagList.clickActionButton, wait: (timeout?: number) => base.wait(timeout), /** * Open & confirm action modal for a row */ openAndConfirmActionModal: async ( rowIndex: number, actionDataHook: string, ) => { await getActionCell(rowIndex).clickSecondaryAction(actionDataHook); return getActionCell(rowIndex).confirmActionModal(); }, /** * Open & confirm delete modal for a row */ openAndConfirmDeleteModal: async ( rowIndex: number, actionDataHook = 'collection-delete-action', ) => { await getActionCell(rowIndex).clickSecondaryAction(actionDataHook); return getActionCell(rowIndex).confirmActionModal(); }, /** * Opens the popover menu inside the action cell of a specific row * @param rowIndex - index of the row */ openActionCellPopoverMenu: (rowIndex: number) => getActionCell(rowIndex).clickPopoverMenu(), /** * Number of action menu items inside the action cell of a specific row * @param rowIndex - index of the row */ getHiddenActionsCount: (rowIndex: number) => getActionCell(rowIndex).getHiddenActionsCount(), /** * Indicates whether a menu item inside the actions cell is disabled * @param rowIndex - index of the row * @param dataHook - data-hook of the menu item */ isSecondaryActionDisabled: (rowIndex: number, dataHook: string) => getActionCell(rowIndex).isSecondaryActionDisabled(dataHook), /** Get action button of the bulk action toolbar */ getBulkActionButton: (dataHook?: string) => bulkActionToolbar.getButton(dataHook), /** Clicks the action button of the bulk action toolbar */ clickBulkActionButton: (dataHook?: string) => bulkActionToolbar.clickButton(dataHook), /** Indicates whether the action button of the bulk action toolbar exists */ bulkActionButtonExists: () => bulkActionToolbar.isButtonExists(), /** Indicates whether the bulk action toolbar exists */ bulkActionToolbarExists: () => bulkActionToolbar.exists(), /** Get the text of the action button of the bulk action toolbar */ getSelectedCountText: () => bulkActionToolbar.getSelectedCountText(), /** Indicates whether the MultiBulkActionToolbar button's tooltip element exist */ isMultiBulkActionButtonTooltipExist: (dataHook: string) => multiBulkActionToolbar.isTooltipExist(dataHook), /** Indicates whether the MultiBulkActionToolbar button's tooltip is shown */ isMultiBulkActionButtonTooltipVisible: (dataHook: string) => multiBulkActionToolbar.isTooltipVisible(dataHook), /** Get the MultiBulkActionToolbar button's tooltip text */ getMultiBulkActionButtonTooltipText: (dataHook: string) => multiBulkActionToolbar.getTooltipText(dataHook), /** Clicks outside of the MultiBulkActionToolbar button's tooltip */ clickOutsideMultiBulkActionButtonTooltip: (dataHook: string) => multiBulkActionToolbar.clickOutsideTooltip(dataHook), /** Triggers the MultiBulkActionToolbar button's tooltip */ mouseEnterMultiBulkActionButtonTooltip: (dataHook: string) => multiBulkActionToolbar.mouseEnterTooltip(dataHook), /** Hides the MultiBulkActionToolbar button's tooltip */ mouseLeaveMultiBulkActionButtonTooltip: (dataHook: string) => multiBulkActionToolbar.mouseLeaveTooltip(dataHook), /** Get action button of the multi bulk action toolbar */ getMultiBulkActionButton: (dataHook: string) => multiBulkActionToolbar.getButton(dataHook), /** Clicks the action button of the multi bulk action toolbar */ clickMultiBulkActionButton: (dataHook: string) => multiBulkActionToolbar.clickButton(dataHook), /** Get primary action popover */ getPrimaryActionPopover: (dataHook?: string) => bulkActionToolbar.getPopover(`${dataHook}-popover`), /** Open primary action popover */ togglePrimaryActionPopover: (dataHook?: string) => bulkActionToolbar.clickButton(`${dataHook}`), /** Checks if primary action popover is open */ isPrimaryActionPopoverOpen: (dataHook?: string) => bulkActionToolbar.getPopover(`${dataHook}-popover`).isMenuOpen(), /** Is the PopoverMenu of the multi bulk action toolbar open */ isMultiBulkActionMoreActionsOpen: () => multiBulkActionToolbar.isMoreActionsOpen(), /** Get number of items under the "more actions" PopoverMenu of the multi bulk action toolbar */ getMultiBulkActionMoreActionsItemsCount: () => multiBulkActionToolbar.getMoreActionsItemsCount(), /** Get item from "more actions" PopoverMenu of the multi bulk action toolbar */ getMultiBulkActionPopoverItemAt: (index: number) => multiBulkActionToolbar.getMoreActionsPopoverItemAt(index), /** Click an item from "more actions" PopoverMenu of the multi bulk action toolbar */ clickMoreActionsPopoverItemAt: (index: number) => multiBulkActionToolbar.clickMoreActionsPopoverItemAt(index), /** Click an item from "more actions" PopoverMenu of the multi bulk action toolbar */ clickMoreActionsPopoverItem: (dataHook: string) => multiBulkActionToolbar.clickMoreActionsPopoverItem(dataHook), /** Open the "more actions" PopoverMenu of the multi bulk action toolbar */ openMultiBulkActionMoreActionPopover: () => multiBulkActionToolbar.openMoreActionPopover(), /** Indicates whether the action button of the multi bulk action toolbar exists */ multiBulkActionButtonExists: (dataHook: string) => multiBulkActionToolbar.isButtonExists(dataHook), /** Indicates whether the multi bulk action toolbar exists */ multiBulkActionToolbarExists: () => multiBulkActionToolbar.exists(), /** Get the text of multi action button toolbar counter */ getMultiSelectedCountText: () => multiBulkActionToolbar.getSelectedCountText(), /** Clicks the Select All / Deselec All button from the multi bulk action toolbar exists */ multiBulkActionToolbarClickSelectAllButton: () => multiBulkActionToolbar.selectAll(), /** Gets the text of select all button text */ getMultiBulkActionToolbarSelectAllButtonText: () => multiBulkActionToolbar.selectAllText(), /** Is 'ExportTo' modal open */ isExportModalOpen: () => getExportButton().getModal().isOpen(), /** Get actions cell of a row */ getActionCell, /** Clicks multiple rows selection checkbox */ clickRowsCheckboxes: async (rowIndexes: number[]) => { for (const index of rowIndexes) { await table.clickRowCheckbox(index); } }, /** * Get current confirmation modal */ getConfirmActionModal: () => MessageModalLayoutUniDriver( body.$('[data-hook="collection-action-modal"]'), body, ), getTopNotification: () => TableTopNotificationUniDriver( base.$('[data-hook="table-top-notification"]'), body, ), /** Get tabs filter driver */ getToolbarTabs: () => TabsFilterUniDriver(base.$('[data-hook="collection-tabs-filter"]'), body), /** Get an export button driver **/ getExportButton, /** Get an export modal driver **/ getExportModal, /** Get an import button driver **/ getImportButton, /** Get an import modal driver **/ getImportModal, getRowDragHandle, escapeDrag: (sourceIndex: number) => getDragAndDrop().escapeDrag(getRowDragHandle(sourceIndex)), rowDragHandleExists: (index: number) => getRowDragHandle(index).exists(), dragStartFromHandleAndKeyboard: async (index: number) => getDragAndDrop().startKeyboardDrag(getRowDragHandle(index)), getLiveRegionText: async () => (await getLiveRegion()).getMessage(), getLiveRegionRole: async () => (await getLiveRegion()).getRole(), getDragAndDropLiveRegionText: () => body.$('[data-hook="collection-table-dnd-live-region"]').text(), getStickyColumnsCount: () => base.$('thead').$$(`[data-sticky="true"]`).count(), isHorizontalScroll: async () => Array.from(await tableContentBase()._prop('classList')).some( (c) => c.includes('tableBodyScrollContent'), ), isResizable: async () => (await base.$$('[data-hook="table-resize-handle"]').count()) > 0, getCustomFieldPanel: () => CustomFieldPanelUniDriver(body, body), getReorderModeToolbar, /* Gets collection summary bar */ getSummaryBar, /* Checks if loading row exists */ loadingRowExists, _loadingRowWithAnimationExists, _getInfoIconTooltipPopoverAt: (colNum: number) => PopoverUniDriver( base .$('thead') .$$(`th`) .get(colNum) .$('[data-hook="infoicon-tooltip"]'), body, ), }; };