mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-06-30 18:14:45 +00:00
initial e2e integration (#329)
* e2e integration with ci * update travis config * try always build image * build the app in production mode * try to stop previous * stop default postgresql service * try upgrade selenium-webdriver * disable Gecko for webdriver-manager * use stable chrome and latest protractor
This commit is contained in:
parent
54a7f3679c
commit
09aeeff204
13
.travis.yml
13
.travis.yml
@ -1,13 +1,24 @@
|
||||
dist: trusty
|
||||
sudo: required
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
addons:
|
||||
chrome: stable
|
||||
|
||||
language: node_js
|
||||
node_js:
|
||||
- "8"
|
||||
|
||||
before_script:
|
||||
# Disable services enabled by default
|
||||
- sudo /etc/init.d/postgresql stop
|
||||
|
||||
install:
|
||||
- npm install -g npm@latest
|
||||
- npm ci
|
||||
|
||||
script:
|
||||
- npm run test:ci
|
||||
# - docker-compose stop
|
||||
- npm run build && npm run e2e:docker
|
||||
|
43
e2e/components/component.ts
Executable file
43
e2e/components/component.ts
Executable file
@ -0,0 +1,43 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, element, by, ExpectedConditions as EC, browser } from 'protractor';
|
||||
import { BROWSER_WAIT_TIMEOUT } from '../configs';
|
||||
|
||||
export abstract class Component {
|
||||
component: ElementFinder;
|
||||
|
||||
constructor(selector: string, ancestor?: ElementFinder) {
|
||||
const locator = by.css(selector);
|
||||
|
||||
this.component = ancestor
|
||||
? ancestor.element(locator)
|
||||
: element(locator);
|
||||
}
|
||||
|
||||
wait() {
|
||||
return browser.wait(EC.presenceOf(this.component), BROWSER_WAIT_TIMEOUT);
|
||||
}
|
||||
}
|
32
e2e/components/components.ts
Executable file
32
e2e/components/components.ts
Executable file
@ -0,0 +1,32 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 './pagination/pagination';
|
||||
export * from './sidenav/sidenav';
|
||||
export * from './toolbar/toolbar';
|
243
e2e/components/data-table/data-table.ts
Executable file
243
e2e/components/data-table/data-table.ts
Executable file
@ -0,0 +1,243 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, promise, by, browser, ExpectedConditions as EC, protractor } from 'protractor';
|
||||
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
|
||||
import { Component } from '../component';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
export class DataTable extends Component {
|
||||
private static selectors = {
|
||||
root: 'adf-datatable',
|
||||
|
||||
head: '.adf-datatable-header',
|
||||
columnHeader: '.adf-datatable-row .adf-datatable-table-cell-header',
|
||||
sortedColumnHeader: `
|
||||
.adf-data-table__header--sorted-asc,
|
||||
.adf-data-table__header--sorted-desc
|
||||
`,
|
||||
|
||||
body: '.adf-datatable-body',
|
||||
row: '.adf-datatable-row[role]',
|
||||
selectedRow: '.adf-datatable-row.is-selected',
|
||||
cell: '.adf-data-table-cell',
|
||||
locationLink: 'app-location-link',
|
||||
|
||||
selectedIcon: '.mat-icon',
|
||||
|
||||
emptyListContainer: 'div.adf-no-content-container',
|
||||
emptyFolderDragAndDrop: '.adf-empty-list_template .adf-empty-folder',
|
||||
|
||||
emptyListTitle: '.app-empty-folder__title',
|
||||
emptyListSubtitle: '.app-empty-folder__subtitle',
|
||||
emptyListText: '.app-empty-folder__text'
|
||||
};
|
||||
|
||||
head: ElementFinder = this.component.element(by.css(DataTable.selectors.head));
|
||||
body: ElementFinder = this.component.element(by.css(DataTable.selectors.body));
|
||||
cell = by.css(DataTable.selectors.cell);
|
||||
locationLink = by.css(DataTable.selectors.locationLink);
|
||||
emptyList: ElementFinder = this.component.element(by.css(DataTable.selectors.emptyListContainer));
|
||||
emptyFolderDragAndDrop: ElementFinder = this.component.element(by.css(DataTable.selectors.emptyFolderDragAndDrop));
|
||||
emptyListTitle: ElementFinder = this.component.element(by.css(DataTable.selectors.emptyListTitle));
|
||||
emptyListSubtitle: ElementFinder = this.component.element(by.css(DataTable.selectors.emptyListSubtitle));
|
||||
emptyListText: ElementArrayFinder = this.component.all(by.css(DataTable.selectors.emptyListText));
|
||||
|
||||
constructor(ancestor?: ElementFinder) {
|
||||
super(DataTable.selectors.root, ancestor);
|
||||
}
|
||||
|
||||
// Wait methods (waits for elements)
|
||||
waitForHeader() {
|
||||
return browser.wait(EC.presenceOf(this.head), BROWSER_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
waitForEmptyState() {
|
||||
return browser.wait(EC.presenceOf(this.emptyList), BROWSER_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
// Header/Column methods
|
||||
getColumnHeaders(): ElementArrayFinder {
|
||||
const locator = by.css(DataTable.selectors.columnHeader);
|
||||
return this.head.all(locator);
|
||||
}
|
||||
|
||||
getNthColumnHeader(nth: number): ElementFinder {
|
||||
return this.getColumnHeaders().get(nth - 1);
|
||||
}
|
||||
|
||||
getColumnHeaderByLabel(label: string): ElementFinder {
|
||||
const locator = by.cssContainingText(DataTable.selectors.columnHeader, label);
|
||||
return this.head.element(locator);
|
||||
}
|
||||
|
||||
getSortedColumnHeader(): ElementFinder {
|
||||
const locator = by.css(DataTable.selectors.sortedColumnHeader);
|
||||
return this.head.element(locator);
|
||||
}
|
||||
|
||||
getSortingOrder() {
|
||||
return this.getSortedColumnHeader().getAttribute('class')
|
||||
.then(str => {
|
||||
if (str.includes('asc')) {
|
||||
return 'asc';
|
||||
} else {
|
||||
if (str.includes('desc')) {
|
||||
return 'desc';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sortByColumn(columnName: string): promise.Promise<void> {
|
||||
const column = this.getColumnHeaderByLabel(columnName);
|
||||
const click = browser.actions().mouseMove(column).click();
|
||||
|
||||
return click.perform();
|
||||
}
|
||||
|
||||
// Rows methods
|
||||
getRows(): ElementArrayFinder {
|
||||
return this.body.all(by.css(DataTable.selectors.row));
|
||||
}
|
||||
|
||||
getSelectedRows(): ElementArrayFinder {
|
||||
return this.body.all(by.css(DataTable.selectors.selectedRow));
|
||||
}
|
||||
|
||||
countSelectedRows(): promise.Promise<number> {
|
||||
return this.getSelectedRows().count();
|
||||
}
|
||||
|
||||
getNthRow(nth: number): ElementFinder {
|
||||
return this.getRows().get(nth - 1);
|
||||
}
|
||||
|
||||
getRowName(name: string): ElementFinder {
|
||||
return this.body.element(by.cssContainingText(`.adf-data-table-cell span`, name));
|
||||
}
|
||||
|
||||
getItemNameTooltip(name: string): promise.Promise<string> {
|
||||
return this.getRowName(name).getAttribute('title');
|
||||
}
|
||||
|
||||
countRows(): promise.Promise<number> {
|
||||
return this.getRows().count();
|
||||
}
|
||||
|
||||
hasCheckMarkIcon(itemName: string) {
|
||||
return this.getRowName(itemName).element(by.xpath(`./ancestor::div[contains(@class, 'adf-datatable-row')]`))
|
||||
.element(by.css(DataTable.selectors.selectedIcon)).isPresent();
|
||||
}
|
||||
|
||||
// Navigation/selection methods
|
||||
doubleClickOnItemName(name: string): promise.Promise<any> {
|
||||
const dblClick = browser.actions()
|
||||
.mouseMove(this.getRowName(name))
|
||||
.click()
|
||||
.click();
|
||||
|
||||
return dblClick.perform();
|
||||
}
|
||||
|
||||
clickOnItemName(name: string): promise.Promise<any> {
|
||||
const item = this.getRowName(name);
|
||||
return Utils.waitUntilElementClickable(item)
|
||||
.then(() => this.getRowName(name).click());
|
||||
}
|
||||
|
||||
selectMultipleItems(names: string[]): promise.Promise<void> {
|
||||
return this.clearSelection()
|
||||
.then(() => browser.actions().sendKeys(protractor.Key.COMMAND).perform())
|
||||
.then(() => {
|
||||
names.forEach(name => {
|
||||
this.clickOnItemName(name);
|
||||
});
|
||||
})
|
||||
.then(() => browser.actions().sendKeys(protractor.Key.NULL).perform());
|
||||
}
|
||||
|
||||
clearSelection(): promise.Promise<void> {
|
||||
return this.getSelectedRows().count()
|
||||
.then(count => {
|
||||
if (count !== 0) { browser.refresh().then(() => this.waitForHeader()); }
|
||||
});
|
||||
}
|
||||
|
||||
getItemLocation(name: string) {
|
||||
return this.getRowName(name).element(by.xpath(`./ancestor::div[contains(@class, 'adf-datatable-row')]`))
|
||||
.element(this.locationLink);
|
||||
}
|
||||
|
||||
getItemLocationTooltip(name: string): promise.Promise<string> {
|
||||
return this.getItemLocation(name).$('a').getAttribute('title');
|
||||
}
|
||||
|
||||
clickItemLocation(name: string) {
|
||||
return this.getItemLocation(name).click();
|
||||
}
|
||||
|
||||
// empty state methods
|
||||
isEmptyList(): promise.Promise<boolean> {
|
||||
return this.emptyList.isPresent();
|
||||
}
|
||||
|
||||
isEmptyWithDragAndDrop(): promise.Promise<boolean> {
|
||||
return this.emptyFolderDragAndDrop.isDisplayed();
|
||||
}
|
||||
|
||||
getEmptyDragAndDropText(): promise.Promise<string> {
|
||||
return this.isEmptyWithDragAndDrop()
|
||||
.then(() => {
|
||||
return this.emptyFolderDragAndDrop.getText();
|
||||
});
|
||||
}
|
||||
|
||||
getEmptyStateTitle(): promise.Promise<string> {
|
||||
return this.isEmptyList()
|
||||
.then(() => {
|
||||
return this.emptyListTitle.getText();
|
||||
});
|
||||
}
|
||||
|
||||
getEmptyStateSubtitle(): promise.Promise<string> {
|
||||
return this.isEmptyList()
|
||||
.then(() => {
|
||||
return this.emptyListSubtitle.getText();
|
||||
});
|
||||
}
|
||||
|
||||
getEmptyStateText(): promise.Promise<string> {
|
||||
return this.isEmptyList()
|
||||
.then(() => {
|
||||
return this.emptyListText.getText();
|
||||
});
|
||||
}
|
||||
|
||||
getCellsContainingName(name: string) {
|
||||
return this.getRows().all(by.cssContainingText(DataTable.selectors.cell, name))
|
||||
.map(cell => cell.getText());
|
||||
}
|
||||
}
|
108
e2e/components/dialog/create-edit-folder-dialog.ts
Executable file
108
e2e/components/dialog/create-edit-folder-dialog.ts
Executable file
@ -0,0 +1,108 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, protractor, ExpectedConditions as EC, promise } from 'protractor';
|
||||
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
|
||||
import { Component } from '../component';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
export class CreateOrEditFolderDialog extends Component {
|
||||
private static selectors = {
|
||||
root: 'adf-folder-dialog',
|
||||
|
||||
title: '.mat-dialog-title',
|
||||
nameInput: 'input[placeholder="Name" i]',
|
||||
descriptionTextArea: 'textarea[placeholder="Description" i]',
|
||||
button: '.mat-dialog-actions button',
|
||||
validationMessage: '.mat-hint span'
|
||||
};
|
||||
|
||||
title: ElementFinder = this.component.element(by.css(CreateOrEditFolderDialog.selectors.title));
|
||||
nameInput: ElementFinder = this.component.element(by.css(CreateOrEditFolderDialog.selectors.nameInput));
|
||||
descriptionTextArea: ElementFinder = this.component.element(by.css(CreateOrEditFolderDialog.selectors.descriptionTextArea));
|
||||
createButton: ElementFinder = this.component.element(by.cssContainingText(CreateOrEditFolderDialog.selectors.button, 'Create'));
|
||||
cancelButton: ElementFinder = this.component.element(by.cssContainingText(CreateOrEditFolderDialog.selectors.button, 'Cancel'));
|
||||
updateButton: ElementFinder = this.component.element(by.cssContainingText(CreateOrEditFolderDialog.selectors.button, 'Update'));
|
||||
validationMessage: ElementFinder = this.component.element(by.css(CreateOrEditFolderDialog.selectors.validationMessage));
|
||||
|
||||
constructor(ancestor?: ElementFinder) {
|
||||
super(CreateOrEditFolderDialog.selectors.root, ancestor);
|
||||
}
|
||||
|
||||
waitForDialogToOpen() {
|
||||
return browser.wait(EC.presenceOf(this.title), BROWSER_WAIT_TIMEOUT)
|
||||
.then(() => browser.wait(EC.presenceOf(browser.element(by.css('.cdk-overlay-backdrop'))), BROWSER_WAIT_TIMEOUT));
|
||||
|
||||
}
|
||||
|
||||
waitForDialogToClose() {
|
||||
return browser.wait(EC.stalenessOf(this.title), BROWSER_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
getTitle(): promise.Promise<string> {
|
||||
return this.title.getText();
|
||||
}
|
||||
|
||||
isValidationMessageDisplayed(): promise.Promise<boolean> {
|
||||
return this.validationMessage.isDisplayed();
|
||||
}
|
||||
|
||||
getValidationMessage(): promise.Promise<string> {
|
||||
return this.isValidationMessageDisplayed()
|
||||
.then(() => this.validationMessage.getText());
|
||||
}
|
||||
|
||||
enterName(name: string) {
|
||||
return this.nameInput.clear()
|
||||
// .then(() => this.nameInput.sendKeys(name));
|
||||
.then(() => Utils.typeInField(this.nameInput, name));
|
||||
}
|
||||
|
||||
enterDescription(description: string) {
|
||||
return this.descriptionTextArea.clear()
|
||||
// .then(() => this.descriptionTextArea.sendKeys(description));
|
||||
.then(() => Utils.typeInField(this.descriptionTextArea, description));
|
||||
}
|
||||
|
||||
deleteNameWithBackspace(): promise.Promise<void> {
|
||||
return this.nameInput.clear()
|
||||
.then(() => {
|
||||
return this.nameInput.sendKeys(' ', protractor.Key.CONTROL, 'a', protractor.Key.NULL, protractor.Key.BACK_SPACE);
|
||||
});
|
||||
}
|
||||
|
||||
clickCreate() {
|
||||
return this.createButton.click();
|
||||
}
|
||||
|
||||
clickCancel() {
|
||||
return this.cancelButton.click()
|
||||
.then(() => this.waitForDialogToClose());
|
||||
}
|
||||
|
||||
clickUpdate() {
|
||||
return this.updateButton.click();
|
||||
}
|
||||
}
|
42
e2e/components/header/header.ts
Executable file
42
e2e/components/header/header.ts
Executable file
@ -0,0 +1,42 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 } from 'protractor';
|
||||
import { Component } from '../component';
|
||||
import { UserInfo } from './user-info';
|
||||
|
||||
export class Header extends Component {
|
||||
private locators = {
|
||||
logoLink: by.css('.app-menu__title'),
|
||||
userInfo: by.css('app-current-user')
|
||||
};
|
||||
|
||||
logoLink: ElementFinder = this.component.element(this.locators.logoLink);
|
||||
userInfo: UserInfo = new UserInfo(this.component);
|
||||
|
||||
constructor(ancestor?: ElementFinder) {
|
||||
super('app-header', ancestor);
|
||||
}
|
||||
}
|
64
e2e/components/header/user-info.ts
Executable file
64
e2e/components/header/user-info.ts
Executable file
@ -0,0 +1,64 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, promise } from 'protractor';
|
||||
import { Menu } from '../menu/menu';
|
||||
import { Component } from '../component';
|
||||
|
||||
export class UserInfo extends Component {
|
||||
private locators = {
|
||||
avatar: by.css('.current-user__avatar'),
|
||||
fullName: by.css('.current-user__full-name'),
|
||||
menuItems: by.css('[mat-menu-item]')
|
||||
};
|
||||
|
||||
fullName: ElementFinder = this.component.element(this.locators.fullName);
|
||||
avatar: ElementFinder = this.component.element(this.locators.avatar);
|
||||
|
||||
menu: Menu = new Menu();
|
||||
|
||||
constructor(ancestor?: ElementFinder) {
|
||||
super('app-current-user', ancestor);
|
||||
}
|
||||
|
||||
openMenu(): promise.Promise<Menu> {
|
||||
const { menu, avatar } = this;
|
||||
|
||||
return avatar.click()
|
||||
.then(() => menu.wait())
|
||||
.then(() => menu);
|
||||
}
|
||||
|
||||
get name(): promise.Promise<string> {
|
||||
return this.fullName.getText();
|
||||
}
|
||||
|
||||
signOut(): promise.Promise<void> {
|
||||
return this.openMenu()
|
||||
.then(menu => {
|
||||
menu.clickMenuItem('Sign out');
|
||||
});
|
||||
}
|
||||
}
|
105
e2e/components/login/login.ts
Executable file
105
e2e/components/login/login.ts
Executable file
@ -0,0 +1,105 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, promise } from 'protractor';
|
||||
import { Component } from '../component';
|
||||
|
||||
export class LoginComponent extends Component {
|
||||
static selector = 'adf-login';
|
||||
|
||||
private locators = {
|
||||
usernameInput: by.css('input#username'),
|
||||
passwordInput: by.css('input#password'),
|
||||
passwordVisibility: by.css('.adf-login-password-icon'),
|
||||
submitButton: by.css('button#login-button'),
|
||||
errorMessage: by.css('.login-error-message'),
|
||||
copyright: by.css('.copyright')
|
||||
};
|
||||
|
||||
usernameInput: ElementFinder = this.component.element(this.locators.usernameInput);
|
||||
passwordInput: ElementFinder = this.component.element(this.locators.passwordInput);
|
||||
submitButton: ElementFinder = this.component.element(this.locators.submitButton);
|
||||
errorMessage: ElementFinder = this.component.element(this.locators.errorMessage);
|
||||
copyright: ElementFinder = this.component.element(this.locators.copyright);
|
||||
passwordVisibility: ElementFinder = this.component.element(this.locators.passwordVisibility);
|
||||
|
||||
constructor(ancestor?: ElementFinder) {
|
||||
super(LoginComponent.selector, ancestor);
|
||||
}
|
||||
|
||||
enterUsername(username: string): LoginComponent {
|
||||
const { usernameInput } = this;
|
||||
|
||||
usernameInput.clear();
|
||||
usernameInput.sendKeys(username);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
enterPassword(password: string): LoginComponent {
|
||||
const { passwordInput } = this;
|
||||
|
||||
passwordInput.clear();
|
||||
passwordInput.sendKeys(password);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
enterCredentials(username: string, password: string) {
|
||||
this.enterUsername(username).enterPassword(password);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
submit(): promise.Promise<void> {
|
||||
return this.submitButton.click();
|
||||
}
|
||||
|
||||
getPasswordVisibility() {
|
||||
return this.passwordVisibility.getText()
|
||||
.then(text => {
|
||||
if (text.endsWith('visibility_off')) {
|
||||
return false;
|
||||
} else {
|
||||
if (text.endsWith('visibility')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
isPasswordShown() {
|
||||
return this.passwordInput.getAttribute('type')
|
||||
.then(type => {
|
||||
if (type === 'text') {
|
||||
return true;
|
||||
} else {
|
||||
if (type === 'password') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
106
e2e/components/menu/menu.ts
Executable file
106
e2e/components/menu/menu.ts
Executable file
@ -0,0 +1,106 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, ExpectedConditions as EC, promise } from 'protractor';
|
||||
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
|
||||
import { Component } from '../component';
|
||||
|
||||
export class Menu extends Component {
|
||||
private static selectors = {
|
||||
root: '.mat-menu-panel',
|
||||
item: '.mat-menu-item',
|
||||
icon: '.mat-icon',
|
||||
uploadFiles: 'input[id="upload-multiple-files"]'
|
||||
};
|
||||
|
||||
items: ElementArrayFinder = this.component.all(by.css(Menu.selectors.item));
|
||||
backdrop: ElementFinder = browser.element(by.css('.cdk-overlay-backdrop'));
|
||||
uploadFiles: ElementFinder = this.component.element(by.css(Menu.selectors.uploadFiles));
|
||||
|
||||
constructor(ancestor?: ElementFinder) {
|
||||
super(Menu.selectors.root, ancestor);
|
||||
}
|
||||
|
||||
waitForMenuToOpen() {
|
||||
return browser.wait(EC.presenceOf(browser.element(by.css('.mat-menu-panel'))), BROWSER_WAIT_TIMEOUT)
|
||||
.then(() => browser.wait(EC.presenceOf(browser.element(by.css('.cdk-overlay-backdrop'))), BROWSER_WAIT_TIMEOUT))
|
||||
.then(() => browser.wait(EC.visibilityOf(this.items.get(0)), BROWSER_WAIT_TIMEOUT));
|
||||
}
|
||||
|
||||
waitForMenuToClose() {
|
||||
return browser.wait(EC.not(EC.presenceOf(browser.element(by.css('.mat-menu-panel')))), BROWSER_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
closeMenu() {
|
||||
if (this.backdrop.isPresent()) {
|
||||
return this.backdrop.click();
|
||||
} else {
|
||||
return browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform();
|
||||
}
|
||||
}
|
||||
|
||||
getNthItem(nth: number): ElementFinder {
|
||||
return this.items.get(nth - 1);
|
||||
}
|
||||
|
||||
getItemByLabel(menuItem: string): ElementFinder {
|
||||
return this.component.element(by.cssContainingText(Menu.selectors.item, menuItem));
|
||||
}
|
||||
|
||||
getItemTooltip(menuItem: string): promise.Promise<string> {
|
||||
return this.getItemByLabel(menuItem).getAttribute('title');
|
||||
}
|
||||
|
||||
getItemIconText(menuItem: string) {
|
||||
return this.getItemByLabel(menuItem).element(by.css(Menu.selectors.icon)).getText();
|
||||
|
||||
}
|
||||
|
||||
getItemsCount(): promise.Promise<number> {
|
||||
return this.items.count();
|
||||
}
|
||||
|
||||
clickNthItem(nth: number): promise.Promise<any> {
|
||||
const elem = this.getNthItem(nth);
|
||||
return browser.wait(EC.elementToBeClickable(elem), BROWSER_WAIT_TIMEOUT)
|
||||
.then(() => browser.actions().mouseMove(elem).click().perform())
|
||||
.then(() => this.waitForMenuToClose());
|
||||
}
|
||||
|
||||
clickMenuItem(menuItem: string): promise.Promise<any> {
|
||||
const elem = this.getItemByLabel(menuItem);
|
||||
return browser.wait(EC.elementToBeClickable(elem), BROWSER_WAIT_TIMEOUT)
|
||||
.then(() => elem.click())
|
||||
.then(() => this.waitForMenuToClose());
|
||||
}
|
||||
|
||||
isMenuItemPresent(title: string): promise.Promise<boolean> {
|
||||
return this.component.element(by.cssContainingText(Menu.selectors.item, title)).isPresent();
|
||||
}
|
||||
|
||||
uploadFile() {
|
||||
return this.uploadFiles;
|
||||
}
|
||||
}
|
98
e2e/components/pagination/pagination.ts
Executable file
98
e2e/components/pagination/pagination.ts
Executable file
@ -0,0 +1,98 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, promise, by } from 'protractor';
|
||||
import { Menu } from '../menu/menu';
|
||||
import { Component } from '../component';
|
||||
|
||||
export class Pagination extends Component {
|
||||
private static selectors = {
|
||||
root: 'adf-pagination',
|
||||
range: '.adf-pagination__range',
|
||||
maxItems: '.adf-pagination__max-items',
|
||||
currentPage: '.adf-pagination__current-page',
|
||||
totalPages: '.adf-pagination__total-pages',
|
||||
|
||||
previousButton: '.adf-pagination__previous-button',
|
||||
nextButton: '.adf-pagination__next-button',
|
||||
maxItemsButton: '.adf-pagination__max-items + button[mat-icon-button]',
|
||||
pagesButton: '.adf-pagination__current-page + button[mat-icon-button]'
|
||||
};
|
||||
|
||||
range: ElementFinder = this.component.element(by.css(Pagination.selectors.range));
|
||||
maxItems: ElementFinder = this.component.element(by.css(Pagination.selectors.maxItems));
|
||||
currentPage: ElementFinder = this.component.element(by.css(Pagination.selectors.currentPage));
|
||||
totalPages: ElementFinder = this.component.element(by.css(Pagination.selectors.totalPages));
|
||||
previousButton: ElementFinder = this.component.element(by.css(Pagination.selectors.previousButton));
|
||||
nextButton: ElementFinder = this.component.element(by.css(Pagination.selectors.nextButton));
|
||||
maxItemsButton: ElementFinder = this.component.element(by.css(Pagination.selectors.maxItemsButton));
|
||||
pagesButton: ElementFinder = this.component.element(by.css(Pagination.selectors.pagesButton));
|
||||
|
||||
menu: Menu = new Menu();
|
||||
|
||||
constructor(ancestor?: ElementFinder) {
|
||||
super(Pagination.selectors.root, ancestor);
|
||||
}
|
||||
|
||||
openMaxItemsMenu(): promise.Promise<Menu> {
|
||||
const { menu, maxItemsButton } = this;
|
||||
|
||||
return maxItemsButton.click()
|
||||
.then(() => menu.waitForMenuToOpen())
|
||||
.then(() => menu);
|
||||
}
|
||||
|
||||
openCurrentPageMenu(): promise.Promise<Menu> {
|
||||
const { menu, pagesButton } = this;
|
||||
|
||||
return pagesButton.click()
|
||||
.then(() => menu.waitForMenuToOpen())
|
||||
.then(() => menu);
|
||||
}
|
||||
|
||||
getText(elem: ElementFinder) {
|
||||
return elem.getText();
|
||||
}
|
||||
|
||||
resetToDefaultPageSize(): promise.Promise<any> {
|
||||
return this.openMaxItemsMenu()
|
||||
.then(menu => menu.clickMenuItem('25'))
|
||||
.then(() => this.menu.waitForMenuToClose());
|
||||
}
|
||||
|
||||
resetToDefaultPageNumber(): promise.Promise<any> {
|
||||
return this.openCurrentPageMenu()
|
||||
.then(menu => menu.clickMenuItem('1'))
|
||||
.then(() => this.menu.waitForMenuToClose());
|
||||
}
|
||||
|
||||
clickNext(): promise.Promise<any> {
|
||||
return this.nextButton.click();
|
||||
}
|
||||
|
||||
clickPrevious(): promise.Promise<any> {
|
||||
return this.previousButton.click();
|
||||
}
|
||||
}
|
82
e2e/components/sidenav/sidenav.ts
Executable file
82
e2e/components/sidenav/sidenav.ts
Executable file
@ -0,0 +1,82 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, promise } from 'protractor';
|
||||
import { Menu } from '../menu/menu';
|
||||
import { Component } from '../component';
|
||||
|
||||
export class Sidenav extends Component {
|
||||
private static selectors = {
|
||||
root: 'app-sidenav',
|
||||
link: '.sidenav-menu__item',
|
||||
label: '.menu__item--label',
|
||||
activeLink: '.menu__item--active',
|
||||
newButton: '.sidenav__section--new__button'
|
||||
};
|
||||
|
||||
links: ElementArrayFinder = this.component.all(by.css(Sidenav.selectors.link));
|
||||
activeLink: ElementFinder = this.component.element(by.css(Sidenav.selectors.activeLink));
|
||||
newButton: ElementArrayFinder = this.component.all(by.css(Sidenav.selectors.newButton));
|
||||
|
||||
menu: Menu = new Menu();
|
||||
|
||||
constructor(ancestor?: ElementFinder) {
|
||||
super(Sidenav.selectors.root, ancestor);
|
||||
}
|
||||
|
||||
openNewMenu(): promise.Promise<Menu> {
|
||||
const { menu, newButton } = this;
|
||||
|
||||
return newButton.click()
|
||||
.then(() => menu.waitForMenuToOpen())
|
||||
.then(() => menu);
|
||||
}
|
||||
|
||||
openCreateDialog(): any {
|
||||
return this.openNewMenu()
|
||||
.then(() => this.menu.clickMenuItem('Create folder'));
|
||||
}
|
||||
|
||||
isActiveByLabel(label: string): promise.Promise<boolean> {
|
||||
return this.getLinkByLabel(label).getAttribute('class')
|
||||
.then(className => className.includes(Sidenav.selectors.activeLink.replace('.', '')));
|
||||
}
|
||||
|
||||
getLink(label: string): ElementFinder {
|
||||
return this.component.element(by.cssContainingText(Sidenav.selectors.link, label));
|
||||
}
|
||||
|
||||
getLinkByLabel(label: string): ElementFinder {
|
||||
return this.component.element(by.cssContainingText(Sidenav.selectors.label, label));
|
||||
}
|
||||
|
||||
getLinkTooltip(label: string): promise.Promise<string> {
|
||||
return this.getLink(label).getAttribute('title');
|
||||
}
|
||||
|
||||
navigateToLinkByLabel(label: string): promise.Promise<any> {
|
||||
return this.getLinkByLabel(label).click();
|
||||
}
|
||||
}
|
64
e2e/components/toolbar/toolbar-actions.ts
Executable file
64
e2e/components/toolbar/toolbar-actions.ts
Executable file
@ -0,0 +1,64 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, promise } from 'protractor';
|
||||
import { Menu } from '../menu/menu';
|
||||
import { Component } from '../component';
|
||||
|
||||
export class ToolbarActions extends Component {
|
||||
private static selectors = {
|
||||
root: 'adf-toolbar',
|
||||
button: '.mat-icon-button'
|
||||
};
|
||||
|
||||
menu: Menu = new Menu();
|
||||
buttons: ElementArrayFinder = this.component.all(by.css(ToolbarActions.selectors.button));
|
||||
|
||||
constructor(ancestor?: ElementFinder) {
|
||||
super(ToolbarActions.selectors.root, ancestor);
|
||||
}
|
||||
|
||||
isEmpty(): promise.Promise<boolean> {
|
||||
return this.buttons.count().then(count => (count === 0));
|
||||
}
|
||||
|
||||
isButtonPresent(title: string): promise.Promise<boolean> {
|
||||
return this.component.element(by.css(`${ToolbarActions.selectors.button}[title="${title}"]`)).isPresent();
|
||||
}
|
||||
|
||||
getButtonByLabel(label: string): ElementFinder {
|
||||
return this.component.element(by.cssContainingText(ToolbarActions.selectors.button, label));
|
||||
}
|
||||
|
||||
getButtonByTitleAttribute(title: string): ElementFinder {
|
||||
return this.component.element(by.css(`${ToolbarActions.selectors.button}[title="${title}"]`));
|
||||
}
|
||||
|
||||
openMoreMenu() {
|
||||
return this.getButtonByTitleAttribute('More actions').click()
|
||||
.then(() => this.menu.waitForMenuToOpen())
|
||||
.then(() => this.menu);
|
||||
}
|
||||
}
|
82
e2e/components/toolbar/toolbar-breadcrumb.ts
Executable file
82
e2e/components/toolbar/toolbar-breadcrumb.ts
Executable file
@ -0,0 +1,82 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, promise } from 'protractor';
|
||||
import { Component } from '../component';
|
||||
|
||||
export class ToolbarBreadcrumb extends Component {
|
||||
private static selectors = {
|
||||
root: 'adf-breadcrumb',
|
||||
item: '.adf-breadcrumb-item',
|
||||
currentItem: '.adf-breadcrumb-item-current'
|
||||
};
|
||||
|
||||
items: ElementArrayFinder = this.component.all(by.css(ToolbarBreadcrumb.selectors.item));
|
||||
currentItem: ElementFinder = this.component.element(by.css(ToolbarBreadcrumb.selectors.currentItem));
|
||||
|
||||
constructor(ancestor?: ElementFinder) {
|
||||
super(ToolbarBreadcrumb.selectors.root, ancestor);
|
||||
}
|
||||
|
||||
getNthItem(nth: number): ElementFinder {
|
||||
return this.items.get(nth - 1);
|
||||
}
|
||||
|
||||
getNthItemName(nth: number) {
|
||||
return this.getNthItem(nth).getText();
|
||||
}
|
||||
|
||||
getItemsCount(): promise.Promise<number> {
|
||||
return this.items.count();
|
||||
}
|
||||
|
||||
getAllItems() {
|
||||
return this.items.map(elem => elem.getText().then(str => str.split('\nchevron_right')[0]));
|
||||
}
|
||||
|
||||
getFirstItemName(): promise.Promise<string> {
|
||||
return this.items.get(0).getText();
|
||||
}
|
||||
|
||||
getCurrentItem() {
|
||||
return this.currentItem;
|
||||
}
|
||||
|
||||
getCurrentItemName(): promise.Promise<string> {
|
||||
return this.currentItem.getText();
|
||||
}
|
||||
|
||||
clickItem(name: string) {
|
||||
return this.component.element(by.css(`${ToolbarBreadcrumb.selectors.item}[title=${name}]`)).click();
|
||||
}
|
||||
|
||||
clickNthItem(nth: number) {
|
||||
return this.getNthItem(nth).click();
|
||||
}
|
||||
|
||||
getNthItemTooltip(nth: number) {
|
||||
return this.getNthItem(nth).getAttribute('title');
|
||||
}
|
||||
}
|
42
e2e/components/toolbar/toolbar.ts
Executable file
42
e2e/components/toolbar/toolbar.ts
Executable file
@ -0,0 +1,42 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 } from 'protractor';
|
||||
import { Component } from '../component';
|
||||
import { ToolbarActions } from './toolbar-actions';
|
||||
import { ToolbarBreadcrumb } from './toolbar-breadcrumb';
|
||||
|
||||
export class Toolbar extends Component {
|
||||
private static selectors = {
|
||||
root: '.inner-layout__header'
|
||||
};
|
||||
|
||||
actions: ToolbarActions = new ToolbarActions(this.component);
|
||||
breadcrumb: ToolbarBreadcrumb = new ToolbarBreadcrumb(this.component);
|
||||
|
||||
constructor(ancestor?: ElementFinder) {
|
||||
super(Toolbar.selectors.root, ancestor);
|
||||
}
|
||||
}
|
78
e2e/configs.ts
Executable file
78
e2e/configs.ts
Executable file
@ -0,0 +1,78 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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_RESOLUTION_WIDTH = 1200;
|
||||
export const BROWSER_RESOLUTION_HEIGHT = 800;
|
||||
|
||||
export const BROWSER_WAIT_TIMEOUT = 30000;
|
||||
|
||||
// Application configs
|
||||
export const APP_HOST = 'http://localhost:3000';
|
||||
|
||||
// Repository configs
|
||||
export const REPO_API_HOST = 'http://localhost:8080';
|
||||
export const REPO_API_TENANT = '-default-';
|
||||
|
||||
// Admin details
|
||||
export const ADMIN_USERNAME = 'admin';
|
||||
export const ADMIN_PASSWORD = 'admin';
|
||||
export const ADMIN_FULL_NAME = 'Administrator';
|
||||
|
||||
// Application Routes
|
||||
export const APP_ROUTES = {
|
||||
FAVORITES: '/favorites',
|
||||
FILE_LIBRARIES: '/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',
|
||||
SHARED_FILES: 'Shared',
|
||||
RECENT_FILES: 'Recent Files',
|
||||
FAVORITES: 'Favorites',
|
||||
TRASH: 'Trash'
|
||||
};
|
||||
|
||||
// Site visibility
|
||||
export const SITE_VISIBILITY = {
|
||||
PUBLIC: 'PUBLIC',
|
||||
MODERATED: 'MODERATED',
|
||||
PRIVATE: 'PRIVATE'
|
||||
};
|
||||
|
||||
// Site roles
|
||||
export const SITE_ROLES = {
|
||||
SITE_CONSUMER: 'SiteConsumer',
|
||||
SITE_COLLABORATOR: 'SiteCollaborator',
|
||||
SITE_CONTRIBUTOR: 'SiteContributor',
|
||||
SITE_MANAGER: 'SiteManager'
|
||||
};
|
40
e2e/pages/browsing-page.ts
Executable file
40
e2e/pages/browsing-page.ts
Executable file
@ -0,0 +1,40 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { promise } from 'protractor';
|
||||
import { Header, DataTable, Pagination, Toolbar, Sidenav } from '../components/components';
|
||||
import { Page } from './page';
|
||||
|
||||
export class BrowsingPage extends Page {
|
||||
header = new Header(this.app);
|
||||
sidenav = new Sidenav(this.app);
|
||||
toolbar = new Toolbar(this.app);
|
||||
dataTable = new DataTable(this.app);
|
||||
pagination = new Pagination(this.app);
|
||||
|
||||
signOut(): promise.Promise<void> {
|
||||
return this.header.userInfo.signOut();
|
||||
}
|
||||
}
|
75
e2e/pages/login-page.ts
Executable file
75
e2e/pages/login-page.ts
Executable file
@ -0,0 +1,75 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, ExpectedConditions as EC, promise } from 'protractor';
|
||||
import { LoginComponent } from '../components/components';
|
||||
import { Page } from './page';
|
||||
import { Utils } from '../utilities/utils';
|
||||
|
||||
import {
|
||||
ADMIN_USERNAME,
|
||||
ADMIN_PASSWORD,
|
||||
BROWSER_WAIT_TIMEOUT,
|
||||
APP_ROUTES
|
||||
} from '../configs';
|
||||
|
||||
export class LoginPage extends Page {
|
||||
login: LoginComponent = new LoginComponent(this.app);
|
||||
|
||||
/** @override */
|
||||
constructor() {
|
||||
super(APP_ROUTES.LOGIN);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
load(): promise.Promise<any> {
|
||||
return super.load().then(() => {
|
||||
const { submitButton } = this.login;
|
||||
const hasSubmitButton = EC.presenceOf(submitButton);
|
||||
|
||||
return browser.wait(hasSubmitButton, BROWSER_WAIT_TIMEOUT)
|
||||
.then(() => Utils.clearLocalStorage())
|
||||
.then(() => browser.manage().deleteAllCookies());
|
||||
});
|
||||
}
|
||||
|
||||
loginWith(username: string, password?: string): promise.Promise<any> {
|
||||
const pass = password || username;
|
||||
return this.load()
|
||||
.then(() => this.login.enterCredentials(username, pass).submit())
|
||||
.then(() => super.waitForApp());
|
||||
}
|
||||
|
||||
loginWithAdmin(): promise.Promise<any> {
|
||||
return this.load()
|
||||
.then(() => this.loginWith(ADMIN_USERNAME, ADMIN_PASSWORD));
|
||||
}
|
||||
|
||||
tryLoginWith(username: string, password?: string): promise.Promise<void> {
|
||||
const pass = password || username;
|
||||
return this.load()
|
||||
.then(() => this.login.enterCredentials(username, pass).submit())
|
||||
.then(() => browser.wait(EC.presenceOf(this.login.errorMessage), BROWSER_WAIT_TIMEOUT));
|
||||
}
|
||||
}
|
43
e2e/pages/logout-page.ts
Executable file
43
e2e/pages/logout-page.ts
Executable file
@ -0,0 +1,43 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { promise } from 'protractor';
|
||||
import { Page } from './page';
|
||||
import { APP_ROUTES } from '../configs';
|
||||
import { Utils } from '../utilities/utils';
|
||||
|
||||
export class LogoutPage extends Page {
|
||||
/** @override */
|
||||
constructor() {
|
||||
super(APP_ROUTES.LOGIN);
|
||||
}
|
||||
|
||||
/** @override */
|
||||
load(): promise.Promise<any> {
|
||||
return Utils.clearLocalStorage()
|
||||
.then(() => Utils.clearSessionStorage())
|
||||
.then(() => super.load());
|
||||
}
|
||||
}
|
110
e2e/pages/page.ts
Executable file
110
e2e/pages/page.ts
Executable file
@ -0,0 +1,110 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, element, by, ElementFinder, promise, ExpectedConditions as EC } from 'protractor';
|
||||
import { BROWSER_WAIT_TIMEOUT } from './../configs';
|
||||
|
||||
export abstract class Page {
|
||||
private static USE_HASH_STRATEGY = true;
|
||||
|
||||
private locators = {
|
||||
app: by.css('app-root'),
|
||||
layout: by.css('app-layout'),
|
||||
overlay: by.css('.cdk-overlay-container'),
|
||||
dialogContainer: by.css('.mat-dialog-container'),
|
||||
snackBarContainer: '.cdk-overlay-pane snack-bar-container.mat-snack-bar-container',
|
||||
snackBar: 'simple-snack-bar',
|
||||
snackBarAction: 'button.mat-simple-snackbar-action'
|
||||
};
|
||||
|
||||
public app: ElementFinder = element(this.locators.app);
|
||||
public layout: ElementFinder = element(this.locators.layout);
|
||||
public overlay: ElementFinder = element(this.locators.overlay);
|
||||
snackBar: ElementFinder = browser.$(this.locators.snackBar);
|
||||
dialogContainer: ElementFinder = element(this.locators.dialogContainer);
|
||||
snackBarContainer: ElementFinder = browser.$(this.locators.snackBarContainer);
|
||||
snackBarAction: ElementFinder = browser.$(this.locators.snackBarAction);
|
||||
|
||||
constructor(public url: string = '') {}
|
||||
|
||||
get title(): promise.Promise<string> {
|
||||
return browser.getTitle();
|
||||
}
|
||||
|
||||
load(relativeUrl: string = ''): promise.Promise<void> {
|
||||
const hash = Page.USE_HASH_STRATEGY ? '/#' : '';
|
||||
const path = `${hash}${this.url}${relativeUrl}`;
|
||||
|
||||
return browser.get(path);
|
||||
}
|
||||
|
||||
waitForApp() {
|
||||
return browser.wait(EC.presenceOf(this.layout), BROWSER_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
waitForSnackBarToAppear() {
|
||||
return browser.wait(EC.visibilityOf(this.snackBarContainer), BROWSER_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
waitForSnackBarToClose() {
|
||||
return browser.wait(EC.not(EC.visibilityOf(this.snackBarContainer)), BROWSER_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
waitForDialog() {
|
||||
return browser.wait(EC.visibilityOf(this.dialogContainer), BROWSER_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
waitForDialogToClose() {
|
||||
return browser.wait(EC.not(EC.visibilityOf(this.dialogContainer)), BROWSER_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
refresh(): promise.Promise<void> {
|
||||
return browser.refresh();
|
||||
}
|
||||
|
||||
getDialogActionByLabel(label) {
|
||||
return element(by.cssContainingText('.mat-button-wrapper', label))
|
||||
}
|
||||
|
||||
isSnackBarDisplayed(): promise.Promise<boolean> {
|
||||
return this.snackBar.isDisplayed();
|
||||
}
|
||||
|
||||
getSnackBarMessage(): promise.Promise<string> {
|
||||
return this.waitForSnackBarToAppear()
|
||||
.then(() => this.snackBar.getAttribute('innerText'));
|
||||
}
|
||||
|
||||
getSnackBarAction() {
|
||||
return this.waitForSnackBarToAppear()
|
||||
.then(() => this.snackBarAction);
|
||||
}
|
||||
|
||||
clickSnackBarAction() {
|
||||
return browser.executeScript(function (elem) {
|
||||
elem.click();
|
||||
}, this.snackBarAction);
|
||||
}
|
||||
}
|
28
e2e/pages/pages.ts
Executable file
28
e2e/pages/pages.ts
Executable file
@ -0,0 +1,28 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 './logout-page';
|
278
e2e/suites/actions/create-folder.test.ts
Executable file
278
e2e/suites/actions/create-folder.test.ts
Executable file
@ -0,0 +1,278 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SIDEBAR_LABELS, SITE_VISIBILITY, SITE_ROLES } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { CreateOrEditFolderDialog } from '../../components/dialog/create-edit-folder-dialog';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Create folder', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const parent = `parent-${Utils.random()}`;
|
||||
const folderName1 = `folder-${Utils.random()}`;
|
||||
const folderName2 = `folder-${Utils.random()}`;
|
||||
const folderDescription = 'description of my folder';
|
||||
const duplicateFolderName = `folder-${Utils.random()}`;
|
||||
const nameWithSpaces = ` folder-${Utils.random()} `;
|
||||
|
||||
const siteName = `site-private-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const personalFilesPage = new BrowsingPage();
|
||||
const createDialog = new CreateOrEditFolderDialog();
|
||||
const { dataTable } = personalFilesPage;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PRIVATE))
|
||||
.then(() => apis.admin.nodes.createFolders([ folderName1 ], `Sites/${siteName}/documentLibrary`))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_CONSUMER))
|
||||
.then(() => apis.user.nodes.createFolders([ duplicateFolderName ], parent))
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise
|
||||
.all([
|
||||
apis.admin.sites.deleteSite(siteName),
|
||||
apis.user.nodes.deleteNodes([ parent ]),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('option is enabled when having enough permissions', () => {
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(parent)
|
||||
.then(() => personalFilesPage.sidenav.openNewMenu())
|
||||
.then(menu => {
|
||||
const isEnabled = menu.getItemByLabel('Create folder').isEnabled();
|
||||
expect(isEnabled).toBe(true, 'Create folder is not enabled');
|
||||
});
|
||||
});
|
||||
|
||||
it('creates new folder with name', () => {
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(parent)
|
||||
.then(() => personalFilesPage.sidenav.openCreateDialog())
|
||||
.then(() => createDialog.waitForDialogToOpen())
|
||||
.then(() => createDialog.enterName(folderName1))
|
||||
.then(() => createDialog.clickCreate())
|
||||
.then(() => createDialog.waitForDialogToClose())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
const isPresent = dataTable.getRowName(folderName1).isPresent();
|
||||
expect(isPresent).toBe(true, 'Folder not displayed in list view');
|
||||
});
|
||||
});
|
||||
|
||||
it('creates new folder with name and description', () => {
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(parent)
|
||||
.then(() => personalFilesPage.sidenav.openCreateDialog())
|
||||
.then(() => createDialog.waitForDialogToOpen())
|
||||
.then(() => createDialog.enterName(folderName2))
|
||||
.then(() => createDialog.enterDescription(folderDescription))
|
||||
.then(() => createDialog.clickCreate())
|
||||
.then(() => createDialog.waitForDialogToClose())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => expect(dataTable.getRowName(folderName2).isPresent()).toBe(true, 'Folder not displayed'))
|
||||
.then(() => apis.user.nodes.getNodeDescription(folderName2, parent))
|
||||
.then(desc => expect(desc).toEqual(folderDescription));
|
||||
});
|
||||
|
||||
it('enabled option tooltip', () => {
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(parent)
|
||||
.then(() => personalFilesPage.sidenav.openNewMenu())
|
||||
.then(menu => browser.actions().mouseMove(menu.getItemByLabel('Create folder')).perform()
|
||||
.then(() => menu))
|
||||
.then(menu => {
|
||||
expect(menu.getItemTooltip('Create folder')).toContain('Create new folder');
|
||||
});
|
||||
});
|
||||
|
||||
it('option is disabled when not enough permissions', () => {
|
||||
const fileLibrariesPage = new BrowsingPage();
|
||||
|
||||
fileLibrariesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => fileLibrariesPage.dataTable.doubleClickOnItemName(siteName))
|
||||
.then(() => fileLibrariesPage.dataTable.doubleClickOnItemName(folderName1))
|
||||
.then(() => fileLibrariesPage.sidenav.openNewMenu())
|
||||
.then(menu => {
|
||||
const isEnabled = menu.getItemByLabel('Create folder').isEnabled();
|
||||
expect(isEnabled).toBe(false, 'Create folder is not disabled');
|
||||
});
|
||||
});
|
||||
|
||||
it('disabled option tooltip', () => {
|
||||
const fileLibrariesPage = new BrowsingPage();
|
||||
|
||||
fileLibrariesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => fileLibrariesPage.dataTable.doubleClickOnItemName(siteName))
|
||||
.then(() => fileLibrariesPage.dataTable.doubleClickOnItemName(folderName1))
|
||||
.then(() => fileLibrariesPage.sidenav.openNewMenu())
|
||||
.then(menu => browser.actions().mouseMove(menu.getItemByLabel('Create folder')).perform()
|
||||
.then(() => menu))
|
||||
.then(menu => {
|
||||
const tooltip = menu.getItemTooltip('Create folder');
|
||||
expect(tooltip).toContain(`You can't create a folder here`);
|
||||
});
|
||||
});
|
||||
|
||||
it('dialog UI elements', () => {
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(parent)
|
||||
.then(() => personalFilesPage.sidenav.openCreateDialog())
|
||||
.then(() => createDialog.waitForDialogToOpen())
|
||||
.then(() => {
|
||||
const dialogTitle = createDialog.getTitle();
|
||||
const isFolderNameDisplayed = createDialog.nameInput.isDisplayed();
|
||||
const isDescriptionDisplayed = createDialog.descriptionTextArea.isDisplayed();
|
||||
const isCreateEnabled = createDialog.createButton.isEnabled();
|
||||
const isCancelEnabled = createDialog.cancelButton.isEnabled();
|
||||
|
||||
expect(dialogTitle).toMatch('Create new folder');
|
||||
expect(isFolderNameDisplayed).toBe(true, 'Name input is not displayed');
|
||||
expect(isDescriptionDisplayed).toBe(true, 'Description field is not displayed');
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
|
||||
expect(isCancelEnabled).toBe(true, 'Cancel button is not enabled');
|
||||
});
|
||||
});
|
||||
|
||||
it('with empty folder name', () => {
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(parent)
|
||||
.then(() => personalFilesPage.sidenav.openCreateDialog())
|
||||
.then(() => createDialog.waitForDialogToOpen())
|
||||
.then(() => createDialog.deleteNameWithBackspace())
|
||||
.then(() => {
|
||||
const isCreateEnabled = createDialog.createButton.isEnabled();
|
||||
const validationMessage = createDialog.getValidationMessage();
|
||||
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is enabled');
|
||||
expect(validationMessage).toMatch('Folder name is required');
|
||||
});
|
||||
});
|
||||
|
||||
it('with folder name ending with a dot "."', () => {
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(parent)
|
||||
.then(() => personalFilesPage.sidenav.openCreateDialog())
|
||||
.then(() => createDialog.waitForDialogToOpen())
|
||||
.then(() => createDialog.enterName('folder-name.'))
|
||||
.then(() => {
|
||||
const isCreateEnabled = createDialog.createButton.isEnabled();
|
||||
const validationMessage = createDialog.getValidationMessage();
|
||||
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
|
||||
expect(validationMessage).toMatch(`Folder name can't end with a period .`);
|
||||
});
|
||||
});
|
||||
|
||||
it('with folder name containing special characters', () => {
|
||||
const namesWithSpecialChars = [ 'a*a', 'a"a', 'a<a', 'a>a', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a' ];
|
||||
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(parent)
|
||||
.then(() => personalFilesPage.sidenav.openCreateDialog())
|
||||
.then(() => createDialog.waitForDialogToOpen())
|
||||
.then(() => namesWithSpecialChars.forEach(name => {
|
||||
createDialog.enterName(name);
|
||||
|
||||
const isCreateEnabled = createDialog.createButton.isEnabled();
|
||||
const validationMessage = createDialog.getValidationMessage();
|
||||
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
|
||||
expect(validationMessage).toContain(`Folder name can't contain these characters`);
|
||||
}));
|
||||
});
|
||||
|
||||
it('with folder name containing only spaces', () => {
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(parent)
|
||||
.then(() => personalFilesPage.sidenav.openCreateDialog())
|
||||
.then(() => createDialog.waitForDialogToOpen())
|
||||
.then(() => createDialog.enterName(' '))
|
||||
.then(() => {
|
||||
const isCreateEnabled = createDialog.createButton.isEnabled();
|
||||
const validationMessage = createDialog.getValidationMessage();
|
||||
|
||||
expect(isCreateEnabled).toBe(false, 'Create button is not disabled');
|
||||
expect(validationMessage).toMatch(`Folder name can't contain only spaces`);
|
||||
});
|
||||
});
|
||||
|
||||
it('cancel folder creation', () => {
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(parent)
|
||||
.then(() => personalFilesPage.sidenav.openCreateDialog())
|
||||
.then(() => createDialog.waitForDialogToOpen())
|
||||
.then(() => createDialog.enterName('test'))
|
||||
.then(() => createDialog.enterDescription('test description'))
|
||||
.then(() => createDialog.clickCancel())
|
||||
.then(() => {
|
||||
expect(createDialog.component.isPresent()).not.toBe(true, 'dialog is not closed');
|
||||
});
|
||||
});
|
||||
|
||||
it('duplicate folder name', () => {
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(parent)
|
||||
.then(() => personalFilesPage.sidenav.openCreateDialog())
|
||||
.then(() => createDialog.waitForDialogToOpen())
|
||||
.then(() => createDialog.enterName(duplicateFolderName))
|
||||
.then(() => createDialog.clickCreate())
|
||||
.then(() => personalFilesPage.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toEqual(`There's already a folder with this name. Try a different name.`);
|
||||
expect(createDialog.component.isPresent()).toBe(true, 'dialog is not present');
|
||||
});
|
||||
});
|
||||
|
||||
it('trim ending spaces from folder name', () => {
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(parent)
|
||||
.then(() => personalFilesPage.sidenav.openCreateDialog())
|
||||
.then(() => createDialog.waitForDialogToOpen())
|
||||
.then(() => createDialog.enterName(nameWithSpaces))
|
||||
.then(() => createDialog.clickCreate())
|
||||
.then(() => createDialog.waitForDialogToClose())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
const isPresent = dataTable.getRowName(nameWithSpaces.trim()).isPresent();
|
||||
expect(isPresent).toBe(true, 'Folder not displayed in list view');
|
||||
});
|
||||
});
|
||||
});
|
503
e2e/suites/actions/delete.test.ts
Executable file
503
e2e/suites/actions/delete.test.ts
Executable file
@ -0,0 +1,503 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { SIDEBAR_LABELS } from '../../configs';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
describe('Delete content', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable, toolbar } = page;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username).then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
apis.admin.trashcan.emptyTrash().then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('on Personal Files', () => {
|
||||
const file1 = `file1-${Utils.random()}.txt`; let file1Id;
|
||||
const file2 = `file2-${Utils.random()}.txt`; let file2Id;
|
||||
const file3 = `file3-${Utils.random()}.txt`;
|
||||
const file4 = `file4-${Utils.random()}.txt`; let file4Id;
|
||||
const folder1 = `folder1-${Utils.random()}`; let folder1Id;
|
||||
const folder2 = `folder2-${Utils.random()}`; let folder2Id;
|
||||
const fileLocked1 = `fileLocked-${Utils.random()}.txt`; let fileLocked1Id;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.createFile(file1).then(resp => file1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(file2).then(resp => file2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolder(folder1).then(resp => folder1Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolder(folder2).then(resp => folder2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(file3, folder1Id))
|
||||
.then(() => apis.user.nodes.createFile(file4, folder2Id).then(resp => file4Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.lockFile(file4Id))
|
||||
|
||||
.then(() => apis.user.nodes.createFile(fileLocked1).then(resp => fileLocked1Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.lockFile(fileLocked1Id))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
page.refresh().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
logoutPage.load(),
|
||||
apis.user.nodes.unlockFile(file4Id)
|
||||
.then(() => apis.user.nodes.unlockFile(fileLocked1Id))
|
||||
.then(() => apis.user.nodes.deleteNodesById([file1Id, file2Id, folder1Id, folder2Id, fileLocked1Id]))
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('delete a file and check notification', () => {
|
||||
let items: number;
|
||||
page.dataTable.countRows().then(number => { items = number; });
|
||||
|
||||
dataTable.clickOnItemName(file1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toContain(`${file1} deleted`);
|
||||
expect(dataTable.getRowName(file1).isPresent()).toBe(false, 'Item was not removed from list');
|
||||
items--;
|
||||
expect(page.pagination.range.getText()).toContain(`1-${items} of ${items}`);
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => expect(dataTable.getRowName(file1).isPresent()).toBe(true, 'Item is not in trash'))
|
||||
|
||||
.then(() => apis.user.trashcan.restore(file1Id));
|
||||
});
|
||||
|
||||
it('delete multiple files and check notification', () => {
|
||||
let items: number;
|
||||
page.dataTable.countRows().then(number => { items = number; });
|
||||
|
||||
dataTable.selectMultipleItems([file1, file2])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toContain(`Deleted 2 items`);
|
||||
expect(dataTable.getRowName(file1).isPresent()).toBe(false, `${file1} was not removed from list`);
|
||||
expect(dataTable.getRowName(file2).isPresent()).toBe(false, `${file2} was not removed from list`);
|
||||
items = items - 2;
|
||||
expect(page.pagination.range.getText()).toContain(`1-${items} of ${items}`);
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(file1).isPresent()).toBe(true, `${file1} is not in trash`);
|
||||
expect(dataTable.getRowName(file2).isPresent()).toBe(true, `${file2} is not in trash`);
|
||||
})
|
||||
|
||||
.then(() => apis.user.trashcan.restore(file1Id))
|
||||
.then(() => apis.user.trashcan.restore(file2Id));
|
||||
});
|
||||
|
||||
it('delete a folder with content', () => {
|
||||
let items: number;
|
||||
page.dataTable.countRows().then(number => { items = number; });
|
||||
|
||||
dataTable.clickOnItemName(folder1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(folder1).isPresent()).toBe(false, 'Item was not removed from list');
|
||||
items--;
|
||||
expect(page.pagination.range.getText()).toContain(`1-${items} of ${items}`);
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(folder1).isPresent()).toBe(true, 'Item is not in trash');
|
||||
expect(dataTable.getRowName(file3).isPresent()).toBe(false, 'Item is in trash');
|
||||
})
|
||||
|
||||
.then(() => apis.user.trashcan.restore(folder1Id));
|
||||
});
|
||||
|
||||
it('delete a folder containing locked files', () => {
|
||||
dataTable.clickOnItemName(folder2)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toContain(`${folder2} couldn't be deleted`);
|
||||
expect(dataTable.getRowName(folder2).isPresent()).toBe(true, 'Item was removed from list');
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(folder2).isPresent()).toBe(false, 'Item is in trash');
|
||||
expect(dataTable.getRowName(file4).isPresent()).toBe(false, 'Item is in trash');
|
||||
});
|
||||
});
|
||||
|
||||
it('notification on multiple items deletion - some items fail to delete', () => {
|
||||
dataTable.selectMultipleItems([file1, folder2])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => expect(message).toContain(`Deleted 1 item, 1 couldn't be deleted`))
|
||||
|
||||
.then(() => apis.user.trashcan.restore(file1Id));
|
||||
});
|
||||
|
||||
it('Notification on multiple items deletion - all items fail to delete', () => {
|
||||
dataTable.selectMultipleItems([fileLocked1, folder2])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => expect(message).toEqual(`2 items couldn't be deleted`));
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Shared Files', () => {
|
||||
const sharedFile1 = `sharedFile1-${Utils.random()}.txt`; let sharedFile1Id;
|
||||
const sharedFile2 = `sharedFile2-${Utils.random()}.txt`; let sharedFile2Id;
|
||||
const sharedFile3 = `sharedFile3-${Utils.random()}.txt`; let sharedFile3Id;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.createFile(sharedFile1).then(resp => sharedFile1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(sharedFile2).then(resp => sharedFile2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(sharedFile3).then(resp => sharedFile3Id = resp.data.entry.id))
|
||||
.then(() => apis.user.shared.shareFilesByIds([sharedFile1Id, sharedFile2Id, sharedFile3Id]))
|
||||
.then(() => apis.user.shared.waitForApi({ expect: 3 }))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
page.refresh().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
logoutPage.load(),
|
||||
apis.user.nodes.deleteNodesById([sharedFile1Id, sharedFile2Id, sharedFile3Id])
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('delete a file and check notification', () => {
|
||||
dataTable.clickOnItemName(sharedFile1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toContain(`${sharedFile1} deleted`);
|
||||
expect(dataTable.getRowName(sharedFile1).isPresent()).toBe(false, 'Item was not removed from list');
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => expect(dataTable.getRowName(sharedFile1).isPresent()).toBe(true, 'Item is not in trash'))
|
||||
|
||||
.then(() => apis.user.trashcan.restore(sharedFile1Id));
|
||||
});
|
||||
|
||||
it('delete multiple files and check notification', () => {
|
||||
dataTable.selectMultipleItems([sharedFile2, sharedFile3])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toContain(`Deleted 2 items`);
|
||||
expect(dataTable.getRowName(sharedFile2).isPresent()).toBe(false, `${sharedFile2} was not removed from list`);
|
||||
expect(dataTable.getRowName(sharedFile3).isPresent()).toBe(false, `${sharedFile3} was not removed from list`);
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(sharedFile2).isPresent()).toBe(true, `${sharedFile2} is not in trash`);
|
||||
expect(dataTable.getRowName(sharedFile3).isPresent()).toBe(true, `${sharedFile3} is not in trash`);
|
||||
})
|
||||
|
||||
.then(() => apis.user.trashcan.restore(sharedFile2Id))
|
||||
.then(() => apis.user.trashcan.restore(sharedFile3Id));
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Favorites', () => {
|
||||
const favoriteFile1 = `favFile1-${Utils.random()}.txt`; let favoriteFile1Id;
|
||||
const favoriteFile2 = `favFile2-${Utils.random()}.txt`; let favoriteFile2Id;
|
||||
const favoriteFile3 = `favFile3-${Utils.random()}.txt`;
|
||||
const favoriteFile4 = `favFile4-${Utils.random()}.txt`; let favoriteFile4Id;
|
||||
const favoriteFolder1 = `favFolder1-${Utils.random()}`; let favoriteFolder1Id;
|
||||
const favoriteFolder2 = `favFolder2-${Utils.random()}`; let favoriteFolder2Id;
|
||||
const favoriteFileLocked1 = `favFileLocked-${Utils.random()}.txt`; let favoriteFileLocked1Id;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.createFile(favoriteFile1).then(resp => favoriteFile1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(favoriteFile2).then(resp => favoriteFile2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolder(favoriteFolder1).then(resp => favoriteFolder1Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolder(favoriteFolder2).then(resp => favoriteFolder2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(favoriteFile3, favoriteFolder1Id))
|
||||
.then(() => apis.user.nodes.createFile(favoriteFile4, favoriteFolder2Id).then(resp => favoriteFile4Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.lockFile(favoriteFile4Id))
|
||||
|
||||
.then(() => apis.user.nodes.createFile(favoriteFileLocked1).then(resp => favoriteFileLocked1Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.lockFile(favoriteFileLocked1Id))
|
||||
|
||||
.then(() => apis.user.favorites.addFavoritesByIds('file', [favoriteFile1Id, favoriteFile2Id, favoriteFileLocked1Id]))
|
||||
.then(() => apis.user.favorites.addFavoritesByIds('folder', [favoriteFolder1Id, favoriteFolder2Id]))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 5 }))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
page.refresh().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
logoutPage.load(),
|
||||
apis.user.nodes.unlockFile(favoriteFile4Id)
|
||||
.then(() => apis.user.nodes.unlockFile(favoriteFileLocked1Id))
|
||||
.then(() => apis.user.nodes.deleteNodesById([
|
||||
favoriteFile1Id, favoriteFile2Id, favoriteFolder1Id, favoriteFolder2Id, favoriteFileLocked1Id
|
||||
]))
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('delete a file and check notification', () => {
|
||||
let items: number;
|
||||
page.dataTable.countRows().then(number => { items = number; });
|
||||
|
||||
dataTable.clickOnItemName(favoriteFile1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toContain(`${favoriteFile1} deleted`);
|
||||
expect(dataTable.getRowName(favoriteFile1).isPresent()).toBe(false, 'Item was not removed from list');
|
||||
items--;
|
||||
expect(page.pagination.range.getText()).toContain(`1-${items} of ${items}`);
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => expect(dataTable.getRowName(favoriteFile1).isPresent()).toBe(true, 'Item is not in trash'))
|
||||
|
||||
.then(() => apis.user.trashcan.restore(favoriteFile1Id));
|
||||
});
|
||||
|
||||
it('delete multiple files and check notification', () => {
|
||||
let items: number;
|
||||
page.dataTable.countRows().then(number => { items = number; });
|
||||
|
||||
dataTable.selectMultipleItems([favoriteFile1, favoriteFile2])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toContain(`Deleted 2 items`);
|
||||
expect(dataTable.getRowName(favoriteFile1).isPresent()).toBe(false, `${favoriteFile1} was not removed from list`);
|
||||
expect(dataTable.getRowName(favoriteFile2).isPresent()).toBe(false, `${favoriteFile2} was not removed from list`);
|
||||
items = items - 2;
|
||||
expect(page.pagination.range.getText()).toContain(`1-${items} of ${items}`);
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(favoriteFile1).isPresent()).toBe(true, `${favoriteFile1} is not in trash`);
|
||||
expect(dataTable.getRowName(favoriteFile2).isPresent()).toBe(true, `${favoriteFile2} is not in trash`);
|
||||
})
|
||||
|
||||
.then(() => apis.user.trashcan.restore(favoriteFile1Id))
|
||||
.then(() => apis.user.trashcan.restore(favoriteFile2Id));
|
||||
});
|
||||
|
||||
it('delete a folder with content', () => {
|
||||
let items: number;
|
||||
page.dataTable.countRows().then(number => { items = number; });
|
||||
dataTable.clickOnItemName(favoriteFolder1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(favoriteFolder1).isPresent()).toBe(false, 'Item was not removed from list');
|
||||
items--;
|
||||
expect(page.pagination.range.getText()).toContain(`1-${items} of ${items}`);
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(favoriteFolder1).isPresent()).toBe(true, 'Item is not in trash');
|
||||
expect(dataTable.getRowName(favoriteFile3).isPresent()).toBe(false, 'Item is in trash');
|
||||
})
|
||||
|
||||
.then(() => apis.user.trashcan.restore(favoriteFolder1Id));
|
||||
});
|
||||
|
||||
it('delete a folder containing locked files', () => {
|
||||
dataTable.clickOnItemName(favoriteFolder2)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toContain(`${favoriteFolder2} couldn't be deleted`);
|
||||
expect(dataTable.getRowName(favoriteFolder2).isPresent()).toBe(true, 'Item was removed from list');
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(favoriteFolder2).isPresent()).toBe(false, 'Item is in trash');
|
||||
expect(dataTable.getRowName(favoriteFile4).isPresent()).toBe(false, 'Item is in trash');
|
||||
});
|
||||
});
|
||||
|
||||
it('notification on multiple items deletion - some items fail to delete', () => {
|
||||
dataTable.selectMultipleItems([favoriteFile1, favoriteFolder2])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toContain(`Deleted 1 item, 1 couldn't be deleted`);
|
||||
})
|
||||
|
||||
.then(() => apis.user.trashcan.restore(favoriteFile1Id));
|
||||
});
|
||||
|
||||
it('Notification on multiple items deletion - all items fail to delete', () => {
|
||||
dataTable.selectMultipleItems([favoriteFileLocked1, favoriteFolder2])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toEqual(`2 items couldn't be deleted`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Recent Files', () => {
|
||||
const recentFile1 = `recentFile1-${Utils.random()}.txt`; let recentFile1Id;
|
||||
const recentFile2 = `recentFile2-${Utils.random()}.txt`; let recentFile2Id;
|
||||
const recentFile3 = `recentFile3-${Utils.random()}.txt`; let recentFile3Id;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.createFile(recentFile1).then(resp => recentFile1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(recentFile2).then(resp => recentFile2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(recentFile3).then(resp => recentFile3Id = resp.data.entry.id))
|
||||
.then(() => apis.user.search.waitForApi(username, { expect: 3 }))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
|
||||
.then((): any => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => dataTable.isEmptyList())
|
||||
.then(empty => {
|
||||
if (empty) {
|
||||
browser.sleep(6000).then(() => page.refresh());
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
page.refresh().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
logoutPage.load(),
|
||||
apis.user.nodes.deleteNodesById([recentFile1Id, recentFile2Id, recentFile3Id])
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('delete a file and check notification', () => {
|
||||
dataTable.clickOnItemName(recentFile1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toContain(`${recentFile1} deleted`);
|
||||
expect(dataTable.getRowName(recentFile1).isPresent()).toBe(false, 'Item was not removed from list');
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => expect(dataTable.getRowName(recentFile1).isPresent()).toBe(true, 'Item is not in trash'))
|
||||
|
||||
.then(() => apis.user.trashcan.restore(recentFile1Id));
|
||||
});
|
||||
|
||||
it('delete multiple files and check notification', () => {
|
||||
dataTable.selectMultipleItems([recentFile2, recentFile3])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toContain(`Deleted 2 items`);
|
||||
expect(dataTable.getRowName(recentFile2).isPresent()).toBe(false, `${recentFile2} was not removed from list`);
|
||||
expect(dataTable.getRowName(recentFile3).isPresent()).toBe(false, `${recentFile3} was not removed from list`);
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(recentFile2).isPresent()).toBe(true, `${recentFile2} is not in trash`);
|
||||
expect(dataTable.getRowName(recentFile3).isPresent()).toBe(true, `${recentFile3} is not in trash`);
|
||||
})
|
||||
|
||||
.then(() => apis.user.trashcan.restore(recentFile2Id))
|
||||
.then(() => apis.user.trashcan.restore(recentFile3Id));
|
||||
});
|
||||
});
|
||||
});
|
187
e2e/suites/actions/edit-folder.test.ts
Executable file
187
e2e/suites/actions/edit-folder.test.ts
Executable file
@ -0,0 +1,187 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { protractor, browser } from 'protractor';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { SIDEBAR_LABELS, SITE_VISIBILITY, SITE_ROLES } from '../../configs';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
import { CreateOrEditFolderDialog } from '../../components/dialog/create-edit-folder-dialog';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
describe('Edit folder', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const parent = `parent-${Utils.random()}`;
|
||||
const folderName = `folder-${Utils.random()}`;
|
||||
const folderDescription = 'my folder description';
|
||||
|
||||
const folderNameToEdit = `folder-${Utils.random()}`;
|
||||
const duplicateFolderName = `folder-${Utils.random()}`;
|
||||
|
||||
const folderNameEdited = `folder-${Utils.random()}`;
|
||||
const folderDescriptionEdited = 'description edited';
|
||||
|
||||
const siteName = `site-private-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const personalFilesPage = new BrowsingPage();
|
||||
const editDialog = new CreateOrEditFolderDialog();
|
||||
const { dataTable } = personalFilesPage;
|
||||
const editButton = personalFilesPage.toolbar.actions.getButtonByTitleAttribute('Edit');
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PRIVATE))
|
||||
.then(() => apis.admin.nodes.createFolders([ folderName ], `Sites/${siteName}/documentLibrary`))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_CONSUMER))
|
||||
|
||||
.then(() => apis.user.nodes.createFolder( parent ))
|
||||
.then(resp => apis.user.nodes.createFolder( folderName, resp.data.entry.id, '', folderDescription ))
|
||||
.then(() => apis.user.nodes.createFolders([ folderNameToEdit, duplicateFolderName ], parent))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.doubleClickOnItemName(parent))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
browser.actions().sendKeys(protractor.Key.ESCAPE).perform().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise
|
||||
.all([
|
||||
apis.admin.sites.deleteSite(siteName),
|
||||
apis.user.nodes.deleteNodes([ parent ]),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('dialog UI defaults', () => {
|
||||
dataTable.clickOnItemName(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => {
|
||||
expect(editDialog.getTitle()).toEqual('Edit folder');
|
||||
expect(editDialog.nameInput.getAttribute('value')).toBe(folderName);
|
||||
expect(editDialog.descriptionTextArea.getAttribute('value')).toBe(folderDescription);
|
||||
expect(editDialog.updateButton.isEnabled()).toBe(true, 'upload button is not enabled');
|
||||
expect(editDialog.cancelButton.isEnabled()).toBe(true, 'cancel button is not enabled');
|
||||
});
|
||||
});
|
||||
|
||||
it('properties are modified when pressing OK', () => {
|
||||
dataTable.clickOnItemName(folderNameToEdit)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.waitForDialogToOpen())
|
||||
.then(() => editDialog.enterDescription(folderDescriptionEdited))
|
||||
.then(() => editDialog.enterName(folderNameEdited))
|
||||
.then(() => editDialog.clickUpdate())
|
||||
.then(() => editDialog.waitForDialogToClose())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => expect(dataTable.getRowName(folderNameEdited).isPresent()).toBe(true, 'Folder not displayed'))
|
||||
.then(() => apis.user.nodes.getNodeDescription(folderNameEdited, parent))
|
||||
.then(desc => expect(desc).toEqual(folderDescriptionEdited));
|
||||
});
|
||||
|
||||
it('with empty folder name', () => {
|
||||
dataTable.clickOnItemName(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.deleteNameWithBackspace())
|
||||
.then(() => {
|
||||
expect(editDialog.updateButton.isEnabled()).toBe(false, 'upload button is not enabled');
|
||||
expect(editDialog.getValidationMessage()).toMatch('Folder name is required');
|
||||
});
|
||||
});
|
||||
|
||||
it('with name with special characters', () => {
|
||||
const namesWithSpecialChars = [ 'a*a', 'a"a', 'a<a', 'a>a', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a' ];
|
||||
|
||||
dataTable.clickOnItemName(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => namesWithSpecialChars.forEach(name => {
|
||||
editDialog.enterName(name);
|
||||
|
||||
expect(editDialog.updateButton.isEnabled()).toBe(false, 'upload button is not disabled');
|
||||
expect(editDialog.getValidationMessage()).toContain(`Folder name can't contain these characters`);
|
||||
}));
|
||||
});
|
||||
|
||||
it('with name ending with a dot', () => {
|
||||
dataTable.clickOnItemName(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.nameInput.sendKeys('.'))
|
||||
.then(() => {
|
||||
expect(editDialog.updateButton.isEnabled()).toBe(false, 'upload button is not enabled');
|
||||
expect(editDialog.getValidationMessage()).toMatch(`Folder name can't end with a period .`);
|
||||
});
|
||||
});
|
||||
|
||||
it('Cancel button', () => {
|
||||
dataTable.clickOnItemName(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.clickCancel())
|
||||
.then(() => {
|
||||
expect(editDialog.component.isPresent()).not.toBe(true, 'dialog is not closed');
|
||||
});
|
||||
});
|
||||
|
||||
it('with duplicate folder name', () => {
|
||||
dataTable.clickOnItemName(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.enterName(duplicateFolderName))
|
||||
.then(() => editDialog.clickUpdate())
|
||||
.then(() => personalFilesPage.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toEqual(`There's already a folder with this name. Try a different name.`);
|
||||
expect(editDialog.component.isPresent()).toBe(true, 'dialog is not present');
|
||||
});
|
||||
});
|
||||
|
||||
it('trim ending spaces', () => {
|
||||
dataTable.clickOnItemName(folderName)
|
||||
.then(() => editButton.click())
|
||||
.then(() => editDialog.nameInput.sendKeys(' '))
|
||||
.then(() => editDialog.clickUpdate())
|
||||
.then(() => editDialog.waitForDialogToClose())
|
||||
.then(() => {
|
||||
expect(personalFilesPage.snackBar.isPresent()).not.toBe(true, 'notification appears');
|
||||
expect(dataTable.getRowName(folderName).isPresent()).toBe(true, 'Folder not displayed in list view');
|
||||
});
|
||||
});
|
||||
});
|
419
e2e/suites/actions/mark-favorite.test.ts
Normal file
419
e2e/suites/actions/mark-favorite.test.ts
Normal file
@ -0,0 +1,419 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { SIDEBAR_LABELS } from '../../configs';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { browser } from 'protractor';
|
||||
|
||||
describe('Mark items as favorites', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const file1NotFav = `file-${Utils.random()}.txt`;
|
||||
const file2NotFav = `file-${Utils.random()}.txt`;
|
||||
const file3Fav = `file-${Utils.random()}.txt`;
|
||||
const file4Fav = `file-${Utils.random()}.txt`;
|
||||
const folder1 = `folder-${Utils.random()}`;
|
||||
|
||||
let file1Id, file2Id, file3Id, file4Id, folder1Id;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable, toolbar } = page;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => apis.user.nodes.createFile( file1NotFav ).then(resp => file1Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile( file2NotFav ).then(resp => file2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile( file3Fav ).then(resp => file3Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile( file4Fav ).then(resp => file4Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolder( folder1 ).then(resp => folder1Id = resp.data.entry.id))
|
||||
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file3Id))
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file4Id))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.user.nodes.deleteNodesById([ file1Id, file2Id, file3Id, file4Id, folder1Id ]),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('on Personal Files', () => {
|
||||
beforeAll(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
// browser.actions().sendKeys(protractor.Key.ESCAPE).perform().then(done);
|
||||
browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform().then(done);
|
||||
});
|
||||
|
||||
it('Favorite action has empty star icon for unfavorited item', () => {
|
||||
dataTable.clickOnItemName(file1NotFav)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => expect(toolbar.actions.menu.getItemIconText('Favorite')).toEqual('star_border'));
|
||||
});
|
||||
|
||||
it('Favorite action has empty star icon for multiple selection of items when some are not favorite', () => {
|
||||
dataTable.selectMultipleItems([ file1NotFav, file3Fav ])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => expect(toolbar.actions.menu.getItemIconText('Favorite')).toEqual('star_border'));
|
||||
});
|
||||
|
||||
it('Favorite action has full star icon for favorited items', () => {
|
||||
dataTable.clickOnItemName(file3Fav)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => expect(toolbar.actions.menu.getItemIconText('Favorite')).toEqual('star'));
|
||||
});
|
||||
|
||||
it('favorite a file', () => {
|
||||
dataTable.clickOnItemName(file1NotFav)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 3 }))
|
||||
.then(() => apis.user.favorites.isFavorite(file1Id))
|
||||
.then(isFavorite => expect(isFavorite).toBe(true, `${file1NotFav} not marked as favorite`))
|
||||
|
||||
.then(() => apis.user.favorites.removeFavoriteById(file1Id));
|
||||
});
|
||||
|
||||
it('favorite a folder', () => {
|
||||
dataTable.clickOnItemName(folder1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 3 }))
|
||||
.then(() => apis.user.favorites.isFavorite(folder1Id))
|
||||
.then(isFavorite => expect(isFavorite).toBe(true, `${folder1} not marked as favorite`))
|
||||
|
||||
.then(() => apis.user.favorites.removeFavoriteById(folder1Id));
|
||||
});
|
||||
|
||||
it('unfavorite an item', () => {
|
||||
dataTable.clickOnItemName(file3Fav)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 1 }))
|
||||
.then(() => apis.user.favorites.isFavorite(file3Id))
|
||||
.then(isFavorite => expect(isFavorite).toBe(false, `${file3Fav} is marked as favorite`))
|
||||
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file3Id));
|
||||
});
|
||||
|
||||
it('favorite multiple items - all unfavorite', () => {
|
||||
dataTable.selectMultipleItems([ file1NotFav, file2NotFav ])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 4 }))
|
||||
.then(() => Promise.all([
|
||||
apis.user.favorites.isFavorite(file1Id),
|
||||
apis.user.favorites.isFavorite(file2Id)
|
||||
]))
|
||||
.then(resp => {
|
||||
expect(resp[0]).toBe(true, 'item not marked as favorite');
|
||||
expect(resp[1]).toBe(true, 'item not marked as favorite');
|
||||
})
|
||||
|
||||
.then(() => apis.user.favorites.removeFavoriteById(file1Id))
|
||||
.then(() => apis.user.favorites.removeFavoriteById(file2Id));
|
||||
});
|
||||
|
||||
it('favorite multiple items - some favorite and some unfavorite', () => {
|
||||
dataTable.selectMultipleItems([ file1NotFav, file3Fav ])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 3 }))
|
||||
.then(() => Promise.all([
|
||||
apis.user.favorites.isFavorite(file1Id),
|
||||
apis.user.favorites.isFavorite(file3Id)
|
||||
]))
|
||||
.then(resp => {
|
||||
expect(resp[0]).toBe(true, 'item not marked as favorite');
|
||||
expect(resp[1]).toBe(true, 'item not marked as favorite');
|
||||
})
|
||||
|
||||
.then(() => apis.user.favorites.removeFavoriteById(file1Id));
|
||||
});
|
||||
|
||||
it('unfavorite multiple items', () => {
|
||||
dataTable.selectMultipleItems([ file3Fav, file4Fav ])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => browser.sleep(2000))
|
||||
.then(() => Promise.all([
|
||||
apis.user.favorites.isFavorite(file3Id),
|
||||
apis.user.favorites.isFavorite(file4Id)
|
||||
]))
|
||||
.then(resp => {
|
||||
expect(resp[0]).toBe(false, 'item marked as favorite');
|
||||
expect(resp[1]).toBe(false, 'item marked as favorite');
|
||||
})
|
||||
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file3Id))
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file4Id));
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Recent Files', () => {
|
||||
beforeAll(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
// browser.actions().sendKeys(protractor.Key.ESCAPE).perform().then(done);
|
||||
browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform().then(done);
|
||||
});
|
||||
|
||||
it('favorite a file', () => {
|
||||
dataTable.clickOnItemName(file1NotFav)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 3 }))
|
||||
.then(() => apis.user.favorites.isFavorite(file1Id))
|
||||
.then(isFavorite => expect(isFavorite).toBe(true, `${file1NotFav} not marked as favorite`))
|
||||
|
||||
.then(() => apis.user.favorites.removeFavoriteById(file1Id));
|
||||
});
|
||||
|
||||
it('unfavorite an item', () => {
|
||||
dataTable.clickOnItemName(file3Fav)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 1 }))
|
||||
.then(() => apis.user.favorites.isFavorite(file3Id))
|
||||
.then(isFavorite => expect(isFavorite).toBe(false, `${file3Fav} is marked as favorite`))
|
||||
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file3Id));
|
||||
});
|
||||
|
||||
it('favorite multiple items - all unfavorite', () => {
|
||||
dataTable.selectMultipleItems([ file1NotFav, file2NotFav ])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 4 }))
|
||||
.then(() => Promise.all([
|
||||
apis.user.favorites.isFavorite(file1Id),
|
||||
apis.user.favorites.isFavorite(file2Id)
|
||||
]))
|
||||
.then(resp => {
|
||||
expect(resp[0]).toBe(true, 'item not marked as favorite');
|
||||
expect(resp[1]).toBe(true, 'item not marked as favorite');
|
||||
})
|
||||
|
||||
.then(() => apis.user.favorites.removeFavoriteById(file1Id))
|
||||
.then(() => apis.user.favorites.removeFavoriteById(file2Id));
|
||||
});
|
||||
|
||||
it('favorite multiple items - some favorite and some unfavorite', () => {
|
||||
dataTable.selectMultipleItems([ file1NotFav, file3Fav ])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 3 }))
|
||||
.then(() => Promise.all([
|
||||
apis.user.favorites.isFavorite(file1Id),
|
||||
apis.user.favorites.isFavorite(file3Id)
|
||||
]))
|
||||
.then(resp => {
|
||||
expect(resp[0]).toBe(true, 'item not marked as favorite');
|
||||
expect(resp[1]).toBe(true, 'item not marked as favorite');
|
||||
})
|
||||
|
||||
.then(() => apis.user.favorites.removeFavoriteById(file1Id));
|
||||
});
|
||||
|
||||
it('unfavorite multiple items', () => {
|
||||
dataTable.selectMultipleItems([ file3Fav, file4Fav ])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => browser.sleep(2000))
|
||||
.then(() => Promise.all([
|
||||
apis.user.favorites.isFavorite(file3Id),
|
||||
apis.user.favorites.isFavorite(file4Id)
|
||||
]))
|
||||
.then(resp => {
|
||||
expect(resp[0]).toBe(false, 'item marked as favorite');
|
||||
expect(resp[1]).toBe(false, 'item marked as favorite');
|
||||
})
|
||||
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file3Id))
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file4Id));
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Shared Files', () => {
|
||||
beforeAll(done => {
|
||||
apis.user.shared.shareFilesByIds([ file1Id, file2Id, file3Id, file4Id ])
|
||||
.then(() => apis.user.shared.waitForApi({ expect: 4 }))
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
// browser.actions().sendKeys(protractor.Key.ESCAPE).perform().then(done);
|
||||
browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform().then(done);
|
||||
});
|
||||
|
||||
it('favorite a file', () => {
|
||||
dataTable.clickOnItemName(file1NotFav)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 3 }))
|
||||
.then(() => apis.user.favorites.isFavorite(file1Id))
|
||||
.then(isFavorite => expect(isFavorite).toBe(true, `${file1NotFav} not marked as favorite`))
|
||||
|
||||
.then(() => apis.user.favorites.removeFavoriteById(file1Id));
|
||||
});
|
||||
|
||||
it('unfavorite an item', () => {
|
||||
dataTable.clickOnItemName(file3Fav)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 1 }))
|
||||
.then(() => apis.user.favorites.isFavorite(file3Id))
|
||||
.then(isFavorite => expect(isFavorite).toBe(false, `${file3Fav} is marked as favorite`))
|
||||
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file3Id));
|
||||
});
|
||||
|
||||
it('favorite multiple items - all unfavorite', () => {
|
||||
dataTable.selectMultipleItems([ file1NotFav, file2NotFav ])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 4 }))
|
||||
.then(() => Promise.all([
|
||||
apis.user.favorites.isFavorite(file1Id),
|
||||
apis.user.favorites.isFavorite(file2Id)
|
||||
]))
|
||||
.then(resp => {
|
||||
expect(resp[0]).toBe(true, 'item not marked as favorite');
|
||||
expect(resp[1]).toBe(true, 'item not marked as favorite');
|
||||
})
|
||||
|
||||
.then(() => apis.user.favorites.removeFavoriteById(file1Id))
|
||||
.then(() => apis.user.favorites.removeFavoriteById(file2Id));
|
||||
});
|
||||
|
||||
it('favorite multiple items - some favorite and some unfavorite', () => {
|
||||
dataTable.selectMultipleItems([ file1NotFav, file3Fav ])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 3 }))
|
||||
.then(() => Promise.all([
|
||||
apis.user.favorites.isFavorite(file1Id),
|
||||
apis.user.favorites.isFavorite(file3Id)
|
||||
]))
|
||||
.then(resp => {
|
||||
expect(resp[0]).toBe(true, 'item not marked as favorite');
|
||||
expect(resp[1]).toBe(true, 'item not marked as favorite');
|
||||
})
|
||||
|
||||
.then(() => apis.user.favorites.removeFavoriteById(file1Id));
|
||||
});
|
||||
|
||||
it('unfavorite multiple items', () => {
|
||||
dataTable.selectMultipleItems([ file3Fav, file4Fav ])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => browser.sleep(2000))
|
||||
.then(() => Promise.all([
|
||||
apis.user.favorites.isFavorite(file3Id),
|
||||
apis.user.favorites.isFavorite(file4Id)
|
||||
]))
|
||||
.then(resp => {
|
||||
expect(resp[0]).toBe(false, 'item marked as favorite');
|
||||
expect(resp[1]).toBe(false, 'item marked as favorite');
|
||||
})
|
||||
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file3Id))
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file4Id));
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Favorites', () => {
|
||||
beforeAll(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
page.refresh().then(done);
|
||||
});
|
||||
|
||||
it('unfavorite an item', () => {
|
||||
dataTable.clickOnItemName(file3Fav)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 1 }))
|
||||
.then(() => apis.user.favorites.isFavorite(file3Id))
|
||||
.then(isFavorite => {
|
||||
expect(isFavorite).toBe(false, 'item is marked as favorite');
|
||||
expect(dataTable.getRowName(file3Fav).isPresent()).toBe(false, 'item still displayed');
|
||||
})
|
||||
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file3Id));
|
||||
});
|
||||
|
||||
it('unfavorite multiple items', () => {
|
||||
dataTable.selectMultipleItems([ file3Fav, file4Fav ])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Favorite'))
|
||||
.then(() => browser.sleep(2000))
|
||||
.then(() => apis.user.favorites.isFavorite(file3Id))
|
||||
.then(resp => {
|
||||
expect(resp).toBe(false, 'file3 marked as favorite');
|
||||
expect(dataTable.getRowName(file3Fav).isPresent()).toBe(false, 'file3 still displayed');
|
||||
})
|
||||
.then(() => apis.user.favorites.isFavorite(file4Id))
|
||||
.then(resp => {
|
||||
expect(resp).toBe(false, 'file4 marked as favorite');
|
||||
expect(dataTable.getRowName(file4Fav).isPresent()).toBe(false, 'file4 still displayed');
|
||||
})
|
||||
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file3Id))
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file4Id));
|
||||
});
|
||||
});
|
||||
|
||||
});
|
122
e2e/suites/actions/permanently-delete.test.ts
Executable file
122
e2e/suites/actions/permanently-delete.test.ts
Executable file
@ -0,0 +1,122 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { SIDEBAR_LABELS } from '../../configs';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
describe('Permanently delete from Trash', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const file1 = `file-${Utils.random()}.txt`;
|
||||
const file2 = `file-${Utils.random()}.txt`;
|
||||
let filesIds;
|
||||
|
||||
const folder1 = `folder-${Utils.random()}`;
|
||||
const folder2 = `folder-${Utils.random()}`;
|
||||
let foldersIds;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const trashPage = new BrowsingPage();
|
||||
const { dataTable, toolbar } = trashPage;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => apis.user.nodes.createFiles([ file1, file2 ]))
|
||||
.then(resp => filesIds = resp.data.list.entries.map(entries => entries.entry.id))
|
||||
.then(() => apis.user.nodes.createFolders([ folder1, folder2 ]))
|
||||
.then(resp => foldersIds = resp.data.list.entries.map(entries => entries.entry.id))
|
||||
|
||||
.then(() => apis.user.nodes.deleteNodesById(filesIds, false))
|
||||
.then(() => apis.user.nodes.deleteNodesById(foldersIds, false))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
trashPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.admin.trashcan.emptyTrash(),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('delete file [C217094] [C217091] [C217092]', () => {
|
||||
dataTable.clickOnItemName(file1)
|
||||
.then(() => toolbar.actions.getButtonByTitleAttribute('Permanently delete').click())
|
||||
.then(() => trashPage.waitForDialog())
|
||||
.then(() => trashPage.getDialogActionByLabel('Delete'))
|
||||
.then((elm) => elm.click())
|
||||
.then(() => trashPage.waitForDialogToClose())
|
||||
.then(() => trashPage.getSnackBarMessage())
|
||||
.then(text => {
|
||||
expect(text).toEqual(`${file1} deleted`);
|
||||
expect(dataTable.getRowName(file1).isPresent()).toBe(false, 'Item was not deleted');
|
||||
});
|
||||
});
|
||||
|
||||
it('delete folder [C217091] [C217092]', () => {
|
||||
dataTable.clickOnItemName(folder1)
|
||||
.then(() => toolbar.actions.getButtonByTitleAttribute('Permanently delete').click())
|
||||
.then(() => trashPage.waitForDialog())
|
||||
.then(() => trashPage.getDialogActionByLabel('Delete'))
|
||||
.then((elm) => elm.click())
|
||||
.then(() => trashPage.waitForDialogToClose())
|
||||
.then(() => trashPage.getSnackBarMessage())
|
||||
.then(text => {
|
||||
expect(text).toEqual(`${folder1} deleted`);
|
||||
expect(dataTable.getRowName(folder1).isPresent()).toBe(false, 'Item was not deleted');
|
||||
});
|
||||
});
|
||||
|
||||
it('delete multiple items [C217093]', () => {
|
||||
dataTable.selectMultipleItems([ file2, folder2 ])
|
||||
.then(() => toolbar.actions.getButtonByTitleAttribute('Permanently delete').click())
|
||||
.then(() => trashPage.waitForDialog())
|
||||
.then(() => trashPage.getDialogActionByLabel('Delete'))
|
||||
.then((elm) => elm.click())
|
||||
.then(() => trashPage.waitForDialogToClose())
|
||||
.then(() => trashPage.getSnackBarMessage())
|
||||
.then(text => {
|
||||
expect(text).toEqual(`2 items deleted`);
|
||||
expect(dataTable.getRowName(file2).isPresent()).toBe(false, 'Item was not deleted');
|
||||
expect(dataTable.getRowName(folder2).isPresent()).toBe(false, 'Item was not deleted');
|
||||
});
|
||||
});
|
||||
});
|
268
e2e/suites/actions/restore.test.ts
Executable file
268
e2e/suites/actions/restore.test.ts
Executable file
@ -0,0 +1,268 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { APP_ROUTES, SIDEBAR_LABELS } from '../../configs';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
describe('Restore from Trash', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable, toolbar } = page;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.admin.trashcan.emptyTrash(),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('successful restore', () => {
|
||||
const file = `file-${Utils.random()}.txt`; let fileId;
|
||||
const folder = `folder-${Utils.random()}`; let folderId;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.createFile(file).then(resp => fileId = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFolder(folder).then(resp => folderId = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.deleteNodesById([ fileId, folderId ], false))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
apis.user.trashcan.emptyTrash().then(done);
|
||||
});
|
||||
|
||||
it('restore file', () => {
|
||||
dataTable.clickOnItemName(file)
|
||||
.then(() => toolbar.actions.getButtonByTitleAttribute('Restore').click())
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(text => {
|
||||
expect(text).toContain(`${file} restored`);
|
||||
expect(text).toContain(`View`);
|
||||
expect(dataTable.getRowName(file).isPresent()).toBe(false, 'Item was not removed from list');
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES))
|
||||
.then(() => page.dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(page.dataTable.getRowName(file).isPresent()).toBe(true, 'Item not displayed in list');
|
||||
})
|
||||
|
||||
.then(() => apis.user.nodes.deleteNodeById(fileId, false));
|
||||
});
|
||||
|
||||
it('restore folder', () => {
|
||||
dataTable.clickOnItemName(folder)
|
||||
.then(() => toolbar.actions.getButtonByTitleAttribute('Restore').click())
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(text => {
|
||||
expect(text).toContain(`${folder} restored`);
|
||||
expect(text).toContain(`View`);
|
||||
expect(dataTable.getRowName(folder).isPresent()).toBe(false, 'Item was not removed from list');
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES))
|
||||
.then(() => page.dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(page.dataTable.getRowName(folder).isPresent()).toBe(true, 'Item not displayed in list');
|
||||
})
|
||||
|
||||
.then(() => apis.user.nodes.deleteNodeById(folderId, false));
|
||||
});
|
||||
|
||||
it('restore multiple items', () => {
|
||||
dataTable.selectMultipleItems([ file, folder ])
|
||||
.then(() => toolbar.actions.getButtonByTitleAttribute('Restore').click())
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(text => {
|
||||
expect(text).toContain(`Restore successful`);
|
||||
expect(text).not.toContain(`View`);
|
||||
expect(dataTable.getRowName(file).isPresent()).toBe(false, 'Item was not removed from list');
|
||||
expect(dataTable.getRowName(folder).isPresent()).toBe(false, 'Item was not removed from list');
|
||||
})
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES))
|
||||
.then(() => page.dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(page.dataTable.getRowName(file).isPresent()).toBe(true, 'Item not displayed in list');
|
||||
expect(page.dataTable.getRowName(folder).isPresent()).toBe(true, 'Item not displayed in list');
|
||||
})
|
||||
|
||||
.then(() => apis.user.nodes.deleteNodesById([ fileId, folderId ], false));
|
||||
});
|
||||
|
||||
it('View from notification', () => {
|
||||
dataTable.clickOnItemName(file)
|
||||
.then(() => toolbar.actions.getButtonByTitleAttribute('Restore').click())
|
||||
.then(() => page.clickSnackBarAction())
|
||||
.then(() => page.dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(page.sidenav.isActiveByLabel('Personal Files')).toBe(true, 'Personal Files sidebar link not active');
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES);
|
||||
})
|
||||
|
||||
.then(() => apis.user.nodes.deleteNodeById(fileId, false));
|
||||
});
|
||||
});
|
||||
|
||||
describe('failure to restore', () => {
|
||||
const file1 = `file-${Utils.random()}.txt`; let file1Id1, file1Id2;
|
||||
const file2 = `file-${Utils.random()}.txt`; let file2Id;
|
||||
|
||||
const folder1 = `folder-${Utils.random()}`; let folder1Id;
|
||||
const folder2 = `folder-${Utils.random()}`; let folder2Id;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.createFolder(folder1).then(resp => folder1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(file1, folder1Id).then(resp => file1Id1 = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.deleteNodeById(file1Id1, false))
|
||||
.then(() => apis.user.nodes.createFile(file1, folder1Id).then(resp => file1Id2 = resp.data.entry.id))
|
||||
|
||||
.then(() => apis.user.nodes.createFolder(folder2).then(resp => folder2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(file2, folder2Id).then(resp => file2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.deleteNodeById(file2Id, false))
|
||||
.then(() => apis.user.nodes.deleteNodeById(folder2Id, false))
|
||||
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.user.nodes.deleteNodeById(file1Id2),
|
||||
apis.user.trashcan.emptyTrash()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('Restore a file when another file with same name exists on the restore location', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => dataTable.clickOnItemName(file1))
|
||||
.then(() => toolbar.actions.getButtonByTitleAttribute('Restore').click())
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(text => expect(text).toEqual(`Can't restore, ${file1} already exists`));
|
||||
});
|
||||
|
||||
it('Restore a file when original location no longer exists', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => dataTable.clickOnItemName(file2))
|
||||
.then(() => toolbar.actions.getButtonByTitleAttribute('Restore').click())
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(text => expect(text).toEqual(`Can't restore ${file2}, the original location no longer exists`));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Notification on partial success', () => {
|
||||
const folder1 = `folder1-${Utils.random()}.txt`; let folder1Id;
|
||||
const folder2 = `folder2-${Utils.random()}.txt`; let folder2Id;
|
||||
const file1 = `file-${Utils.random()}.txt`; let file1Id;
|
||||
const file2 = `file-${Utils.random()}.txt`; let file2Id;
|
||||
|
||||
const folder3 = `folder3-${Utils.random()}.txt`; let folder3Id;
|
||||
const folder4 = `folder4-${Utils.random()}.txt`; let folder4Id;
|
||||
const file3 = `file3-${Utils.random()}.txt`; let file3Id;
|
||||
const file4 = `file4-${Utils.random()}.txt`; let file4Id;
|
||||
const file5 = `file5-${Utils.random()}.txt`; let file5Id;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.createFolder(folder1).then(resp => folder1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(file1, folder1Id).then(resp => file1Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolder(folder2).then(resp => folder2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(file2, folder2Id).then(resp => file2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.deleteNodeById(file1Id, false))
|
||||
.then(() => apis.user.nodes.deleteNodeById(folder1Id, false))
|
||||
.then(() => apis.user.nodes.deleteNodeById(file2Id, false))
|
||||
|
||||
.then(() => apis.user.nodes.createFolder(folder3).then(resp => folder3Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(file3, folder3Id).then(resp => file3Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(file4, folder3Id).then(resp => file4Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolder(folder4).then(resp => folder4Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(file5, folder4Id).then(resp => file5Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.deleteNodeById(file3Id, false))
|
||||
.then(() => apis.user.nodes.deleteNodeById(file4Id, false))
|
||||
.then(() => apis.user.nodes.deleteNodeById(folder3Id, false))
|
||||
.then(() => apis.user.nodes.deleteNodeById(file5Id, false))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.user.trashcan.emptyTrash(),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('one failure', () => {
|
||||
dataTable.selectMultipleItems([ file1, file2 ])
|
||||
.then(() => toolbar.actions.getButtonByTitleAttribute('Restore').click())
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(text => expect(text).toEqual(`Can't restore ${file1}, the original location no longer exists`));
|
||||
});
|
||||
|
||||
it('multiple failures', () => {
|
||||
dataTable.selectMultipleItems([ file3, file4, file5 ])
|
||||
.then(() => toolbar.actions.getButtonByTitleAttribute('Restore').click())
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(text => expect(text).toEqual('2 items not restored because of issues with the restore location'));
|
||||
});
|
||||
});
|
||||
});
|
543
e2e/suites/actions/toolbar-multiple-selection.test.ts
Executable file
543
e2e/suites/actions/toolbar-multiple-selection.test.ts
Executable file
@ -0,0 +1,543 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 } from 'protractor';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
describe('Toolbar actions - multiple selection : ', () => {
|
||||
const user1 = `user-${Utils.random()}`;
|
||||
const user2 = `user-${Utils.random()}`;
|
||||
|
||||
const file1 = `file-${Utils.random()}.txt`;
|
||||
let file1Id;
|
||||
const file2 = `file-${Utils.random()}.txt`;
|
||||
let file2Id;
|
||||
|
||||
const folder1 = `folder-${Utils.random()}`;
|
||||
let folder1Id;
|
||||
const folder2 = `folder-${Utils.random()}`;
|
||||
let folder2Id;
|
||||
|
||||
const fileForDelete1 = `file-${Utils.random()}.txt`; let fileForDelete1Id;
|
||||
const fileForDelete2 = `file-${Utils.random()}.txt`; let fileForDelete2Id;
|
||||
const folderForDelete1 = `folder-${Utils.random()}`; let folderForDelete1Id;
|
||||
const folderForDelete2 = `folder-${Utils.random()}`; let folderForDelete2Id;
|
||||
|
||||
const siteName = `site-private-${Utils.random()}`;
|
||||
const file1Admin = `file-${Utils.random()}.txt`;
|
||||
const file2Admin = `file-${Utils.random()}.txt`;
|
||||
const folder1Admin = `folder-${Utils.random()}`;
|
||||
const folder2Admin = `folder-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(user1, user1)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable } = page;
|
||||
const { toolbar } = page;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(user1)
|
||||
.then(() => apis.user.nodes.createFiles([ file1 ]).then(resp => file1Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFiles([ file2 ]).then(resp => file2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolders([ folder1 ]).then(resp => folder1Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolders([ folder2 ]).then(resp => folder2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFiles([ fileForDelete1 ]).then(resp => fileForDelete1Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFiles([ fileForDelete2 ]).then(resp => fileForDelete2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolders([ folderForDelete1 ]).then(resp => folderForDelete1Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolders([ folderForDelete2 ]).then(resp => folderForDelete2Id = resp.data.entry.id))
|
||||
|
||||
.then(() => apis.user.shared.shareFilesByIds([ file1Id, file2Id ]))
|
||||
|
||||
.then(() => apis.user.favorites.addFavoritesByIds('file', [ file1Id, file2Id ]))
|
||||
.then(() => apis.user.favorites.addFavoritesByIds('folder', [ folder1Id, folder2Id ]))
|
||||
|
||||
.then(() => apis.user.nodes.deleteNodesById([
|
||||
fileForDelete1Id, fileForDelete2Id, folderForDelete1Id, folderForDelete2Id
|
||||
], false))
|
||||
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.user.nodes.deleteNodesById([ file1Id, file2Id, folder1Id, folder2Id ]),
|
||||
apis.user.trashcan.emptyTrash(),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('Personal Files', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(user1).then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('unselect selected items - single click', () => {
|
||||
dataTable.selectMultipleItems([ file1, file2, folder1, folder2 ])
|
||||
.then(() => expect(dataTable.countSelectedRows()).toEqual(4, 'incorrect selected rows number'))
|
||||
.then(() => dataTable.clickOnItemName(file1))
|
||||
.then(() => expect(dataTable.countSelectedRows()).toEqual(1, 'incorrect selected rows number'))
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
|
||||
it('unselect selected items - CMD+click', () => {
|
||||
dataTable.selectMultipleItems([ file1, file2, folder1, folder2 ])
|
||||
.then(() => expect(dataTable.countSelectedRows()).toEqual(4, 'incorrect selected rows number'))
|
||||
.then(() => browser.actions().sendKeys(protractor.Key.COMMAND).perform())
|
||||
.then(() => dataTable.clickOnItemName(file1))
|
||||
.then(() => dataTable.clickOnItemName(file2))
|
||||
.then(() => browser.actions().sendKeys(protractor.Key.NULL).perform())
|
||||
.then(() => expect(dataTable.countSelectedRows()).toEqual(2, 'incorrect selected rows number'))
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
|
||||
it('correct actions appear when multiple files are selected', () => {
|
||||
dataTable.selectMultipleItems([file1, file2])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
|
||||
it('correct actions appear when multiple folders are selected', () => {
|
||||
dataTable.selectMultipleItems([folder1, folder2])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
|
||||
it('correct actions appear when both files and folders are selected', () => {
|
||||
dataTable.selectMultipleItems([file1, file2, folder1, folder2])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
});
|
||||
|
||||
describe('File Libraries', () => {
|
||||
beforeAll(done => {
|
||||
apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC)
|
||||
.then(() => apis.admin.people.createUser(user2))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteName, user1, SITE_ROLES.SITE_MANAGER))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteName, user2, SITE_ROLES.SITE_CONSUMER))
|
||||
.then(() => apis.admin.nodes.createFiles([ file1Admin, file2Admin ], `Sites/${siteName}/documentLibrary`))
|
||||
.then(() => apis.admin.nodes.createFolders([ folder1Admin, folder2Admin ], `Sites/${siteName}/documentLibrary`))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.doubleClickOnItemName(siteName))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
apis.admin.sites.deleteSite(siteName).then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('user is Manager', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(user1).then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('correct actions appear when multiple files are selected', () => {
|
||||
dataTable.selectMultipleItems([file1Admin, file2Admin])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
|
||||
it('correct actions appear when multiple folders are selected', () => {
|
||||
dataTable.selectMultipleItems([folder1Admin, folder2Admin])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
|
||||
it('correct actions appear when both files and folders are selected', () => {
|
||||
dataTable.selectMultipleItems([file1Admin, file2Admin, folder1Admin, folder2Admin])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
});
|
||||
|
||||
describe('user is Consumer', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(user2).then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('correct actions appear when multiple files are selected', () => {
|
||||
dataTable.selectMultipleItems([file1Admin, file2Admin])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
|
||||
it('correct actions appear when multiple folders are selected', () => {
|
||||
dataTable.selectMultipleItems([folder1Admin, folder2Admin])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
|
||||
it('correct actions appear when both files and folders are selected', () => {
|
||||
dataTable.selectMultipleItems([file1Admin, file2Admin, folder1Admin, folder2Admin])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Shared Files', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(user1).then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('correct actions appear when multiple files are selected', () => {
|
||||
dataTable.selectMultipleItems([file1, file2])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
});
|
||||
|
||||
describe('Recent Files', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(user1).then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('correct actions appear when multiple files are selected', () => {
|
||||
dataTable.selectMultipleItems([file1, file2])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
});
|
||||
|
||||
describe('Favorites', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(user1).then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('correct actions appear when multiple files are selected', () => {
|
||||
dataTable.selectMultipleItems([file1, file2])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
|
||||
it('correct actions appear when multiple folders are selected', () => {
|
||||
dataTable.selectMultipleItems([folder1, folder2])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
|
||||
it('correct actions appear when both files and folders are selected', () => {
|
||||
dataTable.selectMultipleItems([file1, file2, folder1, folder2])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, 'View is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, 'Download is not displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, 'Edit is displayed for selected files');
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
// .then(() => browser.$('body').click())
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
});
|
||||
|
||||
// [C217090]
|
||||
describe('Trash', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(user1).then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('correct actions appear when multiple files are selected', () => {
|
||||
dataTable.selectMultipleItems([fileForDelete1, fileForDelete2])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('Permanently delete'))
|
||||
.toBe(true, 'Permanently delete is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed for selected files');
|
||||
})
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
|
||||
it('correct actions appear when multiple folders are selected', () => {
|
||||
dataTable.selectMultipleItems([folderForDelete1, folderForDelete2])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('Permanently delete'))
|
||||
.toBe(true, 'Permanently delete is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed for selected files');
|
||||
})
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
|
||||
it('correct actions appear when both files and folders are selected', () => {
|
||||
dataTable.selectMultipleItems([fileForDelete1, fileForDelete2, folderForDelete1, folderForDelete2])
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('Permanently delete'))
|
||||
.toBe(true, 'Permanently delete is displayed for selected files');
|
||||
expect(toolbar.actions.isButtonPresent('Restore')).toBe(true, 'Restore is not displayed for selected files');
|
||||
})
|
||||
.then(() => dataTable.clearSelection());
|
||||
});
|
||||
});
|
||||
});
|
752
e2e/suites/actions/toolbar-single-selection.test.ts
Executable file
752
e2e/suites/actions/toolbar-single-selection.test.ts
Executable file
@ -0,0 +1,752 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
describe('Toolbar actions - single selection : ', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
const username2 = `user-${Utils.random()}`;
|
||||
|
||||
const fileUser = `file-${Utils.random()}.txt`; let fileUserId;
|
||||
|
||||
const folderUser = `folder-${Utils.random()}`; let folderUserId;
|
||||
|
||||
const fileForDelete = `file-${Utils.random()}.txt`; let fileForDeleteId;
|
||||
|
||||
const folderForDelete = `folder-${Utils.random()}`; let folderForDeleteId;
|
||||
|
||||
const siteName = `site-private-${Utils.random()}`;
|
||||
const fileAdmin = `file-${Utils.random()}.txt`;
|
||||
const folderAdmin = `folder-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable, toolbar } = page;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => apis.user.nodes.createFiles([ fileUser ]))
|
||||
.then(resp => fileUserId = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFiles([ fileForDelete ]))
|
||||
.then(resp => fileForDeleteId = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFolders([ folderForDelete ]))
|
||||
.then(resp => folderForDeleteId = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFolders([ folderUser ]))
|
||||
.then(resp => folderUserId = resp.data.entry.id)
|
||||
.then(() => apis.user.shared.shareFileById(fileUserId))
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', fileUserId))
|
||||
.then(() => apis.user.favorites.addFavoriteById('folder', folderUserId))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.user.nodes.deleteNodeById(fileUserId),
|
||||
apis.user.nodes.deleteNodeById(folderUserId),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('General tests', () => {
|
||||
const userSite = `site-${Utils.random()}`;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.sites.createSite(userSite, SITE_VISIBILITY.PUBLIC)
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.user.sites.deleteSite(userSite),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('actions not displayed for top level of File Libraries', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.clickOnItemName(userSite))
|
||||
.then(() => expect(toolbar.actions.isEmpty()).toBe(true, 'toolbar not empty'));
|
||||
});
|
||||
|
||||
it('selected row is marked with a check circle icon', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.clickOnItemName(fileUser))
|
||||
.then(() => expect(dataTable.hasCheckMarkIcon(fileUser)).toBe(true, 'check mark missing'));
|
||||
});
|
||||
|
||||
describe('granular permissions', () => {
|
||||
const site = `site-${Utils.random()}`;
|
||||
const file1 = `file-${Utils.random()}`; let file1Id;
|
||||
const file2 = `file-${Utils.random()}`; let file2Id;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.sites.createSite(site, SITE_VISIBILITY.PRIVATE)
|
||||
.then(() => apis.admin.nodes.createFiles([ file1 ], `Sites/${site}/documentLibrary`)
|
||||
.then(resp => file1Id = resp.data.entry.id))
|
||||
.then(() => apis.admin.nodes.createFiles([ file2 ], `Sites/${site}/documentLibrary`)
|
||||
.then(resp => file2Id = resp.data.entry.id))
|
||||
.then(() => apis.admin.sites.addSiteMember(site, username, SITE_ROLES.SITE_CONSUMER))
|
||||
.then(() => apis.admin.nodes.setGranularPermission(file1Id, false, username, SITE_ROLES.SITE_CONSUMER))
|
||||
.then(() => apis.admin.nodes.setGranularPermission(file2Id, false, username, SITE_ROLES.SITE_MANAGER))
|
||||
|
||||
.then(() => apis.user.shared.shareFileById(file1Id))
|
||||
.then(() => apis.admin.shared.shareFileById(file2Id))
|
||||
|
||||
.then(() => apis.user.favorites.addFavoritesByIds('file', [file1Id, file2Id]))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.admin.sites.deleteSite(site),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
describe('actions update accordingly for files with different granular permissions', () => {
|
||||
it('on File Libraries', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.doubleClickOnItemName(site))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.clickOnItemName(file1))
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${file1}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${file1}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${file1}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${file1}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for ${file1}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for ${file1}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${file1}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clickOnItemName(file2))
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${file2}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${file2}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${file2}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${file2}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${file2}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${file2}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${file2}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
|
||||
it('on Shared Files', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.clickOnItemName(file1))
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${file1}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${file1}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${file1}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${file1}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for ${file1}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for ${file1}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${file1}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clickOnItemName(file2))
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${file2}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${file2}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${file2}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${file2}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${file2}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${file2}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${file2}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
|
||||
// disabled until ACA-1184 is done
|
||||
xit('on Favorites', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.clickOnItemName(file1))
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${file1}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${file1}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${file1}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${file1}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for ${file1}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for ${file1}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${file1}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform())
|
||||
.then(() => dataTable.clickOnItemName(file2))
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${file2}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${file2}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${file2}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${file2}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${file2}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${file2}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${file2}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
});
|
||||
|
||||
describe('correct actions are displayed when selecting multiple files with different granular permissions', () => {
|
||||
it('on File Libraries', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.doubleClickOnItemName(site))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.selectMultipleItems([ file1, file2 ]))
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, `View is displayed for selected files`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for selected files`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for selected files`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
|
||||
it('on Shared Files', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.selectMultipleItems([ file1, file2 ]))
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, `View is displayed for selected files`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for selected files`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for selected files`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
|
||||
// disabled until ACA-1184 is done
|
||||
xit('on Favorites', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.selectMultipleItems([ file1, file2 ]))
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, `View is displayed for selected files`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for selected files`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for selected files`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for selected files`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for selected files`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
});
|
||||
|
||||
xit('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Personal Files', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username).then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('actions are not displayed when no item is selected', () => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`);
|
||||
});
|
||||
|
||||
it('actions are displayed when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileUser)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('actions are displayed when a folder is selected', () => {
|
||||
dataTable.clickOnItemName(folderUser)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${folderUser}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('correct actions appear when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileUser)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${fileUser}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${fileUser}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${fileUser}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${fileUser}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${fileUser}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${fileUser}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${fileUser}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
|
||||
it('correct actions appear when a folder is selected', () => {
|
||||
dataTable.clickOnItemName(folderUser)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, `View is displayed for ${folderUser}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not enabled for ${folderUser}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(true, `Edit is not displayed for ${folderUser}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${folderUser}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${folderUser}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${folderUser}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${folderUser}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
});
|
||||
|
||||
describe('File Libraries', () => {
|
||||
beforeAll(done => {
|
||||
apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC)
|
||||
.then(() => apis.admin.people.createUser(username2))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_MANAGER))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteName, username2, SITE_ROLES.SITE_CONSUMER))
|
||||
.then(() => apis.admin.nodes.createFiles([ fileAdmin ], `Sites/${siteName}/documentLibrary`))
|
||||
.then(() => apis.admin.nodes.createFolders([ folderAdmin ], `Sites/${siteName}/documentLibrary`))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.doubleClickOnItemName(siteName))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
apis.admin.sites.deleteSite(siteName).then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('user is Manager', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username).then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('actions are not displayed when no item is selected', () => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`);
|
||||
});
|
||||
|
||||
it('actions are displayed when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileAdmin)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileAdmin}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('actions are displayed when a folder is selected', () => {
|
||||
dataTable.clickOnItemName(folderAdmin)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${folderAdmin}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('correct actions appear when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileAdmin)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${fileAdmin}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${fileAdmin}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${fileAdmin}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${fileAdmin}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${fileAdmin}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${fileAdmin}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${fileAdmin}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
|
||||
it('correct actions appear when a folder is selected', () => {
|
||||
dataTable.clickOnItemName(folderAdmin)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, `View is displayed for ${folderAdmin}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not enabled for ${folderAdmin}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(true, `Edit is not displayed for ${folderAdmin}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${folderAdmin}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${folderAdmin}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${folderAdmin}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${folderAdmin}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
});
|
||||
|
||||
describe('user is Consumer', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username2).then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('actions are not displayed when no item is selected', () => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`);
|
||||
});
|
||||
|
||||
it('actions are displayed when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileAdmin)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileAdmin}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('actions are displayed when a folder is selected', () => {
|
||||
dataTable.clickOnItemName(folderAdmin)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${folderAdmin}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('correct actions appear when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileAdmin)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${fileAdmin}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${fileAdmin}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${fileAdmin}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${fileAdmin}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for ${fileAdmin}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for ${fileAdmin}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${fileAdmin}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
|
||||
it('correct actions appear when a folder is selected', () => {
|
||||
dataTable.clickOnItemName(folderAdmin)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, `View is displayed for ${folderAdmin}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not enabled for ${folderAdmin}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${folderAdmin}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${folderAdmin}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(false, `Delete is displayed for ${folderAdmin}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(false, `Move is displayed for ${folderAdmin}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${folderAdmin}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Shared Files', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username).then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('actions are not displayed when no item is selected', () => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`);
|
||||
});
|
||||
|
||||
it('actions are displayed when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileUser)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('correct actions appear when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileUser)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${fileUser}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${fileUser}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${fileUser}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${fileUser}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${fileUser}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${fileUser}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${fileUser}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
});
|
||||
|
||||
describe('Recent Files', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username).then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('actions are not displayed when no item is selected', () => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`);
|
||||
});
|
||||
|
||||
it('actions are displayed when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileUser)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('correct actions appear when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileUser)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${fileUser}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${fileUser}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${fileUser}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${fileUser}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${fileUser}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${fileUser}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${fileUser}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
});
|
||||
|
||||
describe('Favorites', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username).then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('actions are not displayed when no item is selected', () => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`);
|
||||
});
|
||||
|
||||
it('actions are displayed when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileUser)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileUser}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('actions are displayed when a folder is selected', () => {
|
||||
dataTable.clickOnItemName(folderUser)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${folderUser}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('correct actions appear when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileUser)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(true, `View is not displayed for ${fileUser}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not displayed for ${fileUser}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(false, `Edit is displayed for ${fileUser}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${fileUser}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${fileUser}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${fileUser}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${fileUser}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
|
||||
it('correct actions appear when a folder is selected', () => {
|
||||
dataTable.clickOnItemName(folderUser)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('View')).toBe(false, `View is displayed for ${folderUser}`);
|
||||
expect(toolbar.actions.isButtonPresent('Download')).toBe(true, `Download is not enabled for ${folderUser}`);
|
||||
expect(toolbar.actions.isButtonPresent('Edit')).toBe(true, `Edit is not displayed for ${folderUser}`);
|
||||
})
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(menu => {
|
||||
expect(menu.isMenuItemPresent('Copy')).toBe(true, `Copy is not displayed for ${folderUser}`);
|
||||
expect(menu.isMenuItemPresent('Delete')).toBe(true, `Delete is not displayed for ${folderUser}`);
|
||||
expect(menu.isMenuItemPresent('Move')).toBe(true, `Move is not displayed for ${folderUser}`);
|
||||
expect(menu.isMenuItemPresent('Favorite')).toBe(true, `Favorite is not displayed for ${folderUser}`);
|
||||
})
|
||||
.then(() => browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform());
|
||||
});
|
||||
});
|
||||
|
||||
// [C217090]
|
||||
describe('Trash', () => {
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.deleteNodeById(fileForDeleteId, false)
|
||||
.then(() => apis.user.nodes.deleteNodeById(folderForDeleteId, false))
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.user.trashcan.permanentlyDelete(fileForDeleteId),
|
||||
apis.user.trashcan.permanentlyDelete(folderForDeleteId),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('actions are not displayed when no item is selected', () => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(true, `actions displayed though nothing selected`);
|
||||
});
|
||||
|
||||
it('actions are displayed when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileForDelete)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${fileForDelete}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('actions are displayed when a folder is selected', () => {
|
||||
dataTable.clickOnItemName(folderForDelete)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isEmpty()).toBe(false, `actions not displayed for ${folderForDelete}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('correct actions appear when a file is selected', () => {
|
||||
dataTable.clickOnItemName(fileForDelete)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('Permanently delete'))
|
||||
.toBe(true, `Permanently delete is not displayed for ${fileForDelete}`);
|
||||
expect(toolbar.actions.isButtonPresent('Restore')).toBe(true, `Restore is not displayed for ${fileForDelete}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('correct actions appear when a folder is selected', () => {
|
||||
dataTable.clickOnItemName(folderForDelete)
|
||||
.then(() => {
|
||||
expect(toolbar.actions.isButtonPresent('Permanently delete'))
|
||||
.toBe(true, `Permanently delete is displayed for ${folderForDelete}`);
|
||||
expect(toolbar.actions.isButtonPresent('Restore')).toBe(true, `Restore is not enabled for ${folderForDelete}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
423
e2e/suites/actions/undo-delete.test.ts
Executable file
423
e2e/suites/actions/undo-delete.test.ts
Executable file
@ -0,0 +1,423 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { SIDEBAR_LABELS } from '../../configs';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
describe('Undo delete content', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable, toolbar } = page;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username).then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
apis.admin.trashcan.emptyTrash().then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('on Personal Files', () => {
|
||||
const file1 = `file1-${Utils.random()}.txt`; let file1Id;
|
||||
const file2 = `file2-${Utils.random()}.txt`; let file2Id;
|
||||
const file3 = `file3-${Utils.random()}.txt`; let file3Id;
|
||||
const file4 = `file4-${Utils.random()}.txt`;
|
||||
const folder1 = `folder1-${Utils.random()}`; let folder1Id;
|
||||
const folder2 = `folder2-${Utils.random()}`; let folder2Id;
|
||||
const fileLocked2 = `fileLocked2-${Utils.random()}.txt`; let fileLocked2Id;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.createFile(file1).then(resp => file1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(file2).then(resp => file2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(file3).then(resp => file3Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolder(folder1).then(resp => folder1Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(file4, folder1Id))
|
||||
.then(() => apis.user.nodes.createFolder(folder2).then(resp => folder2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(fileLocked2, folder2Id).then(resp => fileLocked2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.lockFile(fileLocked2Id))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
page.refresh().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
logoutPage.load(),
|
||||
apis.user.nodes.unlockFile(fileLocked2Id)
|
||||
.then(() => apis.user.nodes.deleteNodesById([file1Id, file2Id, file3Id, folder1Id, folder2Id]))
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('Successful delete notification shows Undo action', () => {
|
||||
dataTable.clickOnItemName(file1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).toContain(`Undo`);
|
||||
})
|
||||
|
||||
.then(() => apis.user.trashcan.restore(file1Id));
|
||||
});
|
||||
|
||||
it('Unsuccessful delete notification does not show Undo action', () => {
|
||||
dataTable.clickOnItemName(folder2)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => {
|
||||
expect(message).not.toContain(`Undo`);
|
||||
});
|
||||
});
|
||||
|
||||
it('Undo delete of file', () => {
|
||||
let items: number;
|
||||
page.dataTable.countRows().then(number => { items = number; });
|
||||
|
||||
dataTable.clickOnItemName(file1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.clickSnackBarAction())
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(file1).isPresent()).toBe(true, 'Item was not restored');
|
||||
expect(page.pagination.range.getText()).toContain(`1-${items} of ${items}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('Undo delete of folder with content', () => {
|
||||
let items: number;
|
||||
page.dataTable.countRows().then(number => { items = number; });
|
||||
|
||||
dataTable.clickOnItemName(folder1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.clickSnackBarAction())
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(folder1).isPresent()).toBe(true, 'Item was not restored');
|
||||
expect(page.pagination.range.getText()).toContain(`1-${items} of ${items}`);
|
||||
})
|
||||
.then(() => dataTable.doubleClickOnItemName(folder1))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(file4).isPresent()).toBe(true, 'file from folder not restored');
|
||||
});
|
||||
});
|
||||
|
||||
it('undo delete of multiple files', () => {
|
||||
let items: number;
|
||||
page.dataTable.countRows().then(number => { items = number; });
|
||||
|
||||
dataTable.selectMultipleItems([file2, file3])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.clickSnackBarAction())
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(file2).isPresent()).toBe(true, `${file2} was not removed from list`);
|
||||
expect(dataTable.getRowName(file3).isPresent()).toBe(true, `${file3} was not removed from list`);
|
||||
expect(page.pagination.range.getText()).toContain(`1-${items} of ${items}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Shared Files', () => {
|
||||
const sharedFile1 = `sharedFile1-${Utils.random()}`; let sharedFile1Id;
|
||||
const sharedFile2 = `sharedFile2-${Utils.random()}`; let sharedFile2Id;
|
||||
const sharedFile3 = `sharedFile3-${Utils.random()}`; let sharedFile3Id;
|
||||
const sharedFile4 = `sharedFile4-${Utils.random()}`; let sharedFile4Id;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.createFile(sharedFile1).then(resp => sharedFile1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(sharedFile2).then(resp => sharedFile2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(sharedFile3).then(resp => sharedFile3Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(sharedFile4).then(resp => sharedFile4Id = resp.data.entry.id))
|
||||
.then(() => apis.user.shared.shareFilesByIds([sharedFile1Id, sharedFile2Id, sharedFile3Id, sharedFile4Id]))
|
||||
.then(() => apis.user.shared.waitForApi({ expect: 4 }))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
page.refresh().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
logoutPage.load(),
|
||||
apis.user.nodes.deleteNodesById([sharedFile2Id, sharedFile3Id, sharedFile4Id])
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('Successful delete notification shows Undo action', () => {
|
||||
dataTable.clickOnItemName(sharedFile1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => expect(message).toContain(`Undo`));
|
||||
});
|
||||
|
||||
it('Undo delete of file', () => {
|
||||
dataTable.clickOnItemName(sharedFile2)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.clickSnackBarAction())
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => expect(dataTable.getRowName(sharedFile2).isPresent()).toBe(false, 'Item was not restored'));
|
||||
});
|
||||
|
||||
it('undo delete of multiple files', () => {
|
||||
dataTable.selectMultipleItems([sharedFile3, sharedFile4])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.clickSnackBarAction())
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(sharedFile3).isPresent()).toBe(false, `${sharedFile3} was not restored`);
|
||||
expect(dataTable.getRowName(sharedFile4).isPresent()).toBe(false, `${sharedFile4} was not restored`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Favorites', () => {
|
||||
const favoriteFile1 = `favFile1-${Utils.random()}.txt`; let favoriteFile1Id;
|
||||
const favoriteFile2 = `favFile2-${Utils.random()}.txt`; let favoriteFile2Id;
|
||||
const favoriteFile4 = `favFile4-${Utils.random()}.txt`;
|
||||
const favoriteFileLocked2 = `favFileLocked2-${Utils.random()}.txt`; let favoriteFileLocked2Id;
|
||||
const favoriteFolder1 = `favFolder1-${Utils.random()}`; let favoriteFolder1Id;
|
||||
const favoriteFolder2 = `favFolder2-${Utils.random()}`; let favoriteFolder2Id;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.createFile(favoriteFile1).then(resp => favoriteFile1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(favoriteFile2).then(resp => favoriteFile2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolder(favoriteFolder1).then(resp => favoriteFolder1Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(favoriteFile4, favoriteFolder1Id))
|
||||
.then(() => apis.user.nodes.createFolder(favoriteFolder2).then(resp => favoriteFolder2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(favoriteFileLocked2, favoriteFolder2Id)
|
||||
.then(resp => favoriteFileLocked2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.lockFile(favoriteFileLocked2Id))
|
||||
|
||||
.then(() => apis.user.favorites.addFavoritesByIds('file', [favoriteFile1Id, favoriteFile2Id]))
|
||||
.then(() => apis.user.favorites.addFavoritesByIds('folder', [favoriteFolder1Id, favoriteFolder2Id]))
|
||||
.then(() => apis.user.favorites.waitForApi({ expect: 4 }))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
page.refresh().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
logoutPage.load(),
|
||||
apis.user.nodes.unlockFile(favoriteFileLocked2Id)
|
||||
.then(() => apis.user.nodes.deleteNodesById([favoriteFile1Id, favoriteFile2Id, favoriteFolder1Id, favoriteFolder2Id]))
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('Successful delete notification shows Undo action', () => {
|
||||
dataTable.clickOnItemName(favoriteFile1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => expect(message).toContain(`Undo`))
|
||||
|
||||
.then(() => apis.user.trashcan.restore(favoriteFile1Id));
|
||||
});
|
||||
|
||||
it('Unsuccessful delete notification does not show Undo action', () => {
|
||||
dataTable.clickOnItemName(favoriteFolder2)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => expect(message).not.toContain(`Undo`));
|
||||
});
|
||||
|
||||
it('Undo delete of file', () => {
|
||||
let items: number;
|
||||
page.dataTable.countRows().then(number => { items = number; });
|
||||
|
||||
dataTable.clickOnItemName(favoriteFile1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.clickSnackBarAction())
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(favoriteFile1).isPresent()).toBe(true, 'Item was not restored');
|
||||
expect(page.pagination.range.getText()).toContain(`1-${items} of ${items}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('Undo delete of folder with content', () => {
|
||||
let items: number;
|
||||
page.dataTable.countRows().then(number => { items = number; });
|
||||
|
||||
dataTable.clickOnItemName(favoriteFolder1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.clickSnackBarAction())
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(favoriteFolder1).isPresent()).toBe(true, 'Item was not restored');
|
||||
expect(page.pagination.range.getText()).toContain(`1-${items} of ${items}`);
|
||||
})
|
||||
.then(() => dataTable.doubleClickOnItemName(favoriteFolder1))
|
||||
.then(() => expect(dataTable.getRowName(favoriteFile4).isPresent()).toBe(true, 'file from folder not restored'));
|
||||
});
|
||||
|
||||
it('undo delete of multiple files', () => {
|
||||
let items: number;
|
||||
page.dataTable.countRows().then(number => { items = number; });
|
||||
|
||||
dataTable.selectMultipleItems([favoriteFile1, favoriteFile2])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.clickSnackBarAction())
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(favoriteFile1).isPresent()).toBe(true, `${favoriteFile1} was not removed from list`);
|
||||
expect(dataTable.getRowName(favoriteFile2).isPresent()).toBe(true, `${favoriteFile2} was not removed from list`);
|
||||
expect(page.pagination.range.getText()).toContain(`1-${items} of ${items}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Recent Files', () => {
|
||||
const recentFile1 = `recentFile1-${Utils.random()}.txt`; let recentFile1Id;
|
||||
const recentFile2 = `recentFile2-${Utils.random()}.txt`; let recentFile2Id;
|
||||
const recentFile3 = `recentFile3-${Utils.random()}.txt`; let recentFile3Id;
|
||||
const recentFile4 = `recentFile4-${Utils.random()}.txt`; let recentFile4Id;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.createFile(recentFile1).then(resp => recentFile1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(recentFile2).then(resp => recentFile2Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(recentFile3).then(resp => recentFile3Id = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFile(recentFile4).then(resp => recentFile4Id = resp.data.entry.id))
|
||||
.then(() => apis.user.search.waitForApi(username, { expect: 4 }))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
|
||||
.then((): any => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => dataTable.isEmptyList())
|
||||
.then(empty => {
|
||||
if (empty) {
|
||||
browser.sleep(6000).then(() => page.refresh());
|
||||
}
|
||||
})
|
||||
)
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
page.refresh().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
logoutPage.load(),
|
||||
apis.user.nodes.deleteNodesById([recentFile2Id, recentFile3Id, recentFile4Id])
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('Successful delete notification shows Undo action', () => {
|
||||
dataTable.clickOnItemName(recentFile1)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.getSnackBarMessage())
|
||||
.then(message => expect(message).toContain(`Undo`));
|
||||
});
|
||||
|
||||
// due to the fact that the search api is slow to update,
|
||||
// we cannot test that the restored file is displayed in the Recent Files list
|
||||
// without adding a very big browser.sleep followed by a page.refresh
|
||||
// so for the moment we're testing that the restored file is not displayed in the Trash
|
||||
it('Undo delete of file', () => {
|
||||
dataTable.clickOnItemName(recentFile2)
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.clickSnackBarAction())
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => expect(dataTable.getRowName(recentFile2).isPresent()).toBe(false, 'Item is in Trash'));
|
||||
});
|
||||
|
||||
// due to the fact that the search api is slow to update,
|
||||
// we cannot test that the restored file is displayed in the Recent Files list
|
||||
// without adding a very big browser.sleep followed by a page.refresh
|
||||
// so for the moment we're testing that the restored file is not displayed in the Trash
|
||||
it('undo delete of multiple files', () => {
|
||||
dataTable.selectMultipleItems([recentFile3, recentFile4])
|
||||
.then(() => toolbar.actions.openMoreMenu())
|
||||
.then(() => toolbar.actions.menu.clickMenuItem('Delete'))
|
||||
.then(() => page.clickSnackBarAction())
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => {
|
||||
expect(dataTable.getRowName(recentFile3).isPresent()).toBe(false, `${recentFile3} is in Trash`);
|
||||
expect(dataTable.getRowName(recentFile4).isPresent()).toBe(false, `${recentFile4} is in Trash`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
74
e2e/suites/actions/upload-file.test.ts
Executable file
74
e2e/suites/actions/upload-file.test.ts
Executable file
@ -0,0 +1,74 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, promise } from 'protractor';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { SIDEBAR_LABELS } from '../../configs';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
|
||||
describe('Upload files', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const folder1 = `folder1-${Utils.random()}`; let folder1Id;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable } = page;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => apis.user.nodes.createFolder(folder1).then(resp => folder1Id = resp.data.entry.id))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
// apis.user.nodes.deleteNodeById(folder1Id),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('Upload a file', () => {
|
||||
dataTable.doubleClickOnItemName(folder1)
|
||||
.then(() => page.sidenav.openNewMenu())
|
||||
.then(() => page.sidenav.menu.uploadFile().sendKeys(`${__dirname}/create-folder.test.ts`));
|
||||
});
|
||||
});
|
128
e2e/suites/application/page-titles.test.ts
Executable file
128
e2e/suites/application/page-titles.test.ts
Executable file
@ -0,0 +1,128 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
|
||||
describe('Page titles', () => {
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
|
||||
xit('');
|
||||
|
||||
describe('on Login / Logout pages', () => {
|
||||
it('on Login page', () => {
|
||||
loginPage.load()
|
||||
.then(() => {
|
||||
expect(browser.getTitle()).toContain('Sign in');
|
||||
});
|
||||
});
|
||||
|
||||
it('after logout', () => {
|
||||
loginPage.loginWithAdmin()
|
||||
.then(() => page.signOut())
|
||||
.then(() => {
|
||||
expect(browser.getTitle()).toContain('Sign in');
|
||||
});
|
||||
});
|
||||
|
||||
it('when pressing Back after Logout', () => {
|
||||
loginPage.loginWithAdmin()
|
||||
.then(() => page.signOut())
|
||||
.then(() => browser.navigate().back())
|
||||
.then(() => {
|
||||
expect(browser.getTitle()).toContain('Sign in');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('on list views', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWithAdmin().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load()
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('Personal Files page', () => {
|
||||
const label = SIDEBAR_LABELS.PERSONAL_FILES;
|
||||
|
||||
page.sidenav.navigateToLinkByLabel(label)
|
||||
.then(() => {
|
||||
expect(browser.getTitle()).toContain(label);
|
||||
});
|
||||
});
|
||||
|
||||
it('File Libraries page', () => {
|
||||
const label = SIDEBAR_LABELS.FILE_LIBRARIES;
|
||||
|
||||
page.sidenav.navigateToLinkByLabel(label)
|
||||
.then(() => {
|
||||
expect(browser.getTitle()).toContain(label);
|
||||
});
|
||||
});
|
||||
|
||||
it('Shared Files page', () => {
|
||||
const label = SIDEBAR_LABELS.SHARED_FILES;
|
||||
|
||||
page.sidenav.navigateToLinkByLabel(label)
|
||||
.then(() => {
|
||||
expect(browser.getTitle()).toContain(label);
|
||||
});
|
||||
});
|
||||
|
||||
it('Recent Files page', () => {
|
||||
const label = SIDEBAR_LABELS.RECENT_FILES;
|
||||
|
||||
page.sidenav.navigateToLinkByLabel(label)
|
||||
.then(() => {
|
||||
expect(browser.getTitle()).toContain(label);
|
||||
});
|
||||
});
|
||||
|
||||
it('Favorites page', () => {
|
||||
const label = SIDEBAR_LABELS.FAVORITES;
|
||||
|
||||
page.sidenav.navigateToLinkByLabel(label)
|
||||
.then(() => {
|
||||
expect(browser.getTitle()).toContain(label);
|
||||
});
|
||||
});
|
||||
|
||||
it('Trash page', () => {
|
||||
const label = SIDEBAR_LABELS.TRASH;
|
||||
|
||||
page.sidenav.navigateToLinkByLabel(label)
|
||||
.then(() => {
|
||||
expect(browser.getTitle()).toContain(label);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
237
e2e/suites/authentication/login.test.ts
Executable file
237
e2e/suites/authentication/login.test.ts
Executable file
@ -0,0 +1,237 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { APP_ROUTES } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Login', () => {
|
||||
const peopleApi = new RepoClient().people;
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
|
||||
const testUser = `user-${Utils.random()}@alfness`;
|
||||
|
||||
const russianUser = {
|
||||
username: `пользвате${Utils.random()}`,
|
||||
password: '密碼中國'
|
||||
};
|
||||
|
||||
const johnDoe = {
|
||||
username: `user-${Utils.random()}`,
|
||||
get password() { return this.username; },
|
||||
firstName: 'John',
|
||||
lastName: 'Doe'
|
||||
};
|
||||
|
||||
const disabledUser = `user-${Utils.random()}`;
|
||||
const testUser2 = {
|
||||
username: `user-${Utils.random()}`,
|
||||
password: 'user2 password'
|
||||
};
|
||||
const newPassword = 'new password';
|
||||
|
||||
beforeAll(done => {
|
||||
Promise
|
||||
.all([
|
||||
peopleApi.createUser(testUser),
|
||||
peopleApi.createUser(russianUser.username, russianUser.password),
|
||||
peopleApi.createUser(johnDoe.username, johnDoe.password, {
|
||||
firstName: johnDoe.firstName,
|
||||
lastName: johnDoe.lastName
|
||||
}),
|
||||
peopleApi.createUser(disabledUser).then(() => peopleApi.disableUser(disabledUser)),
|
||||
peopleApi.createUser(testUser2.username, testUser2.password)
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
logoutPage.load()
|
||||
.then(() => Utils.clearLocalStorage())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('general tests', () => {
|
||||
beforeEach(done => {
|
||||
loginPage.load().then(done);
|
||||
});
|
||||
|
||||
it('login page default values', () => {
|
||||
expect(loginPage.login.usernameInput.isEnabled()).toBe(true, 'username input is not enabled');
|
||||
expect(loginPage.login.passwordInput.isEnabled()).toBe(true, 'password input is not enabled');
|
||||
expect(loginPage.login.submitButton.isEnabled()).toBe(false, 'SIGN IN button is enabled');
|
||||
expect(loginPage.login.getPasswordVisibility()).toBe(false, 'Password is not hidden by default');
|
||||
});
|
||||
|
||||
it('change password visibility', () => {
|
||||
loginPage.login.enterPassword('some password');
|
||||
expect(loginPage.login.isPasswordShown()).toBe(false, 'password is visible');
|
||||
loginPage.login.passwordVisibility.click()
|
||||
.then(() => {
|
||||
expect(loginPage.login.getPasswordVisibility()).toBe(true, 'Password visibility not changed');
|
||||
expect(loginPage.login.isPasswordShown()).toBe(true, 'password is not visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with valid credentials', () => {
|
||||
it('navigate to "Personal Files"', () => {
|
||||
const { username } = johnDoe;
|
||||
|
||||
loginPage.loginWith(username)
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES);
|
||||
});
|
||||
});
|
||||
|
||||
it(`displays user's name in header`, () => {
|
||||
const { userInfo } = new BrowsingPage(APP_ROUTES.PERSONAL_FILES).header;
|
||||
const { username, firstName, lastName } = johnDoe;
|
||||
|
||||
loginPage.loginWith(username)
|
||||
.then(() => {
|
||||
expect(userInfo.name).toEqual(`${firstName} ${lastName}`);
|
||||
});
|
||||
});
|
||||
|
||||
it(`logs in with user having username containing "@"`, () => {
|
||||
loginPage
|
||||
.loginWith(testUser)
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES);
|
||||
});
|
||||
});
|
||||
|
||||
it('logs in with user with non-latin characters', () => {
|
||||
const { username, password } = russianUser;
|
||||
|
||||
loginPage
|
||||
.loginWith(username, password)
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES);
|
||||
});
|
||||
});
|
||||
|
||||
it('redirects to Home Page when navigating to the Login page while already logged in', () => {
|
||||
const { username } = johnDoe;
|
||||
|
||||
loginPage
|
||||
.loginWith(username)
|
||||
.then(() => browser.get(APP_ROUTES.LOGIN)
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('redirects to Personal Files when pressing browser Back while already logged in ', () => {
|
||||
const { username } = johnDoe;
|
||||
|
||||
loginPage
|
||||
.loginWith(username)
|
||||
.then(() => browser.navigate().back())
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES);
|
||||
});
|
||||
});
|
||||
|
||||
it('user is able to login after changing his password', () => {
|
||||
loginPage.loginWith(testUser2.username, testUser2.password)
|
||||
.then(() => logoutPage.load())
|
||||
.then(() => peopleApi.changePassword(testUser2.username, newPassword))
|
||||
.then(() => loginPage.loginWith(testUser2.username, newPassword))
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with invalid credentials', () => {
|
||||
const { login: loginComponent } = loginPage;
|
||||
const { submitButton, errorMessage } = loginComponent;
|
||||
|
||||
beforeEach(done => {
|
||||
loginPage.load().then(done);
|
||||
});
|
||||
|
||||
it('disabled submit button when no credentials are entered', () => {
|
||||
expect(submitButton.isEnabled()).toBe(false);
|
||||
});
|
||||
|
||||
it('disabled submit button when password is empty', () => {
|
||||
loginComponent.enterUsername('any-username');
|
||||
expect(submitButton.isEnabled()).toBe(false);
|
||||
});
|
||||
|
||||
it('disabled submit button when username is empty', () => {
|
||||
loginPage.login.enterPassword('any-password');
|
||||
expect(submitButton.isEnabled()).toBe(false);
|
||||
});
|
||||
|
||||
it('shows error when entering nonexistent user', () => {
|
||||
loginPage
|
||||
.tryLoginWith('nonexistent-user', 'any-password')
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.LOGIN);
|
||||
expect(errorMessage.isDisplayed()).toBe(true);
|
||||
expect(errorMessage.getText()).toBe(`You've entered an unknown username or password`);
|
||||
});
|
||||
});
|
||||
|
||||
it('shows error when entering invalid password', () => {
|
||||
const { username } = johnDoe;
|
||||
|
||||
loginPage
|
||||
.tryLoginWith(username, 'incorrect-password')
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.LOGIN);
|
||||
expect(errorMessage.isDisplayed()).toBe(true);
|
||||
expect(errorMessage.getText()).toBe(`You've entered an unknown username or password`);
|
||||
});
|
||||
});
|
||||
|
||||
it('unauthenticated user is redirected to Login page', () => {
|
||||
browser.get(APP_ROUTES.PERSONAL_FILES)
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.LOGIN);
|
||||
});
|
||||
});
|
||||
|
||||
it('disabled user is not logged in', () => {
|
||||
loginPage.tryLoginWith(disabledUser)
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.LOGIN);
|
||||
expect(errorMessage.isDisplayed()).toBe(true);
|
||||
expect(errorMessage.getText()).toBe(`You've entered an unknown username or password`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
82
e2e/suites/authentication/logout.test.ts
Executable file
82
e2e/suites/authentication/logout.test.ts
Executable file
@ -0,0 +1,82 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
import { APP_ROUTES } from '../../configs';
|
||||
|
||||
describe('Logout', () => {
|
||||
const page = new BrowsingPage();
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
|
||||
const peopleApi = new RepoClient().people;
|
||||
|
||||
const johnDoe = `user-${Utils.random()}`;
|
||||
|
||||
beforeAll((done) => {
|
||||
peopleApi
|
||||
.createUser(johnDoe)
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach((done) => {
|
||||
loginPage.loginWith(johnDoe).then(done);
|
||||
});
|
||||
|
||||
afterEach((done) => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('Sign out option is available [C213143]', () => {
|
||||
page.header.userInfo.openMenu()
|
||||
.then(() => expect(page.header.userInfo.menu.isMenuItemPresent('Sign out')).toBe(true, 'Sign out option not displayed'));
|
||||
});
|
||||
|
||||
it('redirects to Login page on sign out [C213144]', () => {
|
||||
page.signOut()
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.LOGIN);
|
||||
});
|
||||
});
|
||||
|
||||
it('redirects to Login page when pressing browser Back after logout [C213145]', () => {
|
||||
page.signOut()
|
||||
.then(() => browser.navigate().back())
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.LOGIN);
|
||||
});
|
||||
});
|
||||
|
||||
it('redirects to Login page when trying to access a part of the app after logout [C213146]', () => {
|
||||
page.signOut()
|
||||
.then(() => page.load('/favorites'))
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.LOGIN);
|
||||
});
|
||||
});
|
||||
});
|
108
e2e/suites/list-views/empty-list.test.ts
Executable file
108
e2e/suites/list-views/empty-list.test.ts
Executable file
@ -0,0 +1,108 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Empty list views', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
const password = username;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, password)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable } = page;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('empty Personal Files', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => {
|
||||
expect(dataTable.isEmptyList()).toBe(true, 'list is not empty');
|
||||
expect(dataTable.getEmptyDragAndDropText()).toContain('Drag and drop');
|
||||
});
|
||||
});
|
||||
|
||||
it('empty File Libraries [C217099]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => {
|
||||
expect(dataTable.isEmptyList()).toBe(true, 'list is not empty');
|
||||
expect(dataTable.getEmptyStateTitle()).toContain(`You aren't a member of any File Libraries yet`);
|
||||
expect(dataTable.getEmptyStateSubtitle()).toContain('Join sites to upload, view, and share files.');
|
||||
});
|
||||
});
|
||||
|
||||
it('empty Shared Files', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => {
|
||||
expect(dataTable.isEmptyList()).toBe(true, 'list is not empty');
|
||||
expect(dataTable.getEmptyStateTitle()).toContain('No shared files or folders');
|
||||
expect(dataTable.getEmptyStateSubtitle()).toContain('Items you share using the Share option are shown here.');
|
||||
});
|
||||
});
|
||||
|
||||
it('empty Recent Files [C213169]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => {
|
||||
expect(dataTable.isEmptyList()).toBe(true, 'list is not empty');
|
||||
expect(dataTable.getEmptyStateTitle()).toContain('No recent files');
|
||||
expect(dataTable.getEmptyStateSubtitle()).toContain('Items you upload or edit in the last 30 days are shown here.');
|
||||
});
|
||||
});
|
||||
|
||||
it('empty Favorites', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => {
|
||||
expect(dataTable.isEmptyList()).toBe(true, 'list is not empty');
|
||||
expect(dataTable.getEmptyStateTitle()).toContain('No favorite files or folders');
|
||||
expect(dataTable.getEmptyStateSubtitle()).toContain('Favorite items that you want to easily find later.');
|
||||
});
|
||||
});
|
||||
|
||||
it('empty Trash', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => {
|
||||
expect(dataTable.isEmptyList()).toBe(true, 'list is not empty');
|
||||
expect(dataTable.getEmptyStateTitle()).toContain('Trash is empty');
|
||||
expect(dataTable.getEmptyStateText()).toContain('Items you delete are moved to the Trash.');
|
||||
expect(dataTable.getEmptyStateText()).toContain('Empty Trash to permanently delete items.');
|
||||
});
|
||||
});
|
||||
});
|
156
e2e/suites/list-views/favorites.test.ts
Executable file
156
e2e/suites/list-views/favorites.test.ts
Executable file
@ -0,0 +1,156 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Favorites', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
const password = username;
|
||||
|
||||
const siteName = `site-${Utils.random()}`;
|
||||
const folderName = `folder-${Utils.random()}`;
|
||||
const fileName1 = `file1-${Utils.random()}.txt`;
|
||||
const fileName2 = `file2-${Utils.random()}.txt`;
|
||||
const fileName3 = `file3-${Utils.random()}.txt`; let file3Id;
|
||||
const fileName4 = `file4-${Utils.random()}.txt`; let file4Id;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, password)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const favoritesPage = new BrowsingPage();
|
||||
const { dataTable } = favoritesPage;
|
||||
const { breadcrumb } = favoritesPage.toolbar;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
|
||||
.then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_MANAGER))
|
||||
.then(() => apis.admin.nodes.createFiles([ fileName1 ], `Sites/${siteName}/documentLibrary`)
|
||||
.then(resp => apis.user.favorites.addFavoriteById('file', resp.data.entry.id)))
|
||||
.then(() => apis.user.nodes.createFolders([ folderName ])
|
||||
.then(resp => apis.user.favorites.addFavoriteById('folder', resp.data.entry.id)))
|
||||
.then(() => apis.user.nodes.createFiles([ fileName2 ], folderName)
|
||||
.then(resp => apis.user.favorites.addFavoriteById('file', resp.data.entry.id)))
|
||||
.then(() => apis.user.nodes.createFiles([ fileName3 ], folderName)
|
||||
.then(resp => file3Id = resp.data.entry.id)
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file3Id))
|
||||
.then(() => apis.user.nodes.deleteNodeById(file3Id, false)))
|
||||
.then(() => apis.user.nodes.createFiles([ fileName4 ], folderName)
|
||||
.then(resp => file4Id = resp.data.entry.id)
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', file4Id))
|
||||
.then(() => apis.user.nodes.deleteNodeById(file4Id, false))
|
||||
.then(() => apis.user.trashcan.restore(file4Id)))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
favoritesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.admin.sites.deleteSite(siteName),
|
||||
apis.user.nodes.deleteNodes([ folderName ]),
|
||||
apis.admin.trashcan.emptyTrash(),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('has the correct columns', () => {
|
||||
const labels = [ 'Name', 'Location', 'Size', 'Modified', 'Modified by' ];
|
||||
const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label));
|
||||
|
||||
expect(dataTable.getColumnHeaders().count()).toBe(5 + 1, 'Incorrect number of columns');
|
||||
|
||||
elements.forEach((element, index) => {
|
||||
expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`);
|
||||
});
|
||||
});
|
||||
|
||||
it('displays the favorite files and folders [C213226]', () => {
|
||||
expect(dataTable.countRows()).toEqual(4, 'Incorrect number of items displayed');
|
||||
expect(dataTable.getRowName(fileName1).isPresent()).toBe(true, `${fileName1} not displayed`);
|
||||
expect(dataTable.getRowName(fileName2).isPresent()).toBe(true, `${fileName2} not displayed`);
|
||||
expect(dataTable.getRowName(folderName).isPresent()).toBe(true, `${folderName} not displayed`);
|
||||
});
|
||||
|
||||
it(`file not displayed if it's in the Trashcan [C213228]`, () => {
|
||||
expect(dataTable.getRowName(fileName3).isPresent()).not.toBe(true, `${fileName3} is displayed`);
|
||||
});
|
||||
|
||||
it(`file is displayed after it is restored from Trashcan [C213229]`, () => {
|
||||
expect(dataTable.getRowName(fileName4).isPresent()).toBe(true, `${fileName4} not displayed`);
|
||||
});
|
||||
|
||||
it('Location column displays the parent folder of the files [C213231]', () => {
|
||||
expect(dataTable.getItemLocation(fileName1).getText()).toEqual(siteName);
|
||||
expect(dataTable.getItemLocation(fileName2).getText()).toEqual(folderName);
|
||||
expect(dataTable.getItemLocation(folderName).getText()).toEqual('Personal Files');
|
||||
});
|
||||
|
||||
it('Location column displays a tooltip with the entire path of the file [C213671]', () => {
|
||||
expect(dataTable.getItemLocationTooltip(fileName1)).toEqual(`File Libraries/${siteName}`);
|
||||
expect(dataTable.getItemLocationTooltip(fileName2)).toEqual(`Personal Files/${folderName}`);
|
||||
expect(dataTable.getItemLocationTooltip(folderName)).toEqual('Personal Files');
|
||||
});
|
||||
|
||||
it('Location column redirect - item in user Home [C213650] [C260968]', () => {
|
||||
dataTable.clickItemLocation(folderName)
|
||||
.then(() => expect(breadcrumb.getAllItems()).toEqual([ 'Personal Files' ]));
|
||||
});
|
||||
|
||||
it('Location column redirect - file in folder [C213650] [C260968]', () => {
|
||||
dataTable.clickItemLocation(fileName2)
|
||||
.then(() => expect(breadcrumb.getAllItems()).toEqual([ 'Personal Files', folderName ]));
|
||||
});
|
||||
|
||||
it('Location column redirect - file in site [C213650] [C260969]', () => {
|
||||
dataTable.clickItemLocation(fileName1)
|
||||
.then(() => expect(breadcrumb.getAllItems()).toEqual([ 'File Libraries', siteName ]));
|
||||
});
|
||||
|
||||
it('Navigate into folder from Favorites [C213230]', () => {
|
||||
dataTable.doubleClickOnItemName(folderName)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => breadcrumb.getCurrentItemName())
|
||||
.then(name => {
|
||||
expect(name).toBe(folderName);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
161
e2e/suites/list-views/file-libraries.test.ts
Executable file
161
e2e/suites/list-views/file-libraries.test.ts
Executable file
@ -0,0 +1,161 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('File Libraries', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
const password = username;
|
||||
|
||||
const sitePrivate = `private-${Utils.random()}`;
|
||||
const siteModerated = `moderated-${Utils.random()}`;
|
||||
const sitePublic = `public-${Utils.random()}`;
|
||||
const siteName = `siteName-${Utils.random()}`;
|
||||
const siteId1 = Utils.random();
|
||||
const siteId2 = Utils.random();
|
||||
const adminSite = `admin-${Utils.random()}`;
|
||||
|
||||
const siteDescription = 'my site description';
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, password)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const fileLibrariesPage = new BrowsingPage();
|
||||
const { dataTable } = fileLibrariesPage;
|
||||
|
||||
beforeAll(done => {
|
||||
Promise
|
||||
.all([
|
||||
apis.admin.people.createUser(username),
|
||||
apis.admin.sites.createSite(sitePublic, SITE_VISIBILITY.PUBLIC),
|
||||
apis.admin.sites.createSite(siteModerated, SITE_VISIBILITY.MODERATED, { description: siteDescription }),
|
||||
apis.admin.sites.createSite(sitePrivate, SITE_VISIBILITY.PRIVATE, { description: '' }),
|
||||
apis.admin.sites.createSite(adminSite, SITE_VISIBILITY.PUBLIC),
|
||||
apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC, { id: siteId1 }),
|
||||
apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC, { id: siteId2 })
|
||||
])
|
||||
.then(() => apis.admin.sites.addSiteMember(sitePublic, username, SITE_ROLES.SITE_CONSUMER))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteModerated, username, SITE_ROLES.SITE_MANAGER))
|
||||
.then(() => apis.admin.sites.addSiteMember(sitePrivate, username, SITE_ROLES.SITE_CONTRIBUTOR))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteId1, username, SITE_ROLES.SITE_CONTRIBUTOR))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteId2, username, SITE_ROLES.SITE_CONTRIBUTOR))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
fileLibrariesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.admin.sites.deleteSites([
|
||||
sitePublic,
|
||||
siteModerated,
|
||||
sitePrivate,
|
||||
adminSite,
|
||||
siteId1,
|
||||
siteId2
|
||||
]),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('has the correct columns', () => {
|
||||
const labels = [ 'Title', 'Status' ];
|
||||
const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label));
|
||||
|
||||
expect(dataTable.getColumnHeaders().count()).toBe(2 + 1, 'Incorrect number of columns');
|
||||
|
||||
elements.forEach((element, index) => {
|
||||
expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`);
|
||||
});
|
||||
});
|
||||
|
||||
it('User can see only the sites he is a member of [C217095]', () => {
|
||||
const sitesCount = dataTable.countRows();
|
||||
|
||||
const expectedSites = {
|
||||
[sitePrivate]: SITE_VISIBILITY.PRIVATE,
|
||||
[siteModerated]: SITE_VISIBILITY.MODERATED,
|
||||
[sitePublic]: SITE_VISIBILITY.PUBLIC
|
||||
};
|
||||
|
||||
expect(sitesCount).toEqual(5, 'Incorrect number of sites displayed');
|
||||
expect(dataTable.getRowName(adminSite).isPresent()).toBe(false, 'Incorrect site appears in list');
|
||||
|
||||
dataTable.getRows()
|
||||
.map((row) => {
|
||||
return row.all(dataTable.cell).map(cell => cell.getText());
|
||||
})
|
||||
.then((rowCells) => {
|
||||
return rowCells.reduce((acc, cell) => {
|
||||
acc[cell[1]] = cell[2].toUpperCase();
|
||||
return acc;
|
||||
}, {});
|
||||
})
|
||||
.then((sitesList) => {
|
||||
Object.keys(expectedSites).forEach((site) => {
|
||||
expect(sitesList[site]).toEqual(expectedSites[site]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Site ID is displayed when two sites have the same name [C217098]', () => {
|
||||
const expectedSites = [
|
||||
`${siteName} (${siteId1})`,
|
||||
`${siteName} (${siteId2})`
|
||||
];
|
||||
dataTable.getCellsContainingName(siteName)
|
||||
.then(resp => {
|
||||
const expectedJSON = JSON.stringify(expectedSites.sort());
|
||||
const actualJSON = JSON.stringify(resp.sort());
|
||||
expect(actualJSON).toEqual(expectedJSON);
|
||||
});
|
||||
});
|
||||
|
||||
it('Tooltip for sites without description [C217096]', () => {
|
||||
const tooltip = dataTable.getItemNameTooltip(sitePrivate);
|
||||
expect(tooltip).toBe(`${sitePrivate}`);
|
||||
});
|
||||
|
||||
it('Tooltip for sites with description [C217097]', () => {
|
||||
const tooltip = dataTable.getItemNameTooltip(siteModerated);
|
||||
expect(tooltip).toBe(`${siteDescription}`);
|
||||
});
|
||||
});
|
181
e2e/suites/list-views/permissions.test.ts
Executable file
181
e2e/suites/list-views/permissions.test.ts
Executable file
@ -0,0 +1,181 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Special permissions', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
const password = username;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, password)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const recentFilesPage = new BrowsingPage();
|
||||
const favoritesPage = new BrowsingPage();
|
||||
const sharedPage = new BrowsingPage();
|
||||
const { dataTable } = recentFilesPage;
|
||||
|
||||
xit('');
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username).then(done);
|
||||
});
|
||||
|
||||
describe('file not displayed if user no longer has permissions on it', () => {
|
||||
const sitePrivate = `private-${Utils.random()}`;
|
||||
const fileName = `file-${Utils.random()}.txt`;
|
||||
let fileId;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.sites.createSite(sitePrivate, SITE_VISIBILITY.PRIVATE)
|
||||
.then(() => apis.admin.sites.addSiteMember(sitePrivate, username, SITE_ROLES.SITE_COLLABORATOR))
|
||||
.then(() => apis.admin.nodes.createFiles([ fileName ], `Sites/${sitePrivate}/documentLibrary`)
|
||||
.then(resp => fileId = resp.data.entry.id))
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', fileId))
|
||||
.then(() => apis.admin.shared.shareFileById(fileId))
|
||||
.then(() => apis.user.nodes.editNodeContent(fileId, 'edited by user'))
|
||||
|
||||
.then(() => apis.user.search.waitForApi(username, { expect: 1 }))
|
||||
.then(() => apis.user.shared.waitForApi({ expect: 1 }))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
apis.admin.sites.addSiteMember(sitePrivate, username, SITE_ROLES.SITE_COLLABORATOR).then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.admin.sites.deleteSite(sitePrivate),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('on Recent Files [C213173]', () => {
|
||||
recentFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(1, 'Incorrect number of items');
|
||||
})
|
||||
.then(() => apis.admin.sites.deleteSiteMember(sitePrivate, username))
|
||||
.then(() => recentFilesPage.refresh())
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(0, 'Incorrect number of items');
|
||||
});
|
||||
});
|
||||
|
||||
it('on Favorites [C213227]', () => {
|
||||
favoritesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(1, 'Incorrect number of items');
|
||||
})
|
||||
.then(() => apis.admin.sites.deleteSiteMember(sitePrivate, username))
|
||||
.then(() => favoritesPage.refresh())
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(0, 'Incorrect number of items');
|
||||
});
|
||||
});
|
||||
|
||||
it('on Shared Files [C213116]', () => {
|
||||
sharedPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(1, 'Incorrect number of items');
|
||||
})
|
||||
.then(() => apis.admin.sites.deleteSiteMember(sitePrivate, username))
|
||||
.then(() => sharedPage.refresh())
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(0, 'Incorrect number of items');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe(`Location column is empty if user doesn't have permissions on the file's parent folder`, () => {
|
||||
const sitePrivate = `private-${Utils.random()}`;
|
||||
const fileName = `file-${Utils.random()}.txt`;
|
||||
let fileId;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.sites.createSite(sitePrivate, SITE_VISIBILITY.PRIVATE)
|
||||
.then(() => apis.admin.sites.addSiteMember(sitePrivate, username, SITE_ROLES.SITE_COLLABORATOR))
|
||||
.then(() => apis.admin.sites.getDocLibId(sitePrivate))
|
||||
.then(resp => apis.user.nodes.createFile(fileName, resp))
|
||||
.then(resp => fileId = resp.data.entry.id)
|
||||
.then(() => apis.user.favorites.addFavoriteById('file', fileId))
|
||||
.then(() => apis.user.shared.shareFileById(fileId))
|
||||
.then(() => apis.user.shared.waitForApi({ expect: 1 }))
|
||||
.then(() => apis.user.search.waitForApi(username, { expect: 1 }))
|
||||
.then(() => apis.admin.sites.deleteSiteMember(sitePrivate, username))
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.admin.sites.deleteSite(sitePrivate),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it(`on Recent Files [C213178]`, () => {
|
||||
recentFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(1, 'Incorrect number of items');
|
||||
expect(dataTable.getItemLocation(fileName).getText()).toEqual('');
|
||||
});
|
||||
});
|
||||
|
||||
it(`on Favorites [C213672]`, () => {
|
||||
favoritesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(1, 'Incorrect number of items');
|
||||
expect(dataTable.getItemLocation(fileName).getText()).toEqual('');
|
||||
});
|
||||
});
|
||||
|
||||
it(`on Shared Files [C213668]`, () => {
|
||||
sharedPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(1, 'Incorrect number of items');
|
||||
expect(dataTable.getItemLocation(fileName).getText()).toEqual('');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
176
e2e/suites/list-views/personal-files.test.ts
Executable file
176
e2e/suites/list-views/personal-files.test.ts
Executable file
@ -0,0 +1,176 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SIDEBAR_LABELS, APP_ROUTES } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Personal Files', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const personalFilesPage = new BrowsingPage();
|
||||
const { dataTable } = personalFilesPage;
|
||||
|
||||
const adminFolder = `admin-folder-${Utils.random()}`;
|
||||
|
||||
const userFolder = `user-folder-${Utils.random()}`;
|
||||
const userFile = `file-${Utils.random()}.txt`;
|
||||
|
||||
beforeAll(done => {
|
||||
Promise
|
||||
.all([
|
||||
apis.admin.people.createUser(username),
|
||||
apis.admin.nodes.createFolders([ adminFolder ])
|
||||
])
|
||||
.then(() => apis.user.nodes.createFolders([ userFolder ]))
|
||||
.then(() => apis.user.nodes.createFiles([ userFile ], userFolder))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise
|
||||
.all([
|
||||
apis.admin.nodes.deleteNodes([ adminFolder ]),
|
||||
apis.user.nodes.deleteNodes([ userFolder ])
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe(`Admin user's personal files`, () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWithAdmin().then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('has "Data Dictionary" folder [C213241]', () => {
|
||||
expect(dataTable.getRowName('Data Dictionary').isPresent()).toBe(true);
|
||||
});
|
||||
|
||||
it('has created content', () => {
|
||||
expect(dataTable.getRowName(adminFolder).isPresent()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`Regular user's personal files`, () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username).then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('has the correct columns [C217142]', () => {
|
||||
const labels = [ 'Name', 'Size', 'Modified', 'Modified by' ];
|
||||
const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label));
|
||||
|
||||
expect(dataTable.getColumnHeaders().count()).toBe(4 + 1, 'Incorrect number of columns');
|
||||
|
||||
elements.forEach((element, index) => {
|
||||
expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`);
|
||||
});
|
||||
});
|
||||
|
||||
it('has default sorted column [C217143]', () => {
|
||||
expect(dataTable.getSortedColumnHeader().getText()).toBe('Modified');
|
||||
});
|
||||
|
||||
it('has user created content [C213242]', () => {
|
||||
expect(dataTable.getRowName(userFolder).isPresent())
|
||||
.toBe(true);
|
||||
});
|
||||
|
||||
it('navigates to folder [C213244]', () => {
|
||||
const getNodeIdPromise = apis.user.nodes
|
||||
.getNodeByPath(`/${userFolder}`)
|
||||
.then(response => response.data.entry.id);
|
||||
|
||||
const navigatePromise = dataTable
|
||||
.doubleClickOnItemName(userFolder)
|
||||
.then(() => dataTable.waitForHeader());
|
||||
|
||||
Promise
|
||||
.all([
|
||||
getNodeIdPromise,
|
||||
navigatePromise
|
||||
])
|
||||
.then(([ nodeId ]) => {
|
||||
expect(browser.getCurrentUrl())
|
||||
.toContain(nodeId, 'Node ID is not in the URL');
|
||||
|
||||
expect(dataTable.getRowName(userFile).isPresent())
|
||||
.toBe(true, 'user file is missing');
|
||||
});
|
||||
});
|
||||
|
||||
it('redirects to Personal Files on clicking the link from sidebar [C213245]', () => {
|
||||
personalFilesPage.dataTable.doubleClickOnItemName(userFolder)
|
||||
.then(() => personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES))
|
||||
.then(() => browser.getCurrentUrl())
|
||||
.then(url => expect(url.endsWith(APP_ROUTES.PERSONAL_FILES)).toBe(true, 'incorrect url'));
|
||||
});
|
||||
|
||||
it('page loads correctly after browser refresh [C213246]', () => {
|
||||
personalFilesPage.refresh()
|
||||
.then(() => expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES));
|
||||
});
|
||||
|
||||
it('page load by URL [C213247]', () => {
|
||||
let url;
|
||||
browser.getCurrentUrl()
|
||||
.then(resp => url = resp)
|
||||
.then(() => personalFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => browser.get(url))
|
||||
.then(() => expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES));
|
||||
});
|
||||
});
|
||||
});
|
141
e2e/suites/list-views/recent-files.test.ts
Executable file
141
e2e/suites/list-views/recent-files.test.ts
Executable file
@ -0,0 +1,141 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SITE_VISIBILITY, SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Recent Files', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const folderName = `folder-${Utils.random()}`; let folderId;
|
||||
const fileName1 = `file-${Utils.random()}.txt`;
|
||||
const fileName2 = `file-${Utils.random()}.txt`; let file2Id;
|
||||
const fileName3 = `file-${Utils.random()}.txt`;
|
||||
|
||||
const siteName = `site-${Utils.random()}`;
|
||||
const folderSite = `folder2-${Utils.random()}`; let folderSiteId;
|
||||
const fileSite = `file-${Utils.random()}.txt`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const recentFilesPage = new BrowsingPage();
|
||||
const { dataTable } = recentFilesPage;
|
||||
const { breadcrumb } = recentFilesPage.toolbar;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => apis.user.nodes.createFolders([ folderName ])).then(resp => folderId = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFiles([ fileName1 ], folderName))
|
||||
.then(() => apis.user.nodes.createFiles([ fileName2 ])).then(resp => file2Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFiles([ fileName3 ]).then(resp => apis.user.nodes.deleteNodeById(resp.data.entry.id, false)))
|
||||
|
||||
.then(() => apis.user.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC))
|
||||
.then(() => apis.user.sites.getDocLibId(siteName))
|
||||
.then(resp => apis.user.nodes.createFolder(folderSite, resp)).then(resp => folderSiteId = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(fileSite, folderSiteId))
|
||||
|
||||
.then(() => apis.user.search.waitForApi(username, { expect: 3 }))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
recentFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.user.nodes.deleteNodesById([ folderId, file2Id ]),
|
||||
apis.user.sites.deleteSite(siteName),
|
||||
apis.admin.trashcan.emptyTrash(),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('has the correct columns [C213168]', () => {
|
||||
const labels = [ 'Name', 'Location', 'Size', 'Modified' ];
|
||||
const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label));
|
||||
|
||||
expect(dataTable.getColumnHeaders().count()).toBe(4 + 1, 'Incorrect number of columns');
|
||||
|
||||
elements.forEach((element, index) => {
|
||||
expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`);
|
||||
});
|
||||
});
|
||||
|
||||
it('default sorting column [C213171]', () => {
|
||||
expect(dataTable.getSortedColumnHeader().getText()).toBe('Modified');
|
||||
expect(dataTable.getSortingOrder()).toBe('desc');
|
||||
});
|
||||
|
||||
it('displays the files added by the current user in the last 30 days [C213170]', () => {
|
||||
expect(dataTable.countRows()).toEqual(3, 'Incorrect number of files displayed');
|
||||
expect(dataTable.getRowName(fileName1).isPresent()).toBe(true, `${fileName1} not displayed`);
|
||||
expect(dataTable.getRowName(fileName2).isPresent()).toBe(true, `${fileName2} not displayed`);
|
||||
expect(dataTable.getRowName(fileSite).isPresent()).toBe(true, `${fileSite} not displayed`);
|
||||
});
|
||||
|
||||
it(`file not displayed if it's in the Trashcan [C213174]`, () => {
|
||||
expect(dataTable.getRowName(fileName3).isPresent()).not.toBe(true, `${fileName3} is displayed`);
|
||||
});
|
||||
|
||||
it('Location column displays the parent folder of the file [C213175]', () => {
|
||||
expect(dataTable.getItemLocation(fileName1).getText()).toEqual(folderName);
|
||||
expect(dataTable.getItemLocation(fileName2).getText()).toEqual('Personal Files');
|
||||
expect(dataTable.getItemLocation(fileSite).getText()).toEqual(folderSite);
|
||||
});
|
||||
|
||||
it('Location column displays a tooltip with the entire path of the file [C213177]', () => {
|
||||
expect(dataTable.getItemLocationTooltip(fileName1)).toEqual(`Personal Files/${folderName}`);
|
||||
expect(dataTable.getItemLocationTooltip(fileName2)).toEqual('Personal Files');
|
||||
expect(dataTable.getItemLocationTooltip(fileSite)).toEqual(`File Libraries/${siteName}/${folderSite}`);
|
||||
});
|
||||
|
||||
it('Location column redirect - file in user Home [C213176] [C260968]', () => {
|
||||
dataTable.clickItemLocation(fileName2)
|
||||
.then(() => expect(breadcrumb.getAllItems()).toEqual([ 'Personal Files' ]));
|
||||
});
|
||||
|
||||
it('Location column redirect - file in folder [C213176] [C260968]', () => {
|
||||
dataTable.clickItemLocation(fileName1)
|
||||
.then(() => expect(breadcrumb.getAllItems()).toEqual([ 'Personal Files', folderName ]));
|
||||
});
|
||||
|
||||
it('Location column redirect - file in site [C213176] [C260969]', () => {
|
||||
dataTable.clickItemLocation(fileSite)
|
||||
.then(() => expect(breadcrumb.getAllItems()).toEqual([ 'File Libraries', siteName, folderSite ]));
|
||||
});
|
||||
});
|
142
e2e/suites/list-views/shared-files.test.ts
Executable file
142
e2e/suites/list-views/shared-files.test.ts
Executable file
@ -0,0 +1,142 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Shared Files', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
const password = username;
|
||||
|
||||
const siteName = `site-${Utils.random()}`;
|
||||
const fileAdmin = `file-${Utils.random()}.txt`;
|
||||
|
||||
const folderUser = `folder-${Utils.random()}`;
|
||||
const file1User = `file1-${Utils.random()}.txt`; let file1Id;
|
||||
const file2User = `file2-${Utils.random()}.txt`; let file2Id;
|
||||
const file3User = `file3-${Utils.random()}.txt`; let file3Id;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, password)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const sharedFilesPage = new BrowsingPage();
|
||||
const { dataTable } = sharedFilesPage;
|
||||
const { breadcrumb } = sharedFilesPage.toolbar;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_CONSUMER))
|
||||
.then(() => apis.admin.nodes.createFiles([ fileAdmin ], `Sites/${siteName}/documentLibrary`))
|
||||
.then(resp => apis.admin.shared.shareFileById(resp.data.entry.id))
|
||||
|
||||
.then(() => apis.user.nodes.createFolders([ folderUser ]))
|
||||
.then(() => apis.user.nodes.createFiles([ file1User ], folderUser)).then(resp => file1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(file2User)).then(resp => file2Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(file3User)).then(resp => file3Id = resp.data.entry.id)
|
||||
.then(() => apis.user.shared.shareFilesByIds([file1Id, file2Id, file3Id]))
|
||||
|
||||
.then(() => apis.user.shared.waitForApi({ expect: 4 }))
|
||||
.then(() => apis.user.nodes.deleteNodeById(file2Id))
|
||||
.then(() => apis.user.shared.unshareFile(file3User))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
sharedFilesPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
sharedFilesPage.refresh().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.admin.sites.deleteSite(siteName),
|
||||
apis.user.nodes.deleteNodes([ folderUser ]),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('has the correct columns [C213113]', () => {
|
||||
const labels = [ 'Name', 'Location', 'Size', 'Modified', 'Modified by', 'Shared by' ];
|
||||
const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label));
|
||||
|
||||
expect(dataTable.getColumnHeaders().count()).toBe(6 + 1, 'Incorrect number of columns');
|
||||
|
||||
elements.forEach((element, index) => {
|
||||
expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`);
|
||||
});
|
||||
});
|
||||
|
||||
it('default sorting column [C213115]', () => {
|
||||
expect(dataTable.getSortedColumnHeader().getText()).toBe('Modified');
|
||||
expect(dataTable.getSortingOrder()).toBe('desc');
|
||||
});
|
||||
|
||||
it('displays the files shared by everyone [C213114]', () => {
|
||||
expect(dataTable.getRowName(fileAdmin).isPresent()).toBe(true, `${fileAdmin} not displayed`);
|
||||
expect(dataTable.getRowName(file1User).isPresent()).toBe(true, `${file1User} not displayed`);
|
||||
});
|
||||
|
||||
it(`file not displayed if it's in the Trashcan [C213117]`, () => {
|
||||
expect(dataTable.getRowName(file2User).isPresent()).toBe(false, `${file2User} is displayed`);
|
||||
});
|
||||
|
||||
it('unshared file is not displayed [C213118]', () => {
|
||||
expect(dataTable.getRowName(file3User).isPresent()).toBe(false, `${file3User} is displayed`);
|
||||
});
|
||||
|
||||
it('Location column displays the parent folder of the file [C213665]', () => {
|
||||
expect(dataTable.getItemLocation(fileAdmin).getText()).toEqual(siteName);
|
||||
expect(dataTable.getItemLocation(file1User).getText()).toEqual(folderUser);
|
||||
});
|
||||
|
||||
it('Location column redirect - file in user Home [C213666] [C260968]', () => {
|
||||
dataTable.clickItemLocation(file1User)
|
||||
.then(() => expect(breadcrumb.getAllItems()).toEqual([ 'Personal Files', folderUser ]));
|
||||
});
|
||||
|
||||
it('Location column redirect - file in site [C213666] [C260969]', () => {
|
||||
dataTable.clickItemLocation(fileAdmin)
|
||||
.then(() => expect(breadcrumb.getAllItems()).toEqual([ 'File Libraries', siteName ]));
|
||||
});
|
||||
|
||||
it('Location column displays a tooltip with the entire path of the file [C213667]', () => {
|
||||
expect(dataTable.getItemLocationTooltip(fileAdmin)).toEqual(`File Libraries/${siteName}`);
|
||||
expect(dataTable.getItemLocationTooltip(file1User)).toEqual(`Personal Files/${folderUser}`);
|
||||
});
|
||||
});
|
330
e2e/suites/list-views/tooltips.test.ts
Executable file
330
e2e/suites/list-views/tooltips.test.ts
Executable file
@ -0,0 +1,330 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('File / folder tooltips', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const parent = `parent-${Utils.random()}`;
|
||||
|
||||
const file = `file1-${Utils.random()}`;
|
||||
const fileWithDesc = `file2-${Utils.random()}`;
|
||||
const fileWithTitle = `file3-${Utils.random()}`;
|
||||
const fileWithTitleAndDesc = `file4-${Utils.random()}`;
|
||||
const fileNameEqTitleEqDesc = `file5-${Utils.random()}`;
|
||||
const fileNameEqTitleDiffDesc = `file6-${Utils.random()}`;
|
||||
const fileNameEqDescDiffTitle = `file7-${Utils.random()}`;
|
||||
const fileTitleEqDesc = `file8-${Utils.random()}`;
|
||||
let parentId, file1Id, file2Id, file3Id, file4Id, file5Id, file6Id, file7Id, file8Id;
|
||||
|
||||
const fileTitle = 'file title';
|
||||
const fileDescription = 'file description';
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable } = page;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => apis.user.nodes.createFolder( parent ))
|
||||
.then(resp => parentId = resp.data.entry.id)
|
||||
|
||||
.then(() => Promise.all([
|
||||
apis.user.nodes.createFile(file, parentId).then(resp => file1Id = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileWithDesc, parentId, '', fileDescription).then(resp => file2Id = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileWithTitle, parentId, fileTitle).then(resp => file3Id = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileWithTitleAndDesc, parentId, fileTitle, fileDescription)
|
||||
.then(resp => file4Id = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileNameEqTitleEqDesc, parentId, fileNameEqTitleEqDesc, fileNameEqTitleEqDesc)
|
||||
.then(resp => file5Id = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileNameEqTitleDiffDesc, parentId, fileNameEqTitleDiffDesc, fileDescription)
|
||||
.then(resp => file6Id = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileNameEqDescDiffTitle, parentId, fileTitle, fileNameEqDescDiffTitle)
|
||||
.then(resp => file7Id = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileTitleEqDesc, parentId, fileTitle, fileTitle).then(resp => file8Id = resp.data.entry.id)
|
||||
]))
|
||||
|
||||
.then(() => apis.user.shared.shareFilesByIds([ file1Id, file2Id, file3Id, file4Id, file5Id, file6Id, file7Id, file8Id ]))
|
||||
|
||||
.then(() => apis.user.favorites.addFavoritesByIds('file', [
|
||||
file1Id, file2Id, file3Id, file4Id, file5Id, file6Id, file7Id, file8Id
|
||||
]))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.user.nodes.deleteNodes([ parent ]),
|
||||
apis.admin.trashcan.emptyTrash(),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('on Personal Files', () => {
|
||||
beforeAll(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.doubleClickOnItemName(parent))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('File with name, no title, no description', () => {
|
||||
expect(dataTable.getItemNameTooltip(file)).toEqual(`${file}`);
|
||||
});
|
||||
|
||||
it('File with name and description, no title', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithDesc)).toEqual(`${fileWithDesc}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name and title, no description', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithTitle)).toEqual(`${fileWithTitle}\n${fileTitle}`);
|
||||
});
|
||||
|
||||
it('File with name and title and description, all different', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithTitleAndDesc)).toEqual(`${fileTitle}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name and title and description, all equal', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqTitleEqDesc)).toEqual(`${fileNameEqTitleEqDesc}`);
|
||||
});
|
||||
|
||||
it('File with name = title, different description', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqTitleDiffDesc)).toEqual(`${fileNameEqTitleDiffDesc}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name = description, different title', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqDescDiffTitle)).toEqual(`${fileTitle}\n${fileNameEqDescDiffTitle}`);
|
||||
});
|
||||
|
||||
it('File with title = description, different name', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileTitleEqDesc)).toEqual(`${fileTitle}`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Recent Files', () => {
|
||||
beforeAll(done => {
|
||||
apis.user.search.waitForApi(username, { expect: 8 })
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('File with name, no title, no description', () => {
|
||||
expect(dataTable.getItemNameTooltip(file)).toEqual(`${file}`);
|
||||
});
|
||||
|
||||
it('File with name and description, no title', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithDesc)).toEqual(`${fileWithDesc}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name and title, no description', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithTitle)).toEqual(`${fileWithTitle}\n${fileTitle}`);
|
||||
});
|
||||
|
||||
it('File with name and title and description, all different', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithTitleAndDesc)).toEqual(`${fileTitle}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name and title and description, all equal', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqTitleEqDesc)).toEqual(`${fileNameEqTitleEqDesc}`);
|
||||
});
|
||||
|
||||
it('File with name = title, different description', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqTitleDiffDesc)).toEqual(`${fileNameEqTitleDiffDesc}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name = description, different title', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqDescDiffTitle)).toEqual(`${fileTitle}\n${fileNameEqDescDiffTitle}`);
|
||||
});
|
||||
|
||||
it('File with title = description, different name', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileTitleEqDesc)).toEqual(`${fileTitle}`);
|
||||
});
|
||||
});
|
||||
|
||||
// disabled until ACA-518 is done
|
||||
xdescribe('on Shared Files', () => {
|
||||
beforeAll(done => {
|
||||
apis.user.shared.waitForApi({ expect: 8 })
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('File with name, no title, no description', () => {
|
||||
expect(dataTable.getItemNameTooltip(file)).toEqual(`${file}`);
|
||||
});
|
||||
|
||||
it('File with name and description, no title', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithDesc)).toEqual(`${fileWithDesc}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name and title, no description', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithTitle)).toEqual(`${fileWithTitle}\n${fileTitle}`);
|
||||
});
|
||||
|
||||
it('File with name and title and description, all different', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithTitleAndDesc)).toEqual(`${fileTitle}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name and title and description, all equal', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqTitleEqDesc)).toEqual(`${fileNameEqTitleEqDesc}`);
|
||||
});
|
||||
|
||||
it('File with name = title, different description', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqTitleDiffDesc)).toEqual(`${fileNameEqTitleDiffDesc}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name = description, different title', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqDescDiffTitle)).toEqual(`${fileTitle}\n${fileNameEqDescDiffTitle}`);
|
||||
});
|
||||
|
||||
it('File with title = description, different name', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileTitleEqDesc)).toEqual(`${fileTitle}`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Favorites', () => {
|
||||
beforeAll(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES).then(done);
|
||||
});
|
||||
|
||||
it('File with name, no title, no description', () => {
|
||||
expect(dataTable.getItemNameTooltip(file)).toEqual(`${file}`);
|
||||
});
|
||||
|
||||
it('File with name and description, no title', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithDesc)).toEqual(`${fileWithDesc}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name and title, no description', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithTitle)).toEqual(`${fileWithTitle}\n${fileTitle}`);
|
||||
});
|
||||
|
||||
it('File with name and title and description, all different', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithTitleAndDesc)).toEqual(`${fileTitle}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name and title and description, all equal', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqTitleEqDesc)).toEqual(`${fileNameEqTitleEqDesc}`);
|
||||
});
|
||||
|
||||
it('File with name = title, different description', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqTitleDiffDesc)).toEqual(`${fileNameEqTitleDiffDesc}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name = description, different title', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqDescDiffTitle)).toEqual(`${fileTitle}\n${fileNameEqDescDiffTitle}`);
|
||||
});
|
||||
|
||||
it('File with title = description, different name', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileTitleEqDesc)).toEqual(`${fileTitle}`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Trash', () => {
|
||||
const parentForTrash = `parent-${Utils.random()}`;
|
||||
let parentForTrashId, file1TrashId, file2TrashId, file3TrashId, file4TrashId;
|
||||
let file5TrashId, file6TrashId, file7TrashId, file8TrashId;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.user.nodes.createFolder( parentForTrash )
|
||||
.then(resp => parentForTrashId = resp.data.entry.id)
|
||||
.then(() => Promise.all([
|
||||
apis.user.nodes.createFile(file, parentForTrashId)
|
||||
.then(resp => file1TrashId = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileWithDesc, parentForTrashId, '', fileDescription)
|
||||
.then(resp => file2TrashId = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileWithTitle, parentForTrashId, fileTitle)
|
||||
.then(resp => file3TrashId = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileWithTitleAndDesc, parentForTrashId, fileTitle, fileDescription)
|
||||
.then(resp => file4TrashId = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileNameEqTitleEqDesc, parentForTrashId, fileNameEqTitleEqDesc, fileNameEqTitleEqDesc)
|
||||
.then(resp => file5TrashId = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileNameEqTitleDiffDesc, parentForTrashId, fileNameEqTitleDiffDesc, fileDescription)
|
||||
.then(resp => file6TrashId = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileNameEqDescDiffTitle, parentForTrashId, fileTitle, fileNameEqDescDiffTitle)
|
||||
.then(resp => file7TrashId = resp.data.entry.id),
|
||||
apis.user.nodes.createFile(fileTitleEqDesc, parentForTrashId, fileTitle, fileTitle)
|
||||
.then(resp => file8TrashId = resp.data.entry.id)
|
||||
]))
|
||||
|
||||
.then(() => apis.user.nodes.deleteNodesById([
|
||||
file1TrashId, file2TrashId, file3TrashId, file4TrashId, file5TrashId, file6TrashId, file7TrashId, file8TrashId
|
||||
], false))
|
||||
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
apis.user.nodes.deleteNodes([ parentForTrash ]).then(done);
|
||||
});
|
||||
|
||||
it('File with name, no title, no description', () => {
|
||||
expect(dataTable.getItemNameTooltip(file)).toEqual(`${file}`);
|
||||
});
|
||||
|
||||
it('File with name and description, no title', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithDesc)).toEqual(`${fileWithDesc}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name and title, no description', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithTitle)).toEqual(`${fileWithTitle}\n${fileTitle}`);
|
||||
});
|
||||
|
||||
it('File with name and title and description, all different', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileWithTitleAndDesc)).toEqual(`${fileTitle}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name and title and description, all equal', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqTitleEqDesc)).toEqual(`${fileNameEqTitleEqDesc}`);
|
||||
});
|
||||
|
||||
it('File with name = title, different description', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqTitleDiffDesc)).toEqual(`${fileNameEqTitleDiffDesc}\n${fileDescription}`);
|
||||
});
|
||||
|
||||
it('File with name = description, different title', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileNameEqDescDiffTitle)).toEqual(`${fileTitle}\n${fileNameEqDescDiffTitle}`);
|
||||
});
|
||||
|
||||
it('File with title = description, different name', () => {
|
||||
expect(dataTable.getItemNameTooltip(fileTitleEqDesc)).toEqual(`${fileTitle}`);
|
||||
});
|
||||
});
|
||||
});
|
169
e2e/suites/list-views/trash.test.ts
Executable file
169
e2e/suites/list-views/trash.test.ts
Executable file
@ -0,0 +1,169 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SITE_VISIBILITY, SITE_ROLES, SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Trash', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const siteName = `site-${Utils.random()}`;
|
||||
const fileSite = `file-${Utils.random()}.txt`; let fileSiteId;
|
||||
|
||||
const folderAdmin = `folder-${Utils.random()}`; let folderAdminId;
|
||||
const fileAdmin = `file-${Utils.random()}.txt`; let fileAdminId;
|
||||
|
||||
const folderUser = `folder-${Utils.random()}`; let folderUserId;
|
||||
const fileUser = `file-${Utils.random()}.txt`; let fileUserId;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const trashPage = new BrowsingPage();
|
||||
const { dataTable } = trashPage;
|
||||
const { breadcrumb } = trashPage.toolbar;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => apis.admin.nodes.createFiles([ fileAdmin ]).then(resp => fileAdminId = resp.data.entry.id))
|
||||
.then(() => apis.admin.nodes.createFolders([ folderAdmin ]).then(resp => folderAdminId = resp.data.entry.id))
|
||||
.then(() => apis.admin.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC))
|
||||
.then(() => apis.admin.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_MANAGER))
|
||||
.then(() => apis.admin.nodes.createFiles([ fileSite ], `Sites/${siteName}/documentLibrary`)
|
||||
.then(resp => fileSiteId = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFiles([ fileUser ]).then(resp => fileUserId = resp.data.entry.id))
|
||||
.then(() => apis.user.nodes.createFolders([ folderUser ]).then(resp => folderUserId = resp.data.entry.id))
|
||||
|
||||
.then(() => apis.admin.nodes.deleteNodesById([ fileAdminId, folderAdminId ], false))
|
||||
.then(() => apis.user.nodes.deleteNodesById([ fileSiteId, fileUserId, folderUserId ], false))
|
||||
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.admin.sites.deleteSite(siteName),
|
||||
apis.admin.trashcan.emptyTrash()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('as admin', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWithAdmin().then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
trashPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('has the correct columns', () => {
|
||||
const labels = [ 'Name', 'Location', 'Size', 'Deleted', 'Deleted by' ];
|
||||
const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label));
|
||||
|
||||
expect(dataTable.getColumnHeaders().count()).toBe(5 + 1, 'Incorrect number of columns');
|
||||
|
||||
elements.forEach((element, index) => {
|
||||
expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`);
|
||||
});
|
||||
});
|
||||
|
||||
it('displays the files and folders deleted by everyone [C213217]', () => {
|
||||
expect(dataTable.countRows()).toEqual(5, 'Incorrect number of deleted items displayed');
|
||||
|
||||
expect(dataTable.getRowName(fileAdmin).isPresent()).toBe(true, `${fileAdmin} not displayed`);
|
||||
expect(dataTable.getRowName(folderAdmin).isPresent()).toBe(true, `${folderAdmin} not displayed`);
|
||||
expect(dataTable.getRowName(fileUser).isPresent()).toBe(true, `${fileUser} not displayed`);
|
||||
expect(dataTable.getRowName(folderUser).isPresent()).toBe(true, `${folderUser} not displayed`);
|
||||
expect(dataTable.getRowName(fileSite).isPresent()).toBe(true, `${fileSite} not displayed`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('as user', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username).then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
trashPage.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('has the correct columns', () => {
|
||||
const labels = [ 'Name', 'Location', 'Size', 'Deleted', 'Deleted by' ];
|
||||
const elements = labels.map(label => dataTable.getColumnHeaderByLabel(label));
|
||||
|
||||
expect(dataTable.getColumnHeaders().count()).toBe(5 + 1, 'Incorrect number of columns');
|
||||
|
||||
elements.forEach((element, index) => {
|
||||
expect(element.isPresent()).toBe(true, `"${labels[index]}" is missing`);
|
||||
});
|
||||
});
|
||||
|
||||
it('displays the files and folders deleted by the user [C213218]', () => {
|
||||
expect(dataTable.countRows()).toEqual(3, 'Incorrect number of deleted items displayed');
|
||||
|
||||
expect(dataTable.getRowName(fileSite).isPresent()).toBe(true, `${fileSite} not displayed`);
|
||||
expect(dataTable.getRowName(fileUser).isPresent()).toBe(true, `${fileUser} not displayed`);
|
||||
expect(dataTable.getRowName(folderUser).isPresent()).toBe(true, `${folderUser} not displayed`);
|
||||
expect(dataTable.getRowName(fileAdmin).isPresent()).toBe(false, `${fileAdmin} is displayed`);
|
||||
});
|
||||
|
||||
it('default sorting column [C213219]', () => {
|
||||
expect(dataTable.getSortedColumnHeader().getText()).toBe('Deleted');
|
||||
expect(dataTable.getSortingOrder()).toBe('desc');
|
||||
});
|
||||
|
||||
it('Location column redirect - file in user Home [C217144] [C260968]', () => {
|
||||
dataTable.clickItemLocation(fileUser)
|
||||
.then(() => expect(breadcrumb.getAllItems()).toEqual([ 'Personal Files' ]));
|
||||
});
|
||||
|
||||
it('Location column redirect - file in site [C217144] [C260969]', () => {
|
||||
dataTable.clickItemLocation(fileSite)
|
||||
.then(() => expect(breadcrumb.getAllItems()).toEqual([ 'File Libraries', siteName ]));
|
||||
});
|
||||
});
|
||||
});
|
244
e2e/suites/navigation/breadcrumb.test.ts
Executable file
244
e2e/suites/navigation/breadcrumb.test.ts
Executable file
@ -0,0 +1,244 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SIDEBAR_LABELS, SITE_VISIBILITY } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Breadcrumb', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const parent = `parent-${Utils.random()}`; let parentId;
|
||||
const subfolder1 = `subfolder1-${Utils.random()}`; let subfolder1Id;
|
||||
const subfolder2 = `subfolder2-${Utils.random()}`; let subfolder2Id;
|
||||
const fileName1 = `file1-${Utils.random()}.txt`;
|
||||
|
||||
const siteName = `site-${Utils.random()}`;
|
||||
|
||||
const parent2 = `parent2-${Utils.random()}`; let parent2Id;
|
||||
const folder1 = `folder1-${Utils.random()}`; let folder1Id;
|
||||
const folder1Renamed = `renamed-${Utils.random()}`;
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { breadcrumb } = page.toolbar;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username)
|
||||
.then(() => apis.user.nodes.createFolder(parent)).then(resp => parentId = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFolder(subfolder1, parentId)).then(resp => subfolder1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFolder(subfolder2, subfolder1Id)).then(resp => subfolder2Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(fileName1, subfolder2Id))
|
||||
|
||||
.then(() => apis.user.nodes.createFolder(parent2)).then(resp => parent2Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFolder(folder1, parent2Id)).then(resp => folder1Id = resp.data.entry.id)
|
||||
|
||||
.then(() => apis.user.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC))
|
||||
.then(() => apis.user.sites.getDocLibId(siteName))
|
||||
.then(resp => apis.user.nodes.createFolder(parent, resp)).then(resp => parentId = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFolder(subfolder1, parentId)).then(resp => subfolder1Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFolder(subfolder2, subfolder1Id)).then(resp => subfolder2Id = resp.data.entry.id)
|
||||
.then(() => apis.user.nodes.createFile(fileName1, subfolder2Id))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
apis.user.nodes.deleteNodeById(parentId),
|
||||
apis.user.nodes.deleteNodeById(parent2Id),
|
||||
apis.user.sites.deleteSite(siteName),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('Personal Files breadcrumb main node [C260964]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => {
|
||||
expect(breadcrumb.getItemsCount()).toEqual(1, 'Breadcrumb has incorrect number of items');
|
||||
expect(breadcrumb.getCurrentItemName()).toBe('Personal Files');
|
||||
});
|
||||
});
|
||||
|
||||
it('File Libraries breadcrumb main node [C260966]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => {
|
||||
expect(breadcrumb.getItemsCount()).toEqual(1, 'Breadcrumb has incorrect number of items');
|
||||
expect(breadcrumb.getCurrentItemName()).toBe('File Libraries');
|
||||
});
|
||||
});
|
||||
|
||||
it('Recent Files breadcrumb main node [C260971]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => {
|
||||
expect(breadcrumb.getItemsCount()).toEqual(1, 'Breadcrumb has incorrect number of items');
|
||||
expect(breadcrumb.getCurrentItemName()).toBe('Recent Files');
|
||||
});
|
||||
});
|
||||
|
||||
it('Shared Files breadcrumb main node [C260972]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => {
|
||||
expect(breadcrumb.getItemsCount()).toEqual(1, 'Breadcrumb has incorrect number of items');
|
||||
expect(breadcrumb.getCurrentItemName()).toBe('Shared Files');
|
||||
});
|
||||
});
|
||||
|
||||
it('Favorites breadcrumb main node [C260973]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => {
|
||||
expect(breadcrumb.getItemsCount()).toEqual(1, 'Breadcrumb has incorrect number of items');
|
||||
expect(breadcrumb.getCurrentItemName()).toBe('Favorites');
|
||||
});
|
||||
});
|
||||
|
||||
it('Trash breadcrumb main node [C260974]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => {
|
||||
expect(breadcrumb.getItemsCount()).toEqual(1, 'Breadcrumb has incorrect number of items');
|
||||
expect(breadcrumb.getCurrentItemName()).toBe('Trash');
|
||||
});
|
||||
});
|
||||
|
||||
it('Personal Files breadcrumb for a folder hierarchy [C260965]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => page.dataTable.waitForHeader())
|
||||
.then(() => page.dataTable.doubleClickOnItemName(parent))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(subfolder1))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(subfolder2))
|
||||
.then(() => {
|
||||
const expectedBreadcrumb = [ 'Personal Files', parent, subfolder1, subfolder2 ];
|
||||
expect(breadcrumb.getAllItems()).toEqual(expectedBreadcrumb);
|
||||
});
|
||||
});
|
||||
|
||||
it('File Libraries breadcrumb for a folder hierarchy [C260967]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => page.dataTable.waitForHeader())
|
||||
.then(() => page.dataTable.doubleClickOnItemName(siteName))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(parent))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(subfolder1))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(subfolder2))
|
||||
.then(() => {
|
||||
const expectedItems = [ 'File Libraries', siteName, parent, subfolder1, subfolder2 ];
|
||||
expect(breadcrumb.getAllItems()).toEqual(expectedItems);
|
||||
});
|
||||
});
|
||||
|
||||
it('User can navigate to any location by clicking on a step from the breadcrumb [C213235]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => page.dataTable.waitForHeader())
|
||||
.then(() => page.dataTable.doubleClickOnItemName(parent))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(subfolder1))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(subfolder2))
|
||||
.then(() => breadcrumb.clickItem(subfolder1))
|
||||
.then(() => {
|
||||
const expectedBreadcrumb = [ 'Personal Files', parent, subfolder1 ];
|
||||
expect(breadcrumb.getAllItems()).toEqual(expectedBreadcrumb);
|
||||
});
|
||||
});
|
||||
|
||||
it('Tooltip appears on hover on a step in breadcrumb [C213237]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => page.dataTable.waitForHeader())
|
||||
.then(() => page.dataTable.doubleClickOnItemName(parent))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(subfolder1))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(subfolder2))
|
||||
.then(() => {
|
||||
expect(breadcrumb.getNthItemTooltip(3)).toEqual(subfolder1);
|
||||
});
|
||||
});
|
||||
|
||||
it('Breadcrumb updates correctly when folder is renamed [C213238]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => page.dataTable.waitForHeader())
|
||||
.then(() => page.dataTable.doubleClickOnItemName(parent2))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(folder1))
|
||||
.then(() => page.dataTable.wait())
|
||||
.then(() => apis.user.nodes.renameNode(folder1Id, folder1Renamed).then(done => done))
|
||||
.then(() => page.refresh())
|
||||
.then(() => page.dataTable.wait())
|
||||
.then(() => {
|
||||
expect(breadcrumb.getCurrentItemName()).toEqual(folder1Renamed);
|
||||
});
|
||||
});
|
||||
|
||||
it('Browser back navigates to previous location regardless of breadcrumb steps [C213240]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => page.dataTable.waitForHeader())
|
||||
.then(() => page.dataTable.doubleClickOnItemName(parent))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(subfolder1))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(subfolder2))
|
||||
.then(() => page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH))
|
||||
.then(() => page.dataTable.waitForEmptyState())
|
||||
.then(() => browser.navigate().back())
|
||||
.then(() => {
|
||||
const expectedBreadcrumb = [ 'Personal Files', parent, subfolder1, subfolder2 ];
|
||||
expect(breadcrumb.getAllItems()).toEqual(expectedBreadcrumb);
|
||||
});
|
||||
});
|
||||
|
||||
// disabled cause of ACA-1039
|
||||
xdescribe('as admin', () => {
|
||||
const user2 = 'a_user';
|
||||
const userFolder = `userFolder-${Utils.random()}`; let userFolderId;
|
||||
const user2Api = new RepoClient(user2, user2);
|
||||
|
||||
beforeAll(done => {
|
||||
logoutPage.load()
|
||||
.then(() => apis.admin.people.createUser(user2))
|
||||
.then(() => user2Api.nodes.createFolder(userFolder).then(resp => userFolderId = resp.data.entry.id))
|
||||
.then(() => loginPage.loginWithAdmin())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
user2Api.nodes.deleteNodeById(userFolderId),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it(`Breadcrumb on navigation to a user's home [C260970]`, () => {
|
||||
page.dataTable.doubleClickOnItemName('User Homes')
|
||||
.then(() => page.dataTable.doubleClickOnItemName(user2))
|
||||
.then(() => expect(breadcrumb.getAllItems()).toEqual([ 'Personal Files', 'User Homes', user2 ]))
|
||||
.then(() => page.dataTable.doubleClickOnItemName(userFolder))
|
||||
.then(() => expect(breadcrumb.getAllItems()).toEqual([ 'Personal Files', 'User Homes', user2, userFolder ]));
|
||||
});
|
||||
});
|
||||
});
|
139
e2e/suites/navigation/sidebar.test.ts
Executable file
139
e2e/suites/navigation/sidebar.test.ts
Executable file
@ -0,0 +1,139 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { APP_ROUTES, SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
|
||||
describe('Sidebar', () => {
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { sidenav } = page;
|
||||
|
||||
beforeAll(done => {
|
||||
loginPage.loginWithAdmin().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('has "Personal Files" as default', () => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES);
|
||||
expect(sidenav.isActiveByLabel('Personal Files')).toBe(true, 'Active link');
|
||||
});
|
||||
|
||||
it('navigates to "File Libraries"', () => {
|
||||
sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.FILE_LIBRARIES);
|
||||
expect(sidenav.isActiveByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('navigates to "Personal Files"', () => {
|
||||
sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES);
|
||||
expect(sidenav.isActiveByLabel(SIDEBAR_LABELS.PERSONAL_FILES)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('navigates to "Shared Files"', () => {
|
||||
sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.SHARED_FILES);
|
||||
expect(sidenav.isActiveByLabel(SIDEBAR_LABELS.SHARED_FILES)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('navigates to "Recent Files"', () => {
|
||||
sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.RECENT_FILES);
|
||||
expect(sidenav.isActiveByLabel(SIDEBAR_LABELS.RECENT_FILES)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('navigates to "Favorites"', () => {
|
||||
sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.FAVORITES);
|
||||
expect(sidenav.isActiveByLabel(SIDEBAR_LABELS.FAVORITES)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('navigates to "Trash"', () => {
|
||||
sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.TRASHCAN);
|
||||
expect(sidenav.isActiveByLabel(SIDEBAR_LABELS.TRASH)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('Personal Files tooltip', () => {
|
||||
sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => {
|
||||
expect(sidenav.getLinkTooltip(SIDEBAR_LABELS.PERSONAL_FILES)).toContain('View your Personal Files');
|
||||
});
|
||||
});
|
||||
|
||||
it('File Libraries tooltip', () => {
|
||||
sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FILE_LIBRARIES)
|
||||
.then(() => {
|
||||
expect(sidenav.getLinkTooltip(SIDEBAR_LABELS.FILE_LIBRARIES)).toContain('Access File Libraries');
|
||||
});
|
||||
});
|
||||
|
||||
it('Shared Files tooltip', () => {
|
||||
sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => {
|
||||
expect(sidenav.getLinkTooltip(SIDEBAR_LABELS.SHARED_FILES)).toContain('View files that have been shared');
|
||||
});
|
||||
});
|
||||
|
||||
it('Recent Files tooltip', () => {
|
||||
sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => {
|
||||
expect(sidenav.getLinkTooltip(SIDEBAR_LABELS.RECENT_FILES)).toContain('View files you recently edited');
|
||||
});
|
||||
});
|
||||
|
||||
it('Favorites tooltip', () => {
|
||||
sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => {
|
||||
expect(sidenav.getLinkTooltip(SIDEBAR_LABELS.FAVORITES)).toContain('View your favorite files and folders');
|
||||
});
|
||||
});
|
||||
|
||||
it('Trash tooltip', () => {
|
||||
sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => {
|
||||
expect(sidenav.getLinkTooltip(SIDEBAR_LABELS.TRASH)).toContain('View deleted files in the trash');
|
||||
});
|
||||
});
|
||||
});
|
228
e2e/suites/pagination/pag-favorites.test.ts
Executable file
228
e2e/suites/pagination/pag-favorites.test.ts
Executable file
@ -0,0 +1,228 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Pagination on Favorites', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
const { nodes: nodesApi, favorites: favoritesApi } = apis.user;
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable, pagination } = page;
|
||||
|
||||
const parent = `parent-${Utils.random()}`;
|
||||
const files = Array(101)
|
||||
.fill('file')
|
||||
.map((name, index): string => `${name}-${index + 1}.txt`);
|
||||
let filesIds;
|
||||
|
||||
const file = `file-${Utils.random()}.txt`; let fileId;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username).then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('on empty page', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username).then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('pagination controls not displayed [C213164]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => {
|
||||
expect(pagination.range.isPresent()).toBe(false);
|
||||
expect(pagination.maxItems.isPresent()).toBe(false);
|
||||
expect(pagination.currentPage.isPresent()).toBe(false);
|
||||
expect(pagination.totalPages.isPresent()).toBe(false);
|
||||
expect(pagination.previousButton.isPresent()).toBe(false);
|
||||
expect(pagination.nextButton.isPresent()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('on single page', () => {
|
||||
beforeAll(done => {
|
||||
nodesApi.createFile(file).then(resp => fileId = resp.data.entry.id)
|
||||
.then(() => favoritesApi.addFavoriteById('file', fileId))
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
nodesApi.deleteNodeById(fileId),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('page selector not displayed when having a single page [C213165]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => expect(pagination.pagesButton.isPresent()).toBe(false, 'page selector displayed'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('on multiple pages', () => {
|
||||
beforeAll(done => {
|
||||
nodesApi.createFiles(files, parent)
|
||||
.then(resp => filesIds = resp.data.list.entries.map(entries => entries.entry.id))
|
||||
.then(() => favoritesApi.addFavoritesByIds('file', filesIds))
|
||||
.then(() => favoritesApi.waitForApi({ expect: 101 }))
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
nodesApi.deleteNodes([ parent ]),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('default values [C213157]', () => {
|
||||
expect(pagination.range.getText()).toContain('1-25 of 101');
|
||||
expect(pagination.maxItems.getText()).toContain('25');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 1');
|
||||
expect(pagination.totalPages.getText()).toContain('of 5');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled');
|
||||
});
|
||||
|
||||
it('page sizes [C213157]', () => {
|
||||
pagination.openMaxItemsMenu()
|
||||
.then(() => {
|
||||
const [ first, second, third ] = [1, 2, 3]
|
||||
.map(nth => pagination.menu.getNthItem(nth).getText());
|
||||
expect(first).toBe('25');
|
||||
expect(second).toBe('50');
|
||||
expect(third).toBe('100');
|
||||
})
|
||||
.then(() => pagination.menu.closeMenu());
|
||||
});
|
||||
|
||||
it('change the page size [C213158]', () => {
|
||||
pagination.openMaxItemsMenu()
|
||||
.then(() => pagination.menu.clickMenuItem('50'))
|
||||
.then(() => {
|
||||
expect(pagination.getText(pagination.maxItems)).toContain('50');
|
||||
expect(pagination.getText(pagination.totalPages)).toContain('of 3');
|
||||
})
|
||||
.then(() => pagination.openMaxItemsMenu())
|
||||
.then(() => pagination.menu.clickMenuItem('100'))
|
||||
.then(() => {
|
||||
expect(pagination.getText(pagination.maxItems)).toContain('100');
|
||||
expect(pagination.getText(pagination.totalPages)).toContain('of 2');
|
||||
})
|
||||
.then(() => pagination.resetToDefaultPageSize());
|
||||
});
|
||||
|
||||
it('current page menu items', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => expect(pagination.menu.getItemsCount()).toBe(5))
|
||||
.then(() => pagination.menu.closeMenu());
|
||||
});
|
||||
|
||||
it('change the current page from menu [C260518]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(3))
|
||||
.then(() => {
|
||||
expect(pagination.getText(pagination.range)).toContain('51-75 of 101');
|
||||
expect(pagination.getText(pagination.currentPage)).toContain('Page 3');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(true, 'Previous button is not enabled');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled');
|
||||
expect(dataTable.getRowName('file-40.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('navigate to next page [C213160]', () => {
|
||||
pagination.nextButton.click()
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('26-50 of 101');
|
||||
expect(dataTable.getRowName('file-70.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('navigate to previous page [C213160]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(2))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => pagination.previousButton.click())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('1-25 of 101');
|
||||
expect(dataTable.getRowName('file-88.txt').isPresent())
|
||||
.toBe(true, 'File not found on page');
|
||||
})
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('Previous button is disabled on first page [C260519]', () => {
|
||||
expect(pagination.currentPage.getText()).toContain('Page 1');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled on first page');
|
||||
});
|
||||
|
||||
it('Next button is disabled on last page [C260519]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(5))
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 5');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(false, 'Next button is enabled on last page');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
228
e2e/suites/pagination/pag-personal-files.test.ts
Executable file
228
e2e/suites/pagination/pag-personal-files.test.ts
Executable file
@ -0,0 +1,228 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Pagination on Personal Files', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
const { nodes: nodesApi } = apis.user;
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable, pagination } = page;
|
||||
|
||||
const parent = `parent-${Utils.random()}`;
|
||||
const files = Array(101)
|
||||
.fill('file')
|
||||
.map((name, index): string => `${name}-${index + 1}.txt`);
|
||||
|
||||
const file = `file-${Utils.random()}.txt`; let fileId;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username).then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('on empty page', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username).then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('pagination controls not displayed [C213164]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => {
|
||||
expect(pagination.range.isPresent()).toBe(false);
|
||||
expect(pagination.maxItems.isPresent()).toBe(false);
|
||||
expect(pagination.currentPage.isPresent()).toBe(false);
|
||||
expect(pagination.totalPages.isPresent()).toBe(false);
|
||||
expect(pagination.previousButton.isPresent()).toBe(false);
|
||||
expect(pagination.nextButton.isPresent()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('on single page', () => {
|
||||
beforeAll(done => {
|
||||
nodesApi.createFile(file).then(resp => fileId = resp.data.entry.id)
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
nodesApi.deleteNodeById(fileId),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('page selector not displayed when having a single page [C213165]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => expect(pagination.pagesButton.isPresent()).toBe(false, 'page selector displayed'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('on multiple pages', () => {
|
||||
beforeAll(done => {
|
||||
nodesApi.createFiles(files, parent)
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.PERSONAL_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => dataTable.doubleClickOnItemName(parent))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
nodesApi.deleteNodes([ parent ]),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('default values [C213157]', () => {
|
||||
expect(pagination.range.getText()).toContain('1-25 of 101');
|
||||
expect(pagination.maxItems.getText()).toContain('25');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 1');
|
||||
expect(pagination.totalPages.getText()).toContain('of 5');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled');
|
||||
});
|
||||
|
||||
it('page sizes [C213157]', () => {
|
||||
pagination.openMaxItemsMenu()
|
||||
.then(() => {
|
||||
const [ first, second, third ] = [1, 2, 3]
|
||||
.map(nth => pagination.menu.getNthItem(nth).getText());
|
||||
expect(first).toBe('25');
|
||||
expect(second).toBe('50');
|
||||
expect(third).toBe('100');
|
||||
})
|
||||
.then(() => pagination.menu.closeMenu());
|
||||
});
|
||||
|
||||
it('change the page size [C213158]', () => {
|
||||
pagination.openMaxItemsMenu()
|
||||
.then(() => pagination.menu.clickMenuItem('50'))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.maxItems.getText()).toContain('50');
|
||||
expect(pagination.totalPages.getText()).toContain('of 3');
|
||||
})
|
||||
.then(() => pagination.openMaxItemsMenu())
|
||||
.then(() => pagination.menu.clickMenuItem('100'))
|
||||
.then(() => {
|
||||
expect(pagination.getText(pagination.maxItems)).toContain('100');
|
||||
expect(pagination.getText(pagination.totalPages)).toContain('of 2');
|
||||
})
|
||||
.then(() => pagination.resetToDefaultPageSize());
|
||||
});
|
||||
|
||||
it('current page menu items', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => expect(pagination.menu.getItemsCount()).toBe(5))
|
||||
.then(() => pagination.menu.closeMenu());
|
||||
});
|
||||
|
||||
it('change the current page from menu [C260518]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(3))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('51-75 of 101');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 3');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(true, 'Previous button is not enabled');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled');
|
||||
expect(dataTable.getRowName('file-60.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('navigate to next page [C213160]', () => {
|
||||
pagination.clickNext()
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('26-50 of 101');
|
||||
expect(dataTable.getRowName('file-30.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('navigate to previous page [C213160]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(2))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => pagination.clickPrevious())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('1-25 of 101');
|
||||
expect(dataTable.getRowName('file-12.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('Previous button is disabled on first page [C260519]', () => {
|
||||
expect(pagination.currentPage.getText()).toContain('Page 1');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled on first page');
|
||||
});
|
||||
|
||||
it('Next button is disabled on last page [C260519]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(5))
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 5');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(false, 'Next button is enabled on last page');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
230
e2e/suites/pagination/pag-recent-files.test.ts
Executable file
230
e2e/suites/pagination/pag-recent-files.test.ts
Executable file
@ -0,0 +1,230 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Pagination on Recent Files', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
const { nodes: nodesApi, search: searchApi } = apis.user;
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable, pagination } = page;
|
||||
|
||||
const parent = `parent-${Utils.random()}`;
|
||||
const files = Array(101)
|
||||
.fill('file')
|
||||
.map((name, index): string => `${name}-${index + 1}.txt`);
|
||||
|
||||
const file = `file-${Utils.random()}.txt`; let fileId;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username).then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('on empty page', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username).then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('pagination controls not displayed [C213164]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => {
|
||||
expect(pagination.range.isPresent()).toBe(false);
|
||||
expect(pagination.maxItems.isPresent()).toBe(false);
|
||||
expect(pagination.currentPage.isPresent()).toBe(false);
|
||||
expect(pagination.totalPages.isPresent()).toBe(false);
|
||||
expect(pagination.previousButton.isPresent()).toBe(false);
|
||||
expect(pagination.nextButton.isPresent()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('on single page', () => {
|
||||
beforeAll(done => {
|
||||
nodesApi.createFile(file).then(resp => fileId = resp.data.entry.id)
|
||||
.then(() => searchApi.waitForApi(username, { expect: 1 }))
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
nodesApi.deleteNodeById(fileId),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('page selector not displayed when having a single page [C213165]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => expect(pagination.pagesButton.isPresent()).toBe(false, 'page selector displayed'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('on multiple pages', () => {
|
||||
beforeAll(done => {
|
||||
nodesApi.createFiles(files, parent)
|
||||
.then(() => searchApi.waitForApi(username, { expect: 101 }))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
nodesApi.deleteNodes([ parent ]),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('default values [C213157]', () => {
|
||||
expect(pagination.range.getText()).toContain('1-25 of 101');
|
||||
expect(pagination.maxItems.getText()).toContain('25');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 1');
|
||||
expect(pagination.totalPages.getText()).toContain('of 5');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled');
|
||||
});
|
||||
|
||||
it('page sizes [C213157]', () => {
|
||||
pagination.openMaxItemsMenu()
|
||||
.then(() => {
|
||||
const [ first, second, third ] = [1, 2, 3]
|
||||
.map(nth => pagination.menu.getNthItem(nth).getText());
|
||||
expect(first).toBe('25');
|
||||
expect(second).toBe('50');
|
||||
expect(third).toBe('100');
|
||||
})
|
||||
.then(() => pagination.menu.closeMenu());
|
||||
});
|
||||
|
||||
it('change the page size [C213158]', () => {
|
||||
pagination.openMaxItemsMenu()
|
||||
.then(() => pagination.menu.clickMenuItem('50'))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.maxItems.getText()).toContain('50');
|
||||
expect(pagination.totalPages.getText()).toContain('of 3');
|
||||
})
|
||||
.then(() => pagination.openMaxItemsMenu())
|
||||
.then(() => pagination.menu.clickMenuItem('100'))
|
||||
.then(() => {
|
||||
expect(pagination.getText(pagination.maxItems)).toContain('100');
|
||||
expect(pagination.getText(pagination.totalPages)).toContain('of 2');
|
||||
})
|
||||
.then(() => pagination.resetToDefaultPageSize());
|
||||
});
|
||||
|
||||
it('current page menu items', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => expect(pagination.menu.getItemsCount()).toBe(5))
|
||||
.then(() => pagination.menu.closeMenu());
|
||||
});
|
||||
|
||||
it('change the current page from menu [C260518]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(3))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('51-75 of 101');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 3');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(true, 'Previous button is not enabled');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled');
|
||||
expect(dataTable.getRowName('file-40.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('navigate to next page [C213160]', () => {
|
||||
pagination.nextButton.click()
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('26-50 of 101');
|
||||
expect(dataTable.getRowName('file-70.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('navigate to previous page [C213160]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(2))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => pagination.previousButton.click())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('1-25 of 101');
|
||||
expect(dataTable.getRowName('file-88.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('Previous button is disabled on first page [C260519]', () => {
|
||||
expect(pagination.currentPage.getText()).toContain('Page 1');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled on first page');
|
||||
});
|
||||
|
||||
it('Next button is disabled on last page [C260519]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(5))
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 5');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(false, 'Next button is enabled on last page');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
236
e2e/suites/pagination/pag-shared-files.test.ts
Executable file
236
e2e/suites/pagination/pag-shared-files.test.ts
Executable file
@ -0,0 +1,236 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Pagination on Shared Files', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
const { nodes: nodesApi, shared: sharedApi } = apis.user;
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable, pagination } = page;
|
||||
|
||||
const parent = `parent-${Utils.random()}`;
|
||||
const files = Array(101)
|
||||
.fill('file')
|
||||
.map((name, index): string => `${name}-${index + 1}.txt`);
|
||||
let filesIds;
|
||||
|
||||
const file = `file-${Utils.random()}.txt`; let fileId;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username).then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('on empty page', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username).then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('pagination controls not displayed [C213164]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => {
|
||||
expect(pagination.range.isPresent()).toBe(false);
|
||||
expect(pagination.maxItems.isPresent()).toBe(false);
|
||||
expect(pagination.currentPage.isPresent()).toBe(false);
|
||||
expect(pagination.totalPages.isPresent()).toBe(false);
|
||||
expect(pagination.previousButton.isPresent()).toBe(false);
|
||||
expect(pagination.nextButton.isPresent()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('on single page', () => {
|
||||
beforeAll(done => {
|
||||
nodesApi.createFile(file).then(resp => fileId = resp.data.entry.id)
|
||||
.then(() => sharedApi.shareFileById(fileId))
|
||||
.then(() => sharedApi.waitForApi({ expect: 1 }))
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
nodesApi.deleteNodeById(fileId),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('page selector not displayed when having a single page [C213165]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => expect(pagination.pagesButton.isPresent()).toBe(false, 'page selector displayed'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('on multiple pages', () => {
|
||||
beforeAll(done => {
|
||||
nodesApi.createFiles(files, parent)
|
||||
.then(resp => filesIds = resp.data.list.entries.map(entries => entries.entry.id))
|
||||
|
||||
.then(() => sharedApi.shareFilesByIds(filesIds))
|
||||
.then(() => sharedApi.waitForApi({ expect: 101 }))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.SHARED_FILES)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
nodesApi.deleteNodes([ parent ]),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('default values [C213157]', () => {
|
||||
expect(pagination.range.getText()).toContain('1-25 of 101');
|
||||
expect(pagination.maxItems.getText()).toContain('25');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 1');
|
||||
expect(pagination.totalPages.getText()).toContain('of 5');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled');
|
||||
});
|
||||
|
||||
it('page sizes [C213157]', () => {
|
||||
pagination.openMaxItemsMenu()
|
||||
.then(() => {
|
||||
const [ first, second, third ] = [1, 2, 3]
|
||||
.map(nth => pagination.menu.getNthItem(nth).getText());
|
||||
expect(first).toBe('25');
|
||||
expect(second).toBe('50');
|
||||
expect(third).toBe('100');
|
||||
})
|
||||
.then(() => pagination.menu.closeMenu());
|
||||
});
|
||||
|
||||
it('change the page size [C213158]', () => {
|
||||
pagination.openMaxItemsMenu()
|
||||
.then(() => pagination.menu.clickMenuItem('50'))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.maxItems.getText()).toContain('50');
|
||||
expect(pagination.totalPages.getText()).toContain('of 3');
|
||||
})
|
||||
.then(() => pagination.openMaxItemsMenu())
|
||||
.then(() => pagination.menu.clickMenuItem('100'))
|
||||
.then(() => {
|
||||
expect(pagination.getText(pagination.maxItems)).toContain('100');
|
||||
expect(pagination.getText(pagination.totalPages)).toContain('of 2');
|
||||
})
|
||||
.then(() => pagination.resetToDefaultPageSize());
|
||||
});
|
||||
|
||||
it('current page menu items', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => expect(pagination.menu.getItemsCount()).toBe(5))
|
||||
.then(() => pagination.menu.closeMenu());
|
||||
});
|
||||
|
||||
it('change the current page from menu [C260518]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(3))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('51-75 of 101');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 3');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(true, 'Previous button is not enabled');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled');
|
||||
expect(dataTable.getRowName('file-40.txt').isPresent())
|
||||
.toBe(true, 'File not found on page');
|
||||
})
|
||||
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('navigate to next page [C213160]', () => {
|
||||
pagination.nextButton.click()
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('26-50 of 101');
|
||||
expect(dataTable.getRowName('file-70.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('navigate to previous page [C213160]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(2))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => pagination.previousButton.click())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('1-25 of 101');
|
||||
expect(dataTable.getRowName('file-88.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('Previous button is disabled on first page [C260519]', () => {
|
||||
expect(pagination.currentPage.getText()).toContain('Page 1');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled on first page');
|
||||
});
|
||||
|
||||
it('Next button is disabled on last page [C260519]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(5))
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 5');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(false, 'Next button is enabled on last page');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
233
e2e/suites/pagination/pag-trash.test.ts
Executable file
233
e2e/suites/pagination/pag-trash.test.ts
Executable file
@ -0,0 +1,233 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SIDEBAR_LABELS } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
|
||||
describe('Pagination on Trash', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
|
||||
const apis = {
|
||||
admin: new RepoClient(),
|
||||
user: new RepoClient(username, username)
|
||||
};
|
||||
const { nodes: nodesApi, trashcan: trashApi } = apis.user;
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const logoutPage = new LogoutPage();
|
||||
const page = new BrowsingPage();
|
||||
const { dataTable, pagination } = page;
|
||||
|
||||
const filesForDelete = Array(101)
|
||||
.fill('file')
|
||||
.map((name, index): string => `${name}-${index + 1}.txt`);
|
||||
let filesDeletedIds;
|
||||
|
||||
const file = `file-${Utils.random()}.txt`; let fileId;
|
||||
|
||||
beforeAll(done => {
|
||||
apis.admin.people.createUser(username).then(done);
|
||||
});
|
||||
|
||||
xit('');
|
||||
|
||||
describe('on empty page', () => {
|
||||
beforeAll(done => {
|
||||
loginPage.loginWith(username).then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
logoutPage.load().then(done);
|
||||
});
|
||||
|
||||
it('pagination controls not displayed [C213164]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => {
|
||||
expect(pagination.range.isPresent()).toBe(false);
|
||||
expect(pagination.maxItems.isPresent()).toBe(false);
|
||||
expect(pagination.currentPage.isPresent()).toBe(false);
|
||||
expect(pagination.totalPages.isPresent()).toBe(false);
|
||||
expect(pagination.previousButton.isPresent()).toBe(false);
|
||||
expect(pagination.nextButton.isPresent()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('on single page', () => {
|
||||
beforeAll(done => {
|
||||
nodesApi.createFile(file).then(resp => fileId = resp.data.entry.id)
|
||||
.then(() => nodesApi.deleteNodeById(fileId, false))
|
||||
.then(() => trashApi.waitForApi({ expect: 1 }))
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
trashApi.emptyTrash(),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('page selector not displayed when having a single page [C213165]', () => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => expect(pagination.pagesButton.isPresent()).toBe(false, 'page selector displayed'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('on multiple pages', () => {
|
||||
beforeAll(done => {
|
||||
nodesApi.createFiles(filesForDelete)
|
||||
.then(resp => filesDeletedIds = resp.data.list.entries.map(entries => entries.entry.id))
|
||||
.then(() => nodesApi.deleteNodesById(filesDeletedIds, false))
|
||||
.then(() => trashApi.waitForApi({expect: 101}))
|
||||
|
||||
.then(() => loginPage.loginWith(username))
|
||||
.then(done);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
page.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.TRASH)
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(done);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
browser.actions().mouseMove(browser.$('body'), { x: 0, y: 0 }).click().perform().then(done);
|
||||
});
|
||||
|
||||
afterAll(done => {
|
||||
Promise.all([
|
||||
trashApi.emptyTrash(),
|
||||
logoutPage.load()
|
||||
])
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('default values [C213157]', () => {
|
||||
expect(pagination.range.getText()).toContain('1-25 of 101');
|
||||
expect(pagination.maxItems.getText()).toContain('25');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 1');
|
||||
expect(pagination.totalPages.getText()).toContain('of 5');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled');
|
||||
});
|
||||
|
||||
it('page sizes [C213157]', () => {
|
||||
pagination.openMaxItemsMenu()
|
||||
.then(() => {
|
||||
const [ first, second, third ] = [1, 2, 3]
|
||||
.map(nth => pagination.menu.getNthItem(nth).getText());
|
||||
expect(first).toBe('25');
|
||||
expect(second).toBe('50');
|
||||
expect(third).toBe('100');
|
||||
})
|
||||
.then(() => pagination.menu.closeMenu());
|
||||
});
|
||||
|
||||
it('change the page size [C213158]', () => {
|
||||
pagination.openMaxItemsMenu()
|
||||
.then(() => pagination.menu.clickMenuItem('50'))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.maxItems.getText()).toContain('50');
|
||||
expect(pagination.totalPages.getText()).toContain('of 3');
|
||||
})
|
||||
.then(() => pagination.openMaxItemsMenu())
|
||||
.then(() => pagination.menu.clickMenuItem('100'))
|
||||
.then(() => {
|
||||
expect(pagination.getText(pagination.maxItems)).toContain('100');
|
||||
expect(pagination.getText(pagination.totalPages)).toContain('of 2');
|
||||
})
|
||||
.then(() => pagination.resetToDefaultPageSize());
|
||||
});
|
||||
|
||||
it('current page menu items', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => expect(pagination.menu.getItemsCount()).toBe(5))
|
||||
.then(() => pagination.menu.closeMenu());
|
||||
});
|
||||
|
||||
it('change the current page from menu [C260518]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(3))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('51-75 of 101');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 3');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(true, 'Previous button is not enabled');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(true, 'Next button is not enabled');
|
||||
expect(dataTable.getRowName('file-40.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('navigate to next page [C213160]', () => {
|
||||
pagination.nextButton.click()
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('26-50 of 101');
|
||||
expect(dataTable.getRowName('file-70.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('navigate to previous page [C213160]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(2))
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => pagination.previousButton.click())
|
||||
.then(() => dataTable.waitForHeader())
|
||||
.then(() => {
|
||||
expect(pagination.range.getText()).toContain('1-25 of 101');
|
||||
expect(dataTable.getRowName('file-88.txt').isPresent()).toBe(true, 'File not found on page');
|
||||
})
|
||||
|
||||
.then(() => pagination.resetToDefaultPageNumber());
|
||||
});
|
||||
|
||||
it('Previous button is disabled on first page [C260519]', () => {
|
||||
expect(pagination.currentPage.getText()).toContain('Page 1');
|
||||
expect(pagination.previousButton.isEnabled()).toBe(false, 'Previous button is enabled on first page');
|
||||
});
|
||||
|
||||
it('Next button is disabled on last page [C260519]', () => {
|
||||
pagination.openCurrentPageMenu()
|
||||
.then(() => pagination.menu.clickNthItem(5))
|
||||
.then(() => {
|
||||
expect(dataTable.countRows()).toBe(1, 'Incorrect number of items on the last page');
|
||||
expect(pagination.currentPage.getText()).toContain('Page 5');
|
||||
expect(pagination.nextButton.isEnabled()).toBe(false, 'Next button is enabled on last page');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
0
e2e/tsconfig.e2e.json
Normal file → Executable file
0
e2e/tsconfig.e2e.json
Normal file → Executable file
118
e2e/utilities/repo-client/apis/favorites/favorites-api.ts
Executable file
118
e2e/utilities/repo-client/apis/favorites/favorites-api.ts
Executable file
@ -0,0 +1,118 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { promise } from 'protractor';
|
||||
import { RepoApi } from '../repo-api';
|
||||
import { NodesApi } from '../nodes/nodes-api';
|
||||
import { RepoClient } from './../../repo-client';
|
||||
import { Utils } from '../../../../utilities/utils';
|
||||
|
||||
export class FavoritesApi extends RepoApi {
|
||||
|
||||
addFavorite(api: RepoClient, nodeType: string, name: string): Promise<any> {
|
||||
return api.nodes.getNodeByPath(name)
|
||||
.then((response) => {
|
||||
const { id } = response.data.entry;
|
||||
return ([{
|
||||
target: {
|
||||
[nodeType]: {
|
||||
guid: id
|
||||
}
|
||||
}
|
||||
}]);
|
||||
})
|
||||
.then((data) => {
|
||||
return this.post(`/people/-me-/favorites`, { data });
|
||||
})
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
addFavoriteById(nodeType: 'file' | 'folder', id: string): Promise<any> {
|
||||
const data = [{
|
||||
target: {
|
||||
[nodeType]: {
|
||||
guid: id
|
||||
}
|
||||
}
|
||||
}];
|
||||
return this
|
||||
.post(`/people/-me-/favorites`, { data })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
addFavoritesByIds(nodeType: 'file' | 'folder', ids: string[]): Promise<any[]> {
|
||||
return ids.reduce((previous, current) => (
|
||||
previous.then(() => this.addFavoriteById(nodeType, current))
|
||||
), Promise.resolve());
|
||||
}
|
||||
|
||||
getFavorites(): Promise<any> {
|
||||
return this
|
||||
.get('/people/-me-/favorites')
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
getFavoriteById(nodeId: string): Promise<any> {
|
||||
return this
|
||||
.get(`/people/-me-/favorites/${nodeId}`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
isFavorite(nodeId: string) {
|
||||
return this.getFavorites()
|
||||
.then(resp => JSON.stringify(resp.data.list.entries).includes(nodeId))
|
||||
}
|
||||
|
||||
removeFavorite(api: RepoClient, nodeType: string, name: string): Promise<any> {
|
||||
return api.nodes.getNodeByPath(name)
|
||||
.then((response) => {
|
||||
const { id } = response.data.entry;
|
||||
return this.delete(`/people/-me-/favorites/${id}`);
|
||||
})
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
removeFavoriteById(nodeId: string) {
|
||||
return this
|
||||
.delete(`/people/-me-/favorites/${nodeId}`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
waitForApi(data) {
|
||||
const favoriteFiles = () => {
|
||||
return this.getFavorites()
|
||||
.then(response => response.data.list.pagination.totalItems)
|
||||
.then(totalItems => {
|
||||
if ( totalItems < data.expect) {
|
||||
return Promise.reject(totalItems);
|
||||
} else {
|
||||
return Promise.resolve(totalItems);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return Utils.retryCall(favoriteFiles);
|
||||
}
|
||||
}
|
38
e2e/utilities/repo-client/apis/nodes/node-body-create.ts
Executable file
38
e2e/utilities/repo-client/apis/nodes/node-body-create.ts
Executable file
@ -0,0 +1,38 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 properties?: any[]
|
||||
) {}
|
||||
}
|
85
e2e/utilities/repo-client/apis/nodes/node-content-tree.ts
Executable file
85
e2e/utilities/repo-client/apis/nodes/node-content-tree.ts
Executable file
@ -0,0 +1,85 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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;
|
||||
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
|
||||
}));
|
||||
|
||||
data = data.concat(filesData);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
182
e2e/utilities/repo-client/apis/nodes/nodes-api.ts
Executable file
182
e2e/utilities/repo-client/apis/nodes/nodes-api.ts
Executable file
@ -0,0 +1,182 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, NODE_TYPE_FILE, NODE_TYPE_FOLDER } from './node-body-create';
|
||||
import { NodeContentTree, flattenNodeContentTree } from './node-content-tree';
|
||||
|
||||
export class NodesApi extends RepoApi {
|
||||
// nodes
|
||||
getNodeByPath(relativePath: string = '/'): Promise<any> {
|
||||
return this
|
||||
.get(`/nodes/-my-`, { parameters: { relativePath } })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
getNodeById(id: string): Promise<any> {
|
||||
return this
|
||||
.get(`/nodes/${id}`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
getNodeDescription(name: string, relativePath: string = '/') {
|
||||
relativePath = (relativePath === '/')
|
||||
? `${name}`
|
||||
: `${relativePath}/${name}`;
|
||||
|
||||
return this.getNodeByPath(`${relativePath}`)
|
||||
.then(response => response.data.entry.properties['cm:description']);
|
||||
}
|
||||
|
||||
deleteNodeById(id: string, permanent: boolean = true): Promise<any> {
|
||||
return this
|
||||
.delete(`/nodes/${id}?permanent=${permanent}`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
deleteNodeByPath(path: string, permanent: boolean = true): Promise<any> {
|
||||
return this
|
||||
.getNodeByPath(path)
|
||||
.then((response: any): string => response.data.entry.id)
|
||||
.then((id: string): any => this.deleteNodeById(id, permanent))
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
deleteNodes(names: string[], relativePath: string = '', permanent: boolean = true): Promise<any[]> {
|
||||
return names.reduce((previous, current) => (
|
||||
previous.then(() => this.deleteNodeByPath(`${relativePath}/${current}`, permanent))
|
||||
), Promise.resolve());
|
||||
}
|
||||
|
||||
deleteNodesById(ids: string[], permanent: boolean = true): Promise<any[]> {
|
||||
return ids.reduce((previous, current) => (
|
||||
previous.then(() => this.deleteNodeById(current, permanent))
|
||||
), Promise.resolve());
|
||||
}
|
||||
|
||||
// children
|
||||
getNodeChildren(nodeId: string): Promise<any> {
|
||||
return this
|
||||
.get(`/nodes/${nodeId}/children`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
createNode(nodeType: string, name: string, parentId: string = '-my-', title: string = '', description: string = ''): Promise<any> {
|
||||
const data = {
|
||||
name: name,
|
||||
nodeType: nodeType,
|
||||
properties: {
|
||||
'cm:title': title, 'cm:description': description
|
||||
}
|
||||
};
|
||||
|
||||
return this
|
||||
.post(`/nodes/${parentId}/children`, { data })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
createFile(name: string, parentId: string = '-my-', title: string = '', description: string = ''): Promise<any> {
|
||||
return this.createNode('cm:content', name, parentId, title, description);
|
||||
}
|
||||
|
||||
createFolder(name: string, parentId: string = '-my-', title: string = '', description: string = ''): Promise<any> {
|
||||
return this.createNode('cm:folder', name, parentId, title, description);
|
||||
}
|
||||
|
||||
createChildren(data: NodeBodyCreate[]): Promise<any> {
|
||||
return this
|
||||
.post(`/nodes/-my-/children`, { data })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
createContent(content: NodeContentTree, relativePath: string = '/'): Promise<any> {
|
||||
return this.createChildren(flattenNodeContentTree(content, relativePath));
|
||||
}
|
||||
|
||||
createFolders(names: string[], relativePath: string = '/'): Promise<any> {
|
||||
return this.createContent({ folders: names }, relativePath);
|
||||
}
|
||||
|
||||
createFiles(names: string[], relativePath: string = '/'): Promise<any> {
|
||||
return this.createContent({ files: names }, relativePath);
|
||||
}
|
||||
|
||||
// node content
|
||||
getNodeContent(nodeId: string): Promise<any> {
|
||||
return this
|
||||
.get(`/nodes/${nodeId}/content`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
editNodeContent(nodeId: string, content: string): Promise<any> {
|
||||
return this
|
||||
.put(`/nodes/${nodeId}/content`, { data: content })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
renameNode(nodeId: string, newName: string): Promise<any> {
|
||||
return this
|
||||
.put(`/nodes/${nodeId}`, { data: { name: newName } })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
// node permissions
|
||||
setGranularPermission(nodeId: string, inheritPermissions: boolean = false, username: string, role: string): Promise<any> {
|
||||
const data = {
|
||||
permissions: {
|
||||
isInheritanceEnabled: inheritPermissions,
|
||||
locallySet: [
|
||||
{
|
||||
authorityId: username,
|
||||
name: role
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
return this
|
||||
.put(`/nodes/${nodeId}`, { data })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
getNodePermissions(nodeId: string): Promise<any> {
|
||||
return this
|
||||
.get(`/nodes/${nodeId}?include=permissions`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
// lock node
|
||||
lockFile(nodeId: string, lockType: string = 'FULL') {
|
||||
return this
|
||||
.post(`/nodes/${nodeId}/lock?include=isLocked`, { data: { 'type': lockType } })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
unlockFile(nodeId: string) {
|
||||
return this
|
||||
.post(`/nodes/${nodeId}/unlock`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
}
|
43
e2e/utilities/repo-client/apis/people/people-api-models.ts
Executable file
43
e2e/utilities/repo-client/apis/people/people-api-models.ts
Executable file
@ -0,0 +1,43 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 class Person {
|
||||
id?: string;
|
||||
password?: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
email?: string;
|
||||
properties?: any;
|
||||
|
||||
constructor(username: string, password: string, details: Person) {
|
||||
this.id = username;
|
||||
this.password = password || username;
|
||||
this.firstName = username;
|
||||
this.lastName = username;
|
||||
this.email = `${username}@alfresco.com`;
|
||||
|
||||
Object.assign(this, details);
|
||||
}
|
||||
}
|
70
e2e/utilities/repo-client/apis/people/people-api.ts
Executable file
70
e2e/utilities/repo-client/apis/people/people-api.ts
Executable file
@ -0,0 +1,70 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { Person } from './people-api-models';
|
||||
|
||||
export class PeopleApi extends RepoApi {
|
||||
getUser(username: string) {
|
||||
return this
|
||||
.get(`/people/${username}`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
updateUser(username: string, details?: Person): Promise<any> {
|
||||
if (details.id) {
|
||||
delete details.id;
|
||||
}
|
||||
|
||||
return this
|
||||
.put(`/people/${username}`, { data: details })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
createUser(username: string, password?: string, details?: Person): Promise<any> {
|
||||
const person: Person = new Person(username, password, details);
|
||||
const onSuccess = (response) => response;
|
||||
const onError = (response) => {
|
||||
return (response.statusCode === 409)
|
||||
? Promise.resolve(this.updateUser(username, person))
|
||||
: Promise.reject(response);
|
||||
};
|
||||
|
||||
return this
|
||||
.post(`/people`, { data: person })
|
||||
.then(onSuccess, onError)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
disableUser(username: string): Promise<any> {
|
||||
return this.put(`/people/${username}`, { data: { enabled: false } })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
changePassword(username: string, newPassword: string) {
|
||||
return this.put(`/people/${username}`, { data: { password: newPassword } })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
}
|
71
e2e/utilities/repo-client/apis/repo-api.ts
Executable file
71
e2e/utilities/repo-client/apis/repo-api.ts
Executable file
@ -0,0 +1,71 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { RestClient, RestClientArgs, RestClientResponse } from '../../rest-client/rest-client';
|
||||
import { RepoClientAuth, RepoClientConfig } from '../repo-client-models';
|
||||
|
||||
export abstract class RepoApi {
|
||||
private client: RestClient;
|
||||
private defaults: RepoClientConfig = new RepoClientConfig();
|
||||
|
||||
constructor(
|
||||
auth: RepoClientAuth = new RepoClientAuth(),
|
||||
private config?: RepoClientConfig
|
||||
) {
|
||||
const { username, password } = auth;
|
||||
|
||||
this.client = new RestClient(username, password);
|
||||
}
|
||||
|
||||
private createEndpointUri(endpoint: string, apiDefinition: string = 'alfresco'): string {
|
||||
const { defaults, config } = this;
|
||||
const { host, tenant } = Object.assign(defaults, config);
|
||||
|
||||
return `${host}/alfresco/api/${tenant}/public/${apiDefinition}/versions/1${endpoint}`;
|
||||
}
|
||||
|
||||
protected handleError(response: RestClientResponse) {
|
||||
const { request: { method, path, data }, data: error } = response;
|
||||
|
||||
console.log(`ERROR on ${method}\n${path}\n${data}`);
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
protected get(endpoint: string, args: RestClientArgs = {}, apiDefinition: string = 'alfresco') {
|
||||
return this.client.get(this.createEndpointUri(endpoint, apiDefinition), args);
|
||||
}
|
||||
|
||||
protected post(endpoint: string, args: RestClientArgs = {}, apiDefinition: string = 'alfresco') {
|
||||
return this.client.post(this.createEndpointUri(endpoint, apiDefinition), args);
|
||||
}
|
||||
|
||||
protected put(endpoint: string, args: RestClientArgs = {}, apiDefinition: string = 'alfresco') {
|
||||
return this.client.put(this.createEndpointUri(endpoint, apiDefinition), args);
|
||||
}
|
||||
|
||||
protected delete(endpoint: string, args: RestClientArgs = {}, apiDefinition: string = 'alfresco') {
|
||||
return this.client.delete(this.createEndpointUri(endpoint, apiDefinition), args);
|
||||
}
|
||||
}
|
71
e2e/utilities/repo-client/apis/search/search-api.ts
Executable file
71
e2e/utilities/repo-client/apis/search/search-api.ts
Executable file
@ -0,0 +1,71 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { Utils } from '../../../../utilities/utils';
|
||||
|
||||
export class SearchApi extends RepoApi {
|
||||
apiDefinition = 'search';
|
||||
|
||||
search(data: any[]): Promise<any> {
|
||||
return this
|
||||
.post(`/search`, { data }, this.apiDefinition)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
queryRecentFiles(username: string): Promise<any> {
|
||||
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"` }
|
||||
]
|
||||
};
|
||||
|
||||
return this
|
||||
.post(`/search`, { data }, this.apiDefinition)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
waitForApi(username, data) {
|
||||
const recentFiles = () => {
|
||||
return this.queryRecentFiles(username)
|
||||
.then(response => response.data.list.pagination.totalItems)
|
||||
.then(totalItems => {
|
||||
if ( totalItems < data.expect) {
|
||||
return Promise.reject(totalItems);
|
||||
} else {
|
||||
return Promise.resolve(totalItems);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return Utils.retryCall(recentFiles);
|
||||
}
|
||||
}
|
79
e2e/utilities/repo-client/apis/shared-links/shared-links-api.ts
Executable file
79
e2e/utilities/repo-client/apis/shared-links/shared-links-api.ts
Executable file
@ -0,0 +1,79 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { NodesApi } from '../nodes/nodes-api';
|
||||
import { RepoClient } from './../../repo-client';
|
||||
import { Utils } from '../../../../utilities/utils';
|
||||
|
||||
export class SharedLinksApi extends RepoApi {
|
||||
|
||||
shareFileById(id: string): Promise<any> {
|
||||
const data = [{ nodeId: id }];
|
||||
|
||||
return this.post(`/shared-links`, { data })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
shareFilesByIds(ids: string[]): Promise<any[]> {
|
||||
return ids.reduce((previous, current) => (
|
||||
previous.then(() => this.shareFileById(current))
|
||||
), Promise.resolve());
|
||||
}
|
||||
|
||||
getSharedIdOfNode(name: string) {
|
||||
return this.getSharedLinks()
|
||||
.then(resp => resp.data.list.entries.find(entries => entries.entry.name === name))
|
||||
.then(resp => resp.entry.id)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
unshareFile(name: string) {
|
||||
return this.getSharedIdOfNode(name)
|
||||
.then(id => this.delete(`/shared-links/${id}`))
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
getSharedLinks(): Promise<any> {
|
||||
return this.get(`/shared-links`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
waitForApi(data) {
|
||||
const sharedFiles = () => {
|
||||
return this.getSharedLinks()
|
||||
.then(response => response.data.list.pagination.totalItems)
|
||||
.then(totalItems => {
|
||||
if ( totalItems < data.expect) {
|
||||
return Promise.reject(totalItems);
|
||||
} else {
|
||||
return Promise.resolve(totalItems);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return Utils.retryCall(sharedFiles);
|
||||
}
|
||||
}
|
42
e2e/utilities/repo-client/apis/sites/sites-api-models.ts
Executable file
42
e2e/utilities/repo-client/apis/sites/sites-api-models.ts
Executable file
@ -0,0 +1,42 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { SITE_VISIBILITY } from '../../../../configs';
|
||||
|
||||
export class Site {
|
||||
title?: string;
|
||||
visibility?: string = SITE_VISIBILITY.PUBLIC;
|
||||
id?: string;
|
||||
description?: string;
|
||||
|
||||
constructor(title: string, visibility: string, details: Site) {
|
||||
this.title = title;
|
||||
this.visibility = visibility;
|
||||
this.id = title;
|
||||
this.description = `${title} description`;
|
||||
|
||||
Object.assign(this, details);
|
||||
}
|
||||
}
|
124
e2e/utilities/repo-client/apis/sites/sites-api.ts
Executable file
124
e2e/utilities/repo-client/apis/sites/sites-api.ts
Executable file
@ -0,0 +1,124 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { Site } from './sites-api-models';
|
||||
|
||||
export class SitesApi extends RepoApi {
|
||||
getSite(id: string): Promise<any> {
|
||||
return this
|
||||
.get(`/sites/${id}`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
getSiteContainers(siteId: string): Promise<any> {
|
||||
return this
|
||||
.get(`/sites/${siteId}/containers`)
|
||||
.then(resp => resp.data.list.entries)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
getDocLibId(siteId: string) {
|
||||
return this.getSiteContainers(siteId)
|
||||
.then(resp => resp[0].entry.id)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
updateSite(id: string, details?: Site): Promise<any> {
|
||||
if (details.id) {
|
||||
delete details.id;
|
||||
}
|
||||
|
||||
return this
|
||||
.put(`/sites/${id}`, { data: details })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
createOrUpdateSite(title: string, visibility: string, details?: Site): Promise<any> {
|
||||
const site: Site = new Site(title, visibility, details);
|
||||
const onSuccess = (response) => response;
|
||||
const onError = (response) => {
|
||||
return (response.statusCode === 409)
|
||||
? Promise.resolve(this.updateSite(site.id, site))
|
||||
: Promise.reject(response);
|
||||
};
|
||||
|
||||
return this
|
||||
.post(`/sites`, { data: site })
|
||||
.then(onSuccess, onError)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
createSite(title: string, visibility: string, details?: Site): Promise<any> {
|
||||
const site: Site = new Site(title, visibility, details);
|
||||
return this
|
||||
.post(`/sites`, { data: site })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
createSites(titles: string[], visibility: string): Promise<any[]> {
|
||||
return titles.reduce((previous, current) => (
|
||||
previous.then(() => this.createSite(current, visibility))
|
||||
), Promise.resolve());
|
||||
}
|
||||
|
||||
deleteSite(id: string, permanent: boolean = true): Promise<any> {
|
||||
return this
|
||||
.delete(`/sites/${id}?permanent=${permanent}`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
deleteSites(ids: string[], permanent: boolean = true): Promise<any[]> {
|
||||
return ids.reduce((previous, current) => (
|
||||
previous.then(() => this.deleteSite(current))
|
||||
), Promise.resolve());
|
||||
}
|
||||
|
||||
updateSiteMember(siteId: string, userId: string, role: string): Promise<any> {
|
||||
return this
|
||||
.put(`/sites/${siteId}/members/${userId}`, { data: { role } })
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
addSiteMember(siteId: string, userId: string, role: string): Promise<any> {
|
||||
const onSuccess = (response) => response;
|
||||
const onError = (response) => {
|
||||
return (response.statusCode === 409)
|
||||
? Promise.resolve(this.updateSiteMember(siteId, userId, role))
|
||||
: Promise.reject(response);
|
||||
};
|
||||
|
||||
return this
|
||||
.post(`/sites/${siteId}/members`, { data: { role, id: userId } })
|
||||
.then(onSuccess, onError)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
deleteSiteMember(siteId: string, userId: string): Promise<any> {
|
||||
return this
|
||||
.delete(`/sites/${siteId}/members/${userId}`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
}
|
76
e2e/utilities/repo-client/apis/trashcan/trashcan-api.ts
Executable file
76
e2e/utilities/repo-client/apis/trashcan/trashcan-api.ts
Executable file
@ -0,0 +1,76 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { Utils } from '../../../../utilities/utils';
|
||||
|
||||
export class TrashcanApi extends RepoApi {
|
||||
permanentlyDelete(id: string): Promise<any> {
|
||||
return this
|
||||
.delete(`/deleted-nodes/${id}`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
restore(id: string) {
|
||||
return this
|
||||
.post(`/deleted-nodes/${id}/restore`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
getDeletedNodes(): Promise<any> {
|
||||
return this
|
||||
.get(`/deleted-nodes?maxItems=1000`)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
emptyTrash(): Promise<any> {
|
||||
return this.getDeletedNodes()
|
||||
.then(resp => {
|
||||
return resp.data.list.entries.map(entries => entries.entry.id);
|
||||
})
|
||||
.then(ids => {
|
||||
return ids.reduce((previous, current) => (
|
||||
previous.then(() => this.permanentlyDelete(current))
|
||||
), Promise.resolve());
|
||||
})
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
waitForApi(data) {
|
||||
const deletedFiles = () => {
|
||||
return this.getDeletedNodes()
|
||||
.then(response => response.data.list.pagination.totalItems)
|
||||
.then(totalItems => {
|
||||
if ( totalItems < data.expect) {
|
||||
return Promise.reject(totalItems);
|
||||
} else {
|
||||
return Promise.resolve(totalItems);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return Utils.retryCall(deletedFiles);
|
||||
}
|
||||
}
|
46
e2e/utilities/repo-client/repo-client-models.ts
Executable file
46
e2e/utilities/repo-client/repo-client-models.ts
Executable file
@ -0,0 +1,46 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 {
|
||||
ADMIN_USERNAME,
|
||||
ADMIN_PASSWORD,
|
||||
REPO_API_HOST,
|
||||
REPO_API_TENANT
|
||||
} from '../../configs';
|
||||
|
||||
export class RepoClientAuth {
|
||||
static DEFAULT_USERNAME: string = ADMIN_USERNAME;
|
||||
static DEFAULT_PASSWORD: string = ADMIN_PASSWORD;
|
||||
|
||||
constructor(
|
||||
public username: string = RepoClientAuth.DEFAULT_USERNAME,
|
||||
public password: string = RepoClientAuth.DEFAULT_PASSWORD
|
||||
) {}
|
||||
}
|
||||
|
||||
export class RepoClientConfig {
|
||||
host?: string = REPO_API_HOST;
|
||||
tenant?: string = REPO_API_TENANT;
|
||||
}
|
59
e2e/utilities/repo-client/repo-client.ts
Executable file
59
e2e/utilities/repo-client/repo-client.ts
Executable file
@ -0,0 +1,59 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { RepoClientAuth, RepoClientConfig } from './repo-client-models';
|
||||
|
||||
import { PeopleApi } from './apis/people/people-api';
|
||||
import { NodesApi } from './apis/nodes/nodes-api';
|
||||
import { SitesApi } from './apis/sites/sites-api';
|
||||
import { FavoritesApi } from './apis/favorites/favorites-api';
|
||||
import { SharedLinksApi } from './apis/shared-links/shared-links-api';
|
||||
import { TrashcanApi } from './apis/trashcan/trashcan-api';
|
||||
import { SearchApi } from './apis/search/search-api';
|
||||
|
||||
export class RepoClient {
|
||||
public people: PeopleApi = new PeopleApi(this.auth, this.config);
|
||||
public nodes: NodesApi = new NodesApi(this.auth, this.config);
|
||||
public sites: SitesApi = new SitesApi(this.auth, this.config);
|
||||
public favorites: FavoritesApi = new FavoritesApi(this.auth, this.config);
|
||||
public shared: SharedLinksApi = new SharedLinksApi(this.auth, this.config);
|
||||
public trashcan: TrashcanApi = new TrashcanApi(this.auth, this.config);
|
||||
public search: SearchApi = new SearchApi(this.auth, this.config);
|
||||
|
||||
constructor(
|
||||
private username: string = RepoClientAuth.DEFAULT_USERNAME,
|
||||
private password: string = RepoClientAuth.DEFAULT_PASSWORD,
|
||||
private config?: RepoClientConfig
|
||||
) {}
|
||||
|
||||
private get auth(): RepoClientAuth {
|
||||
const { username, password } = this;
|
||||
return { username, password };
|
||||
}
|
||||
}
|
||||
|
||||
export * from './apis/nodes/node-body-create';
|
||||
export * from './apis/nodes/node-content-tree';
|
||||
export * from './apis/nodes/nodes-api';
|
79
e2e/utilities/reporters/console/console-logger.ts
Executable file
79
e2e/utilities/reporters/console/console-logger.ts
Executable file
@ -0,0 +1,79 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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/>.
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
const chalk = require('chalk');
|
||||
/* tslint:enable */
|
||||
|
||||
export const log = {
|
||||
i: 0,
|
||||
|
||||
get indentation(): string {
|
||||
return new Array(this.i).fill(' ').join('');
|
||||
},
|
||||
|
||||
indent() {
|
||||
this.i++;
|
||||
return this;
|
||||
},
|
||||
|
||||
dedent() {
|
||||
this.i--;
|
||||
return this;
|
||||
},
|
||||
|
||||
log(message: string = '', options: any = { ignoreIndentation: false }) {
|
||||
const indentation = (!options.ignoreIndentation)
|
||||
? this.indentation
|
||||
: '';
|
||||
|
||||
console.log(`${indentation}${message}`);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
blank() {
|
||||
return this.log();
|
||||
},
|
||||
|
||||
info(message: string = '', options: any = { bold: false, title: false }) {
|
||||
const { bold } = options;
|
||||
const style = (bold ? chalk.bold : chalk).gray;
|
||||
|
||||
return this.log(style(message), options);
|
||||
},
|
||||
|
||||
success(message: string = '', options: any = { bold: false }) {
|
||||
const style = options.bold ? chalk.bold.green : chalk.green;
|
||||
|
||||
return this.log(style(message), options);
|
||||
},
|
||||
|
||||
error(message: string = '', options: any = { bold: false }) {
|
||||
const style = options.bold ? chalk.bold.red : chalk.red;
|
||||
|
||||
return this.log(style(message), options);
|
||||
}
|
||||
};
|
90
e2e/utilities/reporters/console/console.ts
Executable file
90
e2e/utilities/reporters/console/console.ts
Executable file
@ -0,0 +1,90 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { log } from './console-logger';
|
||||
|
||||
const errors = [];
|
||||
|
||||
export const consoleReporter = {
|
||||
jasmineStarted(suiteInfo) {
|
||||
log.blank().info(
|
||||
`Running ${suiteInfo.totalSpecsDefined} tests`,
|
||||
{ bold: true, title: true }
|
||||
).blank();
|
||||
},
|
||||
|
||||
suiteStarted(suite) {
|
||||
log.info(suite.description).indent();
|
||||
},
|
||||
|
||||
specDone: (spec) => {
|
||||
const {
|
||||
status,
|
||||
description,
|
||||
failedExpectations
|
||||
} = spec;
|
||||
|
||||
if (status === 'passed') {
|
||||
log.success(`∙ ${description}`);
|
||||
}
|
||||
|
||||
if (status === 'failed') {
|
||||
log.error(`✕ ${description}`, { bold: true });
|
||||
|
||||
errors.push(spec);
|
||||
|
||||
failedExpectations.forEach((failed) => {
|
||||
log.error(` ${failed.message}`);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
suiteDone: (result) => {
|
||||
log.dedent();
|
||||
},
|
||||
|
||||
jasmineDone: (result) => {
|
||||
if (!!errors.length) {
|
||||
log .blank()
|
||||
.blank()
|
||||
.info(`${errors.length} failing tests`, { bold: true, title: true });
|
||||
|
||||
errors.forEach(error => {
|
||||
log .blank()
|
||||
.error(`✕ ${error.fullName}`, { bold: true });
|
||||
|
||||
error.failedExpectations.forEach(failed => {
|
||||
log .info(`${failed.message}`)
|
||||
.blank()
|
||||
.error(`${failed.stack}`);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
log.success(`All tests passed!`, { bold: true });
|
||||
}
|
||||
|
||||
log.blank().blank();
|
||||
}
|
||||
};
|
63
e2e/utilities/rest-client/rest-client-models.ts
Executable file
63
e2e/utilities/rest-client/rest-client-models.ts
Executable file
@ -0,0 +1,63 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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/>.
|
||||
*/
|
||||
|
||||
interface RequestConfig {
|
||||
timeout?: number;
|
||||
noDelay?: boolean;
|
||||
keepAlive?: boolean;
|
||||
keepAliveDelay?: number;
|
||||
}
|
||||
|
||||
interface ResponseConfig {
|
||||
timeout?: number;
|
||||
}
|
||||
|
||||
interface ResponseRequest {
|
||||
method: string;
|
||||
path: string;
|
||||
data: string;
|
||||
}
|
||||
|
||||
export interface NodeRestClient {
|
||||
get(uri: string, callback: Function): Function;
|
||||
post(uri: string, callback: Function): Function;
|
||||
put(uri: string, callback: Function): Function;
|
||||
delete(uri: string, callback: Function): Function;
|
||||
}
|
||||
|
||||
export interface RestClientArgs {
|
||||
data?: any;
|
||||
parameters?: any;
|
||||
headers?: any;
|
||||
requestConfig?: RequestConfig;
|
||||
responseConfig?: ResponseConfig;
|
||||
}
|
||||
|
||||
export interface RestClientResponse {
|
||||
request: ResponseRequest;
|
||||
data: any;
|
||||
statusMessage: string;
|
||||
statusCode: number;
|
||||
}
|
89
e2e/utilities/rest-client/rest-client.ts
Executable file
89
e2e/utilities/rest-client/rest-client.ts
Executable file
@ -0,0 +1,89 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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 { Client } from 'node-rest-client';
|
||||
import { NodeRestClient, RestClientArgs, RestClientResponse } from './rest-client-models';
|
||||
|
||||
export * from './rest-client-models';
|
||||
|
||||
export class RestClient {
|
||||
private static DEFAULT_HEADERS = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'
|
||||
};
|
||||
|
||||
private client: NodeRestClient;
|
||||
|
||||
constructor(user: string, password: string) {
|
||||
this.client = <NodeRestClient>(new Client({ user, password }));
|
||||
}
|
||||
|
||||
get(uri: string, args: RestClientArgs = {}): Promise<RestClientResponse> {
|
||||
return this.promisify('get', uri, args);
|
||||
}
|
||||
|
||||
post(uri: string, args: RestClientArgs = {}): Promise<RestClientResponse> {
|
||||
return this.promisify('post', uri, args);
|
||||
}
|
||||
|
||||
put(uri: string, args: RestClientArgs = {}): Promise<RestClientResponse> {
|
||||
return this.promisify('put', uri, args);
|
||||
}
|
||||
|
||||
delete(uri: string, args: RestClientArgs = {}): Promise<RestClientResponse> {
|
||||
return this.promisify('delete', uri, args);
|
||||
}
|
||||
|
||||
private createArgs(args: RestClientArgs = {}): RestClientArgs {
|
||||
const data = JSON.stringify(args.data);
|
||||
|
||||
return Object.assign({}, RestClient.DEFAULT_HEADERS, args, { data });
|
||||
}
|
||||
|
||||
private promisify(fnName: string, uri: string, args: RestClientArgs): Promise<RestClientResponse> {
|
||||
const fn: Function = this.client[fnName];
|
||||
const fnArgs = [ encodeURI(uri), this.createArgs(args) ];
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const fnCallback = (data, rawResponse) => {
|
||||
const {
|
||||
statusCode, statusMessage,
|
||||
req: { method, path }
|
||||
} = rawResponse;
|
||||
|
||||
const response: RestClientResponse = {
|
||||
data, statusCode, statusMessage,
|
||||
request: { method, path, data: args.data }
|
||||
};
|
||||
|
||||
(response.statusCode >= 400)
|
||||
? reject(response)
|
||||
: resolve(response);
|
||||
};
|
||||
|
||||
fn(...fnArgs, fnCallback);
|
||||
});
|
||||
}
|
||||
}
|
73
e2e/utilities/utils.ts
Executable file
73
e2e/utilities/utils.ts
Executable file
@ -0,0 +1,73 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 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, promise, ElementFinder, ExpectedConditions as EC } from 'protractor';
|
||||
import { BROWSER_WAIT_TIMEOUT } from '../configs';
|
||||
|
||||
export class Utils {
|
||||
// generate a random value
|
||||
static random(): string {
|
||||
return Math.random().toString(36).substring(3, 10).toLowerCase();
|
||||
}
|
||||
|
||||
// local storage
|
||||
static clearLocalStorage(): promise.Promise<any> {
|
||||
return browser.executeScript('window.localStorage.clear();');
|
||||
}
|
||||
|
||||
// session storage
|
||||
static clearSessionStorage(): promise.Promise<any> {
|
||||
return browser.executeScript('window.sessionStorage.clear();');
|
||||
}
|
||||
|
||||
static retryCall(fn: () => Promise <any>, retry: number = 30, delay: number = 1000): Promise<any> {
|
||||
const rerun = (retries, fn) => {
|
||||
fn().catch(err => retries > 1
|
||||
? rerun(retries - 1, fn)
|
||||
: Promise.reject(err));
|
||||
};
|
||||
|
||||
const pause = (duration) => new Promise(res => setTimeout(res, duration));
|
||||
|
||||
const run = (retries, fn, delay = 1000) =>
|
||||
fn().catch(err => retries > 1
|
||||
? pause(delay).then(() => run(retries - 1, fn, delay))
|
||||
: Promise.reject(err));
|
||||
|
||||
return run(retry, fn);
|
||||
}
|
||||
|
||||
static waitUntilElementClickable(element: ElementFinder) {
|
||||
return browser.wait(EC.elementToBeClickable(element), BROWSER_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
static typeInField(elem: ElementFinder, value: string) {
|
||||
for ( let i = 0; i < value.length; i++ ) {
|
||||
const c = value.charAt(i);
|
||||
elem.sendKeys(c);
|
||||
browser.sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
509
package-lock.json
generated
509
package-lock.json
generated
@ -40,15 +40,6 @@
|
||||
"zone.js": "0.8.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"alfresco-js-api": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/alfresco-js-api/-/alfresco-js-api-2.3.0.tgz",
|
||||
"integrity": "sha512-IhsSNoPl8cbw/V24kw420sGoVp6rBakC2kN4gKe3bPdERvSWRehw5bojMQhnSPDmS2PqC5C23HaVV+whOwkpDg==",
|
||||
"requires": {
|
||||
"event-emitter": "0.3.4",
|
||||
"superagent": "3.8.2"
|
||||
}
|
||||
},
|
||||
"core-js": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz",
|
||||
@ -90,18 +81,38 @@
|
||||
"@ngx-translate/core": "9.1.1",
|
||||
"alfresco-js-api": "2.3.0",
|
||||
"chart.js": "2.5.0",
|
||||
"core-js": "2.5.3",
|
||||
"core-js": "2.4.1",
|
||||
"hammerjs": "2.0.8",
|
||||
"minimatch": "3.0.4",
|
||||
"moment": "2.20.1",
|
||||
"ng2-charts": "1.6.0",
|
||||
"pdfjs-dist": "2.0.303",
|
||||
"pdfjs-dist": "1.5.404",
|
||||
"raphael": "2.2.7",
|
||||
"reflect-metadata": "0.1.10",
|
||||
"rxjs": "5.5.2",
|
||||
"systemjs": "0.19.27",
|
||||
"tslib": "1.9.0",
|
||||
"zone.js": "0.8.20"
|
||||
"zone.js": "0.8.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz",
|
||||
"integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4="
|
||||
},
|
||||
"pdfjs-dist": {
|
||||
"version": "1.5.404",
|
||||
"resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-1.5.404.tgz",
|
||||
"integrity": "sha1-hYXGUWquIU1ZCXXo+ys8PzrxTO8=",
|
||||
"requires": {
|
||||
"node-ensure": "0.0.0"
|
||||
}
|
||||
},
|
||||
"zone.js": {
|
||||
"version": "0.8.14",
|
||||
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.14.tgz",
|
||||
"integrity": "sha1-DE2ySxeCMidMy0P3jJnbfzZCts8="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@angular-devkit/build-optimizer": {
|
||||
@ -132,7 +143,7 @@
|
||||
"requires": {
|
||||
"ajv": "5.5.2",
|
||||
"chokidar": "1.7.0",
|
||||
"rxjs": "5.5.9",
|
||||
"rxjs": "5.5.10",
|
||||
"source-map": "0.5.7"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -149,9 +160,9 @@
|
||||
}
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "5.5.9",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.9.tgz",
|
||||
"integrity": "sha512-DHG9AHmCmgaFWgjBcXp6NxFDmh3MvIA62GqTWmLnTzr/3oZ6h5hLD8NA+9j+GF0jEwklNIpI4KuuyLG8UWMEvQ==",
|
||||
"version": "5.5.10",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.10.tgz",
|
||||
"integrity": "sha512-SRjimIDUHJkon+2hFo7xnvNC4ZEHGzCRwh9P7nzX3zPkCGFEg/tuElrNR7L/rZMagnK2JeH2jQwPRpmyXyLB6A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"symbol-observable": "1.0.1"
|
||||
@ -172,13 +183,13 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@ngtools/json-schema": "1.2.0",
|
||||
"rxjs": "5.5.9"
|
||||
"rxjs": "5.5.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"rxjs": {
|
||||
"version": "5.5.9",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.9.tgz",
|
||||
"integrity": "sha512-DHG9AHmCmgaFWgjBcXp6NxFDmh3MvIA62GqTWmLnTzr/3oZ6h5hLD8NA+9j+GF0jEwklNIpI4KuuyLG8UWMEvQ==",
|
||||
"version": "5.5.10",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.10.tgz",
|
||||
"integrity": "sha512-SRjimIDUHJkon+2hFo7xnvNC4ZEHGzCRwh9P7nzX3zPkCGFEg/tuElrNR7L/rZMagnK2JeH2jQwPRpmyXyLB6A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"symbol-observable": "1.0.1"
|
||||
@ -253,11 +264,11 @@
|
||||
"portfinder": "1.0.13",
|
||||
"postcss": "6.0.21",
|
||||
"postcss-import": "11.1.0",
|
||||
"postcss-loader": "2.1.3",
|
||||
"postcss-loader": "2.1.4",
|
||||
"postcss-url": "7.3.2",
|
||||
"raw-loader": "0.5.1",
|
||||
"resolve": "1.7.1",
|
||||
"rxjs": "5.5.9",
|
||||
"rxjs": "5.5.10",
|
||||
"sass-loader": "6.0.7",
|
||||
"semver": "5.5.0",
|
||||
"silent-error": "1.1.0",
|
||||
@ -265,7 +276,7 @@
|
||||
"style-loader": "0.19.1",
|
||||
"stylus": "0.54.5",
|
||||
"stylus-loader": "3.0.2",
|
||||
"uglifyjs-webpack-plugin": "1.2.4",
|
||||
"uglifyjs-webpack-plugin": "1.2.5",
|
||||
"url-loader": "0.6.2",
|
||||
"webpack": "3.11.0",
|
||||
"webpack-dev-middleware": "1.12.2",
|
||||
@ -276,9 +287,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"rxjs": {
|
||||
"version": "5.5.9",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.9.tgz",
|
||||
"integrity": "sha512-DHG9AHmCmgaFWgjBcXp6NxFDmh3MvIA62GqTWmLnTzr/3oZ6h5hLD8NA+9j+GF0jEwklNIpI4KuuyLG8UWMEvQ==",
|
||||
"version": "5.5.10",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.10.tgz",
|
||||
"integrity": "sha512-SRjimIDUHJkon+2hFo7xnvNC4ZEHGzCRwh9P7nzX3zPkCGFEg/tuElrNR7L/rZMagnK2JeH2jQwPRpmyXyLB6A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"symbol-observable": "1.0.1"
|
||||
@ -466,15 +477,15 @@
|
||||
"integrity": "sha512-7aVP4994Hu8vRdTTohXkfGWEwLhrdNP3EZnWyBootm5zshWqlQojUGweZe5zwewsKcixeVOiy2YtW+aI4aGSLA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"rxjs": "5.5.9",
|
||||
"rxjs": "5.5.10",
|
||||
"semver": "5.5.0",
|
||||
"semver-intersect": "1.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"rxjs": {
|
||||
"version": "5.5.9",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.9.tgz",
|
||||
"integrity": "sha512-DHG9AHmCmgaFWgjBcXp6NxFDmh3MvIA62GqTWmLnTzr/3oZ6h5hLD8NA+9j+GF0jEwklNIpI4KuuyLG8UWMEvQ==",
|
||||
"version": "5.5.10",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.10.tgz",
|
||||
"integrity": "sha512-SRjimIDUHJkon+2hFo7xnvNC4ZEHGzCRwh9P7nzX3zPkCGFEg/tuElrNR7L/rZMagnK2JeH2jQwPRpmyXyLB6A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"symbol-observable": "1.0.1"
|
||||
@ -516,9 +527,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/selenium-webdriver": {
|
||||
"version": "2.53.43",
|
||||
"resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz",
|
||||
"integrity": "sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.8.tgz",
|
||||
"integrity": "sha512-yrqQvb1EZhH+ONMzUmsEnBjzitortVv0lynRe5US2+FofdoMWUE4wf7v4peCd62fqXq8COCVTbpS1/jIg5EbuQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/strip-bom": {
|
||||
@ -600,9 +611,9 @@
|
||||
"optional": true
|
||||
},
|
||||
"adm-zip": {
|
||||
"version": "0.4.7",
|
||||
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.7.tgz",
|
||||
"integrity": "sha1-hgbCy/HEJs6MjsABdER/1Jtur8E=",
|
||||
"version": "0.4.4",
|
||||
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz",
|
||||
"integrity": "sha1-ph7VrmkFw66lizplfSUDMJEFJzY=",
|
||||
"dev": true
|
||||
},
|
||||
"after": {
|
||||
@ -1011,7 +1022,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browserslist": "2.11.3",
|
||||
"caniuse-lite": "1.0.30000828",
|
||||
"caniuse-lite": "1.0.30000830",
|
||||
"normalize-range": "0.1.2",
|
||||
"num2fraction": "1.2.2",
|
||||
"postcss": "6.0.21",
|
||||
@ -1257,9 +1268,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz",
|
||||
"integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==",
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
|
||||
"integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==",
|
||||
"dev": true
|
||||
},
|
||||
"base64id": {
|
||||
@ -1372,9 +1383,9 @@
|
||||
}
|
||||
},
|
||||
"blocking-proxy": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-0.0.5.tgz",
|
||||
"integrity": "sha1-RikF4Nz76pcPQao3Ij3anAexkSs=",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz",
|
||||
"integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "1.2.0"
|
||||
@ -1576,7 +1587,7 @@
|
||||
"integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"base64-js": "1.2.3",
|
||||
"base64-js": "1.3.0",
|
||||
"ieee754": "1.1.11"
|
||||
}
|
||||
},
|
||||
@ -1727,7 +1738,7 @@
|
||||
"integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"caniuse-lite": "1.0.30000828",
|
||||
"caniuse-lite": "1.0.30000830",
|
||||
"electron-to-chromium": "1.3.42"
|
||||
}
|
||||
},
|
||||
@ -1737,7 +1748,7 @@
|
||||
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"base64-js": "1.2.3",
|
||||
"base64-js": "1.3.0",
|
||||
"ieee754": "1.1.11",
|
||||
"isarray": "1.0.0"
|
||||
}
|
||||
@ -1906,9 +1917,9 @@
|
||||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30000828",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000828.tgz",
|
||||
"integrity": "sha512-v+ySC6Ih8N8CyGZYd4svPipuFIqskKsTOi18chFM0qtu1G8mGuSYajb+h49XDWgmzX8MRDOp1Agw6KQaPUdIhg==",
|
||||
"version": "1.0.30000830",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000830.tgz",
|
||||
"integrity": "sha512-yMqGkujkoOIZfvOYiWdqPALgY/PVGiqCHUJb6yNq7xhI/pR+gQO0U2K6lRDqAiJv4+CIU3CtTLblNGw0QGnr6g==",
|
||||
"dev": true
|
||||
},
|
||||
"caseless": {
|
||||
@ -2578,7 +2589,7 @@
|
||||
"loader-utils": "1.1.0",
|
||||
"minimatch": "3.0.4",
|
||||
"p-limit": "1.2.0",
|
||||
"serialize-javascript": "1.4.0"
|
||||
"serialize-javascript": "1.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-extglob": {
|
||||
@ -2659,7 +2670,7 @@
|
||||
"cipher-base": "1.0.4",
|
||||
"inherits": "2.0.3",
|
||||
"md5.js": "1.3.4",
|
||||
"ripemd160": "2.0.1",
|
||||
"ripemd160": "2.0.2",
|
||||
"sha.js": "2.4.11"
|
||||
}
|
||||
},
|
||||
@ -2672,7 +2683,7 @@
|
||||
"cipher-base": "1.0.4",
|
||||
"create-hash": "1.2.0",
|
||||
"inherits": "2.0.3",
|
||||
"ripemd160": "2.0.1",
|
||||
"ripemd160": "2.0.2",
|
||||
"safe-buffer": "5.1.1",
|
||||
"sha.js": "2.4.11"
|
||||
}
|
||||
@ -3263,9 +3274,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"ejs": {
|
||||
"version": "2.5.8",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.8.tgz",
|
||||
"integrity": "sha512-QIDZL54fyV8MDcAsO91BMH1ft2qGGaHIJsJIA/+t+7uvXol1dm413fPcUgUb4k8F/9457rx4/KFE4XfDifrQxQ==",
|
||||
"version": "2.5.9",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.9.tgz",
|
||||
"integrity": "sha512-GJCAeDBKfREgkBtgrYSf9hQy9kTb3helv0zGdzqhM7iAkW8FA/ZF97VQDbwFiwIT8MQLLOe5VlPZOEvZAqtUAQ==",
|
||||
"dev": true
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
@ -3493,6 +3504,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz",
|
||||
"integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=",
|
||||
"dev": true
|
||||
},
|
||||
"es6-set": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
|
||||
@ -5673,9 +5690,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"html-minifier": {
|
||||
"version": "3.5.14",
|
||||
"resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.14.tgz",
|
||||
"integrity": "sha512-sZjw6zhQgyUnIlIPU+W80XpRjWjdxHtNcxjfyOskOsCTDKytcfLY04wsQY/83Yqb4ndoiD2FtauiL7Yg6uUQFQ==",
|
||||
"version": "3.5.15",
|
||||
"resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.15.tgz",
|
||||
"integrity": "sha512-OZa4rfb6tZOZ3Z8Xf0jKxXkiDcFWldQePGYFDcgKqES2sXeWaEv9y6QQvWUtX3ySI3feApQi5uCsHLINQ6NoAw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camel-case": "3.0.0",
|
||||
@ -5694,7 +5711,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bluebird": "3.5.1",
|
||||
"html-minifier": "3.5.14",
|
||||
"html-minifier": "3.5.15",
|
||||
"loader-utils": "0.2.17",
|
||||
"lodash": "4.17.5",
|
||||
"pretty-error": "2.1.1",
|
||||
@ -5939,6 +5956,12 @@
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"immediate": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=",
|
||||
"dev": true
|
||||
},
|
||||
"import-local": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz",
|
||||
@ -6541,23 +6564,21 @@
|
||||
"handlebars": "4.0.11"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/items/-/items-2.1.1.tgz",
|
||||
"integrity": "sha1-i9FtnIOxlSneWuoyGsqtp4NkoZg=",
|
||||
"dev": true
|
||||
},
|
||||
"jasmine": {
|
||||
"version": "2.99.0",
|
||||
"resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.99.0.tgz",
|
||||
"integrity": "sha1-jKctEC5jm4Z8ZImFbg4YqceqQrc=",
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz",
|
||||
"integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"exit": "0.1.2",
|
||||
"glob": "7.1.2",
|
||||
"jasmine-core": "2.99.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"jasmine-core": {
|
||||
"version": "2.99.1",
|
||||
"resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz",
|
||||
"integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=",
|
||||
"dev": true
|
||||
}
|
||||
"jasmine-core": "2.8.0"
|
||||
}
|
||||
},
|
||||
"jasmine-core": {
|
||||
@ -6772,6 +6793,53 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"jszip": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz",
|
||||
"integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-js": "2.3.0",
|
||||
"es6-promise": "3.0.2",
|
||||
"lie": "3.1.1",
|
||||
"pako": "1.0.6",
|
||||
"readable-stream": "2.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz",
|
||||
"integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=",
|
||||
"dev": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
||||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
|
||||
"dev": true
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
|
||||
"integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"isarray": "1.0.0",
|
||||
"process-nextick-args": "1.0.7",
|
||||
"string_decoder": "0.10.31",
|
||||
"util-deprecate": "1.0.2"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"karma": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/karma/-/karma-2.0.0.tgz",
|
||||
@ -7017,7 +7085,16 @@
|
||||
"integrity": "sha512-NqAFodJdpBUuf1iD+Ij8hQvF0rCFKlO2KaieoQzAPhFgzLCtJnC7Z7x5gQbGNjoe++wOKAtAmwVEIBLqq2Yp1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ejs": "2.5.8"
|
||||
"ejs": "2.5.9"
|
||||
}
|
||||
},
|
||||
"lie": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||
"integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"immediate": "3.0.6"
|
||||
}
|
||||
},
|
||||
"load-json-file": {
|
||||
@ -7932,7 +8009,7 @@
|
||||
"stream-browserify": "2.0.1",
|
||||
"stream-http": "2.8.1",
|
||||
"string_decoder": "1.1.1",
|
||||
"timers-browserify": "2.0.6",
|
||||
"timers-browserify": "2.0.10",
|
||||
"tty-browserify": "0.0.0",
|
||||
"url": "0.11.0",
|
||||
"util": "0.10.3",
|
||||
@ -7953,6 +8030,60 @@
|
||||
"integrity": "sha1-QAlrCM560OoUaAhjr0ScfHWl0cg=",
|
||||
"dev": true
|
||||
},
|
||||
"node-rest-client": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/node-rest-client/-/node-rest-client-3.1.0.tgz",
|
||||
"integrity": "sha1-4L623aeyDMC2enhHzxLF/EGcN8M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "2.2.0",
|
||||
"follow-redirects": "1.4.1",
|
||||
"xml2js": "0.4.19"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
|
||||
"integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "0.7.1"
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz",
|
||||
"integrity": "sha512-uxYePVPogtya1ktGnAAXOacnbIuRMB4dkvqeNz2qTtTQsuzSfbDolV+wMMKxAmCx0bLgAKLbBOkjItMbbkR1vg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
|
||||
"integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-sass": {
|
||||
"version": "4.8.3",
|
||||
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.8.3.tgz",
|
||||
@ -8771,7 +8902,7 @@
|
||||
"requires": {
|
||||
"create-hash": "1.2.0",
|
||||
"create-hmac": "1.1.7",
|
||||
"ripemd160": "2.0.1",
|
||||
"ripemd160": "2.0.2",
|
||||
"safe-buffer": "5.1.1",
|
||||
"sha.js": "2.4.11"
|
||||
}
|
||||
@ -8861,20 +8992,20 @@
|
||||
"integrity": "sha512-y/bKfbQz2Nn/QBC08bwvYUxEFOVGfPIUOTsJ2CK5inzlXW9SdYR1x4pEsG9blRAF/PX+wRNdOah+gx/hv4q7dw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "2.3.2",
|
||||
"chalk": "2.4.0",
|
||||
"source-map": "0.6.1",
|
||||
"supports-color": "5.3.0"
|
||||
"supports-color": "5.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
|
||||
"integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.0.tgz",
|
||||
"integrity": "sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "3.2.1",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"supports-color": "5.3.0"
|
||||
"supports-color": "5.4.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
@ -8890,9 +9021,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
|
||||
"integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
|
||||
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "3.0.0"
|
||||
@ -8945,9 +9076,9 @@
|
||||
}
|
||||
},
|
||||
"postcss-loader": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.3.tgz",
|
||||
"integrity": "sha512-RuBcNE8rjCkIB0IsbmkGFRmQJTeQJfCI88E0VTarPNTvaNSv9OFv1DvTwgtAN/qlzyiELsmmmtX/tEzKp/cdug==",
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.4.tgz",
|
||||
"integrity": "sha512-L2p654oK945B/gDFUGgOhh7uzj19RWoY1SVMeJVoKno1H2MdbQ0RppR/28JGju4pMb22iRC7BJ9aDzbxXSLf4A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loader-utils": "1.1.0",
|
||||
@ -9025,32 +9156,44 @@
|
||||
"dev": true
|
||||
},
|
||||
"protractor": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/protractor/-/protractor-5.1.2.tgz",
|
||||
"integrity": "sha1-myIXQXCaTGLVzVPGqt1UpxE36V8=",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/protractor/-/protractor-5.3.1.tgz",
|
||||
"integrity": "sha512-AW9qJ0prx2QEMy1gnhJ1Sl1WBQL2R3fx/VnG09FEmWprPIQPK14t0B83OB/pAGddpxiDCAAV0KiNNLf2c2Y/lQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "6.0.105",
|
||||
"@types/node": "6.0.106",
|
||||
"@types/q": "0.0.32",
|
||||
"@types/selenium-webdriver": "2.53.43",
|
||||
"blocking-proxy": "0.0.5",
|
||||
"blocking-proxy": "1.0.1",
|
||||
"chalk": "1.1.3",
|
||||
"glob": "7.1.2",
|
||||
"jasmine": "2.99.0",
|
||||
"jasmine": "2.8.0",
|
||||
"jasminewd2": "2.2.0",
|
||||
"optimist": "0.6.1",
|
||||
"q": "1.4.1",
|
||||
"saucelabs": "1.3.0",
|
||||
"selenium-webdriver": "3.0.1",
|
||||
"selenium-webdriver": "3.6.0",
|
||||
"source-map-support": "0.4.18",
|
||||
"webdriver-js-extender": "1.0.0",
|
||||
"webdriver-manager": "12.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "6.0.105",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.105.tgz",
|
||||
"integrity": "sha512-fMIbw7iw91TSInS3b2DtDse5VaQEZqs0oTjvRNIFHnoHbnji+dLwpzL1L6dYGL39RzDNPHM/Off+VNcMk4ahwQ==",
|
||||
"version": "6.0.106",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.106.tgz",
|
||||
"integrity": "sha512-U4Zv5fx7letrisRv6HgSSPSY00FZM4NMIkilt+IAExvQLuNa6jYVwCKcnSs2NqTN4+KDl9PskvcCiMce9iePCA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/selenium-webdriver": {
|
||||
"version": "2.53.43",
|
||||
"resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz",
|
||||
"integrity": "sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==",
|
||||
"dev": true
|
||||
},
|
||||
"adm-zip": {
|
||||
"version": "0.4.7",
|
||||
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.7.tgz",
|
||||
"integrity": "sha1-hgbCy/HEJs6MjsABdER/1Jtur8E=",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
@ -9119,12 +9262,33 @@
|
||||
"integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=",
|
||||
"dev": true
|
||||
},
|
||||
"selenium-webdriver": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz",
|
||||
"integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jszip": "3.1.5",
|
||||
"rimraf": "2.6.2",
|
||||
"tmp": "0.0.30",
|
||||
"xml2js": "0.4.19"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
},
|
||||
"tmp": {
|
||||
"version": "0.0.30",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz",
|
||||
"integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"os-tmpdir": "1.0.2"
|
||||
}
|
||||
},
|
||||
"webdriver-manager": {
|
||||
"version": "12.0.6",
|
||||
"resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.0.6.tgz",
|
||||
@ -9831,24 +9995,13 @@
|
||||
}
|
||||
},
|
||||
"ripemd160": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
|
||||
"integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
|
||||
"integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"hash-base": "2.0.2",
|
||||
"hash-base": "3.0.4",
|
||||
"inherits": "2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"hash-base": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
|
||||
"integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"inherits": "2.0.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"run-queue": {
|
||||
@ -9860,6 +10013,12 @@
|
||||
"aproba": "1.2.0"
|
||||
}
|
||||
},
|
||||
"rx": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
|
||||
"integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=",
|
||||
"dev": true
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "5.5.2",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.2.tgz",
|
||||
@ -9962,12 +10121,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"selenium-webdriver": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.0.1.tgz",
|
||||
"integrity": "sha1-ot6l2kqX9mcuiefKcnbO+jZRR6c=",
|
||||
"version": "4.0.0-alpha.1",
|
||||
"resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.0.0-alpha.1.tgz",
|
||||
"integrity": "sha512-z88rdjHAv3jmTZ7KSGUkTvo4rGzcDGMq0oXWHNIDK96Gs31JKVdu9+FMtT4KBrVoibg8dUicJDok6GnqqttO5Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"adm-zip": "0.4.7",
|
||||
"jszip": "3.1.5",
|
||||
"rimraf": "2.6.2",
|
||||
"tmp": "0.0.30",
|
||||
"xml2js": "0.4.19"
|
||||
@ -10056,9 +10215,9 @@
|
||||
}
|
||||
},
|
||||
"serialize-javascript": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.4.0.tgz",
|
||||
"integrity": "sha1-fJWFFNtqwkQ6irwGLcn3iGp/YAU=",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz",
|
||||
"integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==",
|
||||
"dev": true
|
||||
},
|
||||
"serve-index": {
|
||||
@ -11113,9 +11272,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"timers-browserify": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.6.tgz",
|
||||
"integrity": "sha512-HQ3nbYRAowdVd0ckGFvmJPPCOH/CHleFN/Y0YQCX1DVaB7t+KFvisuyN09fuP8Jtp1CpfSh8O8bMkHbdbPe6Pw==",
|
||||
"version": "2.0.10",
|
||||
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz",
|
||||
"integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"setimmediate": "1.0.5"
|
||||
@ -11288,7 +11447,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arrify": "1.0.1",
|
||||
"chalk": "2.3.2",
|
||||
"chalk": "2.4.0",
|
||||
"diff": "3.5.0",
|
||||
"make-error": "1.3.4",
|
||||
"minimist": "1.2.0",
|
||||
@ -11300,14 +11459,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
|
||||
"integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.0.tgz",
|
||||
"integrity": "sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "3.2.1",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"supports-color": "5.3.0"
|
||||
"supports-color": "5.4.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
@ -11338,9 +11497,9 @@
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
|
||||
"integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
|
||||
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "3.0.0"
|
||||
@ -11401,7 +11560,7 @@
|
||||
"requires": {
|
||||
"babel-code-frame": "6.26.0",
|
||||
"builtin-modules": "1.1.1",
|
||||
"chalk": "2.3.2",
|
||||
"chalk": "2.4.0",
|
||||
"commander": "2.15.1",
|
||||
"diff": "3.5.0",
|
||||
"glob": "7.1.2",
|
||||
@ -11414,14 +11573,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
|
||||
"integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.0.tgz",
|
||||
"integrity": "sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "3.2.1",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"supports-color": "5.3.0"
|
||||
"supports-color": "5.4.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
@ -11431,9 +11590,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
|
||||
"integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
|
||||
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "3.0.0"
|
||||
@ -11505,9 +11664,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.3.tgz",
|
||||
"integrity": "sha512-ptLSQs2S4QuS6/OD1eAKG+S5G8QQtrU5RT32JULdZQtM1L3WTi34Wsu48Yndzi8xsObRAB9RPt/KhA9wlpEF6w==",
|
||||
"version": "2.7.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz",
|
||||
"integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==",
|
||||
"dev": true
|
||||
},
|
||||
"uglify-js": {
|
||||
@ -11536,15 +11695,15 @@
|
||||
"optional": true
|
||||
},
|
||||
"uglifyjs-webpack-plugin": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.4.tgz",
|
||||
"integrity": "sha512-z0IbjpW8b3O/OVn+TTZN4pI29RN1zktFBXLIzzfZ+++cUtZ1ERSlLWgpE/5OERuEUs1ijVQnpYAkSlpoVmQmSQ==",
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.5.tgz",
|
||||
"integrity": "sha512-hIQJ1yxAPhEA2yW/i7Fr+SXZVMp+VEI3d42RTHBgQd2yhp/1UdBcR3QEWPV5ahBxlqQDMEMTuTEvDHSFINfwSw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cacache": "10.0.4",
|
||||
"find-cache-dir": "1.0.0",
|
||||
"schema-utils": "0.4.5",
|
||||
"serialize-javascript": "1.4.0",
|
||||
"serialize-javascript": "1.5.0",
|
||||
"source-map": "0.6.1",
|
||||
"uglify-es": "3.3.9",
|
||||
"webpack-sources": "1.1.0",
|
||||
@ -11939,6 +12098,52 @@
|
||||
"integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
|
||||
"dev": true
|
||||
},
|
||||
"wait-on": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-2.1.0.tgz",
|
||||
"integrity": "sha512-hDwJ674+7dfiiK/cxtYCwPxlnjXDjto/pCz1PF02sXUhqCqCWsgvxZln0699PReWqXXgkxqkF6DDo5Rj9sjNvw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-js": "2.5.3",
|
||||
"joi": "9.2.0",
|
||||
"minimist": "1.2.0",
|
||||
"request": "2.81.0",
|
||||
"rx": "4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"hoek": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
|
||||
"integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==",
|
||||
"dev": true
|
||||
},
|
||||
"isemail": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/isemail/-/isemail-2.2.1.tgz",
|
||||
"integrity": "sha1-A1PT2aYpUQgMJiwqoKQrjqjp4qY=",
|
||||
"dev": true
|
||||
},
|
||||
"joi": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/joi/-/joi-9.2.0.tgz",
|
||||
"integrity": "sha1-M4WseQGSEwy+Iw6ALsAskhW7/to=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"hoek": "4.2.1",
|
||||
"isemail": "2.2.1",
|
||||
"items": "2.1.1",
|
||||
"moment": "2.20.1",
|
||||
"topo": "2.0.2"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"watchpack": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.5.0.tgz",
|
||||
@ -12325,10 +12530,10 @@
|
||||
"selenium-webdriver": "2.53.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"adm-zip": {
|
||||
"version": "0.4.4",
|
||||
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz",
|
||||
"integrity": "sha1-ph7VrmkFw66lizplfSUDMJEFJzY=",
|
||||
"@types/selenium-webdriver": {
|
||||
"version": "2.53.43",
|
||||
"resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz",
|
||||
"integrity": "sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==",
|
||||
"dev": true
|
||||
},
|
||||
"sax": {
|
||||
@ -12719,7 +12924,7 @@
|
||||
"sockjs-client": "1.1.4",
|
||||
"spdy": "3.4.7",
|
||||
"strip-ansi": "3.0.1",
|
||||
"supports-color": "5.3.0",
|
||||
"supports-color": "5.4.0",
|
||||
"webpack-dev-middleware": "1.12.2",
|
||||
"yargs": "6.6.0"
|
||||
},
|
||||
@ -13086,9 +13291,9 @@
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
|
||||
"integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
|
||||
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "3.0.0"
|
||||
|
19
package.json
19
package.json
@ -6,7 +6,6 @@
|
||||
"ng": "ng",
|
||||
"start": "npm run server-versions && ng serve --open",
|
||||
"start:prod": "npm run server-versions && ng serve --prod --open",
|
||||
"start:docker": "docker-compose up --build",
|
||||
"build": "npm run server-versions && ng build --prod",
|
||||
"build:prod": "npm run server-versions && ng build --prod",
|
||||
"build:dev": "npm run server-versions && ng build",
|
||||
@ -14,8 +13,13 @@
|
||||
"test": "ng test --code-coverage",
|
||||
"test:ci": "ng test --code-coverage --single-run --no-progress && cat ./coverage/lcov.info | ./node_modules/.bin/codacy-coverage && rm -rf ./coverage",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e",
|
||||
"server-versions": "rimraf ./src/versions.json && npm list --depth=0 --json=true --prod=true > ./src/versions.json || exit 0"
|
||||
"server-versions": "rimraf ./src/versions.json && npm list --depth=0 --json=true --prod=true > ./src/versions.json || exit 0",
|
||||
"_e2e": "ng e2e",
|
||||
"wd:update": "webdriver-manager update --gecko=false",
|
||||
"e2e": "npm run wd:update && protractor protractor.conf.js",
|
||||
"start:docker": "docker-compose up -d --build && wait-on http://localhost:8080 && wait-on http://localhost:3000",
|
||||
"stop:docker": "docker-compose stop",
|
||||
"e2e:docker": "npm run start:docker && npm run e2e && npm run stop:docker"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
@ -53,22 +57,27 @@
|
||||
"@types/jasmine": "^2.5.53",
|
||||
"@types/jasminewd2": "^2.0.2",
|
||||
"@types/node": "9.3.0",
|
||||
"@types/selenium-webdriver": "^3.0.8",
|
||||
"codacy-coverage": "^2.0.3",
|
||||
"codelyzer": "^4.0.1",
|
||||
"jasmine-core": "~2.8.0",
|
||||
"jasmine-reporters": "^2.2.1",
|
||||
"jasmine-spec-reporter": "~4.2.1",
|
||||
"jasmine2-protractor-utils": "^1.3.0",
|
||||
"jasminewd2": "^2.2.0",
|
||||
"karma": "~2.0.0",
|
||||
"karma-chrome-launcher": "~2.2.0",
|
||||
"karma-cli": "~1.0.1",
|
||||
"karma-coverage-istanbul-reporter": "^1.2.1",
|
||||
"karma-jasmine": "~1.1.0",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"protractor": "~5.1.2",
|
||||
"node-rest-client": "^3.1.0",
|
||||
"protractor": "5.3.1",
|
||||
"rimraf": "2.6.2",
|
||||
"selenium-webdriver": "4.0.0-alpha.1",
|
||||
"ts-node": "~4.1.0",
|
||||
"tslint": "~5.9.1",
|
||||
"typescript": "~2.5.3"
|
||||
"typescript": "~2.7.2",
|
||||
"wait-on": "2.1.0"
|
||||
}
|
||||
}
|
||||
|
12
protractor.conf.js
Normal file → Executable file
12
protractor.conf.js
Normal file → Executable file
@ -11,9 +11,15 @@ const width = 1366;
|
||||
const height = 768;
|
||||
|
||||
exports.config = {
|
||||
allScriptsTimeout: 30000,
|
||||
allScriptsTimeout: 60000,
|
||||
|
||||
specs: [
|
||||
'./e2e/suites/authentication/*.test.ts',
|
||||
'./e2e/suites/list-views/*.test.ts',
|
||||
'./e2e/suites/application/page-titles.test.ts',
|
||||
'./e2e/suites/navigation/*.test.ts',
|
||||
'./e2e/suites/pagination/*.test.ts',
|
||||
'./e2e/suites/actions/*.test.ts'
|
||||
],
|
||||
|
||||
capabilities: {
|
||||
@ -28,12 +34,12 @@ exports.config = {
|
||||
|
||||
directConnect: true,
|
||||
|
||||
baseUrl: 'http://localhost:4200',
|
||||
baseUrl: 'http://localhost:3000',
|
||||
|
||||
framework: 'jasmine2',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 50000,
|
||||
defaultTimeoutInterval: 90000,
|
||||
print: function() {}
|
||||
},
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user