Unexclude due the timeout (#1805)

* change base method to wait

* fix import

* reduce log

* fix

* data placeholder

* fix

* fix

* fix

* fix style

* change visibility with common method

* fix

* use common get value method

* remove unused import

* fix a few incorrect api calls

* - use separate variables

* correctly wait for items after they have been created

* use browseraction click

* Exclude failing tests

* increase timeout and some fix

* check env before execute test

* simplify conf

* exclude

* rerun

* logs

* refactor pagination tests to use only 51 items
take out pagination tests into a separate stage

* fix check

* remove hardcoded total items. other shared files might already exist

Co-authored-by: Adina Parpalita <Adina.Parpalita@ness.com>
Co-authored-by: iuliaib <iulia.burca@ness.com>
This commit is contained in:
Eugenio Romano
2020-11-19 16:07:57 +00:00
committed by GitHub
parent 509c6b6f75
commit 8308573f3c
82 changed files with 815 additions and 750 deletions

View File

@@ -26,6 +26,7 @@
import { browser, by } from 'protractor';
import { Component } from '../component';
import { waitForPresence, waitForStaleness } from '../../utilities/utils';
import { BrowserActions } from '@alfresco/adf-testing';
export class DropDownBreadcrumb extends Component {
pathOptionCss = '.adf-dropdown-breadcrumb-path-option .mat-option-text';
@@ -47,13 +48,13 @@ export class DropDownBreadcrumb extends Component {
}
async openPath(): Promise<void> {
await this.trigger.click();
await BrowserActions.click(this.trigger);
await this.waitForPathListDropdownToOpen();
}
async clickPathItem(name: string): Promise<void> {
const elem = browser.element(by.cssContainingText(this.pathOptionCss, name));
await elem.click();
await BrowserActions.click(elem);
}
async getPathItems(): Promise<string[]> {

View File

@@ -24,11 +24,11 @@
*/
import { browser, by, ElementArrayFinder, ElementFinder, protractor } from 'protractor';
import { Logger } from '@alfresco/adf-testing';
import { BrowserVisibility, Logger } from '@alfresco/adf-testing';
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
import { Component } from '../component';
import { Menu } from '../menu/menu';
import { Utils, waitForClickable, waitForPresence } from '../../utilities/utils';
import { Utils, waitForPresence } from '../../utilities/utils';
export class DataTable extends Component {
private static selectors = {
@@ -223,7 +223,7 @@ export class DataTable extends Component {
async doubleClickOnRowByName(name: string, location: string = ''): Promise<void> {
try {
const item = this.getRowFirstCell(name, location);
await waitForClickable(item);
await BrowserVisibility.waitUntilElementIsClickable(item);
await browser.actions().mouseMove(item).perform();
await browser.actions().doubleClick().perform();
} catch (error) {

View File

@@ -27,6 +27,7 @@ import { by, browser } from 'protractor';
import { Component } from '../component';
import { isPresentAndDisplayed, waitForStaleness } from '../../utilities/utils';
const moment = require('moment');
import { BrowserActions } from '@alfresco/adf-testing';
export class DateTimePicker extends Component {
calendar = this.byCss('.mat-datetimepicker-popup', browser);
@@ -57,7 +58,7 @@ export class DateTimePicker extends Component {
const year = await this.headerYear.getText();
const firstActiveDay = '.mat-datetimepicker-calendar-body-active .mat-datetimepicker-calendar-body-cell-content';
const elem = this.dayPicker.element(by.cssContainingText(firstActiveDay, `${dayOfTomorrow}`));
await elem.click();
await BrowserActions.click(elem);
return `${date} ${year}`;
}
}

View File

@@ -25,9 +25,10 @@
import { by, browser, protractor } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { Utils, isPresentAndDisplayed, waitForStaleness, waitForPresence, isPresentAndEnabled, waitForClickable } from '../../utilities/utils';
import { isPresentAndDisplayed, waitForStaleness, waitForPresence, isPresentAndEnabled } from '../../utilities/utils';
import { DropDownBreadcrumb } from '../breadcrumb/dropdown-breadcrumb';
import { DataTable } from '../data-table/data-table';
import { BrowserActions } from '@alfresco/adf-testing';
export class ContentNodeSelectorDialog extends GenericDialog {
cancelButton = this.childElement(by.css('[data-automation-id="content-node-selector-actions-cancel"]'));
@@ -53,13 +54,12 @@ export class ContentNodeSelectorDialog extends GenericDialog {
}
async selectLocation(location: string): Promise<void> {
await this.locationDropDown.click();
await waitForPresence(this.locationPersonalFiles);
await BrowserActions.click(this.locationDropDown);
if (location === 'Personal Files') {
await this.locationPersonalFiles.click();
await BrowserActions.click(this.locationPersonalFiles);
} else {
await this.locationFileLibraries.click();
await BrowserActions.click(this.locationFileLibraries);
}
await this.waitForDropDownToClose();
@@ -67,8 +67,7 @@ export class ContentNodeSelectorDialog extends GenericDialog {
async selectDestination(folderName: string): Promise<void> {
const row = this.dataTable.getRowByName(folderName);
await waitForClickable(row);
await row.click();
await BrowserActions.click(row);
await waitForPresence(browser.element(by.css('.adf-is-selected')));
}
@@ -85,7 +84,7 @@ export class ContentNodeSelectorDialog extends GenericDialog {
}
async searchFor(text: string): Promise<void> {
await Utils.clearFieldWithBackspace(this.searchInput);
await BrowserActions.clearWithBackSpace(this.searchInput);
await this.searchInput.sendKeys(text);
await this.searchInput.sendKeys(protractor.Key.ENTER);
}

View File

@@ -25,15 +25,16 @@
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndDisplayed, waitForClickable, isPresentAndEnabled, typeText } from '../../utilities/utils';
import { isPresentAndDisplayed, isPresentAndEnabled, typeText } from '../../utilities/utils';
import { BrowserActions, BrowserVisibility } from '@alfresco/adf-testing';
export class CreateOrEditFolderDialog extends GenericDialog {
createButton = this.childElement(by.cssContainingText('.mat-dialog-actions button', 'Create'));
cancelButton = this.childElement(by.id('adf-folder-cancel-button'));
updateButton = this.childElement(by.cssContainingText('.mat-dialog-actions button', 'Update'));
nameInput = this.rootElem.element(by.css('input[placeholder="Name" i]'));
descriptionTextArea = this.rootElem.element(by.css('textarea[placeholder="Description" i]'));
nameInput = this.rootElem.element(by.css('input[data-placeholder="Name" i]'));
descriptionTextArea = this.rootElem.element(by.css('textarea[data-placeholder="Description" i]'));
validationMessage = this.rootElem.element(by.css('.mat-hint span'));
constructor() {
@@ -42,7 +43,7 @@ export class CreateOrEditFolderDialog extends GenericDialog {
async waitForDialogToOpen() {
await super.waitForDialogToOpen();
await waitForClickable(this.nameInput);
await BrowserVisibility.waitUntilElementIsClickable(this.nameInput);
}
async isUpdateButtonEnabled(): Promise<boolean> {
@@ -66,11 +67,11 @@ export class CreateOrEditFolderDialog extends GenericDialog {
}
async getName(): Promise<string> {
return this.nameInput.getAttribute('value');
return BrowserActions.getInputValue(this.nameInput);
}
async getDescription(): Promise<string> {
return this.descriptionTextArea.getAttribute('value');
return BrowserActions.getInputValue(this.descriptionTextArea);
}
async enterName(name: string): Promise<void> {
@@ -82,7 +83,7 @@ export class CreateOrEditFolderDialog extends GenericDialog {
}
async clickCancel(): Promise<void> {
await this.cancelButton.click();
await BrowserActions.click(this.cancelButton);
await this.waitForDialogToClose();
}
}

View File

@@ -26,14 +26,15 @@
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndDisplayed, isPresentAndEnabled, typeText } from '../../utilities/utils';
import { BrowserActions } from '@alfresco/adf-testing';
export class CreateFromTemplateDialog extends GenericDialog {
createButton = this.childElement(by.cssContainingText('.mat-dialog-actions button', 'Create'));
cancelButton = this.childElement(by.cssContainingText('.mat-dialog-actions button', 'CANCEL'));
nameInput = this.childElement(by.css('input[placeholder="Name" i]'));
titleInput = this.childElement(by.css('input[placeholder="Title" i]'));
descriptionTextArea = this.childElement(by.css('textarea[placeholder="Description" i]'));
nameInput = this.childElement(by.css('input[data-placeholder="Name" i]'));
titleInput = this.childElement(by.css('input[data-placeholder="Title" i]'));
descriptionTextArea = this.childElement(by.css('textarea[data-placeholder="Description" i]'));
validationMessage = this.childElement(by.css('.mat-error'));
constructor() {
@@ -61,11 +62,11 @@ export class CreateFromTemplateDialog extends GenericDialog {
}
async getName(): Promise<string> {
return this.nameInput.getAttribute('value');
return BrowserActions.getInputValue(this.nameInput);
}
async getDescription(): Promise<string> {
return this.descriptionTextArea.getAttribute('value');
return BrowserActions.getInputValue(this.descriptionTextArea);
}
async enterName(name: string): Promise<void> {
@@ -81,7 +82,7 @@ export class CreateFromTemplateDialog extends GenericDialog {
}
async clickCancel(): Promise<void> {
await this.cancelButton.click();
await BrowserActions.click(this.cancelButton);
await this.waitForDialogToClose();
}
}

View File

@@ -25,15 +25,16 @@
import { by, ElementFinder } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { waitForClickable, isPresentAndEnabled, typeText } from '../../utilities/utils';
import { isPresentAndEnabled, typeText } from '../../utilities/utils';
import { BrowserActions, BrowserVisibility } from '@alfresco/adf-testing';
export class CreateLibraryDialog extends GenericDialog {
createButton = this.childElement(by.cssContainingText('.mat-dialog-actions button', 'Create'));
cancelButton = this.childElement(by.cssContainingText('.mat-dialog-actions button', 'Cancel'));
nameInput = this.rootElem.element(by.css('input[placeholder="Name" i]'));
libraryIdInput = this.rootElem.element(by.css('input[placeholder="Library ID" i]'));
descriptionTextArea = this.rootElem.element(by.css('textarea[placeholder="Description" i]'));
nameInput = this.rootElem.element(by.css('input[data-placeholder="Name" i]'));
libraryIdInput = this.rootElem.element(by.css('input[data-placeholder="Library ID" i]'));
descriptionTextArea = this.rootElem.element(by.css('textarea[data-placeholder="Description" i]'));
visibilityPublic = this.rootElem.element(by.cssContainingText('.mat-radio-label', 'Public'));
visibilityModerated = this.rootElem.element(by.cssContainingText('.mat-radio-label', 'Moderated'));
visibilityPrivate = this.rootElem.element(by.cssContainingText('.mat-radio-label', 'Private'));
@@ -46,7 +47,7 @@ export class CreateLibraryDialog extends GenericDialog {
async waitForDialogToOpen(): Promise<void> {
await super.waitForDialogToOpen();
await waitForClickable(this.nameInput);
await BrowserVisibility.waitUntilElementIsClickable(this.nameInput);
}
async getErrorMessage(): Promise<string> {
@@ -77,7 +78,7 @@ export class CreateLibraryDialog extends GenericDialog {
}
async clickCancel(): Promise<void> {
await this.cancelButton.click();
await BrowserActions.click(this.cancelButton);
await this.waitForDialogToClose();
}

View File

@@ -24,7 +24,8 @@
*/
import { ElementFinder, by, browser, Locator } from 'protractor';
import { isPresentAndDisplayed, waitForPresence, waitForVisibility, waitForStaleness } from '../../utilities/utils';
import { isPresentAndDisplayed, waitForPresence, waitForStaleness } from '../../utilities/utils';
import { BrowserVisibility } from '@alfresco/adf-testing';
export abstract class GenericDialog {
protected constructor(private rootCssSelector?: string) {}
@@ -47,7 +48,7 @@ export abstract class GenericDialog {
async waitForDialogToOpen(): Promise<void> {
await waitForPresence(this.rootElem);
await waitForVisibility(this.content);
await BrowserVisibility.waitUntilElementIsVisible(this.content);
await waitForPresence(browser.element(by.css('.cdk-overlay-backdrop')));
}

View File

@@ -25,6 +25,7 @@
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { BrowserActions } from '@alfresco/adf-testing';
export class ManageVersionsDialog extends GenericDialog {
closeButton = this.childElement(by.cssContainingText('.mat-button', 'Close'));
@@ -34,7 +35,7 @@ export class ManageVersionsDialog extends GenericDialog {
}
async clickClose(): Promise<void> {
await this.closeButton.click();
await BrowserActions.click(this.closeButton);
await this.waitForDialogToClose();
}
}

View File

@@ -25,7 +25,8 @@
import { by, browser } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { waitForClickable, isPresentAndEnabled, typeText } from '../../utilities/utils';
import { isPresentAndEnabled, typeText } from '../../utilities/utils';
import { BrowserVisibility } from '@alfresco/adf-testing';
export class PasswordDialog extends GenericDialog {
closeButton = this.childElement(by.css('[data-automation-id="adf-password-dialog-close"]'));
@@ -38,8 +39,7 @@ export class PasswordDialog extends GenericDialog {
}
async waitForDialogToOpen(): Promise<void> {
await super.waitForDialogToOpen();
await waitForClickable(this.passwordInput);
await BrowserVisibility.waitUntilElementIsClickable(this.passwordInput);
}
async isDialogOpen(): Promise<boolean> {

View File

@@ -28,6 +28,7 @@ import { GenericDialog } from '../dialog/generic-dialog';
import { DropDownBreadcrumb } from '../breadcrumb/dropdown-breadcrumb';
import { DataTable } from '../data-table/data-table';
import { isPresentAndEnabled } from '../../utilities/utils';
import { BrowserActions } from '@alfresco/adf-testing';
export class SelectTemplateDialog extends GenericDialog {
nextButton = this.childElement(by.css('[data-automation-id="content-node-selector-actions-choose"]'));
@@ -49,12 +50,12 @@ export class SelectTemplateDialog extends GenericDialog {
}
async clickCancel(): Promise<void> {
await this.cancelButton.click();
await BrowserActions.click(this.cancelButton);
await this.waitForDialogToClose();
}
async clickNext(): Promise<void> {
await this.nextButton.click();
await BrowserActions.click(this.nextButton);
await this.waitForDialogToClose();
}
}

View File

@@ -27,6 +27,7 @@ import { by } from 'protractor';
import { DateTimePicker } from '../../components/datetime-picker/datetime-picker';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndEnabled } from '../../utilities/utils';
import { BrowserActions } from '@alfresco/adf-testing';
export class ShareDialog extends GenericDialog {
dateTimePicker = new DateTimePicker();
@@ -56,7 +57,7 @@ export class ShareDialog extends GenericDialog {
}
async getLinkUrl(): Promise<string> {
return this.url.getAttribute('value');
return BrowserActions.getInputValue(this.url);
}
async isUrlReadOnly(): Promise<boolean> {
@@ -69,7 +70,7 @@ export class ShareDialog extends GenericDialog {
}
async clickClose(): Promise<void> {
await this.closeButton.click();
await BrowserActions.click(this.closeButton);
await this.waitForDialogToClose();
}
@@ -90,11 +91,11 @@ export class ShareDialog extends GenericDialog {
async closeDatetimePicker(): Promise<void> {
if (await this.dateTimePicker.isCalendarOpen()) {
await this.datetimePickerButton.click();
await BrowserActions.click(this.datetimePickerButton);
}
}
async getExpireDate(): Promise<string> {
return this.expireInput.getAttribute('value');
return BrowserActions.getInputValue(this.expireInput);
}
}

View File

@@ -47,7 +47,7 @@ export class Header extends Component {
}
async openMoreMenu(): Promise<void> {
await this.moreActions.click();
await BrowserActions.click(this.moreActions);
await this.menu.waitForMenuToOpen();
}
@@ -63,7 +63,7 @@ export class Header extends Component {
async expandSideNav(): Promise<void> {
const expanded = await this.isSidenavExpanded();
if (!expanded) {
await this.sidenavToggle.click();
await BrowserActions.click(this.sidenavToggle);
await waitElement(`[data-automation-id='expanded']`);
}
}
@@ -71,7 +71,7 @@ export class Header extends Component {
async collapseSideNav(): Promise<void> {
const expanded = await this.isSidenavExpanded();
if (expanded) {
await this.sidenavToggle.click();
await BrowserActions.click(this.sidenavToggle);
await waitElement(`[data-automation-id='collapsed']`);
}
}

View File

@@ -25,6 +25,7 @@
import { Menu } from '../menu/menu';
import { Component } from '../component';
import { BrowserActions } from '@alfresco/adf-testing';
export class UserInfo extends Component {
fullName = this.byCss('.current-user__full-name');
@@ -37,7 +38,7 @@ export class UserInfo extends Component {
}
async openMenu(): Promise<Menu> {
await this.avatar.click();
await BrowserActions.click(this.avatar);
await this.menu.wait();
return this.menu;

View File

@@ -26,7 +26,8 @@
import { by, browser, until } from 'protractor';
import { Component } from '../component';
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
import { waitForVisibility, typeText } from '../../utilities/utils';
import { typeText } from '../../utilities/utils';
import { BrowserActions, BrowserVisibility } from '@alfresco/adf-testing';
export class CommentsTab extends Component {
commentsContainer = this.byCss('.adf-comments-container');
@@ -44,7 +45,7 @@ export class CommentsTab extends Component {
}
async waitForCommentsContainer() {
await waitForVisibility(this.commentsContainer);
await BrowserVisibility.waitUntilElementIsVisible(this.commentsContainer);
}
async getCommentsTabHeaderText(): Promise<string> {
@@ -111,10 +112,10 @@ export class CommentsTab extends Component {
}
async clickAddButton(): Promise<void> {
await this.addCommentButton.click();
await BrowserActions.click(this.addCommentButton);
}
async getCommentTextFromTextArea(): Promise<string> {
return this.commentTextarea.getAttribute('value');
return BrowserActions.getInputValue(this.commentTextarea);
}
}

View File

@@ -25,7 +25,8 @@
import { by, browser, ElementFinder } from 'protractor';
import { Component } from '../component';
import { isPresentAndEnabled, isPresentAndDisplayed, waitForVisibility } from '../../utilities/utils';
import { isPresentAndEnabled, isPresentAndDisplayed } from '../../utilities/utils';
import { BrowserActions, BrowserVisibility } from '@alfresco/adf-testing';
export class ContentMetadata extends Component {
expandedPanel = this.byCss('.mat-expansion-panel.mat-expanded');
@@ -47,7 +48,7 @@ export class ContentMetadata extends Component {
}
async waitForImagePropertiesPanelToExpand(): Promise<void> {
await waitForVisibility(this.expandedImagePropertiesPanel);
await BrowserVisibility.waitUntilElementIsVisible(this.expandedImagePropertiesPanel);
}
async getVisiblePropertiesLabels(): Promise<string[]> {
@@ -95,7 +96,7 @@ export class ContentMetadata extends Component {
const tagName = await elem.getTagName();
if (tagName === 'input' || tagName === 'textarea') {
return elem.getAttribute('value');
return BrowserActions.getInputValue(elem);
}
return elem.getText();

View File

@@ -24,7 +24,7 @@
*/
import { by, browser } from 'protractor';
import { Logger } from '@alfresco/adf-testing';
import { BrowserActions, Logger } from '@alfresco/adf-testing';
import { Component } from '../component';
import { waitForPresence, waitForStaleness, typeText } from '../../utilities/utils';
@@ -83,7 +83,7 @@ export class LibraryMetadata extends Component {
}
private async clickButton(button: string) {
await this.getButton(button).click();
await BrowserActions.click(this.getButton(button));
}
async waitForVisibilityDropDownToClose() {
@@ -155,15 +155,15 @@ export class LibraryMetadata extends Component {
async setVisibility(visibility: string) {
const val = visibility.toLowerCase();
await this.visibilityDropDown.click();
await BrowserActions.click(this.visibilityDropDown);
await waitForPresence(this.visibilityDropDown);
if (val === 'public') {
await this.visibilityPublic.click();
await BrowserActions.click(this.visibilityPublic);
} else if (val === 'private') {
await this.visibilityPrivate.click();
await BrowserActions.click(this.visibilityPrivate);
} else if (val === 'moderated') {
await this.visibilityModerated.click();
await BrowserActions.click(this.visibilityModerated);
} else {
Logger.error('----- invalid visibility', val);
}

View File

@@ -24,12 +24,12 @@
*/
import { by, browser } from 'protractor';
import { Logger } from '@alfresco/adf-testing';
import { BrowserActions, BrowserVisibility, Logger } from '@alfresco/adf-testing';
import { Component } from '../component';
import { CommentsTab } from './info-drawer-comments-tab';
import { LibraryMetadata } from './info-drawer-metadata-library';
import { ContentMetadata } from './info-drawer-metadata-content';
import { waitForVisibility, waitForInvisibility, waitForPresence } from '../../utilities/utils';
import { waitForPresence } from '../../utilities/utils';
export class InfoDrawer extends Component {
commentsTab = new CommentsTab('adf-info-drawer');
@@ -89,7 +89,7 @@ export class InfoDrawer extends Component {
}
async clickTab(title: string) {
await this.getTabByTitle(title).click();
await BrowserActions.click(this.getTabByTitle(title));
}
async getComponentIdOfTab(): Promise<string> {
@@ -118,9 +118,12 @@ export class InfoDrawer extends Component {
async clickCommentsTab() {
try {
await this.getTabByTitle('Comments').click();
await BrowserActions.click(this.getTabByTitle('Comments'));
await this.commentsTab.waitForCommentsContainer();
await Promise.all([waitForVisibility(this.commentsTab.component), waitForInvisibility(this.propertiesTab.component)]);
await Promise.all([
BrowserVisibility.waitUntilElementIsVisible(this.commentsTab.component),
BrowserVisibility.waitUntilElementIsNotVisible(this.propertiesTab.component)
]);
} catch (error) {
Logger.error('--- info-drawer clickCommentsTab catch error: ', error);
}

View File

@@ -24,9 +24,9 @@
*/
import { ElementFinder, by, browser } from 'protractor';
import { Logger } from '@alfresco/adf-testing';
import { Logger, BrowserVisibility, BrowserActions } from '@alfresco/adf-testing';
import { Component } from '../component';
import { Utils, isPresentAndEnabled, waitForPresence, waitForVisibility, waitForStaleness, waitForClickable } from '../../utilities/utils';
import { Utils, isPresentAndEnabled, waitForPresence, waitForStaleness } from '../../utilities/utils';
export class Menu extends Component {
items = this.allByCss('.mat-menu-item');
@@ -72,7 +72,7 @@ export class Menu extends Component {
async waitForMenuToOpen(): Promise<void> {
await waitForPresence(browser.element(by.css('.cdk-overlay-container .mat-menu-panel')));
await waitForVisibility(this.items.get(0));
await BrowserVisibility.waitUntilElementIsVisible(this.items.get(0));
}
async waitForMenuToClose(): Promise<void> {
@@ -126,7 +126,7 @@ export class Menu extends Component {
async clickNthItem(nth: number): Promise<void> {
try {
const elem = this.getNthItem(nth);
await waitForClickable(elem);
await BrowserVisibility.waitUntilElementIsClickable(elem);
await browser.actions().mouseMove(elem).perform();
await browser.actions().click().perform();
await this.waitForMenuToClose();
@@ -138,8 +138,7 @@ export class Menu extends Component {
async clickMenuItem(menuItem: string): Promise<void> {
try {
const elem = this.getItemByLabel(menuItem);
await waitForClickable(elem);
await elem.click();
await BrowserActions.click(elem);
} catch (e) {
Logger.error('___click menu item catch___', e);
}
@@ -148,7 +147,7 @@ export class Menu extends Component {
async mouseOverMenuItem(menuItem: string): Promise<void> {
try {
const elem = this.getItemByLabel(menuItem);
await waitForClickable(elem);
await BrowserVisibility.waitUntilElementIsClickable(elem);
await browser.actions().mouseMove(elem).perform();
await browser.sleep(500);
} catch (error) {
@@ -159,7 +158,7 @@ export class Menu extends Component {
async hasSubMenu(menuItem: string): Promise<boolean> {
try {
const elem = this.getItemByLabel(menuItem);
await waitForClickable(elem);
await BrowserVisibility.waitUntilElementIsClickable(elem);
const elemClass = await elem.getAttribute('class');
return elemClass.includes('mat-menu-item-submenu-trigger');
} catch (error) {
@@ -171,8 +170,7 @@ export class Menu extends Component {
async clickSubMenuItem(subMenuItem: string): Promise<void> {
try {
const elem = this.getSubItemByLabel(subMenuItem);
await waitForClickable(elem);
await elem.click();
await BrowserActions.click(elem);
} catch (e) {
Logger.error('___click submenu item catch___', e);
}

View File

@@ -24,10 +24,9 @@
*/
import { browser } from 'protractor';
import { Logger } from '@alfresco/adf-testing';
import { BrowserActions, Logger } from '@alfresco/adf-testing';
import { Menu } from '../menu/menu';
import { Component } from '../component';
import { waitForClickable } from '../../utilities/utils';
export class Pagination extends Component {
range = this.byCss('.adf-pagination__range');
@@ -47,8 +46,7 @@ export class Pagination extends Component {
async openMaxItemsMenu() {
try {
await waitForClickable(this.maxItemsButton, 'timeout waiting for maxItemsButton to be clickable');
await this.maxItemsButton.click();
await BrowserActions.click(this.maxItemsButton);
await this.menu.waitForMenuToOpen();
} catch (error) {
Logger.error('____ open max items catch ___', error);
@@ -57,8 +55,7 @@ export class Pagination extends Component {
async openCurrentPageMenu() {
try {
await waitForClickable(this.pagesButton, 'timeout waiting for pagesButton to be clickable');
await this.pagesButton.click();
await BrowserActions.click(this.pagesButton);
await this.menu.waitForMenuToOpen();
} catch (error) {
Logger.error('____ open current page menu ___', error);
@@ -86,11 +83,11 @@ export class Pagination extends Component {
}
async clickNext() {
await this.nextButton.click();
await BrowserActions.click(this.nextButton);
}
async clickPrevious() {
await this.previousButton.click();
await BrowserActions.click(this.previousButton);
}
async isNextEnabled() {

View File

@@ -25,7 +25,8 @@
import { ElementFinder, by, protractor } from 'protractor';
import { GenericFilterPanel } from './generic-filter-panel';
import { Utils, isPresentAndDisplayed } from '../../../utilities/utils';
import { isPresentAndDisplayed } from '../../../utilities/utils';
import { BrowserActions } from '@alfresco/adf-testing';
export class CreatedDateFilter extends GenericFilterPanel {
constructor() {
@@ -67,22 +68,18 @@ export class CreatedDateFilter extends GenericFilterPanel {
async clickClearButton(): Promise<void> {
if (await this.isClearButtonEnabled()) {
await this.clearButton.click();
await BrowserActions.click(this.clearButton);
}
}
async clickApplyButton(): Promise<void> {
if (await this.isApplyButtonEnabled()) {
await this.applyButton.click();
await BrowserActions.click(this.applyButton);
}
}
async getFromValue(): Promise<string> {
try {
return await this.fromInput.getAttribute('value');
} catch (error) {
return '';
}
return BrowserActions.getInputValue(this.fromInput);
}
async getFromError(): Promise<string> {
@@ -94,11 +91,7 @@ export class CreatedDateFilter extends GenericFilterPanel {
}
async getToValue(): Promise<string> {
try {
return await this.toInput.getAttribute('value');
} catch (err) {
return '';
}
return BrowserActions.getInputValue(this.fromInput);
}
async getToError(): Promise<string> {
@@ -121,13 +114,13 @@ export class CreatedDateFilter extends GenericFilterPanel {
async enterFromDate(date: string): Promise<void> {
await this.expandPanel();
await Utils.clearFieldWithBackspace(this.fromInput);
await BrowserActions.clearWithBackSpace(this.fromInput);
await this.fromInput.sendKeys(date, protractor.Key.TAB);
}
async enterToDate(date: string): Promise<void> {
await this.expandPanel();
await Utils.clearFieldWithBackspace(this.toInput);
await BrowserActions.clearWithBackSpace(this.toInput);
await this.toInput.sendKeys(date, protractor.Key.TAB);
}
}

View File

@@ -25,13 +25,14 @@
import { ElementFinder, ElementArrayFinder, by, browser } from 'protractor';
import { GenericFilterPanel } from './generic-filter-panel';
import { BrowserActions } from '@alfresco/adf-testing';
export class FacetFilter extends GenericFilterPanel {
private readonly locators = {
checkbox: '.mat-checkbox',
checkboxChecked: '.mat-checkbox.mat-checkbox-checked',
button: '.adf-facet-buttons button',
categoryInput: 'input[placeholder="Filter category"',
categoryInput: 'input[data-placeholder="Filter category"',
facetsFilter: '.adf-facet-result-filter'
};
@@ -67,7 +68,7 @@ export class FacetFilter extends GenericFilterPanel {
if ((await this.selectedFacets.count()) > 0) {
await this.expandPanel();
await this.selectedFacets.each(async (elem) => {
await elem.click();
await BrowserActions.click(elem);
});
}
await this.expandPanel();
@@ -83,7 +84,7 @@ export class FacetFilter extends GenericFilterPanel {
async clickClearButton(): Promise<void> {
if (await this.isClearButtonEnabled()) {
await this.clearButton.click();
await BrowserActions.click(this.clearButton);
}
}

View File

@@ -25,6 +25,7 @@
import { ElementFinder, by, browser } from 'protractor';
import { isPresentAndDisplayed } from '../../../utilities/utils';
import { BrowserActions } from '@alfresco/adf-testing';
export class GenericFilterPanel {
private filterName: string;
@@ -52,7 +53,7 @@ export class GenericFilterPanel {
}
async clickPanelHeader(): Promise<void> {
await this.panelHeader.click();
await BrowserActions.click(this.panelHeader);
}
async isPanelDisplayed(): Promise<boolean> {

View File

@@ -25,6 +25,7 @@
import { ElementFinder, by, ElementArrayFinder } from 'protractor';
import { GenericFilterPanel } from './generic-filter-panel';
import { BrowserActions } from '@alfresco/adf-testing';
export class SizeFilter extends GenericFilterPanel {
constructor() {
@@ -51,7 +52,7 @@ export class SizeFilter extends GenericFilterPanel {
if ((await this.selectedFacets.count()) > 0) {
await this.expandPanel();
await this.selectedFacets.each(async (elem) => {
await elem.click();
await BrowserActions.click(elem);
});
}
await this.collapsePanel();
@@ -63,27 +64,27 @@ export class SizeFilter extends GenericFilterPanel {
async clickClearButton(): Promise<void> {
if (await this.isClearButtonEnabled()) {
await this.clearButton.click();
await BrowserActions.click(this.clearButton);
}
}
async checkSizeSmall(): Promise<void> {
const small = this.facets.filter(async (elem) => (await elem.getText()) === 'Small').first();
await small.click();
await BrowserActions.click(small);
}
async checkSizeMedium(): Promise<void> {
const medium = this.facets.filter(async (elem) => (await elem.getText()) === 'Medium').first();
await medium.click();
await BrowserActions.click(medium);
}
async checkSizeLarge(): Promise<void> {
const large = this.facets.filter(async (elem) => (await elem.getText()) === 'Large').first();
await large.click();
await BrowserActions.click(large);
}
async checkSizeHuge(): Promise<void> {
const huge = this.facets.filter(async (elem) => (await elem.getText()) === 'Huge').first();
await huge.click();
await BrowserActions.click(huge);
}
}

View File

@@ -25,7 +25,8 @@
import { browser, by, protractor } from 'protractor';
import { Component } from '../component';
import { Utils, waitForPresence, waitForClickable, waitElement } from '../../utilities/utils';
import { waitForPresence, waitElement } from '../../utilities/utils';
import { BrowserActions, BrowserVisibility } from '@alfresco/adf-testing';
export class SearchInput extends Component {
searchButton = this.component.element(by.css('.app-search-button'));
@@ -47,7 +48,7 @@ export class SearchInput extends Component {
}
async waitForSearchInputToBeInteractive() {
await waitForClickable(this.searchControl);
await BrowserVisibility.waitUntilElementIsClickable(this.searchControl);
}
async isSearchContainerDisplayed() {
@@ -58,8 +59,7 @@ export class SearchInput extends Component {
}
async clickSearchButton() {
await waitForClickable(this.searchButton);
await this.searchButton.click();
await BrowserActions.click(this.searchButton);
await this.waitForSearchControl();
}
@@ -69,18 +69,15 @@ export class SearchInput extends Component {
}
async clickFilesOption() {
await waitForClickable(this.searchFilesOption);
await this.searchFilesOption.click();
await BrowserActions.click(this.searchFilesOption);
}
async clickFoldersOption() {
await waitForClickable(this.searchFoldersOption);
await this.searchFoldersOption.click();
await BrowserActions.click(this.searchFoldersOption);
}
async clickLibrariesOption() {
await waitForClickable(this.searchLibrariesOption);
await this.searchLibrariesOption.click();
await BrowserActions.click(this.searchLibrariesOption);
}
async isFilesOptionEnabled() {
@@ -131,7 +128,7 @@ export class SearchInput extends Component {
async clickClearSearchButton() {
if (await this.isClearSearchButtonPresent()) {
await this.clearSearchButton.click();
await BrowserActions.click(this.clearSearchButton);
}
}
@@ -158,7 +155,7 @@ export class SearchInput extends Component {
async searchFor(text: string) {
await this.waitForSearchInputToBeInteractive();
await Utils.clearFieldWithBackspace(this.searchInput);
await BrowserActions.clearWithBackSpace(this.searchInput);
await this.searchInput.sendKeys(text);
await this.searchInput.sendKeys(protractor.Key.ENTER);
}

View File

@@ -25,7 +25,8 @@
import { by, browser } from 'protractor';
import { Component } from '../component';
import { isPresentAndDisplayed, waitForVisibility } from '../../utilities/utils';
import { isPresentAndDisplayed } from '../../utilities/utils';
import { BrowserActions, BrowserVisibility } from '@alfresco/adf-testing';
export type SortByType = 'Relevance' | 'Title' | 'Filename' | 'Modified date' | 'Modifier' | 'Created date' | 'Size' | 'Type';
export type SortOrderType = 'ASC' | 'DESC' | '';
@@ -41,7 +42,11 @@ export class SearchSortingPicker extends Component {
}
async waitForSortByDropdownToExpand(): Promise<void> {
await waitForVisibility(this.sortByDropdownExpanded, 'Timeout waiting for sortBy dropdown to expand');
await BrowserVisibility.waitUntilElementIsVisible(
this.sortByDropdownExpanded,
BrowserVisibility.DEFAULT_TIMEOUT,
'Timeout waiting for sortBy dropdown to expand'
);
}
async isSortOrderButtonDisplayed(): Promise<boolean> {
@@ -73,7 +78,7 @@ export class SearchSortingPicker extends Component {
}
async clickSortByDropdown(): Promise<void> {
await this.sortByDropdownCollapsed.click();
await BrowserActions.click(this.sortByDropdownCollapsed);
await this.waitForSortByDropdownToExpand();
}
@@ -88,18 +93,18 @@ export class SearchSortingPicker extends Component {
await this.clickSortByDropdown();
}
const elem = browser.element(by.cssContainingText('.mat-option .mat-option-text', option));
await elem.click();
await BrowserActions.click(elem);
}
async setSortOrderASC(): Promise<void> {
if ((await this.getSortOrder()) !== 'ASC') {
await this.sortOrderButton.click();
await BrowserActions.click(this.sortOrderButton);
}
}
async setSortOrderDESC(): Promise<void> {
if ((await this.getSortOrder()) !== 'DESC') {
await this.sortOrderButton.click();
await BrowserActions.click(this.sortOrderButton);
}
}
}

View File

@@ -28,7 +28,6 @@ import { Logger, BrowserActions } from '@alfresco/adf-testing';
import { SIDEBAR_LABELS, BROWSER_WAIT_TIMEOUT } from '../../configs';
import { Menu } from '../menu/menu';
import { Component } from '../component';
import { waitForClickable } from '../../utilities/utils';
export class Sidenav extends Component {
links = this.component.all(by.css('.item'));
@@ -55,8 +54,7 @@ export class Sidenav extends Component {
return Promise.resolve();
} else {
const link = this.getLink(name);
await waitForClickable(link);
await link.click();
await BrowserActions.click(link);
await element(by.css('.mat-expansion-panel-body')).isPresent();
}
} catch (e) {
@@ -65,7 +63,7 @@ export class Sidenav extends Component {
}
async openNewMenu(): Promise<void> {
await this.newButton.click();
await BrowserActions.click(this.newButton.first());
await this.menu.waitForMenuToOpen();
}
@@ -76,22 +74,22 @@ export class Sidenav extends Component {
async openCreateFolderDialog(): Promise<void> {
await this.openNewMenu();
await this.menu.createFolderAction.click();
await BrowserActions.click(this.menu.createFolderAction);
}
async openCreateLibraryDialog(): Promise<void> {
await this.openNewMenu();
await this.menu.createLibraryAction.click();
await BrowserActions.click(this.menu.createLibraryAction);
}
async openCreateFileFromTemplateDialog(): Promise<void> {
await this.openNewMenu();
await this.menu.createFileFromTemplateAction.click();
await BrowserActions.click(this.menu.createFileFromTemplateAction);
}
async openCreateFolderFromTemplateDialog(): Promise<void> {
await this.openNewMenu();
await this.menu.createFolderFromTemplateAction.click();
await BrowserActions.click(this.menu.createFolderFromTemplateAction);
}
async isActive(name: string): Promise<boolean> {
@@ -144,8 +142,7 @@ export class Sidenav extends Component {
async clickLink(name: string): Promise<void> {
try {
const link = this.getLinkLabel(name);
await waitForClickable(link);
await link.click();
await BrowserActions.click(link);
} catch (error) {
Logger.error('---- sidebar navigation clickLink catch error: ', error);
}

View File

@@ -102,7 +102,7 @@ export class Toolbar extends Component {
}
async clickButton(title: string): Promise<void> {
await this.getButtonByTitleAttribute(title).click();
await BrowserActions.click(this.getButtonByTitleAttribute(title));
}
async isPrintPresent() {

View File

@@ -28,6 +28,7 @@ import { Page } from './page';
import { APP_ROUTES } from '../configs';
import { waitForPresence } from '../utilities/utils';
import { BrowserActions } from '@alfresco/adf-testing';
export class LoginPage extends Page {
login = new LoginComponent(this.appRoot);
@@ -45,7 +46,7 @@ export class LoginPage extends Page {
const pass = password || username;
await this.load();
await this.login.enterCredentials(username, pass);
await this.login.submitButton.click();
await BrowserActions.click(this.login.submitButton);
return super.waitForApp();
}
@@ -58,7 +59,7 @@ export class LoginPage extends Page {
const pass = password || username;
await this.load();
await this.login.enterCredentials(username, pass);
await this.login.submitButton.click();
await BrowserActions.click(this.login.submitButton);
await waitForPresence(this.login.errorMessage);
}
}

View File

@@ -24,9 +24,9 @@
*/
import { browser, by, ElementFinder } from 'protractor';
import { Logger } from '@alfresco/adf-testing';
import { BrowserActions, BrowserVisibility, Logger } from '@alfresco/adf-testing';
import { USE_HASH_STRATEGY } from './../configs';
import { Utils, waitElement, waitForPresence, waitForVisibility, isPresentAndDisplayed } from '../utilities/utils';
import { Utils, waitElement, waitForPresence, isPresentAndDisplayed } from '../utilities/utils';
export abstract class Page {
appRoot = 'app-root';
@@ -61,7 +61,7 @@ export abstract class Page {
}
async waitForDialog() {
await waitForVisibility(this.dialogContainer);
await BrowserVisibility.waitUntilElementIsVisible(this.dialogContainer);
}
async isDialogOpen() {
@@ -80,7 +80,7 @@ export abstract class Page {
async closeUploadDialog(): Promise<void> {
if (await this.isUploadDialogOpen()) {
await this.closeUploadButton.click();
await BrowserActions.click(this.closeUploadButton);
}
}
@@ -96,8 +96,7 @@ export abstract class Page {
async clickSnackBarAction(): Promise<void> {
try {
const action = await waitElement('.mat-simple-snackbar-action button');
await action.click();
await BrowserActions.click(this.byCss('.mat-simple-snackbar-action button'));
} catch (e) {
Logger.error(e, '.......failed on click snack bar action.........');
}

View File

@@ -27,6 +27,7 @@ import { browser, by, By } from 'protractor';
import { BrowsingPage } from './browsing-page';
import { SearchSortingPicker } from '../components/search/search-sorting-picker';
import { SearchFilters } from '../components/search/search-filters';
import { BrowserActions } from '@alfresco/adf-testing';
export class SearchResultsPage extends BrowsingPage {
root = this.byCss('aca-search-results');
@@ -54,6 +55,6 @@ export class SearchResultsPage extends BrowsingPage {
async removeChip(chipName: string): Promise<void> {
const chip = browser.element(By.cssContainingText('.mat-chip', chipName));
const closeChip = chip.element(by.css('.mat-chip-remove'));
await closeChip.click();
await BrowserActions.click(closeChip);
}
}

View File

@@ -77,15 +77,19 @@ export class FavoritesApi extends RepoApi {
}
}
async addFavoritesByIds(nodeType: 'file' | 'folder' | 'site', ids: string[]) {
async addFavoritesByIds(nodeType: 'file' | 'folder' | 'site', ids: string[]): Promise<FavoriteEntry[]> {
const favorites: FavoriteEntry[] = [];
try {
return await ids.reduce(async (previous, current) => {
await previous;
await this.addFavoriteById(nodeType, current);
}, Promise.resolve());
if (ids && ids.length > 0) {
for (const id of ids) {
const favorite = await this.addFavoriteById(nodeType, id);
favorites.push(favorite);
}
}
} catch (error) {
this.handleError(`FavoritesApi addFavoritesByIds : catch : `, error);
}
return favorites;
}
async getFavorites() {

View File

@@ -49,15 +49,19 @@ export class SharedLinksApi extends RepoApi {
}
}
async shareFilesByIds(ids: string[]) {
async shareFilesByIds(ids: string[]): Promise<SharedLinkEntry[]> {
const sharedLinks: SharedLinkEntry[] = [];
try {
return await ids.reduce(async (previous: any, current: any) => {
await previous;
return this.shareFileById(current);
}, Promise.resolve());
if (ids && ids.length > 0) {
for (const id of ids) {
const sharedLink = await this.shareFileById(id);
sharedLinks.push(sharedLink);
}
}
} catch (error) {
this.handleError(`SharedLinksApi shareFilesByIds : catch : `, error);
}
return sharedLinks;
}
async getSharedIdOfNode(name: string): Promise<string> {

View File

@@ -139,15 +139,19 @@ export class SitesApi extends RepoApi {
return this.createSite(title, SITE_VISIBILITY.MODERATED, description, siteId);
}
async createSites(titles: string[], visibility?: string): Promise<any> {
async createSites(siteNames: string[], visibility?: string): Promise<SiteEntry[]> {
const sites: SiteEntry[] = [];
try {
return titles.reduce(async (previous: any, current: any) => {
await previous;
return this.createSite(current, visibility);
}, Promise.resolve());
if (siteNames && siteNames.length > 0) {
for (const siteName of siteNames) {
const site = await this.createSite(siteName, visibility);
sites.push(site);
}
}
} catch (error) {
this.handleError(`SitesApi createSites : catch : `, error);
}
return sites;
}
async createSitesPrivate(siteNames: string[]): Promise<any> {

View File

@@ -24,7 +24,7 @@
*/
import { browser, protractor, ElementFinder, ExpectedConditions as EC, by, logging, until, WebElement } from 'protractor';
import { Logger } from '@alfresco/adf-testing';
import { BrowserVisibility, Logger } from '@alfresco/adf-testing';
import { BROWSER_WAIT_TIMEOUT } from '../configs';
import * as path from 'path';
import * as fs from 'fs';
@@ -45,26 +45,6 @@ export async function waitElement(css: string, errorMessage?: string): Promise<W
return browser.wait(until.elementLocated(by.css(css)), BROWSER_WAIT_TIMEOUT, errorMessage || `Timeout waiting for element: ${css}`);
}
export async function waitForClickable(element: ElementFinder, errorMessage?: string): Promise<void> {
await browser.wait(
EC.elementToBeClickable(element),
BROWSER_WAIT_TIMEOUT,
errorMessage || `Timeout waiting for element to be clickable: ${element.locator()}`
);
}
export async function waitForVisibility(element: ElementFinder, errorMessage?: string): Promise<void> {
await browser.wait(EC.visibilityOf(element), BROWSER_WAIT_TIMEOUT, errorMessage || `Timeout waiting for element visibility: ${element.locator()}`);
}
export async function waitForInvisibility(element: ElementFinder, errorMessage?: string): Promise<void> {
await browser.wait(
EC.invisibilityOf(element),
BROWSER_WAIT_TIMEOUT,
errorMessage || `Timeout waiting for element visibility: ${element.locator()}`
);
}
export async function waitForPresence(element: ElementFinder, errorMessage?: string): Promise<void> {
await browser.wait(EC.presenceOf(element), BROWSER_WAIT_TIMEOUT, errorMessage || `Timeout waiting for element presence: ${element.locator()}`);
}
@@ -74,23 +54,21 @@ export async function waitForStaleness(element: ElementFinder, errorMessage?: st
}
export const isPresentAndEnabled = async (element: ElementFinder): Promise<boolean> => {
const isPresent = await element.isPresent();
if (isPresent) {
try {
await BrowserVisibility.waitUntilElementIsPresent(element);
return element.isEnabled();
} catch (error) {
return false;
}
return false;
};
export const isPresentAndDisplayed = async (element: ElementFinder): Promise<boolean> => {
const isPresent = await element.isPresent();
if (isPresent) {
return element.isDisplayed();
try {
await BrowserVisibility.waitUntilElementIsVisible(element);
return true;
} catch (error) {
return false;
}
return false;
};
export class Utils {
@@ -129,13 +107,6 @@ export class Utils {
return run(retry);
}
static async clearFieldWithBackspace(elem: ElementFinder): Promise<void> {
const text = await elem.getAttribute('value');
for (let i = 0; i < text.length; i++) {
await elem.sendKeys(protractor.Key.BACK_SPACE);
}
}
static async fileExistsOnOS(fileName: string, folderName: string = '', subFolderName: string = ''): Promise<any> {
const config = await browser.getProcessedConfig();
const filePath = path.join(config.params.downloadFolder, folderName, subFolderName, fileName);

View File

@@ -1,17 +1,7 @@
{
"extends": "../../tslint.json",
"rules": {
"directive-selector": [
true,
"attribute",
"lib",
"camelCase"
],
"component-selector": [
true,
"element",
"lib",
"kebab-case"
]
"directive-selector": [true, "attribute", "lib", "camelCase"],
"component-selector": [true, "element", "lib", "kebab-case"]
}
}