diff --git a/ftest/features/search.feature b/ftest/features/search.feature index a2e8ec628c..80b07a23ea 100644 --- a/ftest/features/search.feature +++ b/ftest/features/search.feature @@ -46,17 +46,6 @@ Feature: Search | coverage | Europe/Portugal | 5 | #| size | Between 100 KB and 1 MB | 1 | disabled until scroll works in shadow dom - Scenario: Default Saved Search - When I click the "defaultSearch" button - And I perform a coverage search for Europe/France on defaultSearch - Then I edit the results columns to show "Subjects" - And I save my search as "Local Search" - And I share my "defaultSearch" search with JSmith - When I logout - And I login as "JSmith" - And I click the "defaultSearch" button - Then I can view my saved search "Local Search" on "defaultSearch" - Scenario: Navigate to Default Saved Search by ID Given I have a saved search named "Portugal", for the "default_search" page provider, with the following parameters | key | value | @@ -109,3 +98,14 @@ Feature: Search When I click the "assetsSearch" button And I perform a fulltext search for picture on assetsSearch Then I can see 3 search results + + Scenario: Default Saved Search + When I click the "defaultSearch" button + And I perform a coverage search for Europe/France on defaultSearch + Then I edit the results columns to show "Subjects" + And I save my search as "Local Search" + And I share my "defaultSearch" search with JSmith + When I logout + And I login as "JSmith" + And I click the "defaultSearch" button + Then I can view my saved search "Local Search" on "defaultSearch" diff --git a/packages/nuxeo-web-ui-ftest/features/step_definitions/browser.js b/packages/nuxeo-web-ui-ftest/features/step_definitions/browser.js index 56fc6546d6..2158a39757 100644 --- a/packages/nuxeo-web-ui-ftest/features/step_definitions/browser.js +++ b/packages/nuxeo-web-ui-ftest/features/step_definitions/browser.js @@ -33,7 +33,8 @@ Then('I can navigate to {word} pill', async function(pill) { const ele = await this.ui.browser.el.$(`nuxeo-page-item[name='${pill.toLowerCase()}']`); await ele.waitForVisible(); await ele.click(); - await this.ui.browser.waitForVisible(`#nxContent [name='${pill.toLowerCase()}']`); + const pillTab = await this.ui.browser.el.$(`#nxContent [name='${pill.toLowerCase()}']`); + await pillTab.waitForVisible(); }); Then('I cannot see to {word} pill', async function(pill) { diff --git a/packages/nuxeo-web-ui-ftest/features/step_definitions/create_dialog.js b/packages/nuxeo-web-ui-ftest/features/step_definitions/create_dialog.js index 59c8e86f0b..91175d649e 100644 --- a/packages/nuxeo-web-ui-ftest/features/step_definitions/create_dialog.js +++ b/packages/nuxeo-web-ui-ftest/features/step_definitions/create_dialog.js @@ -3,9 +3,10 @@ import { Then, When } from '../../node_modules/@cucumber/cucumber'; let currentDocType; let selectedTabName; -When('I click the Create Document button', function() { - this.ui.createButton.waitForVisible(); - this.ui.createButton.click(); +When('I click the Create Document button', async function() { + const button = await this.ui.createButton; + await button.waitForVisible(); + await button.click(); }); Then('I click the Create button to finish the import', function() { @@ -44,29 +45,37 @@ Then('I upload the following files on the tab content page:', function(table) { return docs.reduce((current, next) => current.then(next), Promise.resolve([])); }); -When('I select {word} from the Document Type menu', function(docType) { - this.ui.createDialog.waitForVisible(); - const button = this.ui.createDialog.documentCreate.getDoctypeButton(docType); - button.waitForVisible(); - button.click(); +When('I select {word} from the Document Type menu', async function(docType) { + const dialog = await this.ui.createDialog; + await dialog.waitForVisible(); + const button = await this.ui.createDialog.documentCreate.getDoctypeButton(docType); + await button.waitForVisible(); + await button.click(); currentDocType = docType; }); -When('I create a document with the following properties:', function(table) { - this.ui.createDialog.documentCreate.waitForVisible(); - this.ui.createDialog.documentCreate.layout(currentDocType).fillMultipleValues(table); - this.ui.createDialog.documentCreate.layout(currentDocType).getField('title').should.not.be.empty; - const title = this.ui.createDialog.documentCreate.layout(currentDocType).getFieldValue('title'); - this.ui.createDialog.createButton.waitForVisible(); - this.ui.createDialog.createButton.click(); - this.ui.browser.waitForNotVisible('iron-overlay-backdrop'); - this.ui.browser.hasTitle(title).should.be.true; +When('I create a document with the following properties:', async function(table) { + await this.ui.createDialog.documentCreate.waitForVisible(); + const layout = await this.ui.createDialog.documentCreate.layout(currentDocType); + await layout.fillMultipleValues(table); + const field = await layout.getField('title'); + field.should.not.be.empty; + const title = await layout.getFieldValue('title'); + const button = await this.ui.createDialog.createButton; + await button.waitForVisible(); + await button.click(); + await this.ui.browser.waitForNotVisible('iron-overlay-backdrop'); + const hasTitle = await this.ui.browser.hasTitle(title); + hasTitle.should.be.true; this.doc = { type: currentDocType, title }; }); -Then('I see the {word} page', function(docType) { - this.ui.browser.waitForNotVisible('iron-overlay-backdrop'); - this.ui.browser.documentPage(docType).view.waitForVisible(); +Then('I see the {word} page', async function(docType) { + const ele = await this.ui.browser; + await ele.waitForNotVisible('iron-overlay-backdrop'); + const docPage = await ele.documentPage(docType); + const docPageView = await docPage.view; + await docPageView.waitForVisible(); }); Then(/^I can see that a document of the type (.+) and title (.+) is created$/, function(docType, title) { diff --git a/packages/nuxeo-web-ui-ftest/features/step_definitions/search.js b/packages/nuxeo-web-ui-ftest/features/step_definitions/search.js index 11385adcb4..dbd8bdf856 100644 --- a/packages/nuxeo-web-ui-ftest/features/step_definitions/search.js +++ b/packages/nuxeo-web-ui-ftest/features/step_definitions/search.js @@ -111,114 +111,149 @@ When('I browse to the saved search', function() { url(`#!/doc/${this.savedSearch.id}`); }); -Then('I can see that my saved search "{word}" on "{word}" is selected', function(savedSearchName, searchName) { - this.ui.searchForm(searchName).menuButton.waitForVisible(); - const el = this.ui.searchForm(searchName).getSavedSearch(savedSearchName); - el.waitForExist().should.be.true; - el.getAttribute('class').should.equal('iron-selected'); +Then('I can see that my saved search "{word}" on "{word}" is selected', async function(savedSearchName, searchName) { + const searchForm = await this.ui.searchForm(searchName); + const menuButton = await searchForm.menuButton; + await menuButton.waitForVisible(); + const savedSearch = await this.ui.searchForm(searchName).getSavedSearch(savedSearchName); + const savedSearchExist = await savedSearch.waitForExist(); + savedSearchExist.should.be.true; + const attr = await savedSearch.getAttribute('class'); + attr.should.equal('iron-selected'); }); -When(/^I clear the (.+) search on (.+)$/, function(searchType, searchName) { - const searchForm = this.ui.searchForm(searchName); - searchForm.waitForVisible(); - searchForm.search(searchType); +When(/^I clear the (.+) search on (.+)$/, async function(searchType, searchName) { + const searchForm = await this.ui.searchForm(searchName); + await searchForm.waitForVisible(); + await searchForm.search(searchType); }); -When(/^I perform a (.+) search for (.+) on (.+)$/, function(searchType, searchTerm, searchName) { - const searchForm = this.ui.searchForm(searchName); - searchForm.waitForVisible(); - searchForm.search(searchType, searchTerm); +When(/^I perform a (.+) search for (.+) on (.+)$/, async function(searchType, searchTerm, searchName) { + const searchForm = await this.ui.searchForm(searchName); + await searchForm.waitForVisible(); + await searchForm.search(searchType, searchTerm); }); When('I switch to filter view', function() { this.ui.filterView.click(); }); -Then(/^I can see (\d+) search results$/, function(numberOfResults) { - const { displayMode } = this.ui.results; +Then(/^I can see (\d+) search results$/, async function(numberOfResults) { + const uiResult = await this.ui.results; + const displayMode = await uiResult.displayMode; if (numberOfResults === 0) { - driver.waitUntil( - () => this.ui.results.resultsCount(displayMode) === 0, - `Expecting to get ${numberOfResults} results but found ${this.ui.results.resultsCount(displayMode)}`, - ); - this.ui.results.noResults.waitForVisible().should.be.true; + const outResult2 = await uiResult.resultsCount(displayMode); + if (outResult2 !== numberOfResults) { + throw Error(`Expecting to get ${numberOfResults} results but found ${outResult2}`); + } + const emptyResult = await uiResult.noResults; + const emptyResultVisible = await emptyResult.waitForVisible(); + emptyResultVisible.should.be.true; } else { - this.ui.results.resultsCountLabel.waitForVisible(); - driver.waitUntil( - () => - parseInt(this.ui.results.resultsCountLabel.getText(), 10) === numberOfResults && - this.ui.results.resultsCount(displayMode) === numberOfResults, - `Expecting to get ${numberOfResults} results but found ${this.ui.results.resultsCount(displayMode)}`, - ); + const outLabel = await uiResult.resultsCountLabel; + await outLabel.waitForVisible(); + const outText = await outLabel.getText(); + const outResult = parseInt(outText, 10); + if (outResult !== numberOfResults) { + throw Error(`Expecting to get ${numberOfResults} results but found ${outResult}`); + } + const outResult2 = await uiResult.resultsCount(displayMode); + if (outResult2 !== numberOfResults) { + throw Error(`Expecting to get ${numberOfResults} results but found ${outResult}`); + } } }); -Then(/^I can see more than (\d+) search results$/, function(minNumberOfResults) { - const { displayMode } = this.ui.results; - driver.waitUntil( - () => this.ui.results.resultsCount(displayMode) > minNumberOfResults, - `Expecting to get more than ${minNumberOfResults} results but found ${this.ui.results.resultsCount(displayMode)}`, - ); +Then(/^I can see more than (\d+) search results$/, async function(minNumberOfResults) { + const results = await this.ui.results; + const displayMode = await results.displayMode; + const output = await results.resultsCount(displayMode); + if (output > minNumberOfResults) { + return true; + } + throw Error(`Expecting to get more than ${minNumberOfResults} but found ${output}`); }); -Then('I edit the results columns to show {string}', function(heading) { - this.ui.results.actions.waitForVisible(); - if (this.ui.results.displayMode !== 'table' && this.ui.results.toggleTableView.isVisible()) { - this.ui.results.toggleTableView.click(); +Then('I edit the results columns to show {string}', async function(heading) { + const result = await this.ui.results; + const actions = await result.actions; + await actions.waitForVisible(); + const dispMode = await result.displayMode; + const togTableview = await result.toggleTableView; + if ((await dispMode) !== 'table' && (await togTableview.isVisible())) { + await togTableview.click(); } - this.ui.results.toggleColumnSettings.waitForVisible(); - this.ui.results.toggleColumnSettings.click(); - this.ui.results.getColumnCheckbox(heading).waitForExist(); - this.ui.results.checkColumnCheckbox(heading); - this.ui.results.columnsCloseButton.click(); - this.ui.results.getResultsColumn(heading).waitForExist().should.be.true; -}); - -Then(/^I save my search as "(.+)"$/, function(searchName) { - this.ui.searchResults.saveSearchAsButton.waitForVisible(); - this.ui.searchResults.saveSearchAsButton.click(); - this.ui.searchResults.enterInput(searchName); - this.ui.searchResults.confirmSaveSearchButton.click(); -}); - -Then(/^I share my "(.+)" search with (.+)/, function(searchName, username) { - this.ui.searchResults.savedSearchActionButton.waitForVisible(); - this.ui.searchResults.savedSearchActionButton.click(); - this.ui.searchResults.shareAction.waitForVisible(); - this.ui.searchResults.shareAction.click(); - this.ui.searchForm(searchName).permissionsView.newPermissionButton.waitForVisible(); - this.ui.searchForm(searchName).permissionsView.newPermissionButton.click(); - this.ui.searchForm(searchName).permissionsView.setPermissions(username, { + const toggleSettings = await result.toggleColumnSettings; + await toggleSettings.waitForVisible(); + await toggleSettings.click(); + const columnCheckbox = await result.getColumnCheckbox(heading); + await columnCheckbox.waitForExist(); + await result.checkColumnCheckbox(heading); + const button = await result.columnsCloseButton; + await button.click(); + const resultsColumn = await result.getResultsColumn(heading); + const isColumnExist = await resultsColumn.waitForExist(); + isColumnExist.should.be.true; +}); + +Then(/^I save my search as "(.+)"$/, async function(searchName) { + const saveAsButton = await this.ui.searchResults.saveSearchAsButton; + await saveAsButton.waitForVisible(); + await saveAsButton.click(); + await this.ui.searchResults.enterInput(searchName); + const confirmSaveButton = await this.ui.searchResults.confirmSaveSearchButton; + await confirmSaveButton.click(); +}); + +Then(/^I share my "(.+)" search with (.+)/, async function(searchName, username) { + const savedSearchButton = await this.ui.searchResults.savedSearchActionButton; + await savedSearchButton.waitForVisible(); + await savedSearchButton.click(); + const shareActionButton = await this.ui.searchResults.shareAction; + await shareActionButton.waitForVisible(); + await shareActionButton.click(); + const searchForm = await this.ui.searchForm(searchName); + const PremissionButton = await searchForm.permissionsView.newPermissionButton; + await PremissionButton.waitForVisible(); + await PremissionButton.click(); + await searchForm.permissionsView.setPermissions(username, { permission: 'Read', timeFrame: 'permanent', notify: false, }); - this.ui.searchForm(searchName).permissionsView.createPermissionButton.waitForVisible(); - this.ui.searchForm(searchName).permissionsView.createPermissionButton.click(); - this.ui - .searchForm(searchName) - .permissionsView.permission('Read', username, 'permanent') - .waitForVisible(); + const createPermissionButton = await searchForm.permissionsView.createPermissionButton; + await createPermissionButton.waitForVisible(); + await createPermissionButton.click(); + const permissionVisible = await searchForm.permissionsView.permission('Read', username, 'permanent'); + permissionVisible.should.be.true; }); -Then(/^I can view my saved search "(.+)" on "(.+)"$/, function(savedSearchName, searchName) { - this.ui.searchForm(searchName).menuButton.waitForVisible(); - this.ui.searchForm(searchName).menuButton.click(); - this.ui - .searchForm(searchName) - .getSavedSearch(savedSearchName) - .waitForExist().should.be.true; +Then(/^I can view my saved search "(.+)" on "(.+)"$/, async function(savedSearchName, searchName) { + const searchForm = await this.ui.searchForm(searchName); + const menuButton = await searchForm.menuButton; + await menuButton.waitForVisible(); + await menuButton.click(); + const savedSearch = await searchForm.getSavedSearch(savedSearchName); + const savedSearchExist = await savedSearch.waitForExist(); + savedSearchExist.should.be.true; }); -When(/^I click the QuickSearch button$/, function() { - this.ui.searchButton.waitForVisible(); - this.ui.searchButton.click(); +When(/^I click the QuickSearch button$/, async function() { + const button = await this.ui.searchButton; + await button.waitForVisible(); + await button.click(); }); -When(/^I perform a QuickSearch for (.+)/, function(searchTerm) { - return this.ui.quickSearch.enterInput(searchTerm); +When(/^I perform a QuickSearch for (.+)/, async function(searchTerm) { + const quickSearch = await this.ui.quickSearch; + await quickSearch.enterInput(searchTerm); }); -Then(/^I can see (\d+) QuickSearch results$/, function(numberOfResults) { - driver.waitUntil(() => this.ui.quickSearch.quickSearchResultsCount() === numberOfResults); +Then(/^I can see (\d+) QuickSearch results$/, async function(numberOfResults) { + const quickSearch = await this.ui.quickSearch; + await driver.pause(1000); + const result = await quickSearch.quickSearchResultsCount(); + if (result !== numberOfResults) { + throw Error(`Expecting to get ${numberOfResults} results but found ${result}`); + } }); diff --git a/packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/layouts.js b/packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/layouts.js index aefc1c6ae5..6e10151417 100644 --- a/packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/layouts.js +++ b/packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/layouts.js @@ -60,9 +60,11 @@ const suggestionSet = async (element, value) => { } // it's a reset else if (element.getAttribute('multiple') !== null) { - element - .elements('.selectivity-multiple-selected-item') - .forEach((el) => el.element('.selectivity-multiple-selected-item-remove').click()); + const dropdown = element.elements('.selectivity-multiple-selected-item'); + for (let i = 0; i < dropdown.length; i++) { + const dropdownElement = await dropdown[i].element('.selectivity-multiple-selected-item-remove'); + await dropdownElement.click(); + } } else { const item = element.element('.selectivity-single-selected-item'); if (item) { @@ -73,8 +75,9 @@ const suggestionSet = async (element, value) => { global.fieldRegistry.register( 'nuxeo-input', (element) => element.$('.input-element input').getValue(), - (element, value) => { - element.$('.input-element input').setValue(value); + async (element, value) => { + const ele = await element.$('.input-element input'); + await ele.setValue(value); }, ); global.fieldRegistry.register( @@ -106,22 +109,24 @@ global.fieldRegistry.register( global.fieldRegistry.register( 'nuxeo-date-picker', (element) => moment(element.$('vaadin-date-picker input').getValue(), global.dateFormat).format(global.dateFormat), - (element, value) => { - const date = element.$('vaadin-date-picker input'); - if (date.getValue()) { - date.$('div[part="clear-button"]').click(); + async (element, value) => { + const date = await element.$('vaadin-date-picker input'); + if (await date.getValue()) { + const ele = await date.$('div[part="clear-button"]'); + await ele.click(); } - date.click(); - const keys = moment(value, global.dateFormat).format('L'); - driver.keys(keys); - driver.keys('Enter'); + await date.click(); + const keys = await moment(value, global.dateFormat).format('L'); + await driver.keys(keys); + await driver.keys('Enter'); }, ); global.fieldRegistry.register( 'nuxeo-textarea', (element) => element.element('#textarea').getValue(), - (element, value) => { - element.$('#textarea').setValue(value); + async (element, value) => { + const ele = await element.$('#textarea'); + await ele.setValue(value); }, ); global.fieldRegistry.register('nuxeo-user-suggestion', suggestionGet, suggestionSet); @@ -259,9 +264,9 @@ global.fieldRegistry.register( ); fixtures.layouts = { - getValue: (element) => { - const fieldType = element.getTagName(); - return (global.fieldRegistry.contains(fieldType) + getValue: async (element) => { + const fieldType = await element.getTagName(); + await (global.fieldRegistry.contains(fieldType) ? global.fieldRegistry.getValFunc(fieldType) : global.fieldRegistry.getValFunc('generic'))(element); }, diff --git a/packages/nuxeo-web-ui-ftest/features/step_definitions/trash.js b/packages/nuxeo-web-ui-ftest/features/step_definitions/trash.js index ce2769a3f0..aaf3ceae59 100644 --- a/packages/nuxeo-web-ui-ftest/features/step_definitions/trash.js +++ b/packages/nuxeo-web-ui-ftest/features/step_definitions/trash.js @@ -63,9 +63,9 @@ Then('I cannot untrash selected documents', function() { Then('I can trash current document', async function() { const el = await this.ui.browser.trashDocumentButton; - el.waitForVisible(); - el.click(); - driver.alertAccept(); + await el.waitForVisible(); + await el.click(); + await driver.alertAccept(); }); Then('I cannot trash current document', function() { @@ -84,12 +84,13 @@ Then('I cannot untrash current document', function() { this.ui.browser.untrashDocumentButton.isExisting().should.be.false; }); -Then('I can permanently delete current document', function() { - this.ui.browser.trashedInfobar.waitForVisible(); - const el = this.ui.browser.deleteDocumentButton; - el.waitForVisible(); - el.click(); - driver.alertAccept(); +Then('I can permanently delete current document', async function() { + const trashedToolbar = await this.ui.browser.trashedInfobar; + await trashedToolbar.waitForVisible(); + const el = await this.ui.browser.deleteDocumentButton; + await el.waitForVisible(); + await el.click(); + await driver.alertAccept(); }); Then('I cannot permanently delete current document', function() { diff --git a/packages/nuxeo-web-ui-ftest/pages/ui.js b/packages/nuxeo-web-ui-ftest/pages/ui.js index 6347e62d82..0054581327 100644 --- a/packages/nuxeo-web-ui-ftest/pages/ui.js +++ b/packages/nuxeo-web-ui-ftest/pages/ui.js @@ -59,12 +59,14 @@ export default class UI extends BasePage { } get results() { - driver.waitUntil(async () => { - if (await this.el.$('nuxeo-browser').isVisible()) { + return (async () => { + const ele = await this.el.element('nuxeo-browser'); + const isElementVisible = await ele.isVisible(); + if (isElementVisible) { return this.browser.results; } - }); - return new Search('nuxeo-search-results-layout[id="results"]'); + return new Search('nuxeo-search-results-layout[id="results"]'); + })(); } get searchResults() { diff --git a/packages/nuxeo-web-ui-ftest/pages/ui/browser.js b/packages/nuxeo-web-ui-ftest/pages/ui/browser.js index bd7a369d5a..b5417c2a5e 100644 --- a/packages/nuxeo-web-ui-ftest/pages/ui/browser.js +++ b/packages/nuxeo-web-ui-ftest/pages/ui/browser.js @@ -13,8 +13,8 @@ import Results from './results'; import { clickActionMenu, url } from '../helpers'; export default class Browser extends BasePage { - documentPage(docType) { - const page = fixtures.layouts.page[docType] || 'nuxeo-document-page'; + async documentPage(docType) { + const page = (await fixtures.layouts.page[docType]) || 'nuxeo-document-page'; if (page === 'nuxeo-collapsible-document-page') { return new CollapsibleDocumentPage(page, docType); } @@ -370,8 +370,10 @@ export default class Browser extends BasePage { return this.el.$('.document-actions nuxeo-workflow-button #startButton'); } - clickDocumentActionMenu(selector) { - clickActionMenu(this.el.$('nuxeo-actions-menu'), selector); + async clickDocumentActionMenu(selector) { + const ele = await this.el; + const id = await ele.$('nuxeo-actions-menu'); + await clickActionMenu(id, selector); } startWorkflow(workflow) { diff --git a/packages/nuxeo-web-ui-ftest/pages/ui/browser/document_layout.js b/packages/nuxeo-web-ui-ftest/pages/ui/browser/document_layout.js index 6b3721b6c4..b9850a92c2 100644 --- a/packages/nuxeo-web-ui-ftest/pages/ui/browser/document_layout.js +++ b/packages/nuxeo-web-ui-ftest/pages/ui/browser/document_layout.js @@ -9,8 +9,8 @@ export default class DocumentLayout extends BasePage { return result; } - getFieldValue(field) { - const fieldEl = this.getField(field); + async getFieldValue(field) { + const fieldEl = await this.getField(field); return fixtures.layouts.getValue(fieldEl); } @@ -29,8 +29,7 @@ export default class DocumentLayout extends BasePage { const fieldEl = await this.getField(fieldName); await fieldEl.waitForVisible(); await fieldEl.scrollIntoView(); - const result = await fixtures.layouts.setValue(fieldEl, row[1]); - return result; + await fixtures.layouts.setValue(fieldEl, row[1]); } } } diff --git a/packages/nuxeo-web-ui-ftest/pages/ui/browser/document_permissions.js b/packages/nuxeo-web-ui-ftest/pages/ui/browser/document_permissions.js index e00c3dd998..2264bdc9d6 100644 --- a/packages/nuxeo-web-ui-ftest/pages/ui/browser/document_permissions.js +++ b/packages/nuxeo-web-ui-ftest/pages/ui/browser/document_permissions.js @@ -1,8 +1,12 @@ +/* eslint-disable no-await-in-loop */ import BasePage from '../../base'; export default class DocumentPermissions extends BasePage { get newPermissionButton() { - return this.el.element('#localPermissions #newPermissionButton'); + return (async () => { + const ele = await this.el; + return ele.element('#localPermissions #newPermissionButton'); + })(); } get createPermissionButton() { @@ -18,28 +22,32 @@ export default class DocumentPermissions extends BasePage { } get timeFrameButton() { - return this.el.element('paper-radio-button #radioContainer'); + return (async () => { + const ele = await this.el; + return ele.element('paper-radio-button #radioContainer'); + })(); } - permission(permission, name, timeFrame) { - return driver.waitUntil(() => { - const rows = this.el.elements('div.acl-table-row'); - return rows.find((row) => { - const nameCheck = name ? row.isExisting(`span.user[title="${name} - ${name}@test.com"]`) : true; - const permissionCheck = permission ? !!row.hasElementByTextContent('span.label', permission) : true; - // XXX should rely on a class or column header name - const timeFrameCheck = timeFrame ? !!row.hasElementByTextContent('span', permission) : true; - return nameCheck && permissionCheck && timeFrameCheck; - }); - }); + async permission(permission, name, timeFrame) { + const ele = await this.el; + const rows = await ele.elements('div.acl-table-row'); + for (let i = 0; i < rows.length; i++) { + const nameCheck = name ? await rows[i].isExisting(`span.user[title="${name} - ${name}@test.com"]`) : true; + const permissionCheck = permission ? await !!rows[i].hasElementByTextContent('span.label', permission) : true; + // XXX should rely on a class or column header name + const timeFrameCheck = timeFrame ? await !!rows[i].hasElementByTextContent('span', permission) : true; + return nameCheck && permissionCheck && timeFrameCheck; + } + return false; } - getField(field) { - this.el.waitForVisible(); + async getField(field) { + const ele = await this.el; + await ele.waitForVisible(); if (field === 'begin' || field === 'end') { - return this.el.element(`[id="${field}"]`); + return ele.element(`[id="${field}"]`); } - return this.el.element(`[name="${field}"]`); + return ele.element(`[name="${field}"]`); } getEditField(field) { @@ -50,10 +58,11 @@ export default class DocumentPermissions extends BasePage { return this.el.element(`nuxeo-document-acl-table nuxeo-popup-permission [name="${field}"]`); } - setFieldValue(field, value) { - const fieldEl = this.getField(field); - fieldEl.waitForVisible(); - return fixtures.layouts.setValue(fieldEl, value); + async setFieldValue(field, value) { + const fieldEl = await this.getField(field); + await fieldEl.waitForVisible(); + const ret = await fixtures.layouts.setValue(fieldEl, value); + return ret; } editFieldValue(field, value) { @@ -62,7 +71,7 @@ export default class DocumentPermissions extends BasePage { return fixtures.layouts.setValue(fieldEl, value); } - setPermissions(name, opts) { + async setPermissions(name, opts) { opts = opts || {}; const permission = opts.permission || ''; const timeFrame = opts.timeFrame || ''; @@ -70,17 +79,18 @@ export default class DocumentPermissions extends BasePage { const end = opts.end || ''; const { notify } = opts; if (name) { - this.setFieldValue('userGroup', name); + await this.setFieldValue('userGroup', name); } - this.setFieldValue('right', permission); - this.timeFrameButton.click(); + await this.setFieldValue('right', permission); + const timeButton = await this.timeFrameButton; + await timeButton.click(); if (timeFrame === 'datebased') { - this.setFieldValue('begin', begin); + await this.setFieldValue('begin', begin); if (end) { - this.setFieldValue('end', end); + await this.setFieldValue('end', end); } } - this.setFieldValue('notify', notify); + await this.setFieldValue('notify', notify); } editPermissions(opts) { diff --git a/packages/nuxeo-web-ui-ftest/pages/ui/results.js b/packages/nuxeo-web-ui-ftest/pages/ui/results.js index 5b449440e0..d699977185 100644 --- a/packages/nuxeo-web-ui-ftest/pages/ui/results.js +++ b/packages/nuxeo-web-ui-ftest/pages/ui/results.js @@ -1,3 +1,4 @@ +/* eslint-disable no-await-in-loop */ import BasePage from '../base'; export default class Results extends BasePage { @@ -16,10 +17,16 @@ export default class Results extends BasePage { get displayMode() { return (async () => { - this.displayModes.some((displayMode) => displayMode.isVisible()); - const displayMode = await this.displayModes.filter((result) => result.getAttribute('disabled') !== null); - return displayMode[0] - .getAttribute('title') + const displayModesRows = await this.displayModes; + const displayModeArr = []; + for (let i = 0; i < displayModesRows.length; i++) { + const row = displayModesRows[i]; + if ((await row.getAttribute('disabled')) !== null) { + displayModeArr.push(row); + } + } + const attr = await displayModeArr[0].getAttribute('title'); + return attr .replace('Switch to ', '') .replace(/ view| View/, '') .toLowerCase(); @@ -27,7 +34,16 @@ export default class Results extends BasePage { } get toggleTableView() { - return this.displayModes.find((e) => e.getAttribute('title').includes('Table View')); + return (async () => { + const displayModesRows = await this.displayModes; + for (let i = 0; i < displayModesRows.length; i++) { + const row = displayModesRows[i]; + const attr = await row.getAttribute('title'); + if (attr.includes('Table View')) { + return row; + } + } + })(); } get toggleColumnSettings() { @@ -53,36 +69,57 @@ export default class Results extends BasePage { } } - getColumnCheckbox(heading) { - this.el.waitForVisible('nuxeo-data-table[name="table"] nuxeo-dialog[id="columnsSettingsPopup"]'); - const tr = this.el + async getColumnCheckbox(heading) { + const ele = await this.el; + await ele.$('nuxeo-data-table[name="table"] nuxeo-dialog[id="columnsSettingsPopup"]').waitForVisible(); + const rows = await ele.$$('nuxeo-data-table[name="table"] nuxeo-dialog[id="columnsSettingsPopup"] tr'); + const elementTitle = await ele .$$('nuxeo-data-table[name="table"] nuxeo-dialog[id="columnsSettingsPopup"] tr') - .find((e) => e.getText() === heading); - tr.waitForVisible('paper-checkbox'); - return tr.$('paper-checkbox'); + .map((img) => img.getText()); + const index = elementTitle.findIndex((currenTitle) => currenTitle === heading); + const result = await rows[index].$('paper-checkbox'); + await result.waitForVisible(); + return result; } - checkColumnCheckbox(heading) { - const checkbox = this.getColumnCheckbox(heading); - if (checkbox.getAttribute('checked') === null) { + async checkColumnCheckbox(heading) { + const checkbox = await this.getColumnCheckbox(heading); + if ((await checkbox.getAttribute('checked')) === null) { return checkbox.click(); } } - getResultsColumn(heading) { - this.el.waitForVisible('nuxeo-data-table[name="table"] nuxeo-data-table-row[header]'); - const row = this.el.$('nuxeo-data-table[name="table"] nuxeo-data-table-row[header]'); - row.waitForVisible('nuxeo-data-table-cell:not([hidden])'); - return row.$$('nuxeo-data-table-cell:not([hidden])').find((e) => e.getText() === heading); - } - - resultsCount(displayMode) { - const rows = this.getResults(displayMode); - return rows ? rows.filter((result) => result.getAttribute('hidden') === null).length : 0; + async getResultsColumn(heading) { + const ele = await this.el; + await ele.$('nuxeo-data-table[name="table"] nuxeo-data-table-row[header]').waitForVisible(); + const row = await ele.$('nuxeo-data-table[name="table"] nuxeo-data-table-row[header]'); + const rowElement = await row.$('nuxeo-data-table-cell:not([hidden])'); + await rowElement.waitForVisible(); + const titleRows = await row.$$('nuxeo-data-table-cell:not([hidden])'); + const rowTitles = await row.$$('nuxeo-data-table-cell:not([hidden])').map((img) => img.getText()); + const index = rowTitles.findIndex((currenTitle) => currenTitle === heading); + const result = await titleRows[index]; + return result; + } + + async resultsCount(displayMode) { + const rows = await this.getResults(displayMode); + let elementCount = 0; + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + const elementsHidden = await row.getAttribute('hidden'); + if (elementsHidden === null) { + elementCount++; + } + } + return elementCount; } get resultsCountLabel() { - return this.el.$('div.resultActions .resultsCount'); + return (async () => { + const ele = await this.el; + return ele.$('div.resultActions .resultsCount'); + })(); } deleteDocuments() { diff --git a/packages/nuxeo-web-ui-ftest/pages/ui/search.js b/packages/nuxeo-web-ui-ftest/pages/ui/search.js index 9d2686675f..11fb62e906 100644 --- a/packages/nuxeo-web-ui-ftest/pages/ui/search.js +++ b/packages/nuxeo-web-ui-ftest/pages/ui/search.js @@ -8,17 +8,30 @@ export default class Search extends Results { } get saveSearchAsButton() { - driver.waitForVisible('#actions paper-button'); - return driver.elements('#actions paper-button').find((e) => e.getText() === 'Save As'); + return (async () => { + const eles = await driver.$('#actions paper-button'); + await eles.waitForVisible(); + const buttons = await driver.$$('#actions paper-button'); + const rowTitles = await driver.$$('#actions paper-button').map((img) => img.getText()); + const index = rowTitles.findIndex((currenTitle) => currenTitle === 'Save As'); + const result = await buttons[index]; + return result; + })(); } get confirmSaveSearchButton() { - driver.waitForVisible('#saveDialog paper-button.primary'); - return driver.element('#saveDialog paper-button.primary'); + return (async () => { + const ele = await driver.$('#saveDialog paper-button.primary'); + await ele.waitForVisible(); + return ele; + })(); } get menuButton() { - return this.el.element('#menuButton'); + return (async () => { + const ele = await this.el; + return ele.element('#menuButton'); + })(); } get savedSearchActionButton() { @@ -26,30 +39,42 @@ export default class Search extends Results { } get shareAction() { - driver.waitForVisible('nuxeo-saved-search-actions paper-item'); - return driver.elements('nuxeo-saved-search-actions paper-item').find((e) => e.getText() === 'Share'); + return (async () => { + const ele = await driver.$('nuxeo-saved-search-actions paper-item'); + await ele.waitForVisible(); + const buttons = await driver.$$('nuxeo-saved-search-actions paper-item'); + const rowTitles = await driver.$$('nuxeo-saved-search-actions paper-item').map((img) => img.getText()); + const index = rowTitles.findIndex((currenTitle) => currenTitle === 'Share'); + const result = await buttons[index]; + return result; + })(); } get permissionsView() { return new DocumentPermissions(`${this._selector} nuxeo-document-permissions`); } - getSavedSearch(savedSearchName) { - driver.waitUntil(() => { - const els = driver.elements(`${this._selector} #actionsDropdown paper-item`); - return els.length > 1; - }); - return this.el.elements('#actionsDropdown paper-item').find((e) => e.getText() === savedSearchName); + async getSavedSearch(savedSearchName) { + const selector = await this._selector; + const els = await driver.elements(`${selector} #actionsDropdown paper-item`); + if (els.length > 1) { + return els[1]; + } + const ele = await this.el; + const dropdownList = await ele.elements('#actionsDropdown paper-item'); + const dropdownElenent = await dropdownList.find(async (e) => (await e.getText()) === savedSearchName); + return dropdownElenent; } enterInput(text) { return driver.keys(text); } - getField(field) { - driver.waitForExist(this._selector); - driver.waitForVisible(this._selector); - return this.el.element(`[name="${field}"]`); + async getField(field) { + await driver.waitForExist(this._selector); + await driver.waitForVisible(this._selector); + const ele = await this.el.$(`[name="${field}"]`); + return ele; } getFieldValue(field) { @@ -58,29 +83,37 @@ export default class Search extends Results { return fixtures.layouts.getValue(fieldEl); } - setFieldValue(field, value) { - let fieldEl; - driver.waitUntil(() => { - fieldEl = this.getField(field); - return !!fieldEl; - }); - fieldEl.waitForVisible(); - fieldEl.scrollIntoView(); + async setFieldValue(field, value) { + const fieldEl = await this.getField(field); + await fieldEl.waitForVisible(); + await fieldEl.scrollIntoView(); return fixtures.layouts.setValue(fieldEl, value); } - search(searchType, searchTerm) { + async search(searchType, searchTerm) { if (searchType === 'fulltext') { - this.el.element('#searchInput .input-element input').waitForVisible(); - this.el.element('#searchInput .input-element input').setValue(searchTerm); - driver.keys('Enter'); + const ele = await this.el.$('#searchInput .input-element input'); + await ele.waitForVisible(); + await ele.setValue(searchTerm); + await driver.keys('Enter'); } else { - this.setFieldValue(searchType, searchTerm); + await this.setFieldValue(searchType, searchTerm); } } - quickSearchResultsCount() { - const rows = this.el.element('#results #selector').elements('a.item'); - return rows.filter((result) => result.getAttribute('hidden') === null).length; + async quickSearchResultsCount() { + const ele = await this.el; + const selector = await ele.element('#results #selector'); + const rows = await selector.elements('a.item'); + let count = 0; + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + // eslint-disable-next-line no-await-in-loop + const attr = await row.getAttribute('hidden'); + if (attr === null) { + count++; + } + } + return count; } } diff --git a/packages/nuxeo-web-ui-ftest/wdio-compat-plugin.js b/packages/nuxeo-web-ui-ftest/wdio-compat-plugin.js index 2107726b22..0c67b5e0f5 100644 --- a/packages/nuxeo-web-ui-ftest/wdio-compat-plugin.js +++ b/packages/nuxeo-web-ui-ftest/wdio-compat-plugin.js @@ -252,8 +252,9 @@ module.exports = class { browser.addCommand( 'hasElementByTextContent', - function(selector, textContent) { - return this.elements(selector).some((e) => e.getText() === textContent); + async function(selector, textContent) { + const ele = await this.elements(selector); + return ele.some((e) => e.getText() === textContent); }, true, );