Optimize e2e framework (#1428)

* reduce breadcrumb page

* imrpove readability of code

* reduce data-table page size

* reduce datetime-picker code

* fix datatable page

* header and info drawer

* update datatable page

* toolbar cleanup

* more test components cleanup

* even move component cleanup

* move wait utils to the Utils

* unified waits

* cleanup menu page

* code fixes

* fix code

* code improvements

* rename api

* fix code

* fix code

* cleanup dialog pages

* more fixes and dead code removal

* code fixes

* try to fix the flaky teset

* fix code

* fix code

* update code

* fix lint

* unified text input

* fix lint

* add missing await

* reduce the wrapper method around clear text

* resolve element value

Co-authored-by: Cilibiu Bogdan <bogdan.cilibiu@ness.com>
This commit is contained in:
Denys Vuika
2020-04-29 08:40:55 +01:00
committed by GitHub
parent ebdaa39209
commit 5259f840a8
78 changed files with 1521 additions and 2486 deletions

View File

@@ -25,20 +25,17 @@
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndEnabled } from '../../utilities/utils';
export class ConfirmDialog extends GenericDialog {
private static selectors = {
root: 'adf-confirm-dialog',
okButton: by.buttonText('OK'),
cancelButton: by.buttonText('Cancel'),
keepButton: by.buttonText('Keep'),
deleteButton: by.buttonText('Delete'),
removeButton: by.buttonText('Remove')
}
okButton = this.childElement(by.buttonText('OK'));
cancelButton = this.childElement(by.buttonText('Cancel'));
keepButton = this.childElement(by.buttonText('Keep'));
deleteButton = this.childElement(by.buttonText('Delete'));
removeButton = this.childElement(by.buttonText('Remove'));
constructor() {
super(ConfirmDialog.selectors.root);
super('adf-confirm-dialog');
}
async getText(): Promise<string> {
@@ -46,43 +43,22 @@ export class ConfirmDialog extends GenericDialog {
}
async isOkEnabled(): Promise<boolean> {
return this.isButtonEnabled(ConfirmDialog.selectors.okButton);
return isPresentAndEnabled(this.okButton);
}
async isCancelEnabled(): Promise<boolean> {
return this.isButtonEnabled(ConfirmDialog.selectors.cancelButton);
return isPresentAndEnabled(this.cancelButton);
}
async isKeepEnabled(): Promise<boolean> {
return this.isButtonEnabled(ConfirmDialog.selectors.keepButton);
return isPresentAndEnabled(this.keepButton);
}
async isDeleteEnabled(): Promise<boolean> {
return this.isButtonEnabled(ConfirmDialog.selectors.deleteButton);
return isPresentAndEnabled(this.deleteButton);
}
async isRemoveEnabled(): Promise<boolean> {
return this.isButtonEnabled(ConfirmDialog.selectors.removeButton);
return isPresentAndEnabled(this.removeButton);
}
async clickOk(): Promise<void> {
await this.clickButton(ConfirmDialog.selectors.okButton);
}
async clickCancel(): Promise<void> {
await this.clickButton(ConfirmDialog.selectors.cancelButton);
}
async clickKeep(): Promise<void> {
await this.clickButton(ConfirmDialog.selectors.keepButton);
}
async clickDelete(): Promise<void> {
await this.clickButton(ConfirmDialog.selectors.deleteButton);
}
async clickRemove(): Promise<void> {
await this.clickButton(ConfirmDialog.selectors.removeButton);
}
}

View File

@@ -23,73 +23,38 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, browser, ExpectedConditions as EC, protractor } from 'protractor';
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
import { by, browser, protractor } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { Utils, isPresentAndDisplayed } from '../../utilities/utils';
import { Utils, isPresentAndDisplayed, waitForStaleness, waitForPresence, isPresentAndEnabled, waitForClickable } from '../../utilities/utils';
import { DropDownBreadcrumb } from '../breadcrumb/dropdown-breadcrumb';
import { DataTable } from '../data-table/data-table';
export class ContentNodeSelectorDialog extends GenericDialog {
private static selectors = {
root: '.adf-content-node-selector-dialog',
cancelButton = this.childElement(by.css('[data-automation-id="content-node-selector-actions-cancel"]'));
copyButton = this.childElement(by.cssContainingText('[data-automation-id="content-node-selector-actions-choose"]', 'Copy'));
moveButton = this.childElement(by.cssContainingText('[data-automation-id="content-node-selector-actions-choose"]', 'Move'));
locationDropDown: 'site-dropdown-container',
locationOption: '.mat-option .mat-option-text',
locationDropDown = this.rootElem.element(by.id('site-dropdown-container'));
locationPersonalFiles = browser.element(by.cssContainingText('.mat-option .mat-option-text', 'Personal Files'));
locationFileLibraries = browser.element(by.cssContainingText('.mat-option .mat-option-text', 'File Libraries'));
dataTable: '.adf-datatable-body',
selectedRow: '.adf-is-selected',
searchInput = this.rootElem.element(by.css('#searchInput'));
toolbarTitle = this.rootElem.element(by.css('.adf-toolbar-title'));
searchInput: '#searchInput',
toolbarTitle: '.adf-toolbar-title',
cancelButton: by.css('[data-automation-id="content-node-selector-actions-cancel"]'),
copyButton: by.cssContainingText('[data-automation-id="content-node-selector-actions-choose"]', 'Copy'),
moveButton: by.cssContainingText('[data-automation-id="content-node-selector-actions-choose"]', 'Move')
};
locationDropDown: ElementFinder = this.rootElem.element(by.id(ContentNodeSelectorDialog.selectors.locationDropDown));
locationPersonalFiles: ElementFinder = browser.element(by.cssContainingText(ContentNodeSelectorDialog.selectors.locationOption, 'Personal Files'));
locationFileLibraries: ElementFinder = browser.element(by.cssContainingText(ContentNodeSelectorDialog.selectors.locationOption, 'File Libraries'));
searchInput: ElementFinder = this.rootElem.element(by.css(ContentNodeSelectorDialog.selectors.searchInput));
toolbarTitle: ElementFinder = this.rootElem.element(by.css(ContentNodeSelectorDialog.selectors.toolbarTitle));
breadcrumb: DropDownBreadcrumb = new DropDownBreadcrumb();
dataTable: DataTable = new DataTable(ContentNodeSelectorDialog.selectors.root);
breadcrumb = new DropDownBreadcrumb();
dataTable = new DataTable('.adf-content-node-selector-dialog');
constructor() {
super(ContentNodeSelectorDialog.selectors.root);
}
async waitForDropDownToOpen(): Promise<void> {
await browser.wait(EC.presenceOf(this.locationPersonalFiles), BROWSER_WAIT_TIMEOUT);
super('.adf-content-node-selector-dialog');
}
async waitForDropDownToClose(): Promise<void> {
await browser.wait(EC.stalenessOf(browser.$(ContentNodeSelectorDialog.selectors.locationOption)), BROWSER_WAIT_TIMEOUT);
}
async waitForRowToBeSelected(): Promise<void> {
await browser.wait(EC.presenceOf(browser.element(by.css(ContentNodeSelectorDialog.selectors.selectedRow))), BROWSER_WAIT_TIMEOUT);
}
async clickCancel(): Promise<void> {
await this.clickButton(ContentNodeSelectorDialog.selectors.cancelButton);
await this.waitForDialogToClose();
}
async clickCopy(): Promise<void> {
await this.clickButton(ContentNodeSelectorDialog.selectors.copyButton);
}
async clickMove(): Promise<void> {
await this.clickButton(ContentNodeSelectorDialog.selectors.moveButton);
await waitForStaleness(browser.$('.mat-option .mat-option-text'))
}
async selectLocation(location: 'Personal Files' | 'File Libraries'): Promise<void> {
await this.locationDropDown.click();
await this.waitForDropDownToOpen();
await waitForPresence(this.locationPersonalFiles);
if (location === 'Personal Files') {
await this.locationPersonalFiles.click();
@@ -102,13 +67,9 @@ export class ContentNodeSelectorDialog extends GenericDialog {
async selectDestination(folderName: string): Promise<void> {
const row = this.dataTable.getRowByName(folderName);
await Utils.waitUntilElementClickable(row);
await waitForClickable(row);
await row.click();
await this.waitForRowToBeSelected();
}
async isSearchInputPresent(): Promise<boolean> {
return this.searchInput.isPresent();
await waitForPresence(browser.element(by.css('.adf-is-selected')));
}
async isSelectLocationDropdownDisplayed(): Promise<boolean> {
@@ -116,11 +77,11 @@ export class ContentNodeSelectorDialog extends GenericDialog {
}
async isCopyButtonEnabled(): Promise<boolean> {
return this.isButtonEnabled(ContentNodeSelectorDialog.selectors.copyButton);
return isPresentAndEnabled(this.copyButton);
}
async isCancelButtonEnabled(): Promise<boolean> {
return this.isButtonEnabled(ContentNodeSelectorDialog.selectors.cancelButton);
return isPresentAndEnabled(this.cancelButton);
}
async searchFor(text: string): Promise<void> {

View File

@@ -23,64 +23,42 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, protractor, browser, ExpectedConditions as EC } from 'protractor';
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndDisplayed } from '../../utilities/utils';
import { isPresentAndDisplayed, waitForClickable, isPresentAndEnabled, typeText } from '../../utilities/utils';
export class CreateOrEditFolderDialog extends GenericDialog {
private static selectors = {
root: 'adf-folder-dialog',
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: 'input[placeholder="Name" i]',
descriptionTextArea: 'textarea[placeholder="Description" i]',
validationMessage: '.mat-hint span',
createButton: by.cssContainingText('.mat-dialog-actions button', 'Create'),
cancelButton: by.id('adf-folder-cancel-button'),
updateButton: by.cssContainingText('.mat-dialog-actions button', 'Update')
};
nameInput: ElementFinder = this.rootElem.element(by.css(CreateOrEditFolderDialog.selectors.nameInput));
descriptionTextArea: ElementFinder = this.rootElem.element(by.css(CreateOrEditFolderDialog.selectors.descriptionTextArea));
validationMessage: ElementFinder = this.rootElem.element(by.css(CreateOrEditFolderDialog.selectors.validationMessage));
nameInput = this.rootElem.element(by.css('input[placeholder="Name" i]'));
descriptionTextArea = this.rootElem.element(by.css('textarea[placeholder="Description" i]'));
validationMessage = this.rootElem.element(by.css('.mat-hint span'));
constructor() {
super(CreateOrEditFolderDialog.selectors.root);
super('adf-folder-dialog');
}
async waitForDialogToOpen() {
await super.waitForDialogToOpen();
await browser.wait(EC.elementToBeClickable(this.nameInput), BROWSER_WAIT_TIMEOUT, '--- timeout waiting for input to be clickable ---');
}
async isValidationMessageDisplayed(): Promise<boolean> {
return isPresentAndDisplayed(this.validationMessage);
await waitForClickable(this.nameInput);
}
async isUpdateButtonEnabled(): Promise<boolean> {
return this.isButtonEnabled(CreateOrEditFolderDialog.selectors.updateButton);
return isPresentAndEnabled(this.updateButton);
}
async isCreateButtonEnabled(): Promise<boolean> {
return this.isButtonEnabled(CreateOrEditFolderDialog.selectors.createButton);
return isPresentAndEnabled(this.createButton);
}
async isCancelButtonEnabled(): Promise<boolean> {
return this.isButtonEnabled(CreateOrEditFolderDialog.selectors.cancelButton);
}
async isNameDisplayed(): Promise<boolean> {
return this.nameInput.isDisplayed();
}
async isDescriptionDisplayed(): Promise<boolean> {
return this.descriptionTextArea.isDisplayed();
return isPresentAndEnabled(this.cancelButton);
}
async getValidationMessage(): Promise<string> {
if (await this.isValidationMessageDisplayed()) {
if (await isPresentAndDisplayed(this.validationMessage)) {
return this.validationMessage.getText();
} else {
return '';
@@ -96,31 +74,15 @@ export class CreateOrEditFolderDialog extends GenericDialog {
}
async enterName(name: string): Promise<void> {
await this.nameInput.clear();
await this.nameInput.sendKeys(name);
await typeText(this.nameInput, name);
}
async enterDescription(description: string): Promise<void> {
await this.descriptionTextArea.clear();
await this.descriptionTextArea.sendKeys(description);
}
async deleteNameWithBackspace(): Promise<void> {
await this.nameInput.clear();
await this.nameInput.sendKeys(' ', protractor.Key.CONTROL, 'a', protractor.Key.NULL, protractor.Key.BACK_SPACE);
}
async clickCreate(): Promise<void> {
await this.clickButton(CreateOrEditFolderDialog.selectors.createButton);
await typeText(this.descriptionTextArea, description);
}
async clickCancel(): Promise<void> {
await this.clickButton(CreateOrEditFolderDialog.selectors.cancelButton);
await this.cancelButton.click();
await this.waitForDialogToClose();
}
async clickUpdate(): Promise<void> {
await this.clickButton(CreateOrEditFolderDialog.selectors.updateButton);
}
}

View File

@@ -23,30 +23,21 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, protractor } from 'protractor';
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndDisplayed } from '../../utilities/utils';
import { isPresentAndDisplayed, isPresentAndEnabled, typeText } from '../../utilities/utils';
export class CreateFromTemplateDialog extends GenericDialog {
private static selectors = {
root: '.aca-create-from-template-dialog',
createButton = this.childElement(by.cssContainingText('.mat-dialog-actions button', 'Create'));
cancelButton = this.childElement(by.cssContainingText('.mat-dialog-actions button', 'CANCEL'));
nameInput: 'input[placeholder="Name" i]',
titleInput: 'input[placeholder="Title" i]',
descriptionTextArea: 'textarea[placeholder="Description" i]',
validationMessage: '.mat-error',
createButton: by.cssContainingText('.mat-dialog-actions button', 'Create'),
cancelButton: by.cssContainingText('.mat-dialog-actions button', 'CANCEL')
};
nameInput: ElementFinder = this.rootElem.element(by.css(CreateFromTemplateDialog.selectors.nameInput));
titleInput: ElementFinder = this.rootElem.element(by.css(CreateFromTemplateDialog.selectors.titleInput));
descriptionTextArea: ElementFinder = this.rootElem.element(by.css(CreateFromTemplateDialog.selectors.descriptionTextArea));
validationMessage: ElementFinder = this.rootElem.element(by.css(CreateFromTemplateDialog.selectors.validationMessage));
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]'));
validationMessage = this.childElement(by.css('.mat-error'));
constructor() {
super(CreateFromTemplateDialog.selectors.root);
super('.aca-create-from-template-dialog');
}
async isValidationMessageDisplayed(): Promise<boolean> {
@@ -54,23 +45,11 @@ export class CreateFromTemplateDialog extends GenericDialog {
}
async isCreateButtonEnabled(): Promise<boolean> {
return this.isButtonEnabled(CreateFromTemplateDialog.selectors.createButton);
return isPresentAndEnabled(this.createButton);
}
async isCancelButtonEnabled(): Promise<boolean> {
return this.isButtonEnabled(CreateFromTemplateDialog.selectors.cancelButton);
}
async isNameFieldDisplayed(): Promise<boolean> {
return this.nameInput.isDisplayed();
}
async isTitleFieldDisplayed(): Promise<boolean> {
return this.titleInput.isDisplayed();
}
async isDescriptionFieldDisplayed(): Promise<boolean> {
return this.descriptionTextArea.isDisplayed();
return isPresentAndEnabled(this.cancelButton);
}
async getValidationMessage(): Promise<string> {
@@ -90,32 +69,19 @@ export class CreateFromTemplateDialog extends GenericDialog {
}
async enterName(name: string): Promise<void> {
await this.nameInput.clear();
await this.nameInput.sendKeys(name);
await typeText(this.nameInput, name);
}
async enterTitle(title: string): Promise<void> {
await this.titleInput.clear();
await this.titleInput.sendKeys(title);
await typeText(this.titleInput, title);
}
async enterDescription(description: string): Promise<void> {
await this.descriptionTextArea.clear();
await this.descriptionTextArea.sendKeys(description);
}
async deleteNameWithBackspace(): Promise<void> {
await this.nameInput.clear();
await this.nameInput.sendKeys(' ', protractor.Key.CONTROL, 'a', protractor.Key.NULL, protractor.Key.BACK_SPACE);
}
async clickCreate(): Promise<void> {
await this.clickButton(CreateFromTemplateDialog.selectors.createButton);
await typeText(this.descriptionTextArea, description);
}
async clickCancel(): Promise<void> {
await this.clickButton(CreateFromTemplateDialog.selectors.cancelButton);
await this.cancelButton.click();
await this.waitForDialogToClose();
}
}

View File

@@ -23,140 +23,78 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, protractor, browser, ExpectedConditions as EC } from 'protractor';
import { by, ElementFinder } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
import { waitForClickable, isPresentAndEnabled, typeText } from '../../utilities/utils';
export class CreateLibraryDialog extends GenericDialog {
private static selectors = {
root: 'adf-library-dialog',
createButton = this.childElement(by.cssContainingText('.mat-dialog-actions button', 'Create'));
cancelButton = this.childElement(by.cssContainingText('.mat-dialog-actions button', 'Cancel'));
nameInput: 'input[placeholder="Name" i]',
libraryIdInput: 'input[placeholder="Library ID" i]',
descriptionTextArea: 'textarea[placeholder="Description" i]',
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]'));
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'));
radioButton: '.mat-radio-label',
radioChecked: 'mat-radio-checked',
errorMessage: '.mat-error',
createButton: by.cssContainingText('.mat-dialog-actions button', 'Create'),
cancelButton: by.cssContainingText('.mat-dialog-actions button', 'Cancel')
};
nameInput: ElementFinder = this.rootElem.element(by.css(CreateLibraryDialog.selectors.nameInput));
libraryIdInput: ElementFinder = this.rootElem.element(by.css(CreateLibraryDialog.selectors.libraryIdInput));
descriptionTextArea: ElementFinder = this.rootElem.element(by.css(CreateLibraryDialog.selectors.descriptionTextArea));
visibilityPublic: ElementFinder = this.rootElem.element(by.cssContainingText(CreateLibraryDialog.selectors.radioButton, 'Public'));
visibilityModerated: ElementFinder = this.rootElem.element(by.cssContainingText(CreateLibraryDialog.selectors.radioButton, 'Moderated'));
visibilityPrivate: ElementFinder = this.rootElem.element(by.cssContainingText(CreateLibraryDialog.selectors.radioButton, 'Private'));
errorMessage: ElementFinder = this.rootElem.element(by.css(CreateLibraryDialog.selectors.errorMessage));
errorMessage = this.rootElem.element(by.css('.mat-error'));
constructor() {
super(CreateLibraryDialog.selectors.root);
super('adf-library-dialog');
}
async waitForDialogToOpen(): Promise<void> {
await super.waitForDialogToOpen();
await browser.wait(EC.elementToBeClickable(this.nameInput), BROWSER_WAIT_TIMEOUT, '--- timeout waiting for input to be clickable ---');
}
async isErrorMessageDisplayed(): Promise<boolean> {
return this.errorMessage.isDisplayed();
await waitForClickable(this.nameInput);
}
async getErrorMessage(): Promise<string> {
if (await this.isErrorMessageDisplayed()) {
if (await this.errorMessage.isDisplayed()) {
return this.errorMessage.getText();
}
return '';
}
async isNameDisplayed(): Promise<boolean> {
return this.nameInput.isDisplayed();
}
async isLibraryIdDisplayed(): Promise<boolean> {
return this.libraryIdInput.isDisplayed();
}
async isDescriptionDisplayed(): Promise<boolean> {
return this.descriptionTextArea.isDisplayed();
}
async isPublicDisplayed(): Promise<boolean> {
return this.visibilityPublic.isDisplayed();
}
async isModeratedDisplayed(): Promise<boolean> {
return this.visibilityModerated.isDisplayed();
}
async isPrivateDisplayed(): Promise<boolean> {
return this.visibilityPrivate.isDisplayed();
}
async enterName(name: string): Promise<void> {
await this.nameInput.clear();
await this.nameInput.sendKeys(name);
await typeText(this.nameInput, name);
}
async enterLibraryId(id: string): Promise<void> {
await this.libraryIdInput.clear();
await this.libraryIdInput.sendKeys(id);
await typeText(this.libraryIdInput, id);
}
async enterDescription(description: string): Promise<void> {
await this.descriptionTextArea.clear();
await this.descriptionTextArea.sendKeys(description);
}
async deleteNameWithBackspace(): Promise<void> {
await this.nameInput.clear();
await this.nameInput.sendKeys(' ', protractor.Key.CONTROL, 'a', protractor.Key.NULL, protractor.Key.BACK_SPACE);
await typeText(this.descriptionTextArea, description);
}
async isCreateEnabled(): Promise<boolean> {
return this.isButtonEnabled(CreateLibraryDialog.selectors.createButton);
return isPresentAndEnabled(this.createButton);
}
async isCancelEnabled(): Promise<boolean> {
return this.isButtonEnabled(CreateLibraryDialog.selectors.cancelButton);
}
async clickCreate(): Promise<void> {
await this.clickButton(CreateLibraryDialog.selectors.createButton);
return isPresentAndEnabled(this.cancelButton);
}
async clickCancel(): Promise<void> {
await this.clickButton(CreateLibraryDialog.selectors.cancelButton);
await this.cancelButton.click();
await this.waitForDialogToClose();
}
private async isChecked(target: ElementFinder): Promise<boolean> {
const elemClass = await target.element(by.xpath('..')).getAttribute('class');
return elemClass.includes('mat-radio-checked');
}
async isPublicChecked(): Promise<boolean> {
const elemClass = await this.visibilityPublic.element(by.xpath('..')).getAttribute('class');
return elemClass.includes(CreateLibraryDialog.selectors.radioChecked);
return this.isChecked(this.visibilityPublic);
}
async isModeratedChecked(): Promise<boolean> {
const elemClass = await this.visibilityModerated.element(by.xpath('..')).getAttribute('class');
return elemClass.includes(CreateLibraryDialog.selectors.radioChecked);
return this.isChecked(this.visibilityModerated);
}
async isPrivateChecked(): Promise<boolean> {
const elemClass = await this.visibilityPrivate.element(by.xpath('..')).getAttribute('class');
return elemClass.includes(CreateLibraryDialog.selectors.radioChecked);
}
async selectPublic(): Promise<void> {
await this.visibilityPublic.click();
}
async selectModerated(): Promise<void> {
await this.visibilityModerated.click();
}
async selectPrivate(): Promise<void> {
await this.visibilityPrivate.click();
return this.isChecked(this.visibilityPrivate);
}
}

View File

@@ -23,32 +23,23 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, browser, ExpectedConditions as EC, Locator } from 'protractor';
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
import { isPresentAndDisplayed, isPresentAndEnabled } from '../../utilities/utils';
import { ElementFinder, by, browser, Locator } from 'protractor';
import { isPresentAndDisplayed, waitForPresence, waitForVisibility, waitForStaleness } from '../../utilities/utils';
export abstract class GenericDialog {
private static locators = {
title: '.mat-dialog-title',
content: '.mat-dialog-content'
};
private rootCssSelector: string;
constructor(selector?: string) {
this.rootCssSelector = selector;
}
constructor(private rootCssSelector?: string) {}
get rootElem(): ElementFinder {
return browser.element(by.css(this.rootCssSelector));
}
get title(): ElementFinder {
return this.rootElem.element(by.css(GenericDialog.locators.title));
return this.rootElem.element(by.css('.mat-dialog-title'));
}
get content(): ElementFinder {
return this.rootElem.element(by.css(GenericDialog.locators.content));
return this.rootElem.element(by.css('.mat-dialog-content'));
}
async getText(): Promise<string> {
@@ -56,13 +47,13 @@ export abstract class GenericDialog {
}
async waitForDialogToOpen(): Promise<void> {
await browser.wait(EC.presenceOf(this.rootElem), BROWSER_WAIT_TIMEOUT);
await browser.wait(EC.visibilityOf(this.content), BROWSER_WAIT_TIMEOUT);
await browser.wait(EC.presenceOf(browser.element(by.css('.cdk-overlay-backdrop'))), BROWSER_WAIT_TIMEOUT);
await waitForPresence(this.rootElem);
await waitForVisibility(this.content);
await waitForPresence(browser.element(by.css('.cdk-overlay-backdrop')));
}
async waitForDialogToClose(): Promise<void> {
await browser.wait(EC.stalenessOf(this.content), BROWSER_WAIT_TIMEOUT, '---- timeout waiting for dialog to close ----');
await waitForStaleness(this.content);
}
async isDialogOpen(): Promise<boolean> {
@@ -73,15 +64,7 @@ export abstract class GenericDialog {
return this.title.getText();
}
getActionButton(selector: Locator): ElementFinder {
protected childElement(selector: Locator): ElementFinder {
return this.rootElem.element(selector);
}
async isButtonEnabled(selector: Locator): Promise<boolean> {
return isPresentAndEnabled(this.getActionButton(selector));
}
async clickButton(selector: Locator): Promise<void> {
await this.getActionButton(selector).click();
}
}

View File

@@ -27,18 +27,14 @@ import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
export class ManageVersionsDialog extends GenericDialog {
private static selectors = {
root: '.aca-node-versions-dialog',
closeButton: by.cssContainingText('.mat-button', 'Close')
};
closeButton = this.childElement(by.cssContainingText('.mat-button', 'Close'));
constructor() {
super(ManageVersionsDialog.selectors.root);
super('.aca-node-versions-dialog');
}
async clickClose(): Promise<void> {
await this.clickButton(ManageVersionsDialog.selectors.closeButton);
await this.closeButton.click();
await this.waitForDialogToClose();
}
}

View File

@@ -23,35 +23,23 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, browser, ExpectedConditions as EC } from 'protractor';
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
import { by, browser } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { waitForClickable, isPresentAndEnabled, typeText } from '../../utilities/utils';
export class PasswordDialog extends GenericDialog {
private static selectors = {
root: 'adf-pdf-viewer-password-dialog',
passwordInput: 'input[type="Password"]',
errorMessage: '.mat-error',
closeButton: by.css('[data-automation-id="adf-password-dialog-close"]'),
submitButton: by.css('[data-automation-id="adf-password-dialog-submit"]')
};
passwordInput: ElementFinder = this.rootElem.element(by.css(PasswordDialog.selectors.passwordInput));
errorMessage: ElementFinder = this.rootElem.element(by.css(PasswordDialog.selectors.errorMessage));
closeButton = this.childElement(by.css('[data-automation-id="adf-password-dialog-close"]'));
submitButton = this.childElement(by.css('[data-automation-id="adf-password-dialog-submit"]'));
passwordInput = this.childElement(by.css('input[type="Password"]'));
errorMessage = this.childElement(by.css('.mat-error'));
constructor() {
super(PasswordDialog.selectors.root);
}
async waitForPasswordInputToBeInteractive() {
await browser.wait(EC.elementToBeClickable(this.passwordInput), BROWSER_WAIT_TIMEOUT, '--- timeout wait for passwordInput ---');
super('adf-pdf-viewer-password-dialog');
}
async waitForDialogToOpen(): Promise<void> {
await super.waitForDialogToOpen();
await this.waitForPasswordInputToBeInteractive();
await waitForClickable(this.passwordInput);
}
async isDialogOpen(): Promise<boolean> {
@@ -64,19 +52,11 @@ export class PasswordDialog extends GenericDialog {
}
async isCloseEnabled(): Promise<boolean> {
return this.isButtonEnabled(PasswordDialog.selectors.closeButton);
return isPresentAndEnabled(this.closeButton);
}
async isSubmitEnabled(): Promise<boolean> {
return this.isButtonEnabled(PasswordDialog.selectors.submitButton);
}
async clickClose(): Promise<void> {
await this.clickButton(PasswordDialog.selectors.closeButton);
}
async clickSubmit(): Promise<void> {
await this.clickButton(PasswordDialog.selectors.submitButton);
return isPresentAndEnabled(this.submitButton);
}
async isPasswordInputDisplayed(): Promise<boolean> {
@@ -106,7 +86,6 @@ export class PasswordDialog extends GenericDialog {
}
async enterPassword(password: string): Promise<void> {
await this.passwordInput.clear();
await this.passwordInput.sendKeys(password);
await typeText(this.passwordInput, password);
}
}

View File

@@ -27,37 +27,39 @@ import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { DropDownBreadcrumb } from '../breadcrumb/dropdown-breadcrumb';
import { DataTable } from '../data-table/data-table';
import { isPresentAndEnabled } from '../../utilities/utils';
export class SelectTemplateDialog extends GenericDialog {
private static selectors = {
root: '.aca-template-node-selector-dialog',
nextButton = this.childElement(
by.css('[data-automation-id="content-node-selector-actions-choose"]')
);
nextButton: by.css('[data-automation-id="content-node-selector-actions-choose"]'),
cancelButton: by.css('[data-automation-id="content-node-selector-actions-cancel"]')
};
cancelButton = this.childElement(
by.css('[data-automation-id="content-node-selector-actions-cancel"]')
);
breadcrumb: DropDownBreadcrumb = new DropDownBreadcrumb();
dataTable: DataTable = new DataTable(SelectTemplateDialog.selectors.root);
breadcrumb = new DropDownBreadcrumb();
dataTable = new DataTable('.aca-template-node-selector-dialog');
constructor() {
super(SelectTemplateDialog.selectors.root);
super('.aca-template-node-selector-dialog');
}
async isCancelButtonEnabled(): Promise<boolean> {
return this.isButtonEnabled(SelectTemplateDialog.selectors.cancelButton);
return isPresentAndEnabled(this.cancelButton);
}
async isNextButtonEnabled(): Promise<boolean> {
return this.isButtonEnabled(SelectTemplateDialog.selectors.nextButton);
return isPresentAndEnabled(this.nextButton);
}
async clickCancel(): Promise<void> {
await this.clickButton(SelectTemplateDialog.selectors.cancelButton);
await this.cancelButton.click();
await this.waitForDialogToClose();
}
async clickNext(): Promise<void> {
await this.clickButton(SelectTemplateDialog.selectors.nextButton);
await this.nextButton.click();
await this.waitForDialogToClose();
}
}

View File

@@ -23,41 +23,28 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, ElementArrayFinder, by } from 'protractor';
import { by } from 'protractor';
import { DateTimePicker } from '../../components/datetime-picker/datetime-picker';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndEnabled } from '../../utilities/utils';
export class ShareDialog extends GenericDialog {
private static selectors = {
root: '.adf-share-dialog',
dialogTitle: `[data-automation-id='adf-share-dialog-title']`,
info: '.adf-share-link__info',
label: '.adf-share-link__label',
shareToggle: `[data-automation-id='adf-share-toggle']`,
linkUrl: `[data-automation-id='adf-share-link']`,
inputAction: '.adf-input-action',
expireToggle: `[data-automation-id='adf-expire-toggle']`,
datetimePickerButton: '.mat-datetimepicker-toggle',
expirationInput: 'input[formcontrolname="time"]',
closeButton: by.css(`[data-automation-id='adf-share-dialog-close']`)
};
dateTimePicker = new DateTimePicker();
dialogTitle: ElementFinder = this.rootElem.element(by.css(ShareDialog.selectors.dialogTitle));
infoText: ElementFinder = this.rootElem.element(by.css(ShareDialog.selectors.info));
labels: ElementArrayFinder = this.rootElem.all(by.css(ShareDialog.selectors.label));
shareToggle: ElementFinder = this.rootElem.element(by.css(ShareDialog.selectors.shareToggle));
url: ElementFinder = this.rootElem.element(by.css(ShareDialog.selectors.linkUrl));
urlAction: ElementFinder = this.rootElem.element(by.css(ShareDialog.selectors.inputAction));
expireToggle: ElementFinder = this.rootElem.element(by.css(ShareDialog.selectors.expireToggle));
expireInput: ElementFinder = this.rootElem.element(by.css(ShareDialog.selectors.expirationInput));
datetimePickerButton: ElementFinder = this.rootElem.element(by.css(ShareDialog.selectors.datetimePickerButton));
dialogTitle = this.childElement(by.css(`[data-automation-id='adf-share-dialog-title']`));
infoText = this.childElement(by.css('.adf-share-link__info'));
labels = this.rootElem.all(by.css('.adf-share-link__label'));
shareToggle = this.childElement(by.css(`[data-automation-id='adf-share-toggle']`));
url = this.childElement(by.css(`[data-automation-id='adf-share-link']`));
urlAction = this.childElement(by.css('.adf-input-action'));
expireToggle = this.childElement(by.css(`[data-automation-id='adf-expire-toggle']`));
expireInput = this.childElement(by.css('input[formcontrolname="time"]'));
datetimePickerButton = this.childElement(by.css('.mat-datetimepicker-toggle'));
closeButton = this.childElement(by.css(`[data-automation-id='adf-share-dialog-close']`));
constructor() {
super(ShareDialog.selectors.root);
super('.adf-share-dialog');
}
async getTitle(): Promise<string> {
@@ -68,10 +55,6 @@ export class ShareDialog extends GenericDialog {
return this.infoText.getText();
}
getLabels(): ElementArrayFinder {
return this.labels;
}
async getLinkUrl(): Promise<string> {
return this.url.getAttribute('value');
}
@@ -82,49 +65,29 @@ export class ShareDialog extends GenericDialog {
}
async isCloseEnabled(): Promise<boolean> {
return this.isButtonEnabled(ShareDialog.selectors.closeButton);
return isPresentAndEnabled(this.closeButton);
}
async clickClose(): Promise<void> {
await this.clickButton(ShareDialog.selectors.closeButton);
await this.closeButton.click();
await this.waitForDialogToClose();
}
getShareToggle(): ElementFinder {
return this.shareToggle;
}
getExpireToggle(): ElementFinder {
return this.expireToggle;
}
getExpireInput(): ElementFinder {
return this.expireInput;
}
async isShareToggleChecked(): Promise<boolean> {
const toggleClass = await this.getShareToggle().getAttribute('class');
const toggleClass = await this.shareToggle.getAttribute('class');
return toggleClass.includes('checked');
}
async isShareToggleDisabled(): Promise<boolean> {
const toggleClass = await this.getShareToggle().getAttribute('class');
const toggleClass = await this.shareToggle.getAttribute('class');
return toggleClass.includes('mat-disabled');
}
async isExpireToggleEnabled(): Promise<boolean> {
const toggleClass = await this.getExpireToggle().getAttribute('class');
const toggleClass = await this.expireToggle.getAttribute('class');
return toggleClass.includes('checked');
}
async copyUrl(): Promise<void> {
await this.urlAction.click();
}
async openDatetimePicker(): Promise<void> {
await this.datetimePickerButton.click();
}
async closeDatetimePicker(): Promise<void> {
if (await this.dateTimePicker.isCalendarOpen()) {
await this.datetimePickerButton.click();
@@ -132,14 +95,6 @@ export class ShareDialog extends GenericDialog {
}
async getExpireDate(): Promise<string> {
return this.getExpireInput().getAttribute('value');
}
async clickExpirationToggle(): Promise<void> {
await this.expireToggle.click();
}
async clickShareToggle(): Promise<void> {
await this.shareToggle.click();
return this.expireInput.getAttribute('value');
}
}

View File

@@ -23,71 +23,35 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by } from 'protractor';
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndEnabled, typeText } from '../../utilities/utils';
export class UploadNewVersionDialog extends GenericDialog {
private static selectors = {
root: '.aca-node-version-upload-dialog',
cancelButton: by.cssContainingText('.mat-button', 'Cancel'),
uploadButton: by.cssContainingText('.mat-button', 'Upload'),
radioButton: `.mat-radio-label`,
descriptionTextArea: 'textarea'
};
majorOption: ElementFinder = this.rootElem.element(by.cssContainingText(UploadNewVersionDialog.selectors.radioButton, 'Major'));
minorOption: ElementFinder = this.rootElem.element(by.cssContainingText(UploadNewVersionDialog.selectors.radioButton, 'Minor'));
description: ElementFinder = this.rootElem.element(by.css(UploadNewVersionDialog.selectors.descriptionTextArea));
cancelButton = this.childElement(by.cssContainingText('.mat-button', 'Cancel'));
uploadButton = this.childElement(by.cssContainingText('.mat-button', 'Upload'));
majorOption = this.childElement(by.cssContainingText(`.mat-radio-label`, 'Major'));
minorOption = this.childElement(by.cssContainingText(`.mat-radio-label`, 'Minor'));
description = this.childElement(by.css('textarea'));
constructor() {
super(UploadNewVersionDialog.selectors.root);
}
async isDescriptionDisplayed(): Promise<boolean> {
return this.description.isDisplayed();
}
async isMinorOptionDisplayed(): Promise<boolean> {
return this.minorOption.isDisplayed();
}
async isMajorOptionDisplayed(): Promise<boolean> {
return this.majorOption.isDisplayed();
super('.aca-node-version-upload-dialog');
}
async isCancelButtonEnabled(): Promise<boolean> {
return this.isButtonEnabled(UploadNewVersionDialog.selectors.cancelButton);
return isPresentAndEnabled(this.cancelButton);
}
async isUploadButtonEnabled(): Promise<boolean> {
return this.isButtonEnabled(UploadNewVersionDialog.selectors.uploadButton);
return isPresentAndEnabled(this.uploadButton);
}
async clickCancel(): Promise<void> {
await this.clickButton(UploadNewVersionDialog.selectors.cancelButton);
await this.cancelButton.click();
await this.waitForDialogToClose();
}
async clickUpload(): Promise<void> {
await this.clickButton(UploadNewVersionDialog.selectors.uploadButton);
}
async clickMajor(): Promise<void> {
await this.majorOption.click();
}
async clickMinor(): Promise<void> {
await this.minorOption.click();
}
async enterDescription(description: string): Promise<void> {
await this.description.clear();
await this.description.sendKeys(description);
await typeText(this.description, description);
}
}