import { browser , by , ElementArrayFinder , ElementFinder , protractor } from 'protractor' ; import { BrowserActions , BrowserVisibility , Logger } from '@alfresco/adf-testing' ; import { BROWSER_WAIT_TIMEOUT } from '../../configs' ; import { Component } from '../component' ; import { Menu } from '../menu/menu' ; import { Utils , waitForPresence } from '../../utilities/utils' ; export class DataTable extends Component { private static selectors = { columnHeader : '.adf-datatable-row .adf-datatable-cell-header .adf-datatable-cell-value' , sortedColumnHeader : `
      .adf-datatable__header--sorted-asc .adf-datatable-cell-value,
      .adf-datatable__header--sorted-desc .adf-datatable-cell-value
    ` , row : '.adf-datatable-row[data-automation-id^="datatable-row"]' , cell : '.adf-datatable-cell-container' , lockOwner : '.aca-locked-by' , searchResultsRow : 'aca-search-results-row' , searchResultsRowLine : 'span' } ; head = this . byCss ( '.adf-datatable-header' ) ; body = this . byCss ( '.adf-datatable-body' ) ; emptyList = this . byCss ( 'div.adf-no-content-container' ) ; emptyFolderDragAndDrop = this . byCss ( '.adf-empty-list_template .adf-empty-folder' ) ; emptyListTitle = this . byCss ( '.adf-empty-content__title' ) ; emptyListSubtitle = this . byCss ( '.adf-empty-content__subtitle' ) ; emptySearchText = this . byCss ( '.empty-search__text' ) ; selectedRow = this . byCss ( '.adf-datatable-row.adf-is-selected' ) ; columnModified = this . byCss ( '.adf-datatable-header [data-automation-id="auto_id_modifiedAt"]' ) ; menu = new Menu ( ) ; constructor ( ancestor ? ) { super ( 'adf-datatable' , ancestor ) ; } async waitForHeader ( ) { return waitForPresence ( this . head , '--- timeout waitForHeader ---' ) ; } async waitForBody ( ) { return waitForPresence ( this . body , '--- timeout waitForBody ---' ) ; } async waitForEmptyState ( ) { return waitForPresence ( this . emptyList ) ; } private getColumnHeaders ( ) { const locator = by . css ( DataTable . selectors . columnHeader ) ; return this . head . all ( locator ) ; } async getColumnHeadersText ( ) { return this . getColumnHeaders ( ) . getText ( ) ; } getColumnHeaderByLabel ( label ) { const locator = by . cssContainingText ( DataTable . selectors . columnHeader , label ) ; return this . head . element ( locator ) ; } async sortBy ( label , order ) { const sortColumn = await this . getSortedColumnHeaderText ( ) ; const sortOrder = await this . getSortingOrder ( ) ; if ( sortColumn !== label ) { await this . getColumnHeaderByLabel ( label ) . click ( ) ; if ( sortOrder !== order ) { await this . getColumnHeaderByLabel ( label ) . click ( ) ; } } } async sortByModified ( order ) { const sortOrder = await this . getSortingOrder ( ) ; const sortColumn = await this . getSortedColumnHeaderText ( ) ; if ( sortColumn !== 'Modified' ) { await this . columnModified . click ( ) ; if ( sortOrder !== order ) { await this . columnModified . click ( ) ; } } } private getSortedColumnHeader ( ) { const locator = by . css ( DataTable . selectors . sortedColumnHeader ) ; return this . head . element ( locator ) ; } async getSortedColumnHeaderText ( ) { return this . getSortedColumnHeader ( ) . getText ( ) ; } async getSortingOrder ( ) { const str = await this . getSortedColumnHeader ( ) . element ( by . xpath ( '..' ) ) . getAttribute ( 'class' ) ; if ( str . includes ( 'asc' ) ) { return 'asc' ; } if ( str . includes ( 'desc' ) ) { return 'desc' ; } return 'none' ; } private getRows ( ) { return this . body . all ( by . css ( DataTable . selectors . row ) ) ; } async getRowsCount ( ) { return this . getRows ( ) . count ( ) ; } private getSelectedRows ( ) { return this . body . all ( by . css ( '.adf-datatable-row.adf-is-selected' ) ) ; } async getSelectedRowsNames ( ) { return this . getSelectedRows ( ) . map ( ( row ) => { return row . element ( by . css ( '.adf-datatable-cell[title="Name"]' ) ) . getText ( ) ; } ) ; } async getSelectedRowsCount ( ) { return this . getSelectedRows ( ) . count ( ) ; } getRowByName ( name , location = '' ) { if ( location ) { return this . body . all ( by . cssContainingText ( DataTable . selectors . row , name ) ) . filter ( async ( elem ) => browser . isElementPresent ( elem . element ( by . cssContainingText ( DataTable . selectors . cell , location ) ) ) ) . first ( ) ; } return this . body . element ( by . cssContainingText ( DataTable . selectors . row , name ) ) ; } getRowCells ( name , location = '' ) { return this . getRowByName ( name , location ) . all ( by . css ( DataTable . selectors . cell ) ) ; } async getRowCellsCount ( itemName ) { return this . getRowCells ( itemName ) . count ( ) ; } private getRowFirstCell ( name , location = '' ) { return this . getRowCells ( name , location ) . get ( 0 ) ; } private getRowNameCell ( name , location = '' ) { return this . getRowCells ( name , location ) . get ( 1 ) ; } private getRowNameCellSpan ( name , location = '' ) { return this . getRowNameCell ( name , location ) . $ ( 'span' ) ; } async getItemNameTooltip ( name , location = '' ) { return this . getRowNameCellSpan ( name , location ) . getAttribute ( 'title' ) ; } async hasCheckMarkIcon ( itemName , location = '' ) { Logger . info ( `--- check if item already selected : ${ itemName } ${ location }` ) ; const row = this . getRowByName ( itemName , location ) ; return row . element ( by . css ( '.mat-icon[class*="selected"]' ) ) . isPresent ( ) ; } async hasLockIcon ( itemName , location = '' ) { const row = this . getRowByName ( itemName , location ) ; return row . element ( by . css ( 'img[src*="lock"]' ) ) . isPresent ( ) ; } private async hasLockOwnerInfo ( itemName , location = '' ) { const row = this . getRowByName ( itemName , location ) ; return row . element ( by . css ( DataTable . selectors . lockOwner ) ) . isPresent ( ) ; } async getLockOwner ( itemName , location = '' ) { if ( await this . hasLockOwnerInfo ( itemName , location ) ) { const row = this . getRowByName ( itemName , location ) ; return row . $ ( DataTable . selectors . lockOwner ) . $ ( '.locked_by--name' ) . getText ( ) ; } return '' ; } async getLockOwnerToolTip ( itemName , location = '' ) { if ( await this . hasLockIcon ( itemName , location ) ) { const row = this . getRowByName ( itemName , location ) ; return BrowserActions . getAttribute ( row . element ( by . css ( 'img[src*="lock"]' ) ) , 'alt' ) ; } return '' ; } private getNameLink ( itemName ) { return this . getRowNameCell ( itemName ) . $ ( '.adf-datatable-link [role="link"]' ) ; } async hasLinkOnName ( itemName ) { return this . getNameLink ( itemName ) . isPresent ( ) ; } async doubleClickOnRowByName ( name , location = '' ) { try { const item = this . getRowFirstCell ( name , location ) ; await BrowserVisibility . waitUntilElementIsClickable ( item ) ; await browser . actions ( ) . mouseMove ( item ) . perform ( ) ; await browser . actions ( ) . doubleClick ( ) . perform ( ) ; } catch ( error ) { Logger . error ( `--- doubleClickOnRowByName catch : failed to double click on ${ name } from location : ${ location } : ` , error ) ; } } async selectItem ( name , location = '' ) { const isSelected = await this . hasCheckMarkIcon ( name , location ) ; if ( ! isSelected ) { try { Logger . info ( `--- selecting item : ${ name } ${ location }` ) ; const item = this . getRowFirstCell ( name , location ) ; await item . click ( ) ; } catch ( e ) { Logger . error ( `--- select item catch : failed to select ${ name } from location : ${ location } : ` , e ) ; } } } async unselectItem ( name , location = '' ) { const isSelected = await this . hasCheckMarkIcon ( name , location ) ; if ( isSelected ) { try { const item = this . getRowFirstCell ( name , location ) ; await item . click ( ) ; } catch ( e ) { Logger . error ( `--- unselect item catch : failed to unselect ${ name } from location : ${ location } : ` , e ) ; } } } async clickItem ( name , location = '' ) { const item = this . getRowFirstCell ( name , location ) ; await item . click ( ) ; } async clickNameLink ( itemName ) { await this . getNameLink ( itemName ) . click ( ) ; } async selectMultipleItems ( names , location = '' ) { await this . clearSelection ( ) ; await Utils . pressCmd ( ) ; for ( const name of names ) { await this . selectItem ( name , location ) ; } await Utils . releaseKeyPressed ( ) ; } async clearSelection ( ) { try { const count = await this . getSelectedRowsCount ( ) ; if ( count > 0 ) { await browser . refresh ( ) ; await this . wait ( ) ; } } catch ( error ) { Logger . error ( '------ clearSelection catch : ' , error ) ; } } async rightClickOnItem ( itemName ) { const item = this . getRowFirstCell ( itemName ) ; await browser . actions ( ) . mouseMove ( item ) . perform ( ) ; await browser . actions ( ) . click ( protractor . Button . RIGHT ) . perform ( ) ; } async rightClickOnMultipleSelection ( ) { const itemFromSelection = this . getSelectedRows ( ) . get ( 0 ) ; await browser . actions ( ) . mouseMove ( itemFromSelection ) . perform ( ) ; await browser . actions ( ) . click ( protractor . Button . RIGHT ) . perform ( ) ; } private getItemLocationEl ( name ) { return this . getRowByName ( name ) . element ( by . css ( '.aca-location-link' ) ) ; } async getItemLocation ( name ) { return this . getItemLocationEl ( name ) . getText ( ) ; } async getItemLocationTooltip ( name ) { const location = this . getItemLocationEl ( name ) . $ ( 'a' ) ; const condition = ( ) => location . getAttribute ( 'title' ) . then ( ( value ) => value && value . length > 0 ) ; await browser . actions ( ) . mouseMove ( location ) . perform ( ) ; await browser . wait ( condition , BROWSER_WAIT_TIMEOUT ) ; return location . getAttribute ( 'title' ) ; } async clickItemLocation ( name ) { await this . getItemLocationEl ( name ) . click ( ) ; } async isEmpty ( ) { return this . emptyList . isPresent ( ) ; } async getEmptyDragAndDropText ( ) { const isEmpty = await this . emptyFolderDragAndDrop . isDisplayed ( ) ; if ( isEmpty ) { return this . emptyFolderDragAndDrop . getText ( ) ; } return '' ; } async getEmptyStateTitle ( ) { const isEmpty = await this . isEmpty ( ) ; if ( isEmpty ) { return this . emptyListTitle . getText ( ) ; } return '' ; } async getEmptyStateSubtitle ( ) { const isEmpty = await this . isEmpty ( ) ; if ( isEmpty ) { return this . emptyListSubtitle . getText ( ) ; } return '' ; } async getEmptyListText ( ) { const isEmpty = await this . isEmpty ( ) ; if ( isEmpty ) { return this . byCss ( 'adf-custom-empty-content-template' ) . getText ( ) ; } return '' ; } async getCellsContainingName ( name ) { const rows = this . getRows ( ) . all ( by . cssContainingText ( DataTable . selectors . cell , name ) ) ; return rows . map ( async ( cell ) => { return cell . getText ( ) ; } ) ; } async hasContextMenu ( ) { const count = await this . menu . getItemsCount ( ) ; return count > 0 ; } async getLibraryRole ( name ) { return this . getRowByName ( name ) . element ( by . css ( 'adf-library-role-column' ) ) . getText ( ) ; } async isItemPresent ( name , location ? ) { return this . getRowByName ( name , location ) . isPresent ( ) ; } private async getEntireDataTableText ( ) { return this . getRows ( ) . map ( ( row ) => { return row . all ( by . css ( DataTable . selectors . cell ) ) . map ( async ( cell ) => { return cell . getText ( ) ; } ) ; } ) ; } async getSitesNameAndVisibility ( ) { const data = await this . getEntireDataTableText ( ) ; return data . reduce ( ( acc , cell ) => { acc [ cell [ 1 ] ] = cell [ 4 ] . toUpperCase ( ) ; return acc ; } , { } ) ; } async getSitesNameAndRole ( ) { const data = await this . getEntireDataTableText ( ) ; return data . reduce ( ( acc , cell ) => { acc [ cell [ 1 ] ] = cell [ 3 ] ; return acc ; } , { } ) ; } private getSearchResultsRows ( ) { return this . body . all ( by . css ( DataTable . selectors . searchResultsRow ) ) ; } getNthSearchResultsRow ( nth ) { return this . getSearchResultsRows ( ) . get ( nth - 1 ) ; } private getSearchResultsRowByName ( name , location = '' ) { if ( location ) { return this . body . all ( by . cssContainingText ( DataTable . selectors . searchResultsRow , name ) ) . filter ( async ( elem ) => browser . isElementPresent ( elem . element ( by . cssContainingText ( DataTable . selectors . searchResultsRowLine , location ) ) ) ) . first ( ) ; } return this . body . element ( by . cssContainingText ( DataTable . selectors . searchResultsRow , name ) ) ; } private getSearchResultNameLink ( itemName , location = '' ) { return this . getSearchResultsRowByName ( itemName , location ) . $ ( '.link' ) ; } async hasLinkOnSearchResultName ( itemName , location = '' ) { return this . getSearchResultNameLink ( itemName , location ) . isPresent ( ) ; } async clickSearchResultNameLink ( itemName , location = '' ) { await this . getSearchResultNameLink ( itemName , location ) . click ( ) ; } }