mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-07-24 17:31:52 +00:00
[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:
9
projects/aca-testing-shared/package.json
Normal file
9
projects/aca-testing-shared/package.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "aca-testing-shared",
|
||||
"version": "1.11.1",
|
||||
"main": "src/index.ts",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^7.2.0",
|
||||
"@angular/core": "^7.2.0"
|
||||
}
|
||||
}
|
48
projects/aca-testing-shared/src/components/breadcrumb/breadcrumb.ts
Executable file
48
projects/aca-testing-shared/src/components/breadcrumb/breadcrumb.ts
Executable 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();
|
||||
}
|
||||
}
|
73
projects/aca-testing-shared/src/components/breadcrumb/dropdown-breadcrumb.ts
Executable file
73
projects/aca-testing-shared/src/components/breadcrumb/dropdown-breadcrumb.ts
Executable 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;
|
||||
}
|
||||
}
|
82
projects/aca-testing-shared/src/components/component.ts
Executable file
82
projects/aca-testing-shared/src/components/component.ts
Executable 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);
|
||||
}
|
||||
}
|
37
projects/aca-testing-shared/src/components/components.ts
Executable file
37
projects/aca-testing-shared/src/components/components.ts
Executable 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';
|
558
projects/aca-testing-shared/src/components/data-table/data-table.ts
Executable file
558
projects/aca-testing-shared/src/components/data-table/data-table.ts
Executable 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();
|
||||
}
|
||||
}
|
@@ -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}`;
|
||||
}
|
||||
}
|
64
projects/aca-testing-shared/src/components/dialog/confirm-dialog.ts
Executable file
64
projects/aca-testing-shared/src/components/dialog/confirm-dialog.ts
Executable 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);
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
120
projects/aca-testing-shared/src/components/dialog/create-library-dialog.ts
Executable file
120
projects/aca-testing-shared/src/components/dialog/create-library-dialog.ts
Executable 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);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
36
projects/aca-testing-shared/src/components/dialog/index.ts
Normal file
36
projects/aca-testing-shared/src/components/dialog/index.ts
Normal 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';
|
40
projects/aca-testing-shared/src/components/dialog/manage-versions-dialog.ts
Executable file
40
projects/aca-testing-shared/src/components/dialog/manage-versions-dialog.ts
Executable 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();
|
||||
}
|
||||
}
|
101
projects/aca-testing-shared/src/components/dialog/password-dialog.ts
Executable file
101
projects/aca-testing-shared/src/components/dialog/password-dialog.ts
Executable 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);
|
||||
}
|
||||
}
|
65
projects/aca-testing-shared/src/components/dialog/select-template-dialog.ts
Executable file
65
projects/aca-testing-shared/src/components/dialog/select-template-dialog.ts
Executable 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();
|
||||
}
|
||||
}
|
110
projects/aca-testing-shared/src/components/dialog/share-dialog.ts
Executable file
110
projects/aca-testing-shared/src/components/dialog/share-dialog.ts
Executable 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');
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
76
projects/aca-testing-shared/src/components/header/header.ts
Executable file
76
projects/aca-testing-shared/src/components/header/header.ts
Executable 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']`);
|
||||
}
|
||||
}
|
||||
}
|
50
projects/aca-testing-shared/src/components/header/user-info.ts
Executable file
50
projects/aca-testing-shared/src/components/header/user-info.ts
Executable 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');
|
||||
}
|
||||
}
|
43
projects/aca-testing-shared/src/components/index.ts
Normal file
43
projects/aca-testing-shared/src/components/index.ts
Normal 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';
|
@@ -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';
|
@@ -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');
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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');
|
||||
}
|
||||
}
|
141
projects/aca-testing-shared/src/components/info-drawer/info-drawer.ts
Executable file
141
projects/aca-testing-shared/src/components/info-drawer/info-drawer.ts
Executable 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);
|
||||
}
|
||||
}
|
||||
}
|
75
projects/aca-testing-shared/src/components/login/login.ts
Executable file
75
projects/aca-testing-shared/src/components/login/login.ts
Executable 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());
|
||||
}
|
||||
}
|
267
projects/aca-testing-shared/src/components/menu/menu.ts
Executable file
267
projects/aca-testing-shared/src/components/menu/menu.ts
Executable 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);
|
||||
}
|
||||
}
|
@@ -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');
|
||||
}
|
||||
}
|
157
projects/aca-testing-shared/src/components/pagination/pagination.ts
Executable file
157
projects/aca-testing-shared/src/components/pagination/pagination.ts
Executable 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();
|
||||
}
|
||||
}
|
153
projects/aca-testing-shared/src/components/search/filters/created-date-filter.ts
Executable file
153
projects/aca-testing-shared/src/components/search/filters/created-date-filter.ts
Executable 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);
|
||||
}
|
||||
}
|
116
projects/aca-testing-shared/src/components/search/filters/facet-filter.ts
Executable file
116
projects/aca-testing-shared/src/components/search/filters/facet-filter.ts
Executable 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);
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
103
projects/aca-testing-shared/src/components/search/filters/size-filter.ts
Executable file
103
projects/aca-testing-shared/src/components/search/filters/size-filter.ts
Executable 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();
|
||||
}
|
||||
}
|
32
projects/aca-testing-shared/src/components/search/index.ts
Normal file
32
projects/aca-testing-shared/src/components/search/index.ts
Normal 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';
|
52
projects/aca-testing-shared/src/components/search/search-filters.ts
Executable file
52
projects/aca-testing-shared/src/components/search/search-filters.ts
Executable 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);
|
||||
}
|
||||
}
|
176
projects/aca-testing-shared/src/components/search/search-input.ts
Executable file
176
projects/aca-testing-shared/src/components/search/search-input.ts
Executable 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);
|
||||
}
|
||||
}
|
125
projects/aca-testing-shared/src/components/search/search-sorting-picker.ts
Executable file
125
projects/aca-testing-shared/src/components/search/search-sorting-picker.ts
Executable 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();
|
||||
}
|
||||
}
|
||||
}
|
174
projects/aca-testing-shared/src/components/sidenav/sidenav.ts
Executable file
174
projects/aca-testing-shared/src/components/sidenav/sidenav.ts
Executable 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);
|
||||
}
|
||||
}
|
154
projects/aca-testing-shared/src/components/toolbar/toolbar.ts
Executable file
154
projects/aca-testing-shared/src/components/toolbar/toolbar.ts
Executable 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');
|
||||
}
|
||||
}
|
96
projects/aca-testing-shared/src/components/viewer/viewer.ts
Executable file
96
projects/aca-testing-shared/src/components/viewer/viewer.ts
Executable 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;
|
||||
}
|
||||
}
|
122
projects/aca-testing-shared/src/configs.ts
Executable file
122
projects/aca-testing-shared/src/configs.ts
Executable file
@@ -0,0 +1,122 @@
|
||||
/*!
|
||||
* @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 const BROWSER_WAIT_TIMEOUT = 10000;
|
||||
|
||||
// Application configs
|
||||
export const USE_HASH_STRATEGY = true;
|
||||
|
||||
// Dates
|
||||
export const DATE_FORMAT = 'MMM D, YYYY';
|
||||
export const DATE_TIME_FORMAT = 'MMM D, YYYY, H:mm';
|
||||
|
||||
// Application Routes
|
||||
export const APP_ROUTES = {
|
||||
FAVORITES: '/favorites',
|
||||
MY_LIBRARIES: '/libraries',
|
||||
FAVORITE_LIBRARIES: '/favorite/libraries',
|
||||
LOGIN: '/login',
|
||||
LOGOUT: '/logout',
|
||||
PERSONAL_FILES: '/personal-files',
|
||||
RECENT_FILES: '/recent-files',
|
||||
SHARED_FILES: '/shared',
|
||||
TRASHCAN: '/trashcan'
|
||||
};
|
||||
|
||||
// Sidebar labels
|
||||
export const SIDEBAR_LABELS = {
|
||||
PERSONAL_FILES: 'Personal Files',
|
||||
FILE_LIBRARIES: 'File Libraries',
|
||||
MY_LIBRARIES: 'My Libraries',
|
||||
FAVORITE_LIBRARIES: 'Favorite Libraries',
|
||||
SHARED_FILES: 'Shared',
|
||||
RECENT_FILES: 'Recent Files',
|
||||
FAVORITES: 'Favorites',
|
||||
TRASH: 'Trash'
|
||||
};
|
||||
|
||||
// Page titles
|
||||
export const PAGE_TITLES = {
|
||||
PERSONAL_FILES: 'Personal Files',
|
||||
MY_LIBRARIES: 'My Libraries',
|
||||
FAVORITE_LIBRARIES: 'Favorite Libraries',
|
||||
SHARED_FILES: 'Shared',
|
||||
RECENT_FILES: 'Recent Files',
|
||||
FAVORITES: 'Favorites',
|
||||
TRASH: 'Trash',
|
||||
VIEWER: 'Preview',
|
||||
SEARCH: 'Search Results'
|
||||
};
|
||||
|
||||
// Site visibility
|
||||
export const SITE_VISIBILITY = {
|
||||
PUBLIC: 'PUBLIC',
|
||||
MODERATED: 'MODERATED',
|
||||
PRIVATE: 'PRIVATE'
|
||||
};
|
||||
|
||||
// Site roles
|
||||
export const SITE_ROLES = {
|
||||
SITE_CONSUMER: {
|
||||
ROLE: 'SiteConsumer',
|
||||
LABEL: 'Consumer'
|
||||
},
|
||||
SITE_COLLABORATOR: {
|
||||
ROLE: 'SiteCollaborator',
|
||||
LABEL: 'Collaborator'
|
||||
},
|
||||
SITE_CONTRIBUTOR: {
|
||||
ROLE: 'SiteContributor',
|
||||
LABEL: 'Contributor'
|
||||
},
|
||||
SITE_MANAGER: {
|
||||
ROLE: 'SiteManager',
|
||||
LABEL: 'Manager'
|
||||
}
|
||||
};
|
||||
|
||||
export const FILES = {
|
||||
docxFile: 'file-docx.docx',
|
||||
docxFile2: 'file2-docx.docx',
|
||||
xlsxFile: 'file-xlsx.xlsx',
|
||||
xlsxFile2: 'file2-xlsx.xlsx',
|
||||
pdfFile: 'file-pdf.pdf',
|
||||
unsupportedFile: 'file_unsupported.3DS',
|
||||
protectedFile: {
|
||||
name: 'protected.pdf',
|
||||
password: '0000'
|
||||
},
|
||||
jpgFile: 'file-jpg.jpg'
|
||||
};
|
||||
|
||||
export const EXTENSIBILITY_CONFIGS = {
|
||||
DEFAULT_EXTENSIONS_CONFIG: 'extensions-default.json',
|
||||
INFO_DRAWER: 'info-drawer-ext.json',
|
||||
INFO_DRAWER_EMPTY: 'info-drawer-no-tabs-ext.json',
|
||||
VIEWER: 'viewer-ext.json',
|
||||
HEADER: 'header-ext.json',
|
||||
METADATA_PRESETS: 'metadata-ext.json',
|
||||
DOCUMENT_LIST_PRESETS: 'document-presets-ext.json',
|
||||
CONTEXT_SUBMENUS: 'context-submenus-ext.json'
|
||||
};
|
29
projects/aca-testing-shared/src/index.ts
Normal file
29
projects/aca-testing-shared/src/index.ts
Normal 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 './components';
|
||||
export * from './pages';
|
||||
export * from './utilities';
|
||||
export * from './configs';
|
126
projects/aca-testing-shared/src/pages/browsing-page.ts
Executable file
126
projects/aca-testing-shared/src/pages/browsing-page.ts
Executable file
@@ -0,0 +1,126 @@
|
||||
/*!
|
||||
* @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 {
|
||||
Header,
|
||||
DataTable,
|
||||
Pagination,
|
||||
Toolbar,
|
||||
Breadcrumb,
|
||||
Sidenav
|
||||
} from '../components/components';
|
||||
import { SIDEBAR_LABELS } from './../configs';
|
||||
import { Page } from './page';
|
||||
|
||||
export class BrowsingPage extends Page {
|
||||
header = new Header(this.appRoot);
|
||||
sidenav = new Sidenav(this.appRoot);
|
||||
toolbar = new Toolbar(this.appRoot);
|
||||
breadcrumb = new Breadcrumb(this.appRoot);
|
||||
dataTable = new DataTable(this.appRoot);
|
||||
pagination = new Pagination(this.appRoot);
|
||||
|
||||
async signOut(): Promise<void> {
|
||||
await this.header.userInfo.signOut();
|
||||
}
|
||||
|
||||
async clickPersonalFiles(): Promise<void> {
|
||||
await this.sidenav.clickLink(SIDEBAR_LABELS.PERSONAL_FILES);
|
||||
}
|
||||
|
||||
async clickPersonalFilesAndWait(): Promise<void> {
|
||||
await this.clickPersonalFiles();
|
||||
await this.dataTable.waitForHeader();
|
||||
}
|
||||
|
||||
async clickFileLibraries(): Promise<void> {
|
||||
await this.sidenav.clickLink(SIDEBAR_LABELS.FILE_LIBRARIES);
|
||||
}
|
||||
|
||||
async clickFileLibrariesAndWait(): Promise<void> {
|
||||
await this.clickFileLibraries();
|
||||
await this.dataTable.waitForHeader();
|
||||
}
|
||||
|
||||
async goToFavoriteLibraries(): Promise<void> {
|
||||
if (!(await this.sidenav.isFileLibrariesMenuExpanded())) {
|
||||
await this.sidenav.expandFileLibraries();
|
||||
}
|
||||
await this.sidenav.clickLink(SIDEBAR_LABELS.FAVORITE_LIBRARIES);
|
||||
}
|
||||
|
||||
async goToFavoriteLibrariesAndWait(): Promise<void> {
|
||||
await this.goToFavoriteLibraries();
|
||||
await this.dataTable.waitForHeader();
|
||||
}
|
||||
|
||||
async goToMyLibraries(): Promise<void> {
|
||||
if (!(await this.sidenav.isFileLibrariesMenuExpanded())) {
|
||||
await this.sidenav.expandFileLibraries();
|
||||
}
|
||||
await this.sidenav.clickLink(SIDEBAR_LABELS.MY_LIBRARIES);
|
||||
}
|
||||
|
||||
async goToMyLibrariesAndWait(): Promise<void> {
|
||||
await this.goToMyLibraries();
|
||||
await this.dataTable.waitForHeader();
|
||||
}
|
||||
|
||||
async clickRecentFiles(): Promise<void> {
|
||||
await this.sidenav.clickLink(SIDEBAR_LABELS.RECENT_FILES);
|
||||
}
|
||||
|
||||
async clickRecentFilesAndWait(): Promise<void> {
|
||||
await this.clickRecentFiles();
|
||||
await this.dataTable.waitForHeader();
|
||||
}
|
||||
|
||||
async clickSharedFiles(): Promise<void> {
|
||||
await this.sidenav.clickLink(SIDEBAR_LABELS.SHARED_FILES);
|
||||
}
|
||||
|
||||
async clickSharedFilesAndWait(): Promise<void> {
|
||||
await this.clickSharedFiles();
|
||||
await this.dataTable.waitForHeader();
|
||||
}
|
||||
|
||||
async clickFavorites(): Promise<void> {
|
||||
await this.sidenav.clickLink(SIDEBAR_LABELS.FAVORITES);
|
||||
}
|
||||
|
||||
async clickFavoritesAndWait(): Promise<void> {
|
||||
await this.clickFavorites();
|
||||
await this.dataTable.waitForHeader();
|
||||
}
|
||||
|
||||
async clickTrash(): Promise<void> {
|
||||
await this.sidenav.clickLink(SIDEBAR_LABELS.TRASH);
|
||||
}
|
||||
|
||||
async clickTrashAndWait(): Promise<void> {
|
||||
await this.clickTrash();
|
||||
await this.dataTable.waitForHeader();
|
||||
}
|
||||
}
|
28
projects/aca-testing-shared/src/pages/index.ts
Executable file
28
projects/aca-testing-shared/src/pages/index.ts
Executable file
@@ -0,0 +1,28 @@
|
||||
/*!
|
||||
* @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 './browsing-page';
|
||||
export * from './login-page';
|
||||
export * from './search-results-page';
|
67
projects/aca-testing-shared/src/pages/login-page.ts
Executable file
67
projects/aca-testing-shared/src/pages/login-page.ts
Executable file
@@ -0,0 +1,67 @@
|
||||
/*!
|
||||
* @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 { LoginComponent } from '../components/components';
|
||||
import { Page } from './page';
|
||||
|
||||
import { APP_ROUTES } from '../configs';
|
||||
import { waitForPresence } from '../utilities/utils';
|
||||
|
||||
export class LoginPage extends Page {
|
||||
login = new LoginComponent(this.appRoot);
|
||||
|
||||
constructor() {
|
||||
super(APP_ROUTES.LOGIN);
|
||||
}
|
||||
|
||||
async load() {
|
||||
await super.load();
|
||||
await waitForPresence(this.login.submitButton);
|
||||
}
|
||||
|
||||
async loginWith(username: string, password?: string) {
|
||||
const pass = password || username;
|
||||
await this.load();
|
||||
await this.login.enterCredentials(username, pass);
|
||||
await this.login.submitButton.click();
|
||||
return super.waitForApp();
|
||||
}
|
||||
|
||||
async loginWithAdmin() {
|
||||
await this.load();
|
||||
return this.loginWith(
|
||||
browser.params.ADMIN_USERNAME,
|
||||
browser.params.ADMIN_PASSWORD
|
||||
);
|
||||
}
|
||||
|
||||
async tryLoginWith(username: string, password?: string) {
|
||||
const pass = password || username;
|
||||
await this.load();
|
||||
await this.login.enterCredentials(username, pass);
|
||||
await this.login.submitButton.click();
|
||||
await waitForPresence(this.login.errorMessage);
|
||||
}
|
||||
}
|
97
projects/aca-testing-shared/src/pages/page.ts
Executable file
97
projects/aca-testing-shared/src/pages/page.ts
Executable 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 { browser, by, ElementFinder } from 'protractor';
|
||||
import { Logger } from '@alfresco/adf-testing';
|
||||
import { USE_HASH_STRATEGY } from './../configs';
|
||||
import {
|
||||
Utils,
|
||||
waitElement,
|
||||
waitForPresence,
|
||||
waitForVisibility
|
||||
} from '../utilities/utils';
|
||||
|
||||
export abstract class Page {
|
||||
appRoot = 'app-root';
|
||||
|
||||
layout = this.byCss('app-layout');
|
||||
overlay = this.byCss('.cdk-overlay-container');
|
||||
snackBar = this.byCss('.mat-simple-snackbar-action button');
|
||||
dialogContainer = this.byCss('.mat-dialog-container');
|
||||
snackBarContainer = this.byCss('.mat-snack-bar-container');
|
||||
snackBarAction = this.byCss('.mat-simple-snackbar-action button');
|
||||
genericError = this.byCss('aca-generic-error');
|
||||
genericErrorIcon = this.byCss('aca-generic-error .mat-icon');
|
||||
genericErrorTitle = this.byCss('.generic-error__title');
|
||||
|
||||
constructor(public url: string = '') {}
|
||||
|
||||
protected byCss(css: string): ElementFinder {
|
||||
return browser.element(by.css(css));
|
||||
}
|
||||
|
||||
async load(relativeUrl: string = '') {
|
||||
const hash = USE_HASH_STRATEGY ? '/#' : '';
|
||||
const path = `${browser.baseUrl}${hash}${this.url}${relativeUrl}`;
|
||||
return browser.get(path);
|
||||
}
|
||||
|
||||
async waitForApp() {
|
||||
await waitForPresence(this.layout);
|
||||
}
|
||||
|
||||
async waitForDialog() {
|
||||
await waitForVisibility(this.dialogContainer);
|
||||
}
|
||||
|
||||
async isDialogOpen() {
|
||||
return browser.isElementPresent(this.dialogContainer);
|
||||
}
|
||||
|
||||
async closeOpenDialogs() {
|
||||
while (await this.isDialogOpen()) {
|
||||
await Utils.pressEscape();
|
||||
}
|
||||
}
|
||||
|
||||
async refresh(): Promise<void> {
|
||||
await browser.refresh();
|
||||
await this.waitForApp();
|
||||
}
|
||||
|
||||
async getSnackBarMessage(): Promise<string> {
|
||||
const elem = await waitElement('.mat-snack-bar-container');
|
||||
return elem.getAttribute('innerText');
|
||||
}
|
||||
|
||||
async clickSnackBarAction(): Promise<void> {
|
||||
try {
|
||||
const action = await waitElement('.mat-simple-snackbar-action button');
|
||||
await action.click();
|
||||
} catch (e) {
|
||||
Logger.error(e, '.......failed on click snack bar action.........');
|
||||
}
|
||||
}
|
||||
}
|
60
projects/aca-testing-shared/src/pages/search-results-page.ts
Executable file
60
projects/aca-testing-shared/src/pages/search-results-page.ts
Executable file
@@ -0,0 +1,60 @@
|
||||
/*!
|
||||
* @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, By } from 'protractor';
|
||||
import { BrowsingPage } from './browsing-page';
|
||||
import { SearchSortingPicker } from '../components/search/search-sorting-picker';
|
||||
import { SearchFilters } from '../components/search/search-filters';
|
||||
|
||||
export class SearchResultsPage extends BrowsingPage {
|
||||
root = this.byCss('aca-search-results');
|
||||
chipList = this.root.element(by.css('.adf-search-chip-list'));
|
||||
infoText = this.root.element(by.css('.adf-search-results--info-text'));
|
||||
|
||||
sortingPicker = new SearchSortingPicker('aca-search-results');
|
||||
filters = new SearchFilters('aca-search-results');
|
||||
|
||||
async waitForResults(): Promise<void> {
|
||||
await this.dataTable.waitForBody();
|
||||
}
|
||||
|
||||
async getResultsFoundText(): Promise<string> {
|
||||
return this.infoText.getText();
|
||||
}
|
||||
|
||||
async getResultsChipsValues(): Promise<string[]> {
|
||||
const chips = this.chipList.all(by.css('.mat-chip'));
|
||||
const chipsValues: string[] = await chips.map(async elem => {
|
||||
return (await elem.getText()).replace(`\ncancel`, '');
|
||||
});
|
||||
return chipsValues;
|
||||
}
|
||||
|
||||
async removeChip(chipName: string): Promise<void> {
|
||||
const chip = browser.element(By.cssContainingText('.mat-chip', chipName));
|
||||
const closeChip = chip.element(by.css('.mat-chip-remove'));
|
||||
await closeChip.click();
|
||||
}
|
||||
}
|
215
projects/aca-testing-shared/src/utilities/admin-actions.ts
Executable file
215
projects/aca-testing-shared/src/utilities/admin-actions.ts
Executable file
@@ -0,0 +1,215 @@
|
||||
/*!
|
||||
* @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 { RepoClient, NodeContentTree } from './repo-client/repo-client';
|
||||
import { PersonEntry, NodeEntry } from '@alfresco/js-api';
|
||||
import { PersonModel } from './repo-client/apis/people/people-api-models';
|
||||
|
||||
import { SitesApi } from './repo-client/apis/sites/sites-api';
|
||||
import { UploadApi } from './repo-client/apis/upload/upload-api';
|
||||
import { NodesApi } from './repo-client/apis/nodes/nodes-api';
|
||||
import { FavoritesApi } from './repo-client/apis/favorites/favorites-api';
|
||||
import { SearchApi } from './repo-client/apis/search/search-api';
|
||||
|
||||
export class AdminActions {
|
||||
private adminApi: RepoClient;
|
||||
|
||||
constructor() {
|
||||
this.adminApi = new RepoClient();
|
||||
}
|
||||
|
||||
sites: SitesApi = new SitesApi();
|
||||
upload: UploadApi = new UploadApi();
|
||||
nodes: NodesApi = new NodesApi();
|
||||
favorites: FavoritesApi = new FavoritesApi();
|
||||
search: SearchApi = new SearchApi();
|
||||
|
||||
async getDataDictionaryId(): Promise<string> {
|
||||
return this.adminApi.nodes.getNodeIdFromParent('Data Dictionary', '-root-');
|
||||
}
|
||||
|
||||
async getNodeTemplatesFolderId(): Promise<string> {
|
||||
return this.adminApi.nodes.getNodeIdFromParent(
|
||||
'Node Templates',
|
||||
await this.getDataDictionaryId()
|
||||
);
|
||||
}
|
||||
|
||||
async getSpaceTemplatesFolderId(): Promise<string> {
|
||||
return this.adminApi.nodes.getNodeIdFromParent(
|
||||
'Space Templates',
|
||||
await this.getDataDictionaryId()
|
||||
);
|
||||
}
|
||||
|
||||
async createUser(user: PersonModel): Promise<PersonEntry> {
|
||||
return this.adminApi.people.createUser(user);
|
||||
}
|
||||
|
||||
async createNodeTemplate(
|
||||
name: string,
|
||||
title: string = '',
|
||||
description: string = '',
|
||||
author: string = ''
|
||||
): Promise<NodeEntry> {
|
||||
const templatesRootFolderId: string = await this.getNodeTemplatesFolderId();
|
||||
|
||||
return this.adminApi.nodes.createFile(
|
||||
name,
|
||||
templatesRootFolderId,
|
||||
title,
|
||||
description,
|
||||
author
|
||||
);
|
||||
}
|
||||
|
||||
async createNodeTemplatesHierarchy(hierarchy: NodeContentTree): Promise<any> {
|
||||
return this.adminApi.nodes.createContent(
|
||||
hierarchy,
|
||||
`Data Dictionary/Node Templates`
|
||||
);
|
||||
}
|
||||
|
||||
async createSpaceTemplate(
|
||||
name: string,
|
||||
title: string = '',
|
||||
description: string = ''
|
||||
): Promise<NodeEntry> {
|
||||
const templatesRootFolderId: string = await this.getSpaceTemplatesFolderId();
|
||||
|
||||
return this.adminApi.nodes.createFolder(
|
||||
name,
|
||||
templatesRootFolderId,
|
||||
title,
|
||||
description
|
||||
);
|
||||
}
|
||||
|
||||
async createSpaceTemplatesHierarchy(
|
||||
hierarchy: NodeContentTree
|
||||
): Promise<any> {
|
||||
return this.adminApi.nodes.createContent(
|
||||
hierarchy,
|
||||
`Data Dictionary/Space Templates`
|
||||
);
|
||||
}
|
||||
|
||||
async removeUserAccessOnNodeTemplate(nodeName: string): Promise<NodeEntry> {
|
||||
const templatesRootFolderId = await this.getNodeTemplatesFolderId();
|
||||
const nodeId: string = await this.adminApi.nodes.getNodeIdFromParent(
|
||||
nodeName,
|
||||
templatesRootFolderId
|
||||
);
|
||||
|
||||
return this.adminApi.nodes.setInheritPermissions(nodeId, false);
|
||||
}
|
||||
|
||||
async removeUserAccessOnSpaceTemplate(nodeName: string): Promise<NodeEntry> {
|
||||
const templatesRootFolderId = await this.getSpaceTemplatesFolderId();
|
||||
const nodeId: string = await this.adminApi.nodes.getNodeIdFromParent(
|
||||
nodeName,
|
||||
templatesRootFolderId
|
||||
);
|
||||
|
||||
return this.adminApi.nodes.setInheritPermissions(nodeId, false);
|
||||
}
|
||||
|
||||
async cleanupNodeTemplatesFolder(): Promise<void> {
|
||||
return this.adminApi.nodes.deleteNodeChildren(
|
||||
await this.getNodeTemplatesFolderId()
|
||||
);
|
||||
}
|
||||
|
||||
async cleanupSpaceTemplatesFolder(): Promise<void> {
|
||||
const spaceTemplatesNodeId = await this.getSpaceTemplatesFolderId();
|
||||
|
||||
// folder links are deleted automatically when original folder is deleted
|
||||
// Software Engineering Project is the default folder template coming from ACS, should not be deleted
|
||||
const nodesToDelete = (await this.adminApi.nodes.getNodeChildren(
|
||||
spaceTemplatesNodeId
|
||||
)).list.entries
|
||||
.filter(
|
||||
node =>
|
||||
node.entry.nodeType !== 'app:folderlink' &&
|
||||
node.entry.name !== 'Software Engineering Project'
|
||||
)
|
||||
.map(node => node.entry.id);
|
||||
return this.adminApi.nodes.deleteNodesById(nodesToDelete);
|
||||
}
|
||||
|
||||
async createLinkToFileId(
|
||||
originalFileId: string,
|
||||
destinationParentId: string
|
||||
): Promise<NodeEntry> {
|
||||
return this.adminApi.nodes.createFileLink(
|
||||
originalFileId,
|
||||
destinationParentId
|
||||
);
|
||||
}
|
||||
|
||||
async createLinkToFileName(
|
||||
originalFileName: string,
|
||||
originalFileParentId: string,
|
||||
destinationParentId?: string
|
||||
): Promise<NodeEntry> {
|
||||
if (!destinationParentId) {
|
||||
destinationParentId = originalFileParentId;
|
||||
}
|
||||
|
||||
const nodeId = await this.adminApi.nodes.getNodeIdFromParent(
|
||||
originalFileName,
|
||||
originalFileParentId
|
||||
);
|
||||
|
||||
return this.createLinkToFileId(nodeId, destinationParentId);
|
||||
}
|
||||
|
||||
async createLinkToFolderId(
|
||||
originalFolderId: string,
|
||||
destinationParentId: string
|
||||
): Promise<NodeEntry> {
|
||||
return this.adminApi.nodes.createFolderLink(
|
||||
originalFolderId,
|
||||
destinationParentId
|
||||
);
|
||||
}
|
||||
|
||||
async createLinkToFolderName(
|
||||
originalFolderName: string,
|
||||
originalFolderParentId: string,
|
||||
destinationParentId?: string
|
||||
): Promise<NodeEntry> {
|
||||
if (!destinationParentId) {
|
||||
destinationParentId = originalFolderParentId;
|
||||
}
|
||||
|
||||
const nodeId = await this.adminApi.nodes.getNodeIdFromParent(
|
||||
originalFolderName,
|
||||
originalFolderParentId
|
||||
);
|
||||
|
||||
return this.createLinkToFolderId(nodeId, destinationParentId);
|
||||
}
|
||||
}
|
39
projects/aca-testing-shared/src/utilities/browser-utils.ts
Normal file
39
projects/aca-testing-shared/src/utilities/browser-utils.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
/*!
|
||||
* @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 { USE_HASH_STRATEGY } from '../configs';
|
||||
|
||||
export async function navigate(relativePath: string) {
|
||||
const path = [
|
||||
browser.baseUrl,
|
||||
browser.baseUrl.endsWith('/') ? '' : '/',
|
||||
USE_HASH_STRATEGY ? '#' : '',
|
||||
relativePath.startsWith('/') ? '' : '/',
|
||||
relativePath
|
||||
].join('');
|
||||
|
||||
return browser.get(path);
|
||||
}
|
30
projects/aca-testing-shared/src/utilities/index.ts
Normal file
30
projects/aca-testing-shared/src/utilities/index.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
/*!
|
||||
* @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 './repo-client/apis';
|
||||
export * from './repo-client/repo-client';
|
||||
export * from './admin-actions';
|
||||
export * from './browser-utils';
|
||||
export * from './utils';
|
@@ -0,0 +1,41 @@
|
||||
/*!
|
||||
* @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 { RepoApi } from '../repo-api';
|
||||
|
||||
export class AuthenticationApi extends RepoApi {
|
||||
constructor(username?, password?) {
|
||||
super(username, password);
|
||||
}
|
||||
|
||||
async logout() {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
await this.alfrescoJsApi.logout();
|
||||
} catch (error) {
|
||||
this.handleError(`${this.constructor.name} ${this.logout.name}`, error);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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 { RepoApi } from '../repo-api';
|
||||
import { CommentsApi as AdfCommentsApi } from '@alfresco/js-api';
|
||||
|
||||
export class CommentsApi extends RepoApi {
|
||||
commentsApi = new AdfCommentsApi(this.alfrescoJsApi);
|
||||
|
||||
constructor(username?, password?) {
|
||||
super(username, password);
|
||||
}
|
||||
|
||||
async getNodeComments(nodeId: string) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.commentsApi.listComments(nodeId);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getNodeComments.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async addComment(nodeId: string, comment: string) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.commentsApi.createComment(nodeId, { content: comment });
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.addComment.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async addComments(nodeId: string, comment: any) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.commentsApi.createComment(nodeId, comment);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.addComments.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,208 @@
|
||||
/*!
|
||||
* @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 { RepoApi } from '../repo-api';
|
||||
import { Logger } from '@alfresco/adf-testing';
|
||||
import { RepoClient } from './../../repo-client';
|
||||
import { Utils } from '../../../../utilities/utils';
|
||||
import {
|
||||
FavoritesApi as AdfFavoritesApi,
|
||||
SitesApi as AdfSiteApi,
|
||||
FavoriteEntry
|
||||
} from '@alfresco/js-api';
|
||||
|
||||
export class FavoritesApi extends RepoApi {
|
||||
favoritesApi = new AdfFavoritesApi(this.alfrescoJsApi);
|
||||
sitesApi = new AdfSiteApi(this.alfrescoJsApi);
|
||||
|
||||
constructor(username?, password?) {
|
||||
super(username, password);
|
||||
}
|
||||
|
||||
async addFavorite(api: RepoClient, nodeType: string, name: string) {
|
||||
try {
|
||||
const nodeId = (await api.nodes.getNodeByPath(name)).entry.id;
|
||||
const data = {
|
||||
target: {
|
||||
[nodeType]: {
|
||||
guid: nodeId
|
||||
}
|
||||
}
|
||||
};
|
||||
return await this.favoritesApi.createFavorite('-me-', data);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.addFavorite.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async addFavoriteById(
|
||||
nodeType: 'file' | 'folder' | 'site',
|
||||
id: string
|
||||
): Promise<FavoriteEntry | null> {
|
||||
let guid;
|
||||
try {
|
||||
await this.apiAuth();
|
||||
if (nodeType === 'site') {
|
||||
guid = (await this.sitesApi.getSite(id)).entry.guid;
|
||||
} else {
|
||||
guid = id;
|
||||
}
|
||||
const data = {
|
||||
target: {
|
||||
[nodeType]: {
|
||||
guid: guid
|
||||
}
|
||||
}
|
||||
};
|
||||
return await this.favoritesApi.createFavorite('-me-', data);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.addFavoriteById.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async addFavoritesByIds(nodeType: 'file' | 'folder' | 'site', ids: string[]) {
|
||||
try {
|
||||
return await ids.reduce(async (previous, current) => {
|
||||
await previous;
|
||||
await this.addFavoriteById(nodeType, current);
|
||||
}, Promise.resolve());
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.addFavoritesByIds.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async getFavorites() {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.favoritesApi.listFavorites(this.getUsername());
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getFavorites.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getFavoriteById(nodeId: string) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.favoritesApi.getFavorite('-me-', nodeId);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getFavoriteById.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async isFavorite(nodeId: string) {
|
||||
try {
|
||||
return JSON.stringify((await this.getFavorites()).list.entries).includes(
|
||||
nodeId
|
||||
);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.isFavorite.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async isFavoriteWithRetry(nodeId: string, data: { expect: boolean }) {
|
||||
let isFavorite: boolean;
|
||||
try {
|
||||
const favorite = async () => {
|
||||
isFavorite = await this.isFavorite(nodeId);
|
||||
if (isFavorite !== data.expect) {
|
||||
return Promise.reject(isFavorite);
|
||||
} else {
|
||||
return Promise.resolve(isFavorite);
|
||||
}
|
||||
};
|
||||
return await Utils.retryCall(favorite);
|
||||
} catch (error) {
|
||||
// this.handleError(`${this.constructor.name} ${this.isFavoriteWithRetry.name}`, error);
|
||||
}
|
||||
return isFavorite;
|
||||
}
|
||||
|
||||
async removeFavoriteById(nodeId: string) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.favoritesApi.deleteFavorite('-me-', nodeId);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.removeFavoriteById.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async removeFavoritesByIds(ids: string[]) {
|
||||
try {
|
||||
return await ids.reduce(async (previous, current) => {
|
||||
await previous;
|
||||
await this.removeFavoriteById(current);
|
||||
}, Promise.resolve());
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.removeFavoritesByIds.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async waitForApi(data: { expect: number }) {
|
||||
try {
|
||||
const favoriteFiles = async () => {
|
||||
const totalItems = (await this.getFavorites()).list.pagination
|
||||
.totalItems;
|
||||
if (totalItems !== data.expect) {
|
||||
return Promise.reject(totalItems);
|
||||
} else {
|
||||
return Promise.resolve(totalItems);
|
||||
}
|
||||
};
|
||||
return await Utils.retryCall(favoriteFiles);
|
||||
} catch (error) {
|
||||
Logger.error(`${this.constructor.name} ${this.waitForApi.name} catch: `);
|
||||
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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/>.
|
||||
*/
|
||||
|
||||
export * from './authentication/authentication-api';
|
||||
export * from './comments/comments-api';
|
||||
export * from './favorites/favorites-api';
|
||||
export * from './nodes/node-body-create';
|
||||
export * from './nodes/node-content-tree';
|
||||
export * from './nodes/nodes-api';
|
||||
export * from './people/people-api-models';
|
||||
export * from './people/people-api';
|
||||
export * from './queries/queries-api';
|
||||
export * from './search/search-api';
|
||||
export * from './shared-links/shared-links-api';
|
||||
export * from './sites/sites-api';
|
||||
export * from './trashcan/trashcan-api';
|
||||
export * from './upload/upload-api';
|
||||
export * from './repo-api';
|
@@ -0,0 +1,39 @@
|
||||
/*!
|
||||
* @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 const NODE_TYPE_FILE = 'cm:content';
|
||||
export const NODE_TYPE_FOLDER = 'cm:folder';
|
||||
export const NODE_TITLE = 'cm:title';
|
||||
export const NODE_DESCRIPTION = 'cm:description';
|
||||
|
||||
export class NodeBodyCreate {
|
||||
constructor(
|
||||
public name: string,
|
||||
public nodeType: string,
|
||||
public relativePath: string = '/',
|
||||
public aspectNames?: string[],
|
||||
public properties?: any[]
|
||||
) {}
|
||||
}
|
@@ -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 {
|
||||
NodeBodyCreate,
|
||||
NODE_TYPE_FILE,
|
||||
NODE_TYPE_FOLDER,
|
||||
NODE_TITLE,
|
||||
NODE_DESCRIPTION
|
||||
} from './node-body-create';
|
||||
|
||||
export interface NodeContentTree {
|
||||
name?: string;
|
||||
files?: string[];
|
||||
folders?: (string | NodeContentTree)[];
|
||||
title?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export function flattenNodeContentTree(
|
||||
content: NodeContentTree,
|
||||
relativePath: string = '/'
|
||||
): NodeBodyCreate[] {
|
||||
const { name, files, folders, title, description } = content;
|
||||
const aspectNames: string[] = ['cm:versionable'];
|
||||
let data: NodeBodyCreate[] = [];
|
||||
let properties: any;
|
||||
|
||||
properties = {
|
||||
[NODE_TITLE]: title,
|
||||
[NODE_DESCRIPTION]: description
|
||||
};
|
||||
|
||||
if (name) {
|
||||
data = data.concat([
|
||||
{
|
||||
nodeType: NODE_TYPE_FOLDER,
|
||||
name,
|
||||
relativePath,
|
||||
properties
|
||||
}
|
||||
]);
|
||||
|
||||
relativePath =
|
||||
relativePath === '/' ? `/${name}` : `${relativePath}/${name}`;
|
||||
}
|
||||
|
||||
if (folders) {
|
||||
const foldersData: NodeBodyCreate[] = folders
|
||||
.map(
|
||||
(folder: string | NodeContentTree): NodeBodyCreate[] => {
|
||||
const folderData: NodeContentTree =
|
||||
typeof folder === 'string' ? { name: folder } : folder;
|
||||
|
||||
return flattenNodeContentTree(folderData, relativePath);
|
||||
}
|
||||
)
|
||||
.reduce(
|
||||
(nodesData: NodeBodyCreate[], folderData: NodeBodyCreate[]) =>
|
||||
nodesData.concat(folderData),
|
||||
[]
|
||||
);
|
||||
|
||||
data = data.concat(foldersData);
|
||||
}
|
||||
|
||||
if (files) {
|
||||
const filesData: NodeBodyCreate[] = files.map(
|
||||
(filename: string): NodeBodyCreate => ({
|
||||
nodeType: NODE_TYPE_FILE,
|
||||
name: filename,
|
||||
relativePath,
|
||||
aspectNames
|
||||
})
|
||||
);
|
||||
|
||||
data = data.concat(filesData);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
784
projects/aca-testing-shared/src/utilities/repo-client/apis/nodes/nodes-api.ts
Executable file
784
projects/aca-testing-shared/src/utilities/repo-client/apis/nodes/nodes-api.ts
Executable file
@@ -0,0 +1,784 @@
|
||||
/*!
|
||||
* @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 { RepoApi } from '../repo-api';
|
||||
import { NodeBodyCreate } from './node-body-create';
|
||||
import { NodeContentTree, flattenNodeContentTree } from './node-content-tree';
|
||||
import {
|
||||
NodesApi as AdfNodeApi,
|
||||
NodeBodyLock,
|
||||
NodeEntry,
|
||||
NodeChildAssociationPaging
|
||||
} from '@alfresco/js-api';
|
||||
import { Utils } from '../../../../utilities/utils';
|
||||
|
||||
export class NodesApi extends RepoApi {
|
||||
nodesApi = new AdfNodeApi(this.alfrescoJsApi);
|
||||
|
||||
constructor(username?, password?) {
|
||||
super(username, password);
|
||||
}
|
||||
|
||||
async getNodeByPath(relativePath: string = '/'): Promise<NodeEntry | null> {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.nodesApi.getNode('-my-', { relativePath });
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getNodeByPath.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getNodeById(id: string): Promise<NodeEntry | null> {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
const node = await this.nodesApi.getNode(id);
|
||||
return node;
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getNodeById.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getNodeIdFromParent(name: string, parentId: string): Promise<string> {
|
||||
try {
|
||||
const children = (await this.getNodeChildren(parentId)).list.entries;
|
||||
return children.find(elem => elem.entry.name === name).entry.id || '';
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getNodeIdFromParent.name}`,
|
||||
error
|
||||
);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
async getNodeDescription(name: string, parentId: string): Promise<string> {
|
||||
try {
|
||||
const children = (await this.getNodeChildren(parentId)).list.entries;
|
||||
return (
|
||||
children.find(elem => elem.entry.name === name).entry.properties[
|
||||
'cm:description'
|
||||
] || ''
|
||||
);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getNodeDescription.name}`,
|
||||
error
|
||||
);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
async getNodeTitle(name: string, parentId: string): Promise<string> {
|
||||
try {
|
||||
const children = (await this.getNodeChildren(parentId)).list.entries;
|
||||
return (
|
||||
children.find(elem => elem.entry.name === name).entry.properties[
|
||||
'cm:title'
|
||||
] || ''
|
||||
);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getNodeTitle.name}`,
|
||||
error
|
||||
);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
async getNodeProperty(nodeId: string, property: string): Promise<string> {
|
||||
try {
|
||||
const node = await this.getNodeById(nodeId);
|
||||
return (node.entry.properties && node.entry.properties[property]) || '';
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getNodeProperty.name}`,
|
||||
error
|
||||
);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
async getFileVersionType(nodeId: string): Promise<string> {
|
||||
try {
|
||||
const prop = await this.getNodeProperty(nodeId, 'cm:versionType');
|
||||
return prop || '';
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getFileVersionType.name}`,
|
||||
error
|
||||
);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
async getFileVersionLabel(nodeId: string): Promise<string> {
|
||||
try {
|
||||
const prop = await this.getNodeProperty(nodeId, 'cm:versionLabel');
|
||||
return prop || '';
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getFileVersionLabel.name}`,
|
||||
error
|
||||
);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
async getSharedId(nodeId: string): Promise<string> {
|
||||
try {
|
||||
const sharedId = await this.getNodeProperty(nodeId, 'qshare:sharedId');
|
||||
return sharedId || '';
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getSharedId.name}`,
|
||||
error
|
||||
);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
async getSharedExpiryDate(nodeId: string): Promise<string> {
|
||||
try {
|
||||
const expiryDate = await this.getNodeProperty(
|
||||
nodeId,
|
||||
'qshare:expiryDate'
|
||||
);
|
||||
return expiryDate || '';
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getSharedExpiryDate.name}`,
|
||||
error
|
||||
);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
async isFileShared(nodeId: string): Promise<boolean> {
|
||||
try {
|
||||
const sharedId = await this.getSharedId(nodeId);
|
||||
return sharedId !== '';
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.isFileShared.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async deleteNodeById(id: string, permanent: boolean = true): Promise<void> {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
await this.nodesApi.deleteNode(id, { permanent });
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.deleteNodeById.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async deleteNodeByPath(
|
||||
path: string,
|
||||
permanent: boolean = true
|
||||
): Promise<void> {
|
||||
try {
|
||||
const id = (await this.getNodeByPath(path)).entry.id;
|
||||
await this.deleteNodeById(id, permanent);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.deleteNodeByPath.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async deleteNodes(
|
||||
names: string[],
|
||||
relativePath: string = '',
|
||||
permanent: boolean = true
|
||||
): Promise<void> {
|
||||
try {
|
||||
await names.reduce(async (previous, current) => {
|
||||
await previous;
|
||||
const req = await this.deleteNodeByPath(
|
||||
`${relativePath}/${current}`,
|
||||
permanent
|
||||
);
|
||||
return req;
|
||||
}, Promise.resolve());
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.deleteNodes.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async deleteNodesById(
|
||||
ids: string[],
|
||||
permanent: boolean = true
|
||||
): Promise<void> {
|
||||
try {
|
||||
for (const id of ids) {
|
||||
await this.deleteNodeById(id, permanent);
|
||||
}
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.deleteNodesById.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async getNodeChildren(
|
||||
nodeId: string
|
||||
): Promise<NodeChildAssociationPaging | null> {
|
||||
try {
|
||||
const opts = {
|
||||
include: ['properties']
|
||||
};
|
||||
await this.apiAuth();
|
||||
return await this.nodesApi.listNodeChildren(nodeId, opts);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getNodeChildren.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async deleteNodeChildren(
|
||||
parentId: string,
|
||||
exceptNodesNamed?: string[]
|
||||
): Promise<void> {
|
||||
try {
|
||||
const listEntries = (await this.getNodeChildren(parentId)).list.entries;
|
||||
let nodeIds: string[];
|
||||
if (exceptNodesNamed) {
|
||||
nodeIds = listEntries
|
||||
.filter(entries => !exceptNodesNamed.includes(entries.entry.name))
|
||||
.map(entries => entries.entry.id);
|
||||
} else {
|
||||
nodeIds = listEntries.map(entries => entries.entry.id);
|
||||
}
|
||||
await this.deleteNodesById(nodeIds);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.deleteNodeChildren.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async createImageNode(
|
||||
name: string,
|
||||
parentId: string = '-my-',
|
||||
title: string = '',
|
||||
description: string = ''
|
||||
): Promise<NodeEntry | null> {
|
||||
const imageProps = {
|
||||
'exif:pixelXDimension': 1000,
|
||||
'exif:pixelYDimension': 1200
|
||||
};
|
||||
try {
|
||||
return await this.createNode(
|
||||
'cm:content',
|
||||
name,
|
||||
parentId,
|
||||
title,
|
||||
description,
|
||||
imageProps
|
||||
);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createImageNode.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async createNode(
|
||||
nodeType: string,
|
||||
name: string,
|
||||
parentId: string = '-my-',
|
||||
title: string = '',
|
||||
description: string = '',
|
||||
imageProps: any = null,
|
||||
author: string = '',
|
||||
majorVersion: boolean = true,
|
||||
aspectNames: string[] = null
|
||||
): Promise<NodeEntry | null> {
|
||||
if (!aspectNames) {
|
||||
aspectNames = ['cm:versionable']; // workaround for REPO-4772
|
||||
}
|
||||
const nodeBody = {
|
||||
name,
|
||||
nodeType,
|
||||
properties: {
|
||||
'cm:title': title,
|
||||
'cm:description': description,
|
||||
'cm:author': author
|
||||
},
|
||||
aspectNames
|
||||
};
|
||||
if (imageProps) {
|
||||
nodeBody.properties = Object.assign(nodeBody.properties, imageProps);
|
||||
}
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.nodesApi.createNode(parentId, nodeBody, {
|
||||
majorVersion
|
||||
});
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createNode.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async createFile(
|
||||
name: string,
|
||||
parentId: string = '-my-',
|
||||
title: string = '',
|
||||
description: string = '',
|
||||
author: string = '',
|
||||
majorVersion: boolean = true,
|
||||
aspectNames: string[] = null
|
||||
): Promise<NodeEntry> {
|
||||
try {
|
||||
return await this.createNode(
|
||||
'cm:content',
|
||||
name,
|
||||
parentId,
|
||||
title,
|
||||
description,
|
||||
null,
|
||||
author,
|
||||
majorVersion,
|
||||
aspectNames
|
||||
);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createFile.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async createImage(
|
||||
name: string,
|
||||
parentId: string = '-my-',
|
||||
title: string = '',
|
||||
description: string = ''
|
||||
): Promise<NodeEntry | null> {
|
||||
try {
|
||||
return await this.createImageNode(name, parentId, title, description);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createImage.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async createFolder(
|
||||
name: string,
|
||||
parentId: string = '-my-',
|
||||
title: string = '',
|
||||
description: string = '',
|
||||
author: string = '',
|
||||
aspectNames: string[] = null
|
||||
): Promise<NodeEntry | null> {
|
||||
try {
|
||||
return await this.createNode(
|
||||
'cm:folder',
|
||||
name,
|
||||
parentId,
|
||||
title,
|
||||
description,
|
||||
null,
|
||||
author,
|
||||
null,
|
||||
aspectNames
|
||||
);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createFolder.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async createChildren(data: NodeBodyCreate[]): Promise<NodeEntry | any> {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.nodesApi.createNode('-my-', data as any);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createChildren.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async createContent(
|
||||
content: NodeContentTree,
|
||||
relativePath: string = '/'
|
||||
): Promise<NodeEntry | any> {
|
||||
try {
|
||||
return await this.createChildren(
|
||||
flattenNodeContentTree(content, relativePath)
|
||||
);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createContent.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async createFolders(
|
||||
names: string[],
|
||||
relativePath: string = '/'
|
||||
): Promise<NodeEntry | any> {
|
||||
try {
|
||||
return await this.createContent({ folders: names }, relativePath);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createFolders.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async createFiles(
|
||||
names: string[],
|
||||
relativePath: string = '/'
|
||||
): Promise<NodeEntry | any> {
|
||||
try {
|
||||
return await this.createContent({ files: names }, relativePath);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createFiles.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async addAspects(nodeId: string, aspectNames: string[]): Promise<NodeEntry> {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return this.nodesApi.updateNode(nodeId, { aspectNames });
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.addAspects.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async createFileLink(
|
||||
originalNodeId: string,
|
||||
destinationId: string
|
||||
): Promise<NodeEntry | null> {
|
||||
const name = (await this.getNodeById(originalNodeId)).entry.name;
|
||||
const nodeBody = {
|
||||
name: `Link to ${name}.url`,
|
||||
nodeType: 'app:filelink',
|
||||
properties: {
|
||||
'cm:destination': originalNodeId
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
const link = await this.nodesApi.createNode(destinationId, nodeBody);
|
||||
await this.addAspects(originalNodeId, ['app:linked']);
|
||||
return link;
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createFileLink.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async createFolderLink(
|
||||
originalNodeId: string,
|
||||
destinationId: string
|
||||
): Promise<NodeEntry | null> {
|
||||
const name = (await this.getNodeById(originalNodeId)).entry.name;
|
||||
const nodeBody = {
|
||||
name: `Link to ${name}.url`,
|
||||
nodeType: 'app:folderlink',
|
||||
properties: {
|
||||
'cm:title': `Link to ${name}.url`,
|
||||
'cm:destination': originalNodeId,
|
||||
'cm:description': `Link to ${name}.url`,
|
||||
'app:icon': 'space-icon-link'
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
const link = await this.nodesApi.createNode(destinationId, nodeBody);
|
||||
await this.addAspects(originalNodeId, ['app:linked']);
|
||||
return link;
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createFolderLink.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// node content
|
||||
async getNodeContent(nodeId: string): Promise<any> {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.nodesApi.getNodeContent(nodeId);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getNodeContent.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async editNodeContent(
|
||||
nodeId: string,
|
||||
content: string
|
||||
): Promise<NodeEntry | null> {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.nodesApi.updateNodeContent(nodeId, content);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.editNodeContent.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async renameNode(nodeId: string, newName: string): Promise<NodeEntry | null> {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return this.nodesApi.updateNode(nodeId, { name: newName });
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.renameNode.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// node permissions
|
||||
async setInheritPermissions(
|
||||
nodeId: string,
|
||||
inheritPermissions: boolean
|
||||
): Promise<NodeEntry | null> {
|
||||
const data = {
|
||||
permissions: {
|
||||
isInheritanceEnabled: inheritPermissions
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.nodesApi.updateNode(nodeId, data);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.setGranularPermission.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async setGranularPermission(
|
||||
nodeId: string,
|
||||
inheritPermissions: boolean = false,
|
||||
username: string,
|
||||
role: string
|
||||
): Promise<NodeEntry | null> {
|
||||
const data = {
|
||||
permissions: {
|
||||
isInheritanceEnabled: inheritPermissions,
|
||||
locallySet: [
|
||||
{
|
||||
authorityId: username,
|
||||
name: role
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.nodesApi.updateNode(nodeId, data);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.setGranularPermission.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// lock node
|
||||
async lockFile(
|
||||
nodeId: string,
|
||||
lockType: string = 'ALLOW_OWNER_CHANGES'
|
||||
): Promise<NodeEntry | null> {
|
||||
const data = {
|
||||
type: lockType
|
||||
} as NodeBodyLock;
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.nodesApi.lockNode(nodeId, data);
|
||||
} catch (error) {
|
||||
this.handleError(`${this.constructor.name} ${this.lockFile.name}`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async unlockFile(nodeId: string): Promise<NodeEntry | null> {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.nodesApi.unlockNode(nodeId);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.unlockFile.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getLockType(nodeId: string): Promise<string> {
|
||||
try {
|
||||
const lockType = await this.getNodeProperty(nodeId, 'cm:lockType');
|
||||
return lockType || '';
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getLockType.name}`,
|
||||
error
|
||||
);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
async getLockOwner(nodeId: string): Promise<string> {
|
||||
try {
|
||||
const lockOwner = await this.getNodeProperty(nodeId, 'cm:lockOwner');
|
||||
return lockOwner || '';
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getLockOwner.name}`,
|
||||
error
|
||||
);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
async isFileLockedWrite(nodeId: string): Promise<boolean> {
|
||||
try {
|
||||
return (await this.getLockType(nodeId)) === 'WRITE_LOCK';
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.isFileLockedWrite.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async isFileLockedWriteWithRetry(
|
||||
nodeId: string,
|
||||
expect: boolean
|
||||
): Promise<boolean> {
|
||||
const data = {
|
||||
expect: expect,
|
||||
retry: 5
|
||||
};
|
||||
let isLocked: boolean;
|
||||
try {
|
||||
const locked = async () => {
|
||||
isLocked = (await this.getLockType(nodeId)) === 'WRITE_LOCK';
|
||||
if (isLocked !== data.expect) {
|
||||
return Promise.reject(isLocked);
|
||||
} else {
|
||||
return Promise.resolve(isLocked);
|
||||
}
|
||||
};
|
||||
return await Utils.retryCall(locked, data.retry);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.isFileLockedWriteWithRetry.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
return isLocked;
|
||||
}
|
||||
|
||||
async isFileLockedByName(
|
||||
fileName: string,
|
||||
parentId: string
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
const id = await this.getNodeIdFromParent(fileName, parentId);
|
||||
return await this.isFileLockedWrite(id);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.isFileLockedByName.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
/*!
|
||||
* @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 interface PersonModel {
|
||||
username?: string;
|
||||
password?: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
email?: string;
|
||||
enabled?: boolean;
|
||||
properties?: any;
|
||||
}
|
||||
|
||||
export class Person {
|
||||
id: string;
|
||||
password: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
enabled: boolean;
|
||||
properties: any;
|
||||
|
||||
constructor(user: PersonModel) {
|
||||
this.id = user.username;
|
||||
this.password = user.password || user.username;
|
||||
this.firstName = user.firstName || user.username;
|
||||
this.lastName = user.lastName || user.username;
|
||||
this.email = user.email || `${user.username}@alfresco.com`;
|
||||
this.enabled = user.enabled || true;
|
||||
}
|
||||
}
|
@@ -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 { PersonModel, Person } from './people-api-models';
|
||||
import { RepoApi } from '../repo-api';
|
||||
import { PeopleApi as AdfPeopleApi } from '@alfresco/js-api';
|
||||
|
||||
export class PeopleApi extends RepoApi {
|
||||
peopleApi = new AdfPeopleApi(this.alfrescoJsApi);
|
||||
|
||||
constructor(username?: string, password?: string) {
|
||||
super(username, password);
|
||||
}
|
||||
|
||||
async createUser(user: PersonModel) {
|
||||
try {
|
||||
const person = new Person(user);
|
||||
await this.apiAuth();
|
||||
return await this.peopleApi.createPerson(person);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createUser.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getUser(username: string) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.peopleApi.getPerson(username);
|
||||
} catch (error) {
|
||||
this.handleError(`${this.constructor.name} ${this.getUser.name}`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async updateUser(username: string, userDetails?: PersonModel) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return this.peopleApi.updatePerson(username, userDetails);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.updateUser.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async disableUser(username: string) {
|
||||
try {
|
||||
return await this.updateUser(username, { enabled: false });
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.disableUser.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async changePassword(username: string, newPassword: string) {
|
||||
try {
|
||||
return await this.updateUser(username, { password: newPassword });
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.changePassword.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,115 @@
|
||||
/*!
|
||||
* @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 { RepoApi } from '../repo-api';
|
||||
import { Logger } from '@alfresco/adf-testing';
|
||||
import { Utils } from '../../../../utilities/utils';
|
||||
import { QueriesApi as AdfQueriesApi } from '@alfresco/js-api';
|
||||
|
||||
export class QueriesApi extends RepoApi {
|
||||
queriesApi = new AdfQueriesApi(this.alfrescoJsApi);
|
||||
|
||||
constructor(username?: string, password?: string) {
|
||||
super(username, password);
|
||||
}
|
||||
|
||||
async findSites(searchTerm: string) {
|
||||
const data = {
|
||||
term: searchTerm,
|
||||
fields: ['title']
|
||||
};
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return this.queriesApi.findSites(searchTerm, data);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.findSites.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async findNodes(searchTerm: string) {
|
||||
const data = {
|
||||
term: searchTerm,
|
||||
fields: ['name']
|
||||
};
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return this.queriesApi.findNodes(searchTerm, data);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.findNodes.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async waitForSites(searchTerm: string, data: { expect: number }) {
|
||||
try {
|
||||
const sites = async () => {
|
||||
const totalItems = (await this.findSites(searchTerm)).list.pagination
|
||||
.totalItems;
|
||||
if (totalItems !== data.expect) {
|
||||
return Promise.reject(totalItems);
|
||||
} else {
|
||||
return Promise.resolve(totalItems);
|
||||
}
|
||||
};
|
||||
|
||||
return await Utils.retryCall(sites);
|
||||
} catch (error) {
|
||||
Logger.error(
|
||||
`${this.constructor.name} ${this.waitForSites.name} catch: `
|
||||
);
|
||||
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
async waitForFilesAndFolders(searchTerm: string, data: { expect: number }) {
|
||||
try {
|
||||
const nodes = async () => {
|
||||
const totalItems = (await this.findNodes(searchTerm)).list.pagination
|
||||
.totalItems;
|
||||
if (totalItems !== data.expect) {
|
||||
return Promise.reject(totalItems);
|
||||
} else {
|
||||
return Promise.resolve(totalItems);
|
||||
}
|
||||
};
|
||||
|
||||
return await Utils.retryCall(nodes);
|
||||
} catch (error) {
|
||||
Logger.error(
|
||||
`${this.constructor.name} ${this.waitForFilesAndFolders.name} catch: `
|
||||
);
|
||||
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
/*!
|
||||
* @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 { AlfrescoApi } from '@alfresco/js-api';
|
||||
import { Logger } from '@alfresco/adf-testing';
|
||||
|
||||
export abstract class RepoApi {
|
||||
alfrescoJsApi = new AlfrescoApi();
|
||||
|
||||
constructor(
|
||||
private username: string = browser.params.ADMIN_USERNAME,
|
||||
private password: string = browser.params.ADMIN_PASSWORD
|
||||
) {
|
||||
this.alfrescoJsApi.setConfig(browser.params.config);
|
||||
}
|
||||
|
||||
apiAuth(): Promise<any> {
|
||||
return this.alfrescoJsApi.login(this.username, this.password);
|
||||
}
|
||||
|
||||
getUsername(): string {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
protected handleError(message: string, response: any) {
|
||||
Logger.error(`\n--- ${message} error :`);
|
||||
Logger.error('\t>>> username: ', this.username);
|
||||
Logger.error('\t>>> JSON: ', JSON.stringify(browser.params.config));
|
||||
if (response.status && response.response) {
|
||||
try {
|
||||
Logger.error('\t>>> Status: ', response.status);
|
||||
Logger.error('\t>>> Text: ', response.response.text);
|
||||
Logger.error('\t>>> Method: ', response.response.error.method);
|
||||
Logger.error('\t>>> Path: ', response.response.error.path);
|
||||
} catch {
|
||||
Logger.error('\t>>> ', response);
|
||||
}
|
||||
} else Logger.error('\t>>> ', response);
|
||||
}
|
||||
}
|
144
projects/aca-testing-shared/src/utilities/repo-client/apis/search/search-api.ts
Executable file
144
projects/aca-testing-shared/src/utilities/repo-client/apis/search/search-api.ts
Executable file
@@ -0,0 +1,144 @@
|
||||
/*!
|
||||
* @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 { RepoApi } from '../repo-api';
|
||||
import { Logger } from '@alfresco/adf-testing';
|
||||
import { Utils } from '../../../../utilities/utils';
|
||||
import { SearchApi as AdfSearchApi } from '@alfresco/js-api';
|
||||
|
||||
export class SearchApi extends RepoApi {
|
||||
searchApi = new AdfSearchApi(this.alfrescoJsApi);
|
||||
|
||||
constructor(username?, password?) {
|
||||
super(username, password);
|
||||
}
|
||||
|
||||
async queryRecentFiles(username: string) {
|
||||
const data = {
|
||||
query: {
|
||||
query: '*',
|
||||
language: 'afts'
|
||||
},
|
||||
filterQueries: [
|
||||
{ query: `cm:modified:[NOW/DAY-30DAYS TO NOW/DAY+1DAY]` },
|
||||
{ query: `cm:modifier:${username} OR cm:creator:${username}` },
|
||||
{ query: `TYPE:"content" AND -TYPE:"app:filelink" AND -TYPE:"fm:post"` }
|
||||
]
|
||||
};
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return this.searchApi.search(data);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.queryRecentFiles.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async queryNodesNames(searchTerm: string) {
|
||||
const data = {
|
||||
query: {
|
||||
query: `cm:name:\"${searchTerm}*\"`,
|
||||
language: 'afts'
|
||||
},
|
||||
filterQueries: [{ query: `+TYPE:'cm:folder' OR +TYPE:'cm:content'` }]
|
||||
};
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return this.searchApi.search(data);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.queryNodesNames.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async queryNodesExactNames(searchTerm: string) {
|
||||
const data = {
|
||||
query: {
|
||||
query: `cm:name:\"${searchTerm}\"`,
|
||||
language: 'afts'
|
||||
},
|
||||
filterQueries: [{ query: `+TYPE:'cm:folder' OR +TYPE:'cm:content'` }]
|
||||
};
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return this.searchApi.search(data);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.queryNodesExactNames.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async waitForApi(username: string, data: { expect: number }) {
|
||||
try {
|
||||
const recentFiles = async () => {
|
||||
const totalItems = (await this.queryRecentFiles(username)).list
|
||||
.pagination.totalItems;
|
||||
if (totalItems !== data.expect) {
|
||||
return Promise.reject(totalItems);
|
||||
} else {
|
||||
return Promise.resolve(totalItems);
|
||||
}
|
||||
};
|
||||
|
||||
return await Utils.retryCall(recentFiles);
|
||||
} catch (error) {
|
||||
Logger.error(`${this.constructor.name} ${this.waitForApi.name} catch: `);
|
||||
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
async waitForNodes(searchTerm: string, data: { expect: number }) {
|
||||
try {
|
||||
const nodes = async () => {
|
||||
const totalItems = (await this.queryNodesNames(searchTerm)).list
|
||||
.pagination.totalItems;
|
||||
if (totalItems !== data.expect) {
|
||||
return Promise.reject(totalItems);
|
||||
} else {
|
||||
return Promise.resolve(totalItems);
|
||||
}
|
||||
};
|
||||
|
||||
return await Utils.retryCall(nodes);
|
||||
} catch (error) {
|
||||
Logger.error(
|
||||
`${this.constructor.name} ${this.waitForNodes.name} catch: `
|
||||
);
|
||||
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,134 @@
|
||||
/*!
|
||||
* @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 { RepoApi } from '../repo-api';
|
||||
import { Logger } from '@alfresco/adf-testing';
|
||||
import { Utils } from '../../../../utilities/utils';
|
||||
import {
|
||||
SharedlinksApi as AdfSharedlinksApi,
|
||||
SharedLinkEntry
|
||||
} from '@alfresco/js-api';
|
||||
|
||||
export class SharedLinksApi extends RepoApi {
|
||||
sharedlinksApi = new AdfSharedlinksApi(this.alfrescoJsApi);
|
||||
|
||||
constructor(username?, password?) {
|
||||
super(username, password);
|
||||
}
|
||||
|
||||
async shareFileById(
|
||||
id: string,
|
||||
expireDate?: Date
|
||||
): Promise<SharedLinkEntry | null> {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
const data = {
|
||||
nodeId: id,
|
||||
expiresAt: expireDate
|
||||
};
|
||||
return await this.sharedlinksApi.createSharedLink(data);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.shareFileById.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async shareFilesByIds(ids: string[]) {
|
||||
try {
|
||||
return await ids.reduce(async (previous: any, current: any) => {
|
||||
await previous;
|
||||
return this.shareFileById(current);
|
||||
}, Promise.resolve());
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.shareFilesByIds.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async getSharedIdOfNode(name: string) {
|
||||
try {
|
||||
const sharedLinks = (await this.getSharedLinks()).list.entries;
|
||||
const found = sharedLinks.find(
|
||||
sharedLink => sharedLink.entry.name === name
|
||||
);
|
||||
return (found || { entry: { id: null } }).entry.id;
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getSharedIdOfNode.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async unshareFile(name: string) {
|
||||
try {
|
||||
const id = await this.getSharedIdOfNode(name);
|
||||
return await this.sharedlinksApi.deleteSharedLink(id);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.unshareFile.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async getSharedLinks() {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.sharedlinksApi.listSharedLinks();
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getSharedLinks.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async waitForApi(data: { expect: number }) {
|
||||
try {
|
||||
const sharedFiles = async () => {
|
||||
const totalItems = (await this.getSharedLinks()).list.pagination
|
||||
.totalItems;
|
||||
if (totalItems !== data.expect) {
|
||||
return Promise.reject(totalItems);
|
||||
} else {
|
||||
return Promise.resolve(totalItems);
|
||||
}
|
||||
};
|
||||
|
||||
return await Utils.retryCall(sharedFiles);
|
||||
} catch (error) {
|
||||
Logger.error(`${this.constructor.name} ${this.waitForApi.name} catch: `);
|
||||
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
361
projects/aca-testing-shared/src/utilities/repo-client/apis/sites/sites-api.ts
Executable file
361
projects/aca-testing-shared/src/utilities/repo-client/apis/sites/sites-api.ts
Executable file
@@ -0,0 +1,361 @@
|
||||
/*!
|
||||
* @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 { RepoApi } from '../repo-api';
|
||||
import { Logger } from '@alfresco/adf-testing';
|
||||
import {
|
||||
SiteBody,
|
||||
SiteMemberRoleBody,
|
||||
SiteMemberBody,
|
||||
SiteEntry,
|
||||
SiteMembershipRequestEntry,
|
||||
SitesApi as AdfSiteApi,
|
||||
SiteMemberEntry
|
||||
} from '@alfresco/js-api';
|
||||
import { SITE_VISIBILITY, SITE_ROLES } from '../../../../configs';
|
||||
import { Utils } from '../../../../utilities/utils';
|
||||
|
||||
export class SitesApi extends RepoApi {
|
||||
sitesApi = new AdfSiteApi(this.alfrescoJsApi);
|
||||
|
||||
constructor(username?, password?) {
|
||||
super(username, password);
|
||||
}
|
||||
|
||||
async getSite(siteId: string) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.sitesApi.getSite(siteId);
|
||||
} catch (error) {
|
||||
this.handleError(`${this.constructor.name} ${this.getSite.name}`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getSites() {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.sitesApi.listSiteMembershipsForPerson(
|
||||
this.getUsername()
|
||||
);
|
||||
} catch (error) {
|
||||
this.handleError(`${this.constructor.name} ${this.getSites.name}`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getDocLibId(siteId: string) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return (await this.sitesApi.listSiteContainers(siteId)).list.entries[0]
|
||||
.entry.id;
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getDocLibId.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getVisibility(siteId: string) {
|
||||
try {
|
||||
const site = await this.getSite(siteId);
|
||||
return site.entry.visibility;
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getVisibility.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getDescription(siteId: string) {
|
||||
try {
|
||||
const site = await this.getSite(siteId);
|
||||
return site.entry.description;
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getDescription.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getTitle(siteId: string) {
|
||||
try {
|
||||
const site = await this.getSite(siteId);
|
||||
return site.entry.title;
|
||||
} catch (error) {
|
||||
this.handleError(`${this.constructor.name} ${this.getTitle.name}`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async createSite(
|
||||
title: string,
|
||||
visibility?: string,
|
||||
description?: string,
|
||||
siteId?: string
|
||||
): Promise<SiteEntry | null> {
|
||||
const site = {
|
||||
title,
|
||||
visibility: visibility || SITE_VISIBILITY.PUBLIC,
|
||||
description: description,
|
||||
id: siteId || title
|
||||
} as SiteBody;
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.sitesApi.createSite(site);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createSite.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async createSitePrivate(
|
||||
title: string,
|
||||
description?: string,
|
||||
siteId?: string
|
||||
): Promise<SiteEntry> {
|
||||
return this.createSite(title, SITE_VISIBILITY.PRIVATE, description, siteId);
|
||||
}
|
||||
|
||||
async createSiteModerated(
|
||||
title: string,
|
||||
description?: string,
|
||||
siteId?: string
|
||||
): Promise<SiteEntry> {
|
||||
return this.createSite(
|
||||
title,
|
||||
SITE_VISIBILITY.MODERATED,
|
||||
description,
|
||||
siteId
|
||||
);
|
||||
}
|
||||
|
||||
async createSites(titles: string[], visibility?: string): Promise<any> {
|
||||
try {
|
||||
return titles.reduce(async (previous: any, current: any) => {
|
||||
await previous;
|
||||
return this.createSite(current, visibility);
|
||||
}, Promise.resolve());
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.createSites.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async createSitesPrivate(siteNames: string[]): Promise<any> {
|
||||
return this.createSites(siteNames, SITE_VISIBILITY.PRIVATE);
|
||||
}
|
||||
|
||||
async deleteSite(siteId: string, permanent: boolean = true) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.sitesApi.deleteSite(siteId, { permanent });
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.deleteSite.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async deleteSites(siteIds: string[], permanent: boolean = true) {
|
||||
try {
|
||||
return siteIds.reduce(async (previous, current) => {
|
||||
await previous;
|
||||
return this.deleteSite(current, permanent);
|
||||
}, Promise.resolve());
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.deleteSites.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async deleteAllUserSites(permanent: boolean = true) {
|
||||
try {
|
||||
const siteIds = (await this.getSites()).list.entries.map(
|
||||
entries => entries.entry.id
|
||||
);
|
||||
|
||||
return await siteIds.reduce(async (previous, current) => {
|
||||
await previous;
|
||||
return this.deleteSite(current, permanent);
|
||||
}, Promise.resolve());
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.deleteAllUserSites.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async updateSiteMember(siteId: string, userId: string, role: string) {
|
||||
const siteRole = {
|
||||
role: role
|
||||
} as SiteMemberRoleBody;
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.sitesApi.updateSiteMembership(siteId, userId, siteRole);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.updateSiteMember.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async addSiteMember(siteId: string, userId: string, role: string) {
|
||||
const memberBody = {
|
||||
id: userId,
|
||||
role: role
|
||||
} as SiteMemberBody;
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.sitesApi.createSiteMembership(siteId, memberBody);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.addSiteMember.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async addSiteConsumer(
|
||||
siteId: string,
|
||||
userId: string
|
||||
): Promise<SiteMemberEntry> {
|
||||
return this.addSiteMember(siteId, userId, SITE_ROLES.SITE_CONSUMER.ROLE);
|
||||
}
|
||||
|
||||
async addSiteContributor(
|
||||
siteId: string,
|
||||
userId: string
|
||||
): Promise<SiteMemberEntry> {
|
||||
return this.addSiteMember(siteId, userId, SITE_ROLES.SITE_CONTRIBUTOR.ROLE);
|
||||
}
|
||||
|
||||
async addSiteCollaborator(
|
||||
siteId: string,
|
||||
userId: string
|
||||
): Promise<SiteMemberEntry> {
|
||||
return this.addSiteMember(
|
||||
siteId,
|
||||
userId,
|
||||
SITE_ROLES.SITE_COLLABORATOR.ROLE
|
||||
);
|
||||
}
|
||||
|
||||
async addSiteManager(
|
||||
siteId: string,
|
||||
userId: string
|
||||
): Promise<SiteMemberEntry> {
|
||||
return this.addSiteMember(siteId, userId, SITE_ROLES.SITE_MANAGER.ROLE);
|
||||
}
|
||||
|
||||
async deleteSiteMember(siteId: string, userId: string) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.sitesApi.deleteSiteMembership(siteId, userId);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.deleteSiteMember.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async requestToJoin(
|
||||
siteId: string
|
||||
): Promise<SiteMembershipRequestEntry | null> {
|
||||
const body = {
|
||||
id: siteId
|
||||
};
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.sitesApi.createSiteMembershipRequestForPerson(
|
||||
'-me-',
|
||||
body
|
||||
);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.requestToJoin.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async hasMembershipRequest(siteId: string) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
const requests = (await this.sitesApi.getSiteMembershipRequests(
|
||||
'-me-'
|
||||
)).list.entries.map(e => e.entry.id);
|
||||
return requests.includes(siteId);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.hasMembershipRequest.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async waitForApi(data: { expect: number }) {
|
||||
try {
|
||||
const sites = async () => {
|
||||
const totalItems = (await this.getSites()).list.pagination.totalItems;
|
||||
if (totalItems !== data.expect) {
|
||||
return Promise.reject(totalItems);
|
||||
} else {
|
||||
return Promise.resolve(totalItems);
|
||||
}
|
||||
};
|
||||
|
||||
return await Utils.retryCall(sites);
|
||||
} catch (error) {
|
||||
Logger.error(`${this.constructor.name} ${this.waitForApi.name} catch: `);
|
||||
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,112 @@
|
||||
/*!
|
||||
* @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 { RepoApi } from '../repo-api';
|
||||
import { Logger } from '@alfresco/adf-testing';
|
||||
import { Utils } from '../../../../utilities/utils';
|
||||
import { TrashcanApi as AdfTrashcanApi } from '@alfresco/js-api';
|
||||
|
||||
export class TrashcanApi extends RepoApi {
|
||||
trashcanApi = new AdfTrashcanApi(this.alfrescoJsApi);
|
||||
|
||||
constructor(username?: string, password?: string) {
|
||||
super(username, password);
|
||||
}
|
||||
|
||||
async permanentlyDelete(id: string) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.trashcanApi.deleteDeletedNode(id);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.permanentlyDelete.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async restore(id: string) {
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.trashcanApi.restoreDeletedNode(id);
|
||||
} catch (error) {
|
||||
this.handleError(`${this.constructor.name} ${this.restore.name}`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getDeletedNodes() {
|
||||
const opts = {
|
||||
maxItems: 1000
|
||||
};
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.trashcanApi.listDeletedNodes(opts);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.getDeletedNodes.name}`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async emptyTrash() {
|
||||
try {
|
||||
const ids = (await this.getDeletedNodes()).list.entries.map(
|
||||
entries => entries.entry.id
|
||||
);
|
||||
|
||||
return await ids.reduce(async (previous, current) => {
|
||||
await previous;
|
||||
return this.permanentlyDelete(current);
|
||||
}, Promise.resolve());
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.emptyTrash.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async waitForApi(data: { expect: number }) {
|
||||
try {
|
||||
const deletedFiles = async () => {
|
||||
const totalItems = (await this.getDeletedNodes()).list.pagination
|
||||
.totalItems;
|
||||
if (totalItems !== data.expect) {
|
||||
return Promise.reject(totalItems);
|
||||
} else {
|
||||
return Promise.resolve(totalItems);
|
||||
}
|
||||
};
|
||||
|
||||
return await Utils.retryCall(deletedFiles);
|
||||
} catch (error) {
|
||||
Logger.error(`${this.constructor.name} ${this.waitForApi.name} catch: `);
|
||||
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,92 @@
|
||||
/*!
|
||||
* @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 { RepoApi } from '../repo-api';
|
||||
import { UploadApi as AdfUploadApi } from '@alfresco/js-api';
|
||||
import { browser } from 'protractor';
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
export class UploadApi extends RepoApi {
|
||||
upload = new AdfUploadApi(this.alfrescoJsApi);
|
||||
e2eRootPath = browser.params.e2eRootPath;
|
||||
|
||||
constructor(username?, password?) {
|
||||
super(username, password);
|
||||
}
|
||||
|
||||
async uploadFile(fileName: string, parentFolderId: string = '-my-') {
|
||||
const file = fs.createReadStream(
|
||||
`${this.e2eRootPath}/resources/test-files/${fileName}`
|
||||
);
|
||||
const opts = {
|
||||
name: file.name,
|
||||
nodeType: 'cm:content'
|
||||
};
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.upload.uploadFile(file, '', parentFolderId, null, opts);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.uploadFile.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async uploadFileWithRename(
|
||||
fileName: string,
|
||||
parentId: string = '-my-',
|
||||
newName: string,
|
||||
title: string = '',
|
||||
description: string = ''
|
||||
) {
|
||||
const file = fs.createReadStream(
|
||||
`${this.e2eRootPath}/resources/test-files/${fileName}`
|
||||
);
|
||||
const nodeProps = {
|
||||
properties: {
|
||||
'cm:title': title,
|
||||
'cm:description': description
|
||||
}
|
||||
};
|
||||
|
||||
const opts = {
|
||||
name: newName,
|
||||
nodeType: 'cm:content'
|
||||
};
|
||||
|
||||
try {
|
||||
await this.apiAuth();
|
||||
return await this.upload.uploadFile(file, '', parentId, nodeProps, opts);
|
||||
} catch (error) {
|
||||
this.handleError(
|
||||
`${this.constructor.name} ${this.uploadFileWithRename.name}`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
97
projects/aca-testing-shared/src/utilities/repo-client/repo-client.ts
Executable file
97
projects/aca-testing-shared/src/utilities/repo-client/repo-client.ts
Executable 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 { browser } from 'protractor';
|
||||
import { PeopleApi } from './apis/people/people-api';
|
||||
import { NodesApi } from './apis/nodes/nodes-api';
|
||||
import { CommentsApi } from './apis/comments/comments-api';
|
||||
import { SitesApi } from './apis/sites/sites-api';
|
||||
import { FavoritesApi } from './apis/favorites/favorites-api';
|
||||
import { QueriesApi } from './apis/queries/queries-api';
|
||||
import { SharedLinksApi } from './apis/shared-links/shared-links-api';
|
||||
import { TrashcanApi } from './apis/trashcan/trashcan-api';
|
||||
import { SearchApi } from './apis/search/search-api';
|
||||
import { UploadApi } from './apis/upload/upload-api';
|
||||
import { AuthenticationApi } from './apis/authentication/authentication-api';
|
||||
|
||||
export class RepoClient {
|
||||
constructor(
|
||||
private username: string = browser.params.ADMIN_USERNAME,
|
||||
private password: string = browser.params.ADMIN_PASSWORD
|
||||
) {}
|
||||
|
||||
private get auth() {
|
||||
const { username, password } = this;
|
||||
return { username, password };
|
||||
}
|
||||
|
||||
get people() {
|
||||
return new PeopleApi(this.auth.username, this.auth.password);
|
||||
}
|
||||
|
||||
get nodes() {
|
||||
return new NodesApi(this.auth.username, this.auth.password);
|
||||
}
|
||||
|
||||
get comments() {
|
||||
return new CommentsApi(this.auth.username, this.auth.password);
|
||||
}
|
||||
|
||||
get sites() {
|
||||
return new SitesApi(this.auth.username, this.auth.password);
|
||||
}
|
||||
|
||||
get favorites() {
|
||||
return new FavoritesApi(this.auth.username, this.auth.password);
|
||||
}
|
||||
|
||||
get shared() {
|
||||
return new SharedLinksApi(this.auth.username, this.auth.password);
|
||||
}
|
||||
|
||||
get trashcan() {
|
||||
return new TrashcanApi(this.auth.username, this.auth.password);
|
||||
}
|
||||
|
||||
get search() {
|
||||
return new SearchApi(this.auth.username, this.auth.password);
|
||||
}
|
||||
|
||||
get queries() {
|
||||
return new QueriesApi(this.auth.username, this.auth.password);
|
||||
}
|
||||
|
||||
get upload() {
|
||||
return new UploadApi(this.auth.username, this.auth.password);
|
||||
}
|
||||
|
||||
get authentication() {
|
||||
return new AuthenticationApi(this.auth.username, this.auth.password);
|
||||
}
|
||||
}
|
||||
|
||||
export * from './apis/nodes/node-body-create';
|
||||
export * from './apis/nodes/node-content-tree';
|
||||
export * from './apis/nodes/nodes-api';
|
344
projects/aca-testing-shared/src/utilities/utils.ts
Normal file
344
projects/aca-testing-shared/src/utilities/utils.ts
Normal file
@@ -0,0 +1,344 @@
|
||||
/*!
|
||||
* @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,
|
||||
protractor,
|
||||
ElementFinder,
|
||||
ExpectedConditions as EC,
|
||||
by,
|
||||
logging,
|
||||
until,
|
||||
WebElement
|
||||
} from 'protractor';
|
||||
import { Logger } from '@alfresco/adf-testing';
|
||||
import { BROWSER_WAIT_TIMEOUT } from '../configs';
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const StreamZip = require('node-stream-zip');
|
||||
|
||||
export async function typeText(
|
||||
element: ElementFinder,
|
||||
text: string
|
||||
): Promise<void> {
|
||||
await element.clear();
|
||||
await element.sendKeys(text);
|
||||
}
|
||||
|
||||
export async function clearTextWithBackspace(
|
||||
element: ElementFinder
|
||||
): Promise<void> {
|
||||
await element.clear();
|
||||
await element.sendKeys(
|
||||
' ',
|
||||
protractor.Key.CONTROL,
|
||||
'a',
|
||||
protractor.Key.NULL,
|
||||
protractor.Key.BACK_SPACE
|
||||
);
|
||||
}
|
||||
|
||||
export async function waitElement(
|
||||
css: string,
|
||||
errorMessage?: string
|
||||
): Promise<WebElement> {
|
||||
return browser.wait(
|
||||
until.elementLocated(by.css(css)),
|
||||
BROWSER_WAIT_TIMEOUT,
|
||||
errorMessage || `Timeout waiting for element: ${css}`
|
||||
);
|
||||
}
|
||||
|
||||
export async function waitForClickable(
|
||||
element: ElementFinder,
|
||||
errorMessage?: string
|
||||
): Promise<void> {
|
||||
await browser.wait(
|
||||
EC.elementToBeClickable(element),
|
||||
BROWSER_WAIT_TIMEOUT,
|
||||
errorMessage ||
|
||||
`Timeout waiting for element to be clickable: ${element.locator()}`
|
||||
);
|
||||
}
|
||||
|
||||
export async function waitForVisibility(
|
||||
element: ElementFinder,
|
||||
errorMessage?: string
|
||||
): Promise<void> {
|
||||
await browser.wait(
|
||||
EC.visibilityOf(element),
|
||||
BROWSER_WAIT_TIMEOUT,
|
||||
errorMessage ||
|
||||
`Timeout waiting for element visibility: ${element.locator()}`
|
||||
);
|
||||
}
|
||||
|
||||
export async function waitForInvisibility(
|
||||
element: ElementFinder,
|
||||
errorMessage?: string
|
||||
): Promise<void> {
|
||||
await browser.wait(
|
||||
EC.invisibilityOf(element),
|
||||
BROWSER_WAIT_TIMEOUT,
|
||||
errorMessage ||
|
||||
`Timeout waiting for element visibility: ${element.locator()}`
|
||||
);
|
||||
}
|
||||
|
||||
export async function waitForPresence(
|
||||
element: ElementFinder,
|
||||
errorMessage?: string
|
||||
): Promise<void> {
|
||||
await browser.wait(
|
||||
EC.presenceOf(element),
|
||||
BROWSER_WAIT_TIMEOUT,
|
||||
errorMessage || `Timeout waiting for element presence: ${element.locator()}`
|
||||
);
|
||||
}
|
||||
|
||||
export async function waitForStaleness(
|
||||
element: ElementFinder,
|
||||
errorMessage?: string
|
||||
): Promise<void> {
|
||||
await browser.wait(
|
||||
EC.stalenessOf(element),
|
||||
BROWSER_WAIT_TIMEOUT,
|
||||
errorMessage || `Timeout waiting element staleness: ${element.locator()}`
|
||||
);
|
||||
}
|
||||
|
||||
export const isPresentAndEnabled = async (
|
||||
element: ElementFinder
|
||||
): Promise<boolean> => {
|
||||
const isPresent = await element.isPresent();
|
||||
|
||||
if (isPresent) {
|
||||
return element.isEnabled();
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const isPresentAndDisplayed = async (
|
||||
element: ElementFinder
|
||||
): Promise<boolean> => {
|
||||
const isPresent = await element.isPresent();
|
||||
|
||||
if (isPresent) {
|
||||
return element.isDisplayed();
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export class Utils {
|
||||
static string257 =
|
||||
'assembly doctor offender limit clearance inspiration baker fraud active apples trait brainstorm concept breaks down presidential \
|
||||
reluctance summary communication patience books opponent banana economist head develop project swear unanimous read conservation';
|
||||
|
||||
static string513 =
|
||||
'great indirect brain tune other expectation fun silver drain tumble rhythm harmful wander picture distribute opera complication copyright \
|
||||
explosion snack ride pool machinery pair frog joint wrestle video referee drive window cage falsify happen tablet horror thank conception \
|
||||
extension decay dismiss platform respect ceremony applaud absorption presentation dominate race courtship soprano body \
|
||||
lighter track cinema tread tick climate lend summit singer radical flower visual negotiation promises cooperative live';
|
||||
|
||||
static random(): string {
|
||||
return Math.random()
|
||||
.toString(36)
|
||||
.substring(5, 10)
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
static async clearLocalStorage(): Promise<void> {
|
||||
await browser.executeScript('window.localStorage.clear();');
|
||||
}
|
||||
|
||||
static async setSessionStorageFromConfig(
|
||||
configFileName: string
|
||||
): Promise<void> {
|
||||
const configFile = `${
|
||||
browser.params.e2eRootPath
|
||||
}/resources/extensibility-configs/${configFileName}`;
|
||||
const fileContent = JSON.stringify(
|
||||
fs.readFileSync(configFile, { encoding: 'utf8' })
|
||||
);
|
||||
|
||||
await browser.executeScript(
|
||||
`window.sessionStorage.setItem('app.extension.config', ${fileContent});`
|
||||
);
|
||||
}
|
||||
|
||||
static retryCall(
|
||||
fn: () => Promise<any>,
|
||||
retry: number = 30,
|
||||
delay: number = 1000
|
||||
): Promise<any> {
|
||||
const pause = duration => new Promise(res => setTimeout(res, duration));
|
||||
|
||||
const run = retries => {
|
||||
return fn().catch(err =>
|
||||
retries > 1
|
||||
? pause(delay).then(() => run(retries - 1))
|
||||
: Promise.reject(err)
|
||||
);
|
||||
};
|
||||
|
||||
return run(retry);
|
||||
}
|
||||
|
||||
static async clearFieldWithBackspace(elem: ElementFinder): Promise<void> {
|
||||
const text = await elem.getAttribute('value');
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
await elem.sendKeys(protractor.Key.BACK_SPACE);
|
||||
}
|
||||
}
|
||||
|
||||
static async fileExistsOnOS(
|
||||
fileName: string,
|
||||
folderName: string = '',
|
||||
subFolderName: string = ''
|
||||
): Promise<any> {
|
||||
const config = await browser.getProcessedConfig();
|
||||
const filePath = path.join(
|
||||
config.params.downloadFolder,
|
||||
folderName,
|
||||
subFolderName,
|
||||
fileName
|
||||
);
|
||||
|
||||
let tries = 15;
|
||||
|
||||
return new Promise(function(resolve) {
|
||||
const checkExist = setInterval(() => {
|
||||
fs.access(filePath, function(error) {
|
||||
tries--;
|
||||
|
||||
if (error && tries === 0) {
|
||||
clearInterval(checkExist);
|
||||
resolve(false);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
clearInterval(checkExist);
|
||||
resolve(true);
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
static async renameFile(oldName: string, newName: string): Promise<void> {
|
||||
const config = await browser.getProcessedConfig();
|
||||
const oldFilePath = path.join(config.params.downloadFolder, oldName);
|
||||
const newFilePath = path.join(config.params.downloadFolder, newName);
|
||||
|
||||
const fileExists = await this.fileExistsOnOS(oldName);
|
||||
|
||||
if (fileExists) {
|
||||
fs.rename(oldFilePath, newFilePath, function(err) {
|
||||
if (err) {
|
||||
Logger.error('==== rename err: ', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static async unzip(
|
||||
filename: string,
|
||||
unzippedName: string = ''
|
||||
): Promise<void> {
|
||||
const config = await browser.getProcessedConfig();
|
||||
const filePath = path.join(config.params.downloadFolder, filename);
|
||||
const output = path.join(
|
||||
config.params.downloadFolder,
|
||||
unzippedName ? unzippedName : ''
|
||||
);
|
||||
|
||||
const zip = new StreamZip({
|
||||
file: filePath,
|
||||
storeEntries: true
|
||||
});
|
||||
|
||||
await zip.on('error', err => {
|
||||
Logger.error('=== unzip err: ', err);
|
||||
});
|
||||
|
||||
await zip.on('ready', async () => {
|
||||
if (unzippedName) {
|
||||
await fs.mkdirSync(output);
|
||||
}
|
||||
await zip.extract(null, output, async () => {
|
||||
await zip.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static async pressEscape(): Promise<void> {
|
||||
await browser
|
||||
.actions()
|
||||
.sendKeys(protractor.Key.ESCAPE)
|
||||
.perform();
|
||||
}
|
||||
|
||||
static async pressTab(): Promise<void> {
|
||||
await browser
|
||||
.actions()
|
||||
.sendKeys(protractor.Key.TAB)
|
||||
.perform();
|
||||
}
|
||||
|
||||
static async pressCmd(): Promise<void> {
|
||||
await browser
|
||||
.actions()
|
||||
.sendKeys(protractor.Key.COMMAND)
|
||||
.perform();
|
||||
}
|
||||
|
||||
static async releaseKeyPressed(): Promise<void> {
|
||||
await browser
|
||||
.actions()
|
||||
.sendKeys(protractor.Key.NULL)
|
||||
.perform();
|
||||
}
|
||||
|
||||
static async getBrowserLog(): Promise<logging.Entry[]> {
|
||||
return browser
|
||||
.manage()
|
||||
.logs()
|
||||
.get('browser');
|
||||
}
|
||||
|
||||
static formatDate(date: string): string {
|
||||
return new Date(date).toLocaleDateString('en-US');
|
||||
}
|
||||
|
||||
static async uploadFileNewVersion(fileFromOS: string): Promise<void> {
|
||||
const el = browser.element(by.id('app-upload-file-version'));
|
||||
await el.sendKeys(
|
||||
`${browser.params.e2eRootPath}/resources/test-files/${fileFromOS}`
|
||||
);
|
||||
}
|
||||
}
|
32
projects/aca-testing-shared/tsconfig.lib.json
Normal file
32
projects/aca-testing-shared/tsconfig.lib.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/aca-testing",
|
||||
"target": "es2015",
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"inlineSources": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"importHelpers": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"annotateForClosureCompiler": true,
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"fullTemplateTypeCheck": true,
|
||||
"strictInjectionParameters": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
17
projects/aca-testing-shared/tslint.json
Normal file
17
projects/aca-testing-shared/tslint.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"lib",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"lib",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user