[ACA-3392] Create aca-testing-shared project to be reused in ADW (#1480)

* Move e2e framework to aca-shared/testing

* * Update e2e suites imports from @alfresco/aca-shared/testing
* Remove testing framework from 'e2e' directory

* Move e2e testing framework to `aca-testing-shared` project
This commit is contained in:
Roxana Diacenco
2020-06-04 23:40:07 +03:00
committed by GitHub
parent 33327bb505
commit 6e17405787
166 changed files with 2745 additions and 1128 deletions

View File

@@ -0,0 +1,48 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component } from '../component';
export class Breadcrumb extends Component {
items = this.allByCss('.adf-breadcrumb-item');
currentItem = this.byCss('.adf-breadcrumb-item-current');
constructor(ancestor?: string) {
super('adf-breadcrumb', ancestor);
}
async getAllItems(): Promise<string[]> {
const items: string[] = await this.items.map(async elem => {
const str = await elem.getText();
return str.split('\nchevron_right')[0];
});
return items;
}
async clickItem(name: string): Promise<void> {
const elem = this.byCss(`.adf-breadcrumb-item[title=${name}]`);
await elem.click();
}
}

View File

@@ -0,0 +1,73 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser } from 'protractor';
import { Component } from '../component';
import { waitForPresence, waitForStaleness } from '../../utilities/utils';
export class DropDownBreadcrumb extends Component {
pathOptionCss = '.adf-dropdown-breadcrumb-path-option .mat-option-text';
trigger = this.byCss('.adf-dropdown-breadcrumb-trigger');
pathItems = browser.$$(this.pathOptionCss);
pathItemsContainer = this.byCss('.mat-select-panel', browser);
currentFolder = this.byCss('.adf-current-folder');
constructor(ancestor?: string) {
super('.adf-dropdown-breadcrumb', ancestor);
}
async waitForPathListDropdownToOpen(): Promise<void> {
return waitForPresence(
this.pathItemsContainer,
'Timeout waiting for breadcrumb dropdown to open'
);
}
async waitForPathListDropdownToClose(): Promise<void> {
return waitForStaleness(
browser.$(this.pathOptionCss),
'Timeout waiting for breadcrumb dropdown to close'
);
}
async openPath(): Promise<void> {
await this.trigger.click();
await this.waitForPathListDropdownToOpen();
}
async clickPathItem(name: string): Promise<void> {
const elem = browser.element(
by.cssContainingText(this.pathOptionCss, name)
);
await elem.click();
}
async getPathItems(): Promise<string[]> {
const items: string[] = await this.pathItems.map(async elem => {
return elem.getText();
});
return items;
}
}

View File

@@ -0,0 +1,82 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
ElementFinder,
browser,
by,
ElementArrayFinder,
ProtractorBrowser
} from 'protractor';
import { waitForPresence } from '../utilities/utils';
export abstract class Component {
component: ElementFinder;
protected byCss(
css: string,
root: ElementFinder | ProtractorBrowser = this.component
): ElementFinder {
return root.element(by.css(css));
}
protected byCssText(
css: string,
text: string,
root: ElementFinder | ProtractorBrowser = this.component
): ElementFinder {
return root.element(by.cssContainingText(css, text));
}
protected byId(
css: string,
root: ElementFinder | ProtractorBrowser = this.component
): ElementFinder {
return root.element(by.id(css));
}
protected allByCss(
css: string,
root: ElementFinder | ProtractorBrowser = this.component
): ElementArrayFinder {
return root.all(by.css(css));
}
constructor(selector: string, ancestor?: string) {
const locator = selector;
this.component = ancestor
? browser
.$$(ancestor)
.first()
.$$(locator)
.first()
: browser.$$(locator).first();
}
async wait() {
await waitForPresence(this.component);
}
}

View File

@@ -0,0 +1,37 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
export * from './login/login';
export * from './header/header';
export * from './header/user-info';
export * from './data-table/data-table';
export * from './dialog/confirm-dialog';
export * from './dialog/create-edit-folder-dialog';
export * from './dialog/password-dialog';
export * from './pagination/pagination';
export * from './sidenav/sidenav';
export * from './toolbar/toolbar';
export * from './breadcrumb/breadcrumb';
export * from './viewer/viewer';

View File

@@ -0,0 +1,558 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
ElementFinder,
ElementArrayFinder,
by,
browser,
protractor
} from 'protractor';
import { Logger } from '@alfresco/adf-testing';
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
import { Component } from '../component';
import { Menu } from '../menu/menu';
import {
Utils,
waitForPresence,
waitForClickable
} from '../../utilities/utils';
export class DataTable extends Component {
private static selectors = {
columnHeader:
'.adf-datatable-row .adf-datatable-cell-header .adf-datatable-cell-value',
sortedColumnHeader: `
.adf-datatable__header--sorted-asc .adf-datatable-cell-value,
.adf-datatable__header--sorted-desc .adf-datatable-cell-value
`,
row: '.adf-datatable-row[role]',
cell: '.adf-datatable-cell-container',
lockOwner: '.aca-locked-by',
searchResultsRow: 'aca-search-results-row',
searchResultsRowLine: '.line'
};
head = this.byCss('.adf-datatable-header');
body = this.byCss('.adf-datatable-body');
emptyList = this.byCss('div.adf-no-content-container');
emptyFolderDragAndDrop = this.byCss(
'.adf-empty-list_template .adf-empty-folder'
);
emptyListTitle = this.byCss('.adf-empty-content__title');
emptyListSubtitle = this.byCss('.adf-empty-content__subtitle');
emptySearchText = this.byCss('.empty-search__text');
selectedRow = this.byCss('.adf-datatable-row.adf-is-selected');
menu = new Menu();
constructor(ancestor?: string) {
super('adf-datatable', ancestor);
}
async waitForHeader(): Promise<void> {
return waitForPresence(this.head, '--- timeout waitForHeader ---');
}
async waitForBody(): Promise<void> {
return waitForPresence(this.body, '--- timeout waitForBody ---');
}
async waitForEmptyState(): Promise<void> {
return waitForPresence(this.emptyList);
}
private getColumnHeaders(): ElementArrayFinder {
const locator = by.css(DataTable.selectors.columnHeader);
return this.head.all(locator);
}
async getColumnHeadersText(): Promise<string> {
return this.getColumnHeaders().getText();
}
getColumnHeaderByLabel(label: string): ElementFinder {
const locator = by.cssContainingText(
DataTable.selectors.columnHeader,
label
);
return this.head.element(locator);
}
private getSortedColumnHeader(): ElementFinder {
const locator = by.css(DataTable.selectors.sortedColumnHeader);
return this.head.element(locator);
}
async getSortedColumnHeaderText(): Promise<string> {
return this.getSortedColumnHeader().getText();
}
async getSortingOrder(): Promise<string> {
const str = await this.getSortedColumnHeader()
.element(by.xpath('..'))
.getAttribute('class');
if (str.includes('asc')) {
return 'asc';
}
if (str.includes('desc')) {
return 'desc';
}
return 'none';
}
private getRows(): ElementArrayFinder {
return this.body.all(by.css(DataTable.selectors.row));
}
async getRowsCount(): Promise<number> {
return this.getRows().count();
}
private getSelectedRows(): ElementArrayFinder {
return this.body.all(by.css('.adf-datatable-row.adf-is-selected'));
}
async getSelectedRowsNames(): Promise<string[]> {
const rowsText: string[] = await this.getSelectedRows().map(row => {
return row.element(by.css('.adf-datatable-cell[title="Name"]')).getText();
});
return rowsText;
}
async getSelectedRowsCount(): Promise<number> {
return this.getSelectedRows().count();
}
getRowByName(name: string, location: string = ''): ElementFinder {
if (location) {
return this.body
.all(by.cssContainingText(DataTable.selectors.row, name))
.filter(async elem =>
browser.isElementPresent(
elem.element(
by.cssContainingText(DataTable.selectors.cell, location)
)
)
)
.first();
}
return this.body.element(
by.cssContainingText(DataTable.selectors.row, name)
);
}
getRowCells(name: string, location: string = ''): ElementArrayFinder {
return this.getRowByName(name, location).all(
by.css(DataTable.selectors.cell)
);
}
async getRowCellsCount(itemName: string): Promise<number> {
return this.getRowCells(itemName).count();
}
private getRowFirstCell(name: string, location: string = ''): ElementFinder {
return this.getRowCells(name, location).get(0);
}
private getRowNameCell(name: string, location: string = ''): ElementFinder {
return this.getRowCells(name, location).get(1);
}
private getRowNameCellSpan(
name: string,
location: string = ''
): ElementFinder {
return this.getRowNameCell(name, location).$('span');
}
async getItemNameTooltip(
name: string,
location: string = ''
): Promise<string> {
return this.getRowNameCellSpan(name, location).getAttribute('title');
}
async hasCheckMarkIcon(
itemName: string,
location: string = ''
): Promise<boolean> {
const row = this.getRowByName(itemName, location);
return row.element(by.css('.mat-icon[class*="selected"]')).isPresent();
}
async hasLockIcon(itemName: string, location: string = ''): Promise<boolean> {
const row = this.getRowByName(itemName, location);
return row.element(by.css('img[src*="lock"]')).isPresent();
}
private async hasLockOwnerInfo(
itemName: string,
location: string = ''
): Promise<boolean> {
const row = this.getRowByName(itemName, location);
return row.element(by.css(DataTable.selectors.lockOwner)).isPresent();
}
async getLockOwner(itemName: string, location: string = ''): Promise<string> {
if (await this.hasLockOwnerInfo(itemName, location)) {
const row = this.getRowByName(itemName, location);
return row
.$(DataTable.selectors.lockOwner)
.$('.locked_by--name')
.getText();
}
return '';
}
private getNameLink(itemName: string): ElementFinder {
return this.getRowNameCell(itemName).$('.adf-datatable-link');
}
async hasLinkOnName(itemName: string): Promise<boolean> {
return this.getNameLink(itemName).isPresent();
}
async doubleClickOnRowByName(
name: string,
location: string = ''
): Promise<void> {
try {
const item = this.getRowFirstCell(name, location);
await waitForClickable(item);
await browser
.actions()
.mouseMove(item)
.perform();
await browser
.actions()
.doubleClick()
.perform();
} catch (error) {
Logger.error('--- catch: doubleClickOnRowByName', error);
}
}
async selectItem(name: string, location: string = ''): Promise<void> {
const isSelected = await this.hasCheckMarkIcon(name, location);
if (!isSelected) {
try {
const item = this.getRowFirstCell(name, location);
await item.click();
} catch (e) {
Logger.error('--- select item catch : ', e);
}
}
}
async unselectItem(name: string, location: string = ''): Promise<void> {
const isSelected = await this.hasCheckMarkIcon(name, location);
if (isSelected) {
try {
const item = this.getRowFirstCell(name, location);
await item.click();
} catch (e) {
Logger.error('--- unselect item catch : ', e);
}
}
}
async clickItem(name: string, location: string = ''): Promise<void> {
const item = this.getRowFirstCell(name, location);
await item.click();
}
async clickNameLink(itemName: string): Promise<void> {
await this.getNameLink(itemName).click();
}
async selectMultipleItems(
names: string[],
location: string = ''
): Promise<void> {
await this.clearSelection();
await Utils.pressCmd();
for (const name of names) {
await this.selectItem(name, location);
}
await Utils.releaseKeyPressed();
}
async clearSelection(): Promise<void> {
try {
const count = await this.getSelectedRowsCount();
if (count !== 0) {
await browser.refresh();
await this.wait();
}
} catch (error) {
Logger.error('------ clearSelection catch : ', error);
}
}
async rightClickOnItem(itemName: string): Promise<void> {
const item = this.getRowFirstCell(itemName);
await browser
.actions()
.mouseMove(item)
.perform();
await browser
.actions()
.click(protractor.Button.RIGHT)
.perform();
}
async rightClickOnMultipleSelection(): Promise<void> {
const itemFromSelection = this.getSelectedRows().get(0);
await browser
.actions()
.mouseMove(itemFromSelection)
.perform();
await browser
.actions()
.click(protractor.Button.RIGHT)
.perform();
}
private getItemLocationEl(name: string): ElementFinder {
return this.getRowByName(name).element(by.css('.aca-location-link'));
}
async getItemLocation(name: string): Promise<string> {
return this.getItemLocationEl(name).getText();
}
async getItemLocationTooltip(name: string): Promise<string> {
const location = this.getItemLocationEl(name).$('a');
const condition = () =>
location.getAttribute('title').then(value => value && value.length > 0);
await browser
.actions()
.mouseMove(location)
.perform();
await browser.wait(condition, BROWSER_WAIT_TIMEOUT);
return location.getAttribute('title');
}
async clickItemLocation(name: string): Promise<void> {
await this.getItemLocationEl(name).click();
}
async isEmpty(): Promise<boolean> {
return this.emptyList.isPresent();
}
async getEmptyDragAndDropText(): Promise<string> {
const isEmpty = await this.emptyFolderDragAndDrop.isDisplayed();
if (isEmpty) {
return this.emptyFolderDragAndDrop.getText();
}
return '';
}
async getEmptyStateTitle(): Promise<string> {
const isEmpty = await this.isEmpty();
if (isEmpty) {
return this.emptyListTitle.getText();
}
return '';
}
async getEmptyStateSubtitle(): Promise<string> {
const isEmpty = await this.isEmpty();
if (isEmpty) {
return this.emptyListSubtitle.getText();
}
return '';
}
async getEmptyListText(): Promise<string> {
const isEmpty = await this.isEmpty();
if (isEmpty) {
return this.byCss('adf-custom-empty-content-template').getText();
}
return '';
}
async getCellsContainingName(name: string): Promise<string[]> {
const rows = this.getRows().all(
by.cssContainingText(DataTable.selectors.cell, name)
);
const cellsText: string[] = await rows.map(async cell => {
return cell.getText();
});
return cellsText;
}
async hasContextMenu(): Promise<boolean> {
const count = await this.menu.getItemsCount();
return count > 0;
}
async getLibraryRole(name: string): Promise<string> {
return this.getRowByName(name)
.element(by.css('adf-library-role-column'))
.getText();
}
async isItemPresent(name: string, location?: string): Promise<boolean> {
return this.getRowByName(name, location).isPresent();
}
private async getEntireDataTableText(): Promise<string[]> {
const text: string[] = await this.getRows().map(row => {
return row.all(by.css(DataTable.selectors.cell)).map(async cell => {
return cell.getText();
});
});
return text;
}
async getSitesNameAndVisibility(): Promise<{}> {
const data = await this.getEntireDataTableText();
return data.reduce((acc, cell) => {
acc[cell[1]] = cell[3].toUpperCase();
return acc;
}, {});
}
async getSitesNameAndRole(): Promise<{}> {
const data = await this.getEntireDataTableText();
return data.reduce((acc, cell) => {
acc[cell[1]] = cell[2];
return acc;
}, {});
}
private getSearchResultsRows(): ElementArrayFinder {
return this.body.all(by.css(DataTable.selectors.searchResultsRow));
}
getNthSearchResultsRow(nth: number): ElementFinder {
return this.getSearchResultsRows().get(nth - 1);
}
private getSearchResultsRowByName(
name: string,
location: string = ''
): ElementFinder {
if (location) {
return this.body
.all(by.cssContainingText(DataTable.selectors.searchResultsRow, name))
.filter(async elem =>
browser.isElementPresent(
elem.element(
by.cssContainingText(
DataTable.selectors.searchResultsRowLine,
location
)
)
)
)
.first();
}
return this.body.element(
by.cssContainingText(DataTable.selectors.searchResultsRow, name)
);
}
private getSearchResultRowLines(
name: string,
location: string = ''
): ElementArrayFinder {
return this.getSearchResultsRowByName(name, location).all(
by.css(DataTable.selectors.searchResultsRowLine)
);
}
async getSearchResultLinesCount(
name: string,
location: string = ''
): Promise<number> {
return this.getSearchResultRowLines(name, location).count();
}
private getSearchResultNthLine(
name: string,
location: string = '',
index: number
): ElementFinder {
return this.getSearchResultRowLines(name, location).get(index);
}
async getSearchResultNameAndTitle(
name: string,
location: string = ''
): Promise<string> {
return this.getSearchResultNthLine(name, location, 0).getText();
}
async getSearchResultDescription(
name: string,
location: string = ''
): Promise<string> {
return this.getSearchResultNthLine(name, location, 1).getText();
}
async getSearchResultModified(
name: string,
location: string = ''
): Promise<string> {
return this.getSearchResultNthLine(name, location, 2).getText();
}
async getSearchResultLocation(
name: string,
location: string = ''
): Promise<string> {
return this.getSearchResultNthLine(name, location, 3).getText();
}
private getSearchResultNameLink(
itemName: string,
location: string = ''
): ElementFinder {
return this.getSearchResultsRowByName(itemName, location).$('.link');
}
async hasLinkOnSearchResultName(
itemName: string,
location: string = ''
): Promise<boolean> {
return this.getSearchResultNameLink(itemName, location).isPresent();
}
async clickSearchResultNameLink(
itemName: string,
location: string = ''
): Promise<void> {
await this.getSearchResultNameLink(itemName, location).click();
}
}

View File

@@ -0,0 +1,66 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser } from 'protractor';
import { Component } from '../component';
import * as moment from 'moment';
import { isPresentAndDisplayed, waitForStaleness } from '../../utilities/utils';
export class DateTimePicker extends Component {
calendar = this.byCss('.mat-datetimepicker-popup', browser);
headerDate = this.byCss('.mat-datetimepicker-calendar-header-date');
headerYear = this.byCss('.mat-datetimepicker-calendar-header-year');
dayPicker = this.byCss('mat-datetimepicker-month-view');
rootElemLocator = by.css('.mat-datetimepicker-popup');
constructor(ancestor?: string) {
super('.mat-datetimepicker-popup', ancestor);
}
async waitForDateTimePickerToClose(): Promise<void> {
return waitForStaleness(this.calendar);
}
async isCalendarOpen(): Promise<boolean> {
const element = browser.element(this.rootElemLocator);
return isPresentAndDisplayed(element);
}
async setDefaultDay(): Promise<string> {
const today = moment();
const tomorrow = today.add(1, 'day');
const dayOfTomorrow = tomorrow.date();
const date = await this.headerDate.getText();
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();
return `${date} ${year}`;
}
}

View File

@@ -0,0 +1,64 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndEnabled } from '../../utilities/utils';
export class ConfirmDialog extends GenericDialog {
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('adf-confirm-dialog');
}
async getText(): Promise<string> {
return this.content.getText();
}
async isOkEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.okButton);
}
async isCancelEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.cancelButton);
}
async isKeepEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.keepButton);
}
async isDeleteEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.deleteButton);
}
async isRemoveEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.removeButton);
}
}

View File

@@ -0,0 +1,119 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser, protractor } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
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 {
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 = 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', 'My Libraries')
);
searchInput = this.rootElem.element(by.css('#searchInput'));
toolbarTitle = this.rootElem.element(by.css('.adf-toolbar-title'));
breadcrumb = new DropDownBreadcrumb();
dataTable = new DataTable('.adf-content-node-selector-dialog');
constructor() {
super('.adf-content-node-selector-dialog');
}
async waitForDropDownToClose(): Promise<void> {
await waitForStaleness(browser.$('.mat-option .mat-option-text'));
}
async selectLocation(location: string): Promise<void> {
await this.locationDropDown.click();
await waitForPresence(this.locationPersonalFiles);
if (location === 'Personal Files') {
await this.locationPersonalFiles.click();
} else {
await this.locationFileLibraries.click();
}
await this.waitForDropDownToClose();
}
async selectDestination(folderName: string): Promise<void> {
const row = this.dataTable.getRowByName(folderName);
await waitForClickable(row);
await row.click();
await waitForPresence(browser.element(by.css('.adf-is-selected')));
}
async isSelectLocationDropdownDisplayed(): Promise<boolean> {
return isPresentAndDisplayed(this.locationDropDown);
}
async isCopyButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.copyButton);
}
async isCancelButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.cancelButton);
}
async searchFor(text: string): Promise<void> {
await Utils.clearFieldWithBackspace(this.searchInput);
await this.searchInput.sendKeys(text);
await this.searchInput.sendKeys(protractor.Key.ENTER);
}
async getToolbarTitle(): Promise<string> {
return this.toolbarTitle.getText();
}
}

View File

@@ -0,0 +1,99 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import {
isPresentAndDisplayed,
waitForClickable,
isPresentAndEnabled,
typeText
} from '../../utilities/utils';
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]')
);
validationMessage = this.rootElem.element(by.css('.mat-hint span'));
constructor() {
super('adf-folder-dialog');
}
async waitForDialogToOpen() {
await super.waitForDialogToOpen();
await waitForClickable(this.nameInput);
}
async isUpdateButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.updateButton);
}
async isCreateButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.createButton);
}
async isCancelButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.cancelButton);
}
async getValidationMessage(): Promise<string> {
if (await isPresentAndDisplayed(this.validationMessage)) {
return this.validationMessage.getText();
} else {
return '';
}
}
async getName(): Promise<string> {
return this.nameInput.getAttribute('value');
}
async getDescription(): Promise<string> {
return this.descriptionTextArea.getAttribute('value');
}
async enterName(name: string): Promise<void> {
await typeText(this.nameInput, name);
}
async enterDescription(description: string): Promise<void> {
await typeText(this.descriptionTextArea, description);
}
async clickCancel(): Promise<void> {
await this.cancelButton.click();
await this.waitForDialogToClose();
}
}

View File

@@ -0,0 +1,97 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import {
isPresentAndDisplayed,
isPresentAndEnabled,
typeText
} from '../../utilities/utils';
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]')
);
validationMessage = this.childElement(by.css('.mat-error'));
constructor() {
super('.aca-create-from-template-dialog');
}
async isValidationMessageDisplayed(): Promise<boolean> {
return isPresentAndDisplayed(this.validationMessage);
}
async isCreateButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.createButton);
}
async isCancelButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.cancelButton);
}
async getValidationMessage(): Promise<string> {
if (await this.isValidationMessageDisplayed()) {
return this.validationMessage.getText();
} else {
return '';
}
}
async getName(): Promise<string> {
return this.nameInput.getAttribute('value');
}
async getDescription(): Promise<string> {
return this.descriptionTextArea.getAttribute('value');
}
async enterName(name: string): Promise<void> {
await typeText(this.nameInput, name);
}
async enterTitle(title: string): Promise<void> {
await typeText(this.titleInput, title);
}
async enterDescription(description: string): Promise<void> {
await typeText(this.descriptionTextArea, description);
}
async clickCancel(): Promise<void> {
await this.cancelButton.click();
await this.waitForDialogToClose();
}
}

View File

@@ -0,0 +1,120 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, ElementFinder } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import {
waitForClickable,
isPresentAndEnabled,
typeText
} from '../../utilities/utils';
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]')
);
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')
);
errorMessage = this.rootElem.element(by.css('.mat-error'));
constructor() {
super('adf-library-dialog');
}
async waitForDialogToOpen(): Promise<void> {
await super.waitForDialogToOpen();
await waitForClickable(this.nameInput);
}
async getErrorMessage(): Promise<string> {
if (await this.errorMessage.isDisplayed()) {
return this.errorMessage.getText();
}
return '';
}
async enterName(name: string): Promise<void> {
await typeText(this.nameInput, name);
}
async enterLibraryId(id: string): Promise<void> {
await typeText(this.libraryIdInput, id);
}
async enterDescription(description: string): Promise<void> {
await typeText(this.descriptionTextArea, description);
}
async isCreateEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.createButton);
}
async isCancelEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.cancelButton);
}
async clickCancel(): Promise<void> {
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> {
return this.isChecked(this.visibilityPublic);
}
async isModeratedChecked(): Promise<boolean> {
return this.isChecked(this.visibilityModerated);
}
async isPrivateChecked(): Promise<boolean> {
return this.isChecked(this.visibilityPrivate);
}
}

View File

@@ -0,0 +1,74 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, browser, Locator } from 'protractor';
import {
isPresentAndDisplayed,
waitForPresence,
waitForVisibility,
waitForStaleness
} from '../../utilities/utils';
export abstract class GenericDialog {
constructor(private rootCssSelector?: string) {}
get rootElem(): ElementFinder {
return browser.element(by.css(this.rootCssSelector));
}
get title(): ElementFinder {
return this.rootElem.element(by.css('.mat-dialog-title'));
}
get content(): ElementFinder {
return this.rootElem.element(by.css('.mat-dialog-content'));
}
async getText(): Promise<string> {
return this.content.getText();
}
async waitForDialogToOpen(): Promise<void> {
await waitForPresence(this.rootElem);
await waitForVisibility(this.content);
await waitForPresence(browser.element(by.css('.cdk-overlay-backdrop')));
}
async waitForDialogToClose(): Promise<void> {
await waitForStaleness(this.content);
}
async isDialogOpen(): Promise<boolean> {
return isPresentAndDisplayed(this.rootElem);
}
async getTitle(): Promise<string> {
return this.title.getText();
}
protected childElement(selector: Locator): ElementFinder {
return this.rootElem.element(selector);
}
}

View File

@@ -0,0 +1,36 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
export * from './confirm-dialog';
export * from './content-node-selector-dialog';
export * from './create-edit-folder-dialog';
export * from './create-from-template-dialog';
export * from './create-library-dialog';
export * from './generic-dialog';
export * from './manage-versions-dialog';
export * from './password-dialog';
export * from './select-template-dialog';
export * from './share-dialog';
export * from './upload-new-version-dialog';

View File

@@ -0,0 +1,40 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
export class ManageVersionsDialog extends GenericDialog {
closeButton = this.childElement(by.cssContainingText('.mat-button', 'Close'));
constructor() {
super('.aca-node-versions-dialog');
}
async clickClose(): Promise<void> {
await this.closeButton.click();
await this.waitForDialogToClose();
}
}

View File

@@ -0,0 +1,101 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import {
waitForClickable,
isPresentAndEnabled,
typeText
} from '../../utilities/utils';
export class PasswordDialog extends GenericDialog {
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('adf-pdf-viewer-password-dialog');
}
async waitForDialogToOpen(): Promise<void> {
await super.waitForDialogToOpen();
await waitForClickable(this.passwordInput);
}
async isDialogOpen(): Promise<boolean> {
try {
await this.waitForDialogToOpen();
return true;
} catch (error) {
return false;
}
}
async isCloseEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.closeButton);
}
async isSubmitEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.submitButton);
}
async isPasswordInputDisplayed(): Promise<boolean> {
const present = await browser.isElementPresent(this.passwordInput);
if (present) {
return this.passwordInput.isDisplayed();
} else {
return false;
}
}
async isErrorDisplayed(): Promise<boolean> {
try {
await this.waitForDialogToOpen();
return (
(await this.errorMessage.isPresent()) &&
(await this.errorMessage.isDisplayed())
);
} catch (error) {
return false;
}
}
async getErrorMessage(): Promise<string> {
if (await this.isErrorDisplayed()) {
return this.errorMessage.getText();
}
return '';
}
async enterPassword(password: string): Promise<void> {
await typeText(this.passwordInput, password);
}
}

View File

@@ -0,0 +1,65 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
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 {
nextButton = this.childElement(
by.css('[data-automation-id="content-node-selector-actions-choose"]')
);
cancelButton = this.childElement(
by.css('[data-automation-id="content-node-selector-actions-cancel"]')
);
breadcrumb = new DropDownBreadcrumb();
dataTable = new DataTable('.aca-template-node-selector-dialog');
constructor() {
super('.aca-template-node-selector-dialog');
}
async isCancelButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.cancelButton);
}
async isNextButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.nextButton);
}
async clickCancel(): Promise<void> {
await this.cancelButton.click();
await this.waitForDialogToClose();
}
async clickNext(): Promise<void> {
await this.nextButton.click();
await this.waitForDialogToClose();
}
}

View File

@@ -0,0 +1,110 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
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 {
dateTimePicker = new DateTimePicker();
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('.adf-share-dialog');
}
async getTitle(): Promise<string> {
return this.dialogTitle.getText();
}
async getInfoText(): Promise<string> {
return this.infoText.getText();
}
async getLinkUrl(): Promise<string> {
return this.url.getAttribute('value');
}
async isUrlReadOnly(): Promise<boolean> {
const urlAttr = await this.url.getAttribute('readonly');
return urlAttr === 'true';
}
async isCloseEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.closeButton);
}
async clickClose(): Promise<void> {
await this.closeButton.click();
await this.waitForDialogToClose();
}
async isShareToggleChecked(): Promise<boolean> {
const toggleClass = await this.shareToggle.getAttribute('class');
return toggleClass.includes('checked');
}
async isShareToggleDisabled(): Promise<boolean> {
const toggleClass = await this.shareToggle.getAttribute('class');
return toggleClass.includes('mat-disabled');
}
async isExpireToggleEnabled(): Promise<boolean> {
const toggleClass = await this.expireToggle.getAttribute('class');
return toggleClass.includes('checked');
}
async closeDatetimePicker(): Promise<void> {
if (await this.dateTimePicker.isCalendarOpen()) {
await this.datetimePickerButton.click();
}
}
async getExpireDate(): Promise<string> {
return this.expireInput.getAttribute('value');
}
}

View File

@@ -0,0 +1,65 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndEnabled, typeText } from '../../utilities/utils';
export class UploadNewVersionDialog extends GenericDialog {
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('.aca-node-version-upload-dialog');
}
async isCancelButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.cancelButton);
}
async isUploadButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.uploadButton);
}
async clickCancel(): Promise<void> {
await this.cancelButton.click();
await this.waitForDialogToClose();
}
async enterDescription(description: string): Promise<void> {
await typeText(this.description, description);
}
}

View File

@@ -0,0 +1,76 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser } from 'protractor';
import { Component } from '../component';
import { UserInfo } from './user-info';
import { Menu } from '../menu/menu';
import { Toolbar } from './../toolbar/toolbar';
import { SearchInput } from '../search/search-input';
import { waitElement } from '../../utilities/utils';
export class Header extends Component {
logoLink = this.byCss('.app-menu__title');
moreActions = browser.element(by.id('app.header.more'));
sidenavToggle = this.byCss(`[id='adf-sidebar-toggle-start']`);
userInfo = new UserInfo();
menu = new Menu();
toolbar = new Toolbar();
searchInput = new SearchInput();
constructor(ancestor?: string) {
super('adf-layout-header', ancestor);
}
async openMoreMenu(): Promise<void> {
await this.moreActions.click();
await this.menu.waitForMenuToOpen();
}
async isSignOutDisplayed(): Promise<boolean> {
return this.userInfo.menu.isMenuItemPresent('Sign out');
}
async isSidenavExpanded(): Promise<boolean> {
return browser.isElementPresent(by.css(`[data-automation-id='expanded']`));
}
async expandSideNav(): Promise<void> {
const expanded = await this.isSidenavExpanded();
if (!expanded) {
await this.sidenavToggle.click();
await waitElement(`[data-automation-id='expanded']`);
}
}
async collapseSideNav(): Promise<void> {
const expanded = await this.isSidenavExpanded();
if (expanded) {
await this.sidenavToggle.click();
await waitElement(`[data-automation-id='collapsed']`);
}
}
}

View File

@@ -0,0 +1,50 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { Menu } from '../menu/menu';
import { Component } from '../component';
export class UserInfo extends Component {
fullName = this.byCss('.current-user__full-name');
avatar = this.byCss('.current-user__avatar');
menu = new Menu();
constructor(ancestor?: string) {
super('aca-current-user', ancestor);
}
async openMenu(): Promise<Menu> {
await this.avatar.click();
await this.menu.wait();
return this.menu;
}
async signOut(): Promise<void> {
const menu = await this.openMenu();
await menu.clickMenuItem('Sign out');
}
}

View File

@@ -0,0 +1,43 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
export * from './breadcrumb/breadcrumb';
export * from './breadcrumb/dropdown-breadcrumb';
export * from './data-table/data-table';
export * from './datetime-picker/datetime-picker';
export * from './dialog';
export * from './header/header';
export * from './header/user-info';
export * from './info-drawer';
export * from './login/login';
export * from './menu/menu';
export * from './metadata-card/metadata-card';
export * from './pagination/pagination';
export * from './search';
export * from './sidenav/sidenav';
export * from './toolbar/toolbar';
export * from './viewer/viewer';
export * from './component';
export * from './components';

View File

@@ -0,0 +1,29 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
export * from './info-drawer-comments-tab';
export * from './info-drawer-metadata-content';
export * from './info-drawer-metadata-library';
export * from './info-drawer';

View File

@@ -0,0 +1,128 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser, until } from 'protractor';
import { Component } from '../component';
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
import { waitForVisibility, typeText } from '../../utilities/utils';
export class CommentsTab extends Component {
commentsContainer = this.byCss('.adf-comments-container');
commentsHeader = this.byCss('.adf-comments-header');
commentTextarea = this.byCss('.adf-comments-input-container textarea');
addCommentButton = this.byCss('button.adf-comments-input-add');
commentListItem = by.css('.adf-comment-list-item');
commentUserAvatar = by.id('comment-user-icon');
commentUser = by.id('comment-user');
commentText = by.id('comment-message');
commentTime = by.id('comment-time');
constructor(ancestor?: string) {
super('adf-comments', ancestor);
}
async waitForCommentsContainer() {
await waitForVisibility(this.commentsContainer);
}
async getCommentsTabHeaderText(): Promise<string> {
return this.commentsHeader.getText();
}
async isCommentTextAreaDisplayed(): Promise<boolean> {
return browser.isElementPresent(this.commentTextarea);
}
async isAddCommentButtonEnabled(): Promise<boolean> {
const present = await browser.isElementPresent(this.addCommentButton);
if (present) {
return this.addCommentButton.isEnabled();
}
return false;
}
private async getCommentListItem() {
return browser.wait(
until.elementLocated(this.commentListItem),
BROWSER_WAIT_TIMEOUT / 2
);
}
async getCommentById(commentId?: string) {
if (commentId) {
return browser.wait(
until.elementLocated(by.id(`adf-comment-${commentId}`)),
BROWSER_WAIT_TIMEOUT / 2
);
}
return this.getCommentListItem();
}
async isCommentDisplayed(commentId?: string) {
return browser.isElementPresent(await this.getCommentById(commentId));
}
async isCommentUserAvatarDisplayed(commentId?: string) {
const commentElement = await this.getCommentById(commentId);
return browser.isElementPresent(
commentElement.findElement(this.commentUserAvatar)
);
}
async getCommentText(commentId?: string) {
const commentElement = await this.getCommentById(commentId);
const message = await commentElement.findElement(this.commentText);
return message.getText();
}
async getCommentUserName(commentId?: string): Promise<string> {
const commentElement = await this.getCommentById(commentId);
const user = await commentElement.findElement(this.commentUser);
return user.getText();
}
async getCommentTime(commentId?: string): Promise<string> {
const commentElement = await this.getCommentById(commentId);
const time = await commentElement.findElement(this.commentTime);
return time.getText();
}
async getNthCommentId(index: number): Promise<string> {
const list = this.allByCss('.adf-comment-list-item');
return list.get(index - 1).getAttribute('id');
}
async typeComment(text: string): Promise<void> {
await typeText(this.commentTextarea, text);
}
async clickAddButton(): Promise<void> {
await this.addCommentButton.click();
}
async getCommentTextFromTextArea(): Promise<string> {
return this.commentTextarea.getAttribute('value');
}
}

View File

@@ -0,0 +1,117 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser, ElementFinder } from 'protractor';
import { Component } from '../component';
import {
isPresentAndEnabled,
isPresentAndDisplayed,
waitForVisibility
} from '../../utilities/utils';
export class ContentMetadata extends Component {
expandedPanel = this.byCss('.mat-expansion-panel.mat-expanded');
propertyList = this.byCss('.adf-property-list');
propertyListElements = this.allByCss('.adf-property');
propertyValue = this.byCss('.adf-property-value');
editPropertiesButton = this.byCss(`button[title='Edit']`);
lessInfoButton = this.byCssText(
`[data-automation-id='meta-data-card-toggle-expand']`,
'Less information'
);
moreInfoButton = this.byCssText(
`[data-automation-id='meta-data-card-toggle-expand']`,
'More information'
);
imagePropertiesPanel = this.byCss(
`[data-automation-id='adf-metadata-group-APP.CONTENT_METADATA.EXIF_GROUP_TITLE']`
);
expandedImagePropertiesPanel = this.byCss(
`[data-automation-id='adf-metadata-group-APP.CONTENT_METADATA.EXIF_GROUP_TITLE'].mat-expanded`
);
constructor(ancestor?: string) {
super('adf-content-metadata-card', ancestor);
}
async isPropertiesListExpanded(): Promise<boolean> {
return browser.isElementPresent(this.expandedPanel);
}
async waitForImagePropertiesPanelToExpand(): Promise<void> {
await waitForVisibility(this.expandedImagePropertiesPanel);
}
async getVisiblePropertiesLabels(): Promise<string[]> {
return this.allByCss('.adf-property-label')
.filter(async elem => elem.isDisplayed())
.map(async elem => elem.getText());
}
async getVisiblePropertiesValues() {
return this.allByCss('.adf-property-value')
.filter(async elem => elem.isDisplayed())
.map(async elem => {
if (await elem.isElementPresent(by.css('.mat-checkbox'))) {
if (await elem.isElementPresent(by.css('.mat-checkbox-checked'))) {
return true;
}
return false;
}
return this.getElementValue(elem);
});
}
async isEditPropertiesButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.editPropertiesButton);
}
async isLessInfoButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.lessInfoButton);
}
async isMoreInfoButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.moreInfoButton);
}
async isMoreInfoButtonDisplayed(): Promise<boolean> {
return browser.isElementPresent(this.moreInfoButton);
}
async isImagePropertiesPanelDisplayed(): Promise<boolean> {
return isPresentAndDisplayed(this.imagePropertiesPanel);
}
private async getElementValue(elem: ElementFinder): Promise<string> {
const tagName = await elem.getTagName();
if (tagName === 'input' || tagName === 'textarea') {
return elem.getAttribute('value');
}
return elem.getText();
}
}

View File

@@ -0,0 +1,241 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser } from 'protractor';
import { Logger } from '@alfresco/adf-testing';
import { Component } from '../component';
import {
waitForPresence,
waitForStaleness,
typeText
} from '../../utilities/utils';
export class LibraryMetadata extends Component {
metadataTabContent = this.byCss('.mat-card-content');
metadataTabAction = this.byCss('.mat-card-actions .mat-button');
fieldLabelWrapper = this.byCss('.mat-form-field-label-wrapper');
fieldInput = this.byCss('.mat-input-element');
visibilityDropDown = this.component.element(by.css('.mat-select'));
visibilityPublic = this.byCssText(
'.mat-option .mat-option-text',
'Public',
browser
);
visibilityPrivate = this.byCssText(
'.mat-option .mat-option-text',
'Private',
browser
);
visibilityModerated = this.byCssText(
'.mat-option .mat-option-text',
'Moderated',
browser
);
hint = this.byCss('.mat-hint');
error = this.byCss('.mat-error');
constructor(ancestor?: string) {
super('app-library-metadata-form', ancestor);
}
private getLabelWrapper(label: string) {
return this.byCssText('.mat-form-field-label-wrapper', label);
}
private getFieldByName(fieldName: string) {
const wrapper = this.getLabelWrapper(fieldName);
return wrapper
.element(by.xpath('..'))
.element(by.css('.mat-input-element'));
}
private async isFieldDisplayed(fieldName: string) {
return browser.isElementPresent(this.getFieldByName(fieldName));
}
private async isInputEnabled(fieldName: string) {
return this.getFieldByName(fieldName).isEnabled();
}
private async getValueOfField(fieldName: string) {
return this.getFieldByName(fieldName).getText();
}
private async enterTextInInput(fieldName: string, text: string) {
const input = this.getFieldByName(fieldName);
await typeText(input, text);
}
private getButton(button: string) {
return this.byCssText('.mat-card-actions .mat-button', button);
}
private async isButtonDisplayed(button: string) {
return browser.isElementPresent(this.getButton(button));
}
private async isButtonEnabled(button: string) {
return this.getButton(button).isEnabled();
}
private async clickButton(button: string) {
await this.getButton(button).click();
}
async waitForVisibilityDropDownToClose() {
await waitForStaleness(browser.$('.mat-option .mat-option-text'));
}
async isMessageDisplayed() {
return browser.isElementPresent(this.hint);
}
async getMessage() {
return this.hint.getText();
}
async isErrorDisplayed() {
return browser.isElementPresent(this.error);
}
async getError() {
return this.error.getText();
}
async isNameDisplayed() {
return this.isFieldDisplayed('Name');
}
async isNameEnabled() {
return this.isInputEnabled('Name');
}
async getName(): Promise<string> {
return this.getValueOfField('Name');
}
async enterName(name: string): Promise<void> {
await this.enterTextInInput('Name', name);
}
async isDescriptionDisplayed() {
return this.isFieldDisplayed('Description');
}
async isDescriptionEnabled() {
return this.isInputEnabled('Description');
}
async getDescription(): Promise<string> {
return this.getValueOfField('Description');
}
async enterDescription(desc: string) {
await this.enterTextInInput('Description', desc);
}
async isVisibilityEnabled() {
const wrapper = this.getLabelWrapper('Visibility');
const field = wrapper
.element(by.xpath('..'))
.element(by.css('.mat-select'));
return field.isEnabled();
}
async isVisibilityDisplayed() {
return this.isFieldDisplayed('Visibility');
}
async getVisibility(): Promise<string> {
return this.getValueOfField('Visibility');
}
async setVisibility(visibility: string) {
const val = visibility.toLowerCase();
await this.visibilityDropDown.click();
await waitForPresence(this.visibilityDropDown);
if (val === 'public') {
await this.visibilityPublic.click();
} else if (val === 'private') {
await this.visibilityPrivate.click();
} else if (val === 'moderated') {
await this.visibilityModerated.click();
} else {
Logger.error('----- invalid visibility', val);
}
await this.waitForVisibilityDropDownToClose();
}
async isLibraryIdDisplayed() {
return this.isFieldDisplayed('Library ID');
}
async isLibraryIdEnabled() {
return this.isInputEnabled('Library ID');
}
async getLibraryId() {
return this.getValueOfField('Library ID');
}
async isEditLibraryPropertiesEnabled() {
return this.isButtonEnabled('Edit');
}
async isEditLibraryPropertiesDisplayed() {
return this.isButtonDisplayed('Edit');
}
async clickEditLibraryProperties() {
await this.clickButton('Edit');
}
async isUpdateEnabled() {
return this.isButtonEnabled('Update');
}
async isUpdateDisplayed() {
return this.isButtonDisplayed('Update');
}
async clickUpdate() {
await this.clickButton('Update');
}
async isCancelEnabled() {
return this.isButtonEnabled('Cancel');
}
async isCancelDisplayed() {
return this.isButtonDisplayed('Cancel');
}
async clickCancel() {
await this.clickButton('Cancel');
}
}

View File

@@ -0,0 +1,141 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser } from 'protractor';
import { 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';
export class InfoDrawer extends Component {
commentsTab = new CommentsTab('adf-info-drawer');
aboutTab = new LibraryMetadata('adf-info-drawer');
propertiesTab = new ContentMetadata('adf-info-drawer');
header = this.byCss('.adf-info-drawer-layout-header');
headerTitle = this.byCss('.adf-info-drawer-layout-header-title');
tabLabel = this.byCss('.mat-tab-label-content');
tabLabelsList = this.allByCss('.mat-tab-label-content');
tabActiveLabel = this.byCss('.mat-tab-label-active');
tabActiveContent = this.byCss(
'.mat-tab-body-active .mat-tab-body-content adf-dynamic-tab'
);
nextButton = this.byCss(
'.mat-tab-header-pagination-after .mat-tab-header-pagination-chevron'
);
previousButton = this.byCss(
'.mat-tab-header-pagination-before .mat-tab-header-pagination-chevron'
);
constructor(ancestor?: string) {
super('adf-info-drawer', ancestor);
}
async waitForInfoDrawerToOpen() {
await waitForPresence(this.header);
}
async isOpen() {
return browser.isElementPresent(this.header);
}
async isEmpty() {
return !(await browser.isElementPresent(by.css('.adf-info-drawer-tabs')));
}
getTabByTitle(title: string) {
return this.byCssText('.mat-tab-label-content', title);
}
async getTabsCount(): Promise<number> {
return this.allByCss('.mat-tab-label-content').count();
}
async isTabPresent(title: string) {
return this.getTabByTitle(title).isPresent();
}
async isTabDisplayed(title: string): Promise<boolean> {
if (await browser.isElementPresent(this.getTabByTitle(title))) {
return this.getTabByTitle(title).isDisplayed();
}
return false;
}
async getTabTitle(index: number): Promise<string> {
return this.tabLabelsList.get(index - 1).getAttribute('innerText');
}
async getActiveTabTitle(): Promise<string> {
return this.tabActiveLabel.getText();
}
async clickTab(title: string) {
await this.getTabByTitle(title).click();
}
async getComponentIdOfTab(): Promise<string> {
return this.tabActiveContent.getAttribute('data-automation-id');
}
async getHeaderTitle(): Promise<string> {
return this.headerTitle.getText();
}
async isAboutTabDisplayed() {
return this.isTabDisplayed('About');
}
async isPropertiesTabDisplayed() {
return this.isTabDisplayed('Properties');
}
async isPropertiesTabActive() {
return (await this.getActiveTabTitle()) === 'PROPERTIES';
}
async isCommentsTabDisplayed() {
return this.isTabDisplayed('Comments');
}
async clickCommentsTab() {
try {
await this.getTabByTitle('Comments').click();
await this.commentsTab.waitForCommentsContainer();
await Promise.all([
waitForVisibility(this.commentsTab.component),
waitForInvisibility(this.propertiesTab.component)
]);
} catch (error) {
Logger.error('--- info-drawer clickCommentsTab catch error: ', error);
}
}
}

View File

@@ -0,0 +1,75 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component } from '../component';
import { typeText } from '../../utilities/utils';
export class LoginComponent extends Component {
usernameInput = this.byCss('input#username');
passwordInput = this.byCss('input#password');
submitButton = this.byCss('button#login-button');
errorMessage = this.byCss('.adf-login-error-message');
copyright = this.byCss('.adf-copyright');
passwordVisibility = this.byCss('.adf-login-password-icon');
constructor(ancestor?: string) {
super('adf-login', ancestor);
}
async enterUsername(username: string): Promise<void> {
await typeText(this.usernameInput, username);
}
async enterPassword(password: string): Promise<void> {
await typeText(this.passwordInput, password);
}
async enterCredentials(username: string, password: string): Promise<void> {
await this.enterUsername(username);
await this.enterPassword(password);
}
private async getPasswordVisibility(): Promise<boolean> {
const text = await this.passwordVisibility.getText();
return text.endsWith('visibility');
}
async isPasswordDisplayed(): Promise<boolean> {
const type = await this.passwordInput.getAttribute('type');
if (type === 'text') {
return true;
} else {
if (type === 'password') {
return false;
}
}
return false;
}
async isPasswordHidden() {
return !(await this.getPasswordVisibility());
}
}

View File

@@ -0,0 +1,267 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, browser } from 'protractor';
import { Logger } from '@alfresco/adf-testing';
import { Component } from '../component';
import {
Utils,
isPresentAndEnabled,
waitForPresence,
waitForVisibility,
waitForStaleness,
waitForClickable
} from '../../utilities/utils';
export class Menu extends Component {
items = this.allByCss('.mat-menu-item');
backdrop = this.byCss('.cdk-overlay-backdrop', browser);
uploadFilesInput = this.byId('app-upload-files', browser);
submenus = browser.element.all(
by.css('app-context-menu-item .mat-menu-item')
);
uploadFileAction = this.byId('app.create.uploadFile');
uploadFolderAction = this.byId('app.create.uploadFolder');
createFolderAction = this.byId('app.create.folder');
createLibraryAction = this.byId('app.create.library');
createFileFromTemplateAction = this.byId('app.create.fileFromTemplate');
createFolderFromTemplateAction = this.byId('app.create.folderFromTemplate');
cancelEditingAction = this.byCss(`.mat-menu-item[title='Cancel Editing']`);
cancelJoinAction = this.byCssText('.mat-menu-item', 'Cancel Join');
copyAction = this.byCssText('.mat-menu-item', 'Copy');
deleteAction = this.byCssText('.mat-menu-item', 'Delete');
downloadAction = this.byCssText('.mat-menu-item', 'Download');
editFolderAction = this.byCss(`.mat-menu-item[id$='editFolder']`);
editOfflineAction = this.byCss(`.mat-menu-item[title='Edit Offline']`);
favoriteAction = this.byCss(`.mat-menu-item[id$='favorite.add']`);
removeFavoriteAction = this.byCss(`.mat-menu-item[id$='favorite.remove']`);
toggleFavoriteAction = this.byCssText('.mat-menu-item', 'Favorite');
toggleRemoveFavoriteAction = this.byCssText(
'.mat-menu-item',
'Remove Favorite'
);
joinAction = this.byCssText('.mat-menu-item', 'Join');
leaveAction = this.byCssText('.mat-menu-item', 'Leave');
managePermissionsAction = this.byCssText('.mat-menu-item', 'Permissions');
manageVersionsAction = this.byCssText('.mat-menu-item', 'Manage Versions');
uploadNewVersionAction = this.byCssText(
'.mat-menu-item',
'Upload New Version'
);
moveAction = this.byCssText('.mat-menu-item', 'Move');
permanentDeleteAction = this.byCssText(
'.mat-menu-item',
'Permanently Delete'
);
restoreAction = this.byCssText('.mat-menu-item', 'Restore');
shareAction = this.byCssText('.mat-menu-item', 'Share');
shareEditAction = this.byCssText('.mat-menu-item', 'Shared Link Settings');
viewAction = this.byCssText('.mat-menu-item', 'View');
viewDetailsAction = this.byCssText('.mat-menu-item', 'View Details');
constructor(ancestor?: string) {
super('.mat-menu-panel', ancestor);
}
async waitForMenuToOpen(): Promise<void> {
await waitForPresence(
browser.element(by.css('.cdk-overlay-container .mat-menu-panel'))
);
await waitForVisibility(this.items.get(0));
}
async waitForMenuToClose(): Promise<void> {
await waitForStaleness(
browser.element(by.css('.cdk-overlay-container .mat-menu-panel'))
);
}
async closeMenu(): Promise<void> {
await Utils.pressEscape();
await this.waitForMenuToClose();
}
getNthItem(nth: number): ElementFinder {
return this.items.get(nth - 1);
}
private getItemByLabel(menuItem: string): ElementFinder {
return this.byCssText('.mat-menu-item', menuItem);
}
private getSubItemByLabel(subMenuItem: string): ElementFinder {
return this.byCssText('app-context-menu-item .mat-menu-item', subMenuItem);
}
getItemById(id: string): ElementFinder {
return this.byId(id);
}
async getItemTooltip(menuItem: string): Promise<string> {
return this.getItemByLabel(menuItem).getAttribute('title');
}
async getItemIconText(menuItem: string): Promise<string> {
return this.getItemByLabel(menuItem)
.element(by.css('.mat-icon'))
.getText();
}
async getItemIdAttribute(menuItem: string): Promise<string> {
return this.getItemByLabel(menuItem).getAttribute('id');
}
async getItemsCount(): Promise<number> {
return this.items.count();
}
async getMenuItems(): Promise<string[]> {
const items: string[] = await this.items.map(async elem => {
const span = elem.element(by.css('span'));
return span.getText();
});
return items;
}
async clickNthItem(nth: number): Promise<void> {
try {
const elem = this.getNthItem(nth);
await waitForClickable(elem);
await browser
.actions()
.mouseMove(elem)
.perform();
await browser
.actions()
.click()
.perform();
await this.waitForMenuToClose();
} catch (e) {
Logger.error('____ click nth menu item catch ___', e);
}
}
async clickMenuItem(menuItem: string): Promise<void> {
try {
const elem = this.getItemByLabel(menuItem);
await waitForClickable(elem);
await elem.click();
} catch (e) {
Logger.error('___click menu item catch___', e);
}
}
async mouseOverMenuItem(menuItem: string): Promise<void> {
try {
const elem = this.getItemByLabel(menuItem);
await waitForClickable(elem);
await browser
.actions()
.mouseMove(elem)
.perform();
await browser.sleep(500);
} catch (error) {
Logger.error('----- mouse over error: ', error);
}
}
async hasSubMenu(menuItem: string): Promise<boolean> {
try {
const elem = this.getItemByLabel(menuItem);
await waitForClickable(elem);
const elemClass = await elem.getAttribute('class');
return elemClass.includes('mat-menu-item-submenu-trigger');
} catch (error) {
Logger.error('---- has submenu error: ', error);
return false;
}
}
async clickSubMenuItem(subMenuItem: string): Promise<void> {
try {
const elem = this.getSubItemByLabel(subMenuItem);
await waitForClickable(elem);
await elem.click();
} catch (e) {
Logger.error('___click submenu item catch___', e);
}
}
async isMenuItemPresent(title: string): Promise<boolean> {
return browser
.element(by.cssContainingText('.mat-menu-item', title))
.isPresent();
}
async isSubMenuItemPresent(title: string): Promise<boolean> {
return browser
.element(
by.cssContainingText('app-context-menu-item .mat-menu-item', title)
)
.isPresent();
}
async getSubmenuItemsCount(): Promise<number> {
return this.submenus.count();
}
async isMenuItemDisabled(title: string): Promise<string | null> {
try {
const item = this.getItemByLabel(title);
const disabled = await item.getAttribute('disabled');
return disabled;
} catch (error) {
Logger.error('----- isMenuItemDisabled catch: ', error);
return null;
}
}
async isCreateFolderEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.createFolderAction);
}
async isCreateLibraryEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.createLibraryAction);
}
async isUploadFileEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.uploadFileAction);
}
async isUploadFolderEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.uploadFolderAction);
}
async isCreateFileFromTemplateEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.createFileFromTemplateAction);
}
async isCreateFolderFromTemplateEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.createFolderFromTemplateAction);
}
}

View File

@@ -0,0 +1,57 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component } from '../component';
import { waitForPresence } from '../../utilities/utils';
export class MetadataCard extends Component {
footer = this.byCss('.adf-content-metadata-card-footer');
expandButton = this.byCss(
'[data-automation-id="meta-data-card-toggle-expand"]'
);
expansionPanels = this.allByCss(
'.adf-metadata-grouped-properties-container mat-expansion-panel'
);
constructor(ancestor?: string) {
super('adf-content-metadata-card', ancestor);
}
async isExpandPresent() {
return this.expandButton.isPresent();
}
async waitForFirstExpansionPanel() {
await waitForPresence(this.expansionPanels.get(0));
}
async isExpansionPanelPresent(index: number) {
return this.expansionPanels.get(index).isPresent();
}
async getComponentIdOfPanel(index: number) {
return this.expansionPanels.get(index).getAttribute('data-automation-id');
}
}

View File

@@ -0,0 +1,157 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { browser } from 'protractor';
import { 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');
maxItems = this.byCss('.adf-pagination__max-items');
currentPage = this.byCss('.adf-pagination__current-page');
totalPages = this.byCss('.adf-pagination__total-pages');
previousButton = this.byCss('.adf-pagination__previous-button');
nextButton = this.byCss('.adf-pagination__next-button');
maxItemsButton = this.byCss(
'.adf-pagination__max-items + button[mat-icon-button]'
);
pagesButton = this.byCss(
'.adf-pagination__current-page + button[mat-icon-button]'
);
menu: Menu = new Menu();
constructor(ancestor?: string) {
super('adf-pagination', ancestor);
}
async openMaxItemsMenu() {
try {
await waitForClickable(
this.maxItemsButton,
'timeout waiting for maxItemsButton to be clickable'
);
await this.maxItemsButton.click();
await this.menu.waitForMenuToOpen();
} catch (error) {
Logger.error('____ open max items catch ___', error);
}
}
async openCurrentPageMenu() {
try {
await waitForClickable(
this.pagesButton,
'timeout waiting for pagesButton to be clickable'
);
await this.pagesButton.click();
await this.menu.waitForMenuToOpen();
} catch (error) {
Logger.error('____ open current page menu ___', error);
}
}
async resetToDefaultPageSize() {
try {
await this.openMaxItemsMenu();
await this.menu.clickNthItem(1);
await this.menu.waitForMenuToClose();
} catch (error) {
Logger.error('___ reset to default page size catch ___', error);
}
}
async resetToDefaultPageNumber() {
try {
await this.openCurrentPageMenu();
await this.menu.clickNthItem(1);
await this.menu.waitForMenuToClose();
} catch (error) {
Logger.error('____ reset to default page number catch ___', error);
}
}
async clickNext() {
await this.nextButton.click();
}
async clickPrevious() {
await this.previousButton.click();
}
async isNextEnabled() {
return this.nextButton.isEnabled();
}
async isPreviousEnabled() {
return this.previousButton.isEnabled();
}
async isPagesButtonPresent() {
return browser.isElementPresent(this.pagesButton);
}
async isRangePresent() {
return this.range.isPresent();
}
async isMaxItemsPresent() {
return this.maxItems.isPresent();
}
async isCurrentPagePresent() {
return this.currentPage.isPresent();
}
async isTotalPagesPresent() {
return this.totalPages.isPresent();
}
async isPreviousButtonPresent() {
return this.previousButton.isPresent();
}
async isNextButtonPresent() {
return this.nextButton.isPresent();
}
async getCurrentPage() {
return this.currentPage.getText();
}
async getRange() {
return this.range.getText();
}
async getMaxItems() {
return this.maxItems.getText();
}
async getTotalPages() {
return this.totalPages.getText();
}
}

View File

@@ -0,0 +1,153 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, protractor } from 'protractor';
import { GenericFilterPanel } from './generic-filter-panel';
import { Utils, isPresentAndDisplayed } from '../../../utilities/utils';
export class CreatedDateFilter extends GenericFilterPanel {
constructor() {
super('Created date');
}
fromField: ElementFinder = this.panelExpanded.element(
by.cssContainingText('.adf-search-date-range .mat-form-field', 'From')
);
fromInput: ElementFinder = this.fromField.element(
by.css(`[data-automation-id='date-range-from-input']`)
);
fromFieldError: ElementFinder = this.fromField.element(
by.css(`[data-automation-id='date-range-from-error']`)
);
toField: ElementFinder = this.panelExpanded.element(
by.cssContainingText('.adf-search-date-range .mat-form-field', 'To')
);
toInput: ElementFinder = this.toField.element(
by.css(`[data-automation-id='date-range-to-input']`)
);
toFieldError: ElementFinder = this.toField.element(
by.css(`[data-automation-id='date-range-to-error']`)
);
clearButton: ElementFinder = this.panel.element(
by.css('.adf-facet-buttons [data-automation-id="date-range-clear-btn"]')
);
applyButton: ElementFinder = this.panel.element(
by.css('.adf-facet-buttons [data-automation-id="date-range-apply-btn"]')
);
async isFromFieldDisplayed(): Promise<boolean> {
return isPresentAndDisplayed(this.fromField);
}
async isFromErrorDisplayed(): Promise<boolean> {
return isPresentAndDisplayed(this.fromFieldError);
}
async isToFieldDisplayed(): Promise<boolean> {
return isPresentAndDisplayed(this.toField);
}
async isToErrorDisplayed(): Promise<boolean> {
return isPresentAndDisplayed(this.toFieldError);
}
async isClearButtonEnabled(): Promise<boolean> {
return this.clearButton.isEnabled();
}
async isApplyButtonEnabled(): Promise<boolean> {
return this.applyButton.isEnabled();
}
async clickClearButton(): Promise<void> {
if (await this.isClearButtonEnabled()) {
await this.clearButton.click();
}
}
async clickApplyButton(): Promise<void> {
if (await this.isApplyButtonEnabled()) {
await this.applyButton.click();
}
}
async getFromValue(): Promise<string> {
try {
const value = await this.fromInput.getAttribute('value');
return value;
} catch (error) {
return '';
}
}
async getFromError(): Promise<string> {
try {
const error = await this.fromFieldError.getText();
return error;
} catch (err) {
return '';
}
}
async getToValue(): Promise<string> {
try {
const value = await this.toInput.getAttribute('value');
return value;
} catch (err) {
return '';
}
}
async getToError(): Promise<string> {
try {
const error = await this.toFieldError.getText();
return error;
} catch (err) {
return '';
}
}
async resetPanel(): Promise<void> {
const fromValue = await this.getFromValue();
const toValue = await this.getToValue();
if (fromValue.length > 0 || toValue.length > 0) {
await this.expandPanel();
await this.clickClearButton();
await this.collapsePanel();
}
}
async enterFromDate(date: string): Promise<void> {
await this.expandPanel();
await Utils.clearFieldWithBackspace(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 this.toInput.sendKeys(date, protractor.Key.TAB);
}
}

View File

@@ -0,0 +1,116 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, ElementArrayFinder, by, browser } from 'protractor';
import { GenericFilterPanel } from './generic-filter-panel';
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"',
facetsFilter: '.adf-facet-result-filter'
};
get facets(): ElementArrayFinder {
return this.panelExpanded.all(by.css(this.locators.checkbox));
}
get selectedFacets(): ElementArrayFinder {
return this.panel.all(by.css(this.locators.checkboxChecked));
}
get clearButton(): ElementFinder {
return this.panel.element(
by.cssContainingText(this.locators.button, 'Clear all')
);
}
get facetsFilter(): ElementFinder {
return this.panelExpanded.element(by.css(this.locators.facetsFilter));
}
get filterCategoryInput(): ElementFinder {
return this.facetsFilter.element(by.css(this.locators.categoryInput));
}
async getFiltersValues(): Promise<string[]> {
const list: string[] = await this.facets.map(option => {
return option.getText();
});
return list;
}
async getFiltersCheckedValues(): Promise<string[]> {
const list: string[] = await this.selectedFacets.map(option => {
return option.getText();
});
return list;
}
async resetPanel(): Promise<void> {
if ((await this.selectedFacets.count()) > 0) {
await this.expandPanel();
await this.selectedFacets.each(async elem => {
await elem.click();
});
}
await this.expandPanel();
}
async isFilterFacetsDisplayed(): Promise<boolean> {
return this.facetsFilter.isDisplayed();
}
async isClearButtonEnabled(): Promise<boolean> {
return this.clearButton.isEnabled();
}
async clickClearButton(): Promise<void> {
if (await this.isClearButtonEnabled()) {
await this.clearButton.click();
}
}
async isFilterCategoryInputDisplayed(): Promise<boolean> {
return this.filterCategoryInput.isDisplayed();
}
async checkCategory(name: string): Promise<void> {
const option = this.facets
.filter(async elem => (await elem.getText()).includes(name))
.first();
await browser.executeScript(`arguments[0].scrollIntoView();`, option);
await browser
.actions()
.mouseMove(option)
.perform();
await browser
.actions()
.click()
.perform();
}
async filterCategoriesBy(name: string): Promise<void> {
await this.filterCategoryInput.sendKeys(name);
}
}

View File

@@ -0,0 +1,81 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, browser } from 'protractor';
import { isPresentAndDisplayed } from '../../../utilities/utils';
export class GenericFilterPanel {
private filterName: string;
constructor(filterName: string) {
this.filterName = filterName;
}
private readonly selectors = {
root: 'adf-search-filter',
panel: '.mat-expansion-panel',
panelExpanded: '.mat-expansion-panel.mat-expanded',
panelHeader: '.mat-expansion-panel-header'
};
get panel(): ElementFinder {
return browser.element(
by.cssContainingText(this.selectors.panel, this.filterName)
);
}
get panelExpanded(): ElementFinder {
return browser.element(
by.cssContainingText(this.selectors.panelExpanded, this.filterName)
);
}
get panelHeader(): ElementFinder {
return this.panel.element(by.css(this.selectors.panelHeader));
}
async clickPanelHeader(): Promise<void> {
await this.panelHeader.click();
}
async isPanelDisplayed(): Promise<boolean> {
return isPresentAndDisplayed(this.panel);
}
async isPanelExpanded(): Promise<boolean> {
return isPresentAndDisplayed(this.panelExpanded);
}
async expandPanel(): Promise<void> {
if (!(await this.isPanelExpanded())) {
await this.clickPanelHeader();
}
}
async collapsePanel(): Promise<void> {
if (await this.isPanelExpanded()) {
await this.clickPanelHeader();
}
}
}

View File

@@ -0,0 +1,103 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, ElementArrayFinder } from 'protractor';
import { GenericFilterPanel } from './generic-filter-panel';
export class SizeFilter extends GenericFilterPanel {
constructor() {
super('Size');
}
facets: ElementArrayFinder = this.panelExpanded.all(by.css('.mat-checkbox'));
selectedFacets: ElementArrayFinder = this.panel.all(
by.css('.mat-checkbox.mat-checkbox-checked')
);
clearButton: ElementFinder = this.panel.element(
by.cssContainingText('.adf-facet-buttons button', 'Clear all')
);
async getFiltersValues(): Promise<string[]> {
const list: string[] = await this.facets.map(option => {
return option.getText();
});
return list;
}
async getFiltersCheckedValues(): Promise<string[]> {
const list: string[] = await this.selectedFacets.map(option => {
return option.getText();
});
return list;
}
async resetPanel(): Promise<void> {
if ((await this.selectedFacets.count()) > 0) {
await this.expandPanel();
await this.selectedFacets.each(async elem => {
await elem.click();
});
}
await this.collapsePanel();
}
async isClearButtonEnabled(): Promise<boolean> {
return this.clearButton.isEnabled();
}
async clickClearButton(): Promise<void> {
if (await this.isClearButtonEnabled()) {
await this.clearButton.click();
}
}
async checkSizeSmall(): Promise<void> {
const small = this.facets
.filter(async elem => (await elem.getText()) === 'Small')
.first();
await small.click();
}
async checkSizeMedium(): Promise<void> {
const medium = this.facets
.filter(async elem => (await elem.getText()) === 'Medium')
.first();
await medium.click();
}
async checkSizeLarge(): Promise<void> {
const large = this.facets
.filter(async elem => (await elem.getText()) === 'Large')
.first();
await large.click();
}
async checkSizeHuge(): Promise<void> {
const huge = this.facets
.filter(async elem => (await elem.getText()) === 'Huge')
.first();
await huge.click();
}
}

View File

@@ -0,0 +1,32 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
export * from './filters/created-date-filter';
export * from './filters/facet-filter';
export * from './filters/generic-filter-panel';
export * from './filters/size-filter';
export * from './search-filters';
export * from './search-input';
export * from './search-sorting-picker';

View File

@@ -0,0 +1,52 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser } from 'protractor';
import { Component } from '../component';
import { SizeFilter } from './filters/size-filter';
import { CreatedDateFilter } from './filters/created-date-filter';
import { FacetFilter } from './filters/facet-filter';
import { isPresentAndDisplayed } from '../../utilities/utils';
export class SearchFilters extends Component {
mainPanel = browser.element(by.css('adf-search-filter'));
resetAllButton = this.byCssText('.mat-button', 'Reset all');
size = new SizeFilter();
createdDate = new CreatedDateFilter();
fileType = new FacetFilter('File type');
creator = new FacetFilter('Creator');
modifier = new FacetFilter('Modifier');
location = new FacetFilter('Location');
modifiedDate = new FacetFilter('Modified date');
constructor(ancestor?: string) {
super('adf-search-filter', ancestor);
}
async isSearchFiltersPanelDisplayed(): Promise<boolean> {
return isPresentAndDisplayed(this.mainPanel);
}
}

View File

@@ -0,0 +1,176 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { browser, by, protractor } from 'protractor';
import { Component } from '../component';
import {
Utils,
waitForPresence,
waitForClickable,
waitElement
} from '../../utilities/utils';
export class SearchInput extends Component {
searchButton = this.component.element(by.css('.app-search-button'));
searchContainer = browser.element(by.css('.app-search-container'));
searchControl = browser.element(by.css('.app-search-control'));
searchInput = browser.element(by.css(`input[id='app-control-input']`));
searchOptionsArea = browser.element(by.id('search-options'));
searchFilesOption = this.searchOptionsArea.element(
by.cssContainingText('.mat-checkbox', 'Files')
);
searchFoldersOption = this.searchOptionsArea.element(
by.cssContainingText('.mat-checkbox', 'Folders')
);
searchLibrariesOption = this.searchOptionsArea.element(
by.cssContainingText('.mat-checkbox', 'Libraries')
);
clearSearchButton = this.searchContainer.$('.app-clear-icon');
constructor(ancestor?: string) {
super('aca-search-input', ancestor);
}
async waitForSearchControl() {
await waitForPresence(this.searchControl);
}
async waitForSearchInputToBeInteractive() {
await waitForClickable(this.searchControl);
}
async isSearchContainerDisplayed() {
const isContainerDisplayed = await this.searchContainer.isDisplayed();
const isSearchButtonDisplayed = await this.searchButton.isDisplayed();
return isContainerDisplayed && isSearchButtonDisplayed;
}
async clickSearchButton() {
await waitForClickable(this.searchButton);
await this.searchButton.click();
await this.waitForSearchControl();
}
async isOptionsAreaDisplayed() {
await waitElement('.app-search-control');
return browser.isElementPresent(this.searchOptionsArea);
}
async clickFilesOption() {
await waitForClickable(this.searchFilesOption);
await this.searchFilesOption.click();
}
async clickFoldersOption() {
await waitForClickable(this.searchFoldersOption);
await this.searchFoldersOption.click();
}
async clickLibrariesOption() {
await waitForClickable(this.searchLibrariesOption);
await this.searchLibrariesOption.click();
}
async isFilesOptionEnabled() {
const optClass = await this.searchFilesOption.getAttribute('class');
return !optClass.includes('mat-checkbox-disabled');
}
async isFoldersOptionEnabled() {
const optClass = await this.searchFoldersOption.getAttribute('class');
return !optClass.includes('mat-checkbox-disabled');
}
async isLibrariesOptionEnabled() {
const optClass = await this.searchLibrariesOption.getAttribute('class');
return !optClass.includes('mat-checkbox-disabled');
}
async isFilesOptionChecked() {
const optClass = await this.searchFilesOption.getAttribute('class');
return optClass.includes('mat-checkbox-checked');
}
async isFoldersOptionChecked() {
const optClass = await this.searchFoldersOption.getAttribute('class');
return optClass.includes('mat-checkbox-checked');
}
async isLibrariesOptionChecked() {
const optClass = await this.searchLibrariesOption.getAttribute('class');
return optClass.includes('mat-checkbox-checked');
}
async clearOptions() {
if (await this.isFilesOptionChecked()) {
await this.clickFilesOption();
}
if (await this.isFoldersOptionChecked()) {
await this.clickFoldersOption();
}
if (await this.isLibrariesOptionChecked()) {
await this.clickLibrariesOption();
}
}
async isClearSearchButtonPresent() {
return browser.isElementPresent(this.clearSearchButton);
}
async clickClearSearchButton() {
if (await this.isClearSearchButtonPresent()) {
await this.clearSearchButton.click();
}
}
async checkOnlyFiles() {
await this.clearOptions();
await this.clickFilesOption();
}
async checkOnlyFolders() {
await this.clearOptions();
await this.clickFoldersOption();
}
async checkFilesAndFolders() {
await this.clearOptions();
await this.clickFilesOption();
await this.clickFoldersOption();
}
async checkLibraries() {
await this.clearOptions();
await this.clickLibrariesOption();
}
async searchFor(text: string) {
await this.waitForSearchInputToBeInteractive();
await Utils.clearFieldWithBackspace(this.searchInput);
await this.searchInput.sendKeys(text);
await this.searchInput.sendKeys(protractor.Key.ENTER);
}
}

View File

@@ -0,0 +1,125 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser } from 'protractor';
import { Component } from '../component';
import {
isPresentAndDisplayed,
waitForVisibility
} from '../../utilities/utils';
export type SortByType =
| 'Relevance'
| 'Title'
| 'Filename'
| 'Modified date'
| 'Modifier'
| 'Created date'
| 'Size'
| 'Type';
export type SortOrderType = 'ASC' | 'DESC' | '';
export class SearchSortingPicker extends Component {
sortOrderButton = this.byCss('button[mat-icon-button]');
sortByDropdownCollapsed = this.byCss('.mat-select');
sortByDropdownExpanded = browser.element(by.css('.mat-select-panel'));
sortByList = this.sortByDropdownExpanded.all(
by.css('.mat-option .mat-option-text')
);
constructor(ancestor?: string) {
super('adf-search-sorting-picker', ancestor);
}
async waitForSortByDropdownToExpand(): Promise<void> {
await waitForVisibility(
this.sortByDropdownExpanded,
'Timeout waiting for sortBy dropdown to expand'
);
}
async isSortOrderButtonDisplayed(): Promise<boolean> {
return isPresentAndDisplayed(this.sortOrderButton);
}
async getSortOrder(): Promise<SortOrderType> {
const orderArrow = await this.sortOrderButton.getText();
if (orderArrow.includes('upward')) {
return 'ASC';
} else if (orderArrow.includes('downward')) {
return 'DESC';
} else {
return '';
}
}
async isSortByOptionDisplayed(): Promise<boolean> {
return isPresentAndDisplayed(this.sortByDropdownCollapsed);
}
async isSortByDropdownExpanded(): Promise<boolean> {
return isPresentAndDisplayed(this.sortByDropdownExpanded);
}
async getSelectedSortByOption(): Promise<string> {
return this.sortByDropdownCollapsed.getText();
}
async clickSortByDropdown(): Promise<void> {
await this.sortByDropdownCollapsed.click();
await this.waitForSortByDropdownToExpand();
}
async getSortByOptionsList(): Promise<string[]> {
const list: string[] = await this.sortByList.map(async option => {
return option.getText();
});
return list;
}
async sortBy(option: SortByType): Promise<void> {
if (!(await this.isSortByDropdownExpanded())) {
await this.clickSortByDropdown();
}
const elem = browser.element(
by.cssContainingText('.mat-option .mat-option-text', option)
);
await elem.click();
}
async setSortOrderASC(): Promise<void> {
if ((await this.getSortOrder()) !== 'ASC') {
await this.sortOrderButton.click();
}
}
async setSortOrderDESC(): Promise<void> {
if ((await this.getSortOrder()) !== 'DESC') {
await this.sortOrderButton.click();
}
}
}

View File

@@ -0,0 +1,174 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, element, browser } from 'protractor';
import { Logger } 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'));
activeLink = this.byCss('.action-button--active');
newButton = this.allByCss('[data-automation-id="create-button"]');
personalFiles = this.byCss(`[data-automation-id='app.navbar.personalFiles']`);
fileLibraries = this.byCss(
`[data-automation-id='app.navbar.libraries.menu']`
);
myLibraries = this.byCss(
`[data-automation-id='app.navbar.libraries.files']`,
browser
);
favoriteLibraries = this.byCss(
`[data-automation-id='app.navbar.libraries.favorite']`,
browser
);
shared = this.byCss(`[data-automation-id='app.navbar.shared']`);
recentFiles = this.byCss(`[data-automation-id='app.navbar.recentFiles']`);
favorites = this.byCss(`[data-automation-id='app.navbar.favorites']`);
trash = this.byCss(`[data-automation-id='app.navbar.trashcan']`);
menu: Menu = new Menu();
constructor(ancestor?: string) {
super('app-sidenav', ancestor);
}
private async expandMenu(name: string): Promise<void> {
try {
if (
await element(by.cssContainingText('.mat-expanded', name)).isPresent()
) {
return Promise.resolve();
} else {
const link = this.getLink(name);
await waitForClickable(link);
await link.click();
await element(by.css('.mat-expansion-panel-body')).isPresent();
}
} catch (e) {
Logger.error('---- sidebar navigation catch expandMenu: ', e);
}
}
async openNewMenu(): Promise<void> {
await this.newButton.click();
await this.menu.waitForMenuToOpen();
}
async openCreateFolderDialog(): Promise<void> {
await this.openNewMenu();
await this.menu.createFolderAction.click();
}
async openCreateLibraryDialog(): Promise<void> {
await this.openNewMenu();
await this.menu.createLibraryAction.click();
}
async openCreateFileFromTemplateDialog(): Promise<void> {
await this.openNewMenu();
await this.menu.createFileFromTemplateAction.click();
}
async openCreateFolderFromTemplateDialog(): Promise<void> {
await this.openNewMenu();
await this.menu.createFolderFromTemplateAction.click();
}
async isActive(name: string): Promise<boolean> {
const cssClass = await this.getLinkLabel(name).getAttribute('class');
return cssClass.includes('action-button--active');
}
async childIsActive(name: string): Promise<boolean> {
const childClass = await this.getLinkLabel(name)
.element(by.css('span'))
.getAttribute('class');
return childClass.includes('action-button--active');
}
getLink(name: string): ElementFinder {
return this.getLinkLabel(name).element(by.xpath('..'));
}
private getLinkLabel(name: string): ElementFinder {
switch (name) {
case 'Personal Files':
return this.personalFiles;
case 'File Libraries':
return this.fileLibraries;
case 'My Libraries':
return this.myLibraries;
case 'Favorite Libraries':
return this.favoriteLibraries;
case 'Shared':
return this.shared;
case 'Recent Files':
return this.recentFiles;
case 'Favorites':
return this.favorites;
case 'Trash':
return this.trash;
default:
return this.personalFiles;
}
}
async getLinkTooltip(name: string): Promise<string> {
const link = this.getLinkLabel(name);
const condition = () =>
link.getAttribute('title').then(value => value && value.length > 0);
await browser
.actions()
.mouseMove(link)
.perform();
await browser.wait(condition, BROWSER_WAIT_TIMEOUT);
return link.getAttribute('title');
}
async clickLink(name: string): Promise<void> {
try {
const link = this.getLinkLabel(name);
await waitForClickable(link);
await link.click();
} catch (error) {
Logger.error('---- sidebar navigation clickLink catch error: ', error);
}
}
async isFileLibrariesMenuExpanded(): Promise<boolean> {
return element(
by.cssContainingText('.mat-expanded', SIDEBAR_LABELS.FILE_LIBRARIES)
).isPresent();
}
async expandFileLibraries(): Promise<void> {
await this.expandMenu(SIDEBAR_LABELS.FILE_LIBRARIES);
}
}

View File

@@ -0,0 +1,154 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, browser } from 'protractor';
import { Menu } from '../menu/menu';
import { Component } from '../component';
import { Utils } from '../../utilities/utils';
export class Toolbar extends Component {
menu = new Menu();
buttons = this.allByCss('button');
shareButton = this.byCss(`.mat-icon-button[title='Share']`);
shareEditButton = this.byCss(
`.mat-icon-button[title='Shared Link Settings']`
);
viewButton = this.byCss(`.mat-icon-button[title='View']`);
searchFiltersToggleButton = this.byCss(
`.mat-icon-button[title='Toggle search filter']`
);
downloadButton = this.byCss(`.mat-icon-button[title='Download']`);
editFolderButton = this.byId('app.toolbar.editFolder');
viewDetailsButton = this.byCss(`.mat-icon-button[title='View Details']`);
printButton = this.byCss(`.mat-icon-button[title='Print']`);
fullScreenButton = this.byCss(
`.mat-icon-button[title='Activate full-screen mode']`
);
joinButton = this.byCss(`.mat-icon-button[title='Join']`);
leaveButton = this.byCss(`.mat-icon-button[title='Leave Library']`);
permanentlyDeleteButton = this.byCss(
`.mat-icon-button[title='Permanently Delete']`
);
restoreButton = this.byCss(`.mat-icon-button[title='Restore']`);
constructor(ancestor?: string) {
super('.adf-toolbar', ancestor);
}
async isEmpty(): Promise<boolean> {
const count = await this.buttons.count();
return count === 0;
}
async getButtons(): Promise<string[]> {
return this.buttons.map(async elem => {
return elem.getAttribute('title');
});
}
async isButtonPresent(title: string) {
const element = this.byCss(`button[title="${title}"]`);
return element.isPresent();
}
getButtonByTitleAttribute(title: string) {
return this.byCss(`button[title="${title}"]`);
}
getButtonById(id: string) {
return this.component.element(by.id(id));
}
async openMoreMenu(): Promise<void> {
await this.isButtonPresent('More Actions');
const moreMenu = this.getButtonByTitleAttribute('More Actions');
await moreMenu.click();
await this.menu.waitForMenuToOpen();
}
async closeMoreMenu() {
await Utils.pressEscape();
}
async getButtonTooltip(button: ElementFinder): Promise<string> {
return button.getAttribute('title');
}
async clickButton(title: string): Promise<void> {
await this.getButtonByTitleAttribute(title).click();
}
async isPrintPresent() {
return browser.isElementPresent(this.printButton);
}
async clickMoreActionsFavorite(): Promise<void> {
await this.openMoreMenu();
await this.menu.clickMenuItem('Favorite');
}
async clickMoreActionsRemoveFavorite(): Promise<void> {
await this.openMoreMenu();
await this.menu.clickMenuItem('Remove Favorite');
}
async clickMoreActionsDelete(): Promise<void> {
await this.openMoreMenu();
await this.menu.clickMenuItem('Delete');
}
async clickMoreActionsManageVersions(): Promise<void> {
await this.openMoreMenu();
await this.menu.clickMenuItem('Manage Versions');
}
async clickMoreActionsMove(): Promise<void> {
await this.openMoreMenu();
await this.menu.clickMenuItem('Move');
}
async clickMoreActionsCopy(): Promise<void> {
await this.openMoreMenu();
await this.menu.clickMenuItem('Copy');
}
async clickMoreActionsEditOffline(): Promise<void> {
await this.openMoreMenu();
await this.menu.clickMenuItem('Edit Offline');
}
async clickMoreActionsCancelEditing(): Promise<void> {
await this.openMoreMenu();
await this.menu.clickMenuItem('Cancel Editing');
}
async clickMoreActionsUploadNewVersion(): Promise<void> {
await this.openMoreMenu();
await this.menu.clickMenuItem('Upload New Version');
}
}

View File

@@ -0,0 +1,96 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { browser } from 'protractor';
import { Logger } from '@alfresco/adf-testing';
import { Component } from '../component';
import { Toolbar } from '../toolbar/toolbar';
import { waitForPresence } from '../../utilities/utils';
export class Viewer extends Component {
root = browser.$('adf-viewer');
viewerLayout = this.byCss('.adf-viewer-layout-content');
viewerContainer = this.byCss('.adf-viewer-content-container');
closeButton = this.byCss('.adf-viewer-close-button');
fileTitle = this.byCss('.adf-viewer__file-title');
viewerExtensionContent = this.byCss('adf-preview-extension');
pdfViewerContentPages = this.allByCss('.adf-pdf-viewer__content .page');
toolbar = new Toolbar('adf-viewer');
constructor(ancestor?: string) {
super('adf-viewer', ancestor);
}
async waitForViewerToOpen() {
try {
await waitForPresence(this.viewerContainer);
await waitForPresence(this.viewerLayout);
} catch (error) {
Logger.error('\n-----> catch waitForViewerToOpen <-----\n', error);
}
}
async isViewerOpened() {
return browser.isElementPresent(this.viewerLayout);
}
async isViewerToolbarDisplayed() {
return browser.isElementPresent(this.toolbar.component);
}
async isCloseButtonDisplayed() {
return browser.isElementPresent(this.closeButton);
}
async isFileTitleDisplayed() {
return browser.isElementPresent(this.fileTitle);
}
async getCloseButtonTooltip(): Promise<string> {
return this.toolbar.getButtonTooltip(this.closeButton);
}
async getFileTitle(): Promise<string> {
return this.fileTitle.getText();
}
async isCustomContentPresent() {
return browser.isElementPresent(this.viewerExtensionContent);
}
async getComponentIdOfView(): Promise<string> {
if (await this.isCustomContentPresent()) {
return this.viewerExtensionContent.getAttribute('data-automation-id');
}
return '';
}
async isPdfViewerContentDisplayed(): Promise<boolean> {
const count = await this.pdfViewerContentPages.count();
return count > 0;
}
}