[ACS-6563] cleanup protractor configs and e2e for extensibility (#3591)

* cleanup extensibility configs and protractor e2e

* cleanup

* cleanup
This commit is contained in:
Denys Vuika
2024-01-10 09:09:11 -05:00
committed by GitHub
parent 58070d9666
commit 09aba59b06
45 changed files with 36 additions and 12837 deletions

View File

@@ -26,7 +26,6 @@ import { Component } from '../component';
export class Breadcrumb extends Component {
items = this.allByCss('.adf-breadcrumb-item');
currentItem = this.byCss('.adf-breadcrumb-item-current');
constructor(ancestor?: string) {
super('adf-breadcrumb', ancestor);

View File

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

View File

@@ -23,7 +23,7 @@
*/
import { ElementFinder, browser, by, ElementArrayFinder, ProtractorBrowser } from 'protractor';
import { waitForPresence } from '../utilities/utils';
import { waitForPresence } from '../utilities';
export abstract class Component {
component: ElementFinder;

View File

@@ -22,12 +22,11 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { browser, by, ElementArrayFinder, ElementFinder, protractor } from 'protractor';
import { browser, by, ElementArrayFinder, ElementFinder } from 'protractor';
import { BrowserVisibility, Logger } from '@alfresco/adf-testing';
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
import { Component } from '../component';
import { Menu } from '../menu/menu';
import { Utils, waitForPresence } from '../../utilities/utils';
import { Utils, waitForPresence } from '../../utilities';
export class DataTable extends Component {
private static selectors = {
@@ -65,15 +64,6 @@ export class DataTable extends Component {
return waitForPresence(this.body, '--- timeout waitForBody ---');
}
async waitForEmptyState(): Promise<void> {
return waitForPresence(this.emptyList);
}
async waitForFirstElementToChange(name: string): Promise<void> {
const firstElementWithName = this.byCss(`[data-automation-id='datatable-row-0'][aria-label='${name}']`);
await BrowserVisibility.waitUntilElementIsNotVisible(firstElementWithName);
}
private getColumnHeaders(): ElementArrayFinder {
const locator = by.css(DataTable.selectors.columnHeader);
return this.head.all(locator);
@@ -83,46 +73,6 @@ export class DataTable extends Component {
return this.getColumnHeaders().getText();
}
getColumnHeaderByLabel(label: string): ElementFinder {
const locator = by.cssContainingText(DataTable.selectors.columnHeader, label);
return this.head.element(locator);
}
async sortBy(label: string, order: 'asc' | 'desc'): Promise<void> {
const sortColumn = await this.getSortedColumnHeaderText();
let sortOrder = await this.getSortingOrder();
if (sortColumn !== label) {
await browser.actions().mouseMove(this.getColumnHeaderByLabel(label)).perform();
await this.getColumnHeaderByLabel(label).click();
sortOrder = await this.getSortingOrder();
}
if (sortOrder !== order) {
await this.getColumnHeaderByLabel(label).click();
}
}
private getSortedColumnHeader(): ElementFinder {
const locator = by.css(DataTable.selectors.sortedColumnHeader);
return this.head.element(locator);
}
async getSortedColumnHeaderText(): Promise<string> {
return this.getSortedColumnHeader().getText();
}
async getSortingOrder(): Promise<string> {
const str = await this.getSortedColumnHeader().element(by.xpath('../..')).getAttribute('class');
if (str.includes('asc')) {
return 'asc';
}
if (str.includes('desc')) {
return 'desc';
}
return 'none';
}
private getRows(): ElementArrayFinder {
return this.body.all(by.css(DataTable.selectors.row));
}
@@ -157,18 +107,6 @@ export class DataTable extends Component {
return this.getRowCells(name, location).get(0);
}
private getRowNameCell(name: string, location: string = ''): ElementFinder {
return this.getRowCells(name, location).get(1);
}
private getRowNameCellSpan(name: string, location: string = ''): ElementFinder {
return this.getRowNameCell(name, location).$('span');
}
async getItemNameTooltip(name: string, location: string = ''): Promise<string> {
return this.getRowNameCellSpan(name, location).getAttribute('title');
}
async hasCheckMarkIcon(itemName: string, location: string = ''): Promise<boolean> {
Logger.info(`--- check if item already selected : ${itemName} ${location}`);
const row = this.getRowByName(itemName, location);
@@ -250,30 +188,10 @@ export class DataTable extends Component {
}
}
async rightClickOnItem(itemName: string): Promise<void> {
const item = this.getRowFirstCell(itemName);
await browser.actions().mouseMove(item).perform();
await browser.actions().click(protractor.Button.RIGHT).perform();
}
private getItemLocationEl(name: string): ElementFinder {
return this.getRowByName(name).element(by.css('.aca-location-link'));
}
async getItemLocation(name: string): Promise<string> {
return this.getItemLocationEl(name).getText();
}
async getItemLocationTooltip(name: string): Promise<string> {
const location = this.getItemLocationEl(name).$('a');
const condition = () => location.getAttribute('title').then((value) => value && value.length > 0);
await browser.actions().mouseMove(location).perform();
await browser.wait(condition, BROWSER_WAIT_TIMEOUT);
return location.getAttribute('title');
}
async clickItemLocation(name: string): Promise<void> {
await this.getItemLocationEl(name).click();
}
@@ -298,25 +216,6 @@ export class DataTable extends Component {
return '';
}
async getEmptyListText(): Promise<string> {
const isEmpty = await this.isEmpty();
if (isEmpty) {
return this.byCss('adf-custom-empty-content-template').getText();
}
return '';
}
async getCellsContainingName(name: string): Promise<string[]> {
const rows = this.getRows().all(by.cssContainingText(DataTable.selectors.cell, name));
return rows.map(async (cell) => {
return cell.getText();
});
}
async getLibraryRole(name: string): Promise<string> {
return this.getRowByName(name).element(by.css('adf-library-role-column')).getText();
}
async isItemPresent(name: string, location?: string): Promise<boolean> {
return this.getRowByName(name, location).isPresent();
}

View File

@@ -1,65 +0,0 @@
/*!
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser } from 'protractor';
import { Component } from '../component';
import { isPresentAndDisplayed, waitForStaleness } from '../../utilities/utils';
import { BrowserActions } from '@alfresco/adf-testing';
export class DateTimePicker extends Component {
calendar = this.byCss('.mat-datepicker-popup', browser);
dayPicker = this.byCss('mat-month-view');
nextMonthBtn = this.byCss('.mat-calendar-next-button');
rootElemLocator = by.css('.mat-datepicker-popup');
constructor(ancestor?: string) {
super('.mat-datepicker-popup', ancestor);
}
async waitForDateTimePickerToClose(): Promise<void> {
return waitForStaleness(this.calendar);
}
async isCalendarOpen(): Promise<boolean> {
const element = browser.element(this.rootElemLocator);
return isPresentAndDisplayed(element);
}
async pickDateTime(): Promise<void> {
const today = new Date();
const nextAvailableDay = new Date();
nextAvailableDay.setDate(today.getDate() + 2);
if (nextAvailableDay.getMonth() !== today.getMonth()) {
await BrowserActions.click(this.nextMonthBtn);
}
await this.selectDay(nextAvailableDay.getDate());
}
async selectDay(day: number): Promise<void> {
const firstActiveDay = '.mat-calendar-body-cell-content';
const firstActiveDayElem = this.dayPicker.element(by.cssContainingText(firstActiveDay, `${day}`));
await BrowserActions.click(firstActiveDayElem);
}
}

View File

@@ -23,14 +23,13 @@
*/
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndEnabled } from '../../utilities/utils';
import { GenericDialog } from './generic-dialog';
import { isPresentAndEnabled } from '../../utilities';
export class ConfirmDialog extends GenericDialog {
cancelButton = this.childElement(by.buttonText('Cancel'));
keepButton = this.childElement(by.buttonText('Keep'));
deleteButton = this.childElement(by.buttonText('Delete'));
removeButton = this.childElement(by.buttonText('Remove'));
constructor() {
super('adf-confirm-dialog');
@@ -40,10 +39,6 @@ export class ConfirmDialog extends GenericDialog {
return this.content.getText();
}
async isCancelEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.cancelButton);
}
async isKeepEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.keepButton);
}
@@ -51,8 +46,4 @@ export class ConfirmDialog extends GenericDialog {
async isDeleteEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.deleteButton);
}
async isRemoveEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.removeButton);
}
}

View File

@@ -22,9 +22,9 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser, protractor } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { waitForStaleness, waitForPresence } from '../../utilities/utils';
import { by, browser } from 'protractor';
import { GenericDialog } from './generic-dialog';
import { waitForStaleness, waitForPresence } from '../../utilities';
import { DataTable } from '../data-table/data-table';
import { BrowserActions } from '@alfresco/adf-testing';
@@ -68,10 +68,4 @@ export class ContentNodeSelectorDialog extends GenericDialog {
await BrowserActions.click(row);
await waitForPresence(browser.element(by.css('.adf-is-selected')));
}
async searchFor(text: string): Promise<void> {
await BrowserActions.clearWithBackSpace(this.searchInput);
await this.searchInput.sendKeys(text);
await this.searchInput.sendKeys(protractor.Key.ENTER);
}
}

View File

@@ -23,8 +23,8 @@
*/
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndDisplayed, isPresentAndEnabled, typeText } from '../../utilities/utils';
import { GenericDialog } from './generic-dialog';
import { isPresentAndDisplayed, isPresentAndEnabled, typeText } from '../../utilities';
import { BrowserActions, BrowserVisibility } from '@alfresco/adf-testing';
export class CreateOrEditFolderDialog extends GenericDialog {

View File

@@ -23,7 +23,7 @@
*/
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { GenericDialog } from './generic-dialog';
import { BrowserActions } from '@alfresco/adf-testing';
import { Menu } from '../menu/menu';

View File

@@ -23,72 +23,19 @@
*/
import { by } from 'protractor';
import { DateTimePicker } from '../../components/datetime-picker/datetime-picker';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndEnabled } from '../../utilities/utils';
import { BrowserActions } from '@alfresco/adf-testing';
import { GenericDialog } from './generic-dialog';
export class ShareDialog extends GenericDialog {
dateTimePicker = new DateTimePicker();
dialogTitle = this.childElement(by.css(`[data-automation-id='adf-share-dialog-title']`));
infoText = this.childElement(by.css('.adf-share-link__info'));
labels = this.rootElem.all(by.css('.adf-share-link__label'));
shareToggle = this.childElement(by.css(`[data-automation-id='adf-share-toggle']`));
url = this.childElement(by.css(`[data-automation-id='adf-share-link']`));
urlAction = this.childElement(by.css('.adf-input-action'));
expireToggle = this.childElement(by.css(`[data-automation-id='adf-expire-toggle']`));
expireInput = this.childElement(by.css('input[formcontrolname="time"]'));
datetimePickerButton = this.childElement(by.css('.mat-datepicker-toggle'));
closeButton = this.childElement(by.css(`[data-automation-id='adf-share-dialog-close']`));
constructor() {
super('.adf-share-dialog');
}
async getDialogTitle(): Promise<string> {
return this.dialogTitle.getText();
}
async getInfoText(): Promise<string> {
return this.infoText.getText();
}
async getLinkUrl(): Promise<string> {
return BrowserActions.getInputValue(this.url);
}
async isUrlReadOnly(): Promise<boolean> {
const urlAttr = await this.url.getAttribute('readonly');
return urlAttr === 'true';
}
async isCloseEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.closeButton);
}
async clickClose(): Promise<void> {
await this.closeButton.click();
await this.waitForDialogToClose();
}
async isShareToggleChecked(): Promise<boolean> {
const toggleClass = await this.shareToggle.getAttribute('class');
return toggleClass.includes('checked');
}
async isShareToggleDisabled(): Promise<boolean> {
const toggleClass = await this.shareToggle.getAttribute('class');
return toggleClass.includes('mat-disabled');
}
async isExpireToggleEnabled(): Promise<boolean> {
const toggleClass = await this.expireToggle.getAttribute('class');
return toggleClass.includes('checked');
}
async getExpireDate(): Promise<string> {
return BrowserActions.getInputValue(this.expireInput);
}
}

View File

@@ -23,8 +23,8 @@
*/
import { by } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
import { isPresentAndEnabled, typeText } from '../../utilities/utils';
import { GenericDialog } from './generic-dialog';
import { isPresentAndEnabled, typeText } from '../../utilities';
export class UploadNewVersionDialog extends GenericDialog {
cancelButton = this.childElement(by.cssContainingText('.mat-button-wrapper', 'Cancel'));

View File

@@ -25,9 +25,9 @@
import { by, browser } from 'protractor';
import { Component } from '../component';
import { Menu } from '../menu/menu';
import { Toolbar } from './../toolbar/toolbar';
import { SearchInput } from '../search/search-input';
import { waitElement } from '../../utilities/utils';
import { Toolbar } from '../toolbar/toolbar';
import { SearchInput } from '../search';
import { waitElement } from '../../utilities';
import { BrowserActions } from '@alfresco/adf-testing';
export class Header extends Component {
@@ -47,11 +47,6 @@ export class Header extends Component {
await this.menu.waitForMenuToOpen();
}
async closeMoreMenu(): Promise<void> {
await BrowserActions.click(this.userMenuButton);
await this.menu.waitForMenuToClose();
}
async isSidenavExpanded(): Promise<boolean> {
return browser.isElementPresent(by.css(`[data-automation-id='expanded']`));
}

View File

@@ -23,15 +23,12 @@
*/
export * from './breadcrumb/breadcrumb';
export * from './breadcrumb/dropdown-breadcrumb';
export * from './data-table/data-table';
export * from './datetime-picker/datetime-picker';
export * from './dialog';
export * from './header/header';
export * from './info-drawer';
export * from './login/login';
export * from './menu/menu';
export * from './metadata-card/metadata-card';
export * from './pagination/pagination';
export * from './search';
export * from './sidenav/sidenav';

View File

@@ -23,6 +23,5 @@
*/
export * from './info-drawer-comments-tab';
export * from './info-drawer-metadata-content';
export * from './info-drawer-metadata-library';
export * from './info-drawer';

View File

@@ -25,7 +25,7 @@
import { by, browser, until } from 'protractor';
import { Component } from '../component';
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
import { typeText } from '../../utilities/utils';
import { typeText } from '../../utilities';
import { BrowserActions, BrowserVisibility } from '@alfresco/adf-testing';
export class CommentsTab extends Component {

View File

@@ -1,53 +0,0 @@
/*!
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
* 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 { Component } from '../component';
import { isPresentAndEnabled } from '../../utilities/utils';
export class ContentMetadata extends Component {
expandedPanel = this.byCss('.mat-expansion-panel.mat-expanded');
lessInfoButton = this.byCssText(`[data-automation-id='meta-data-card-toggle-expand']`, 'Less information');
moreInfoButton = this.byCssText(`[data-automation-id='meta-data-card-toggle-expand']`, 'More information');
constructor(ancestor?: string) {
super('adf-content-metadata-card', ancestor);
}
async isPropertiesListExpanded(): Promise<boolean> {
return browser.isElementPresent(this.expandedPanel);
}
async isLessInfoButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.lessInfoButton);
}
async isMoreInfoButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.moreInfoButton);
}
async isMoreInfoButtonDisplayed(): Promise<boolean> {
return browser.isElementPresent(this.moreInfoButton);
}
}

View File

@@ -25,7 +25,7 @@
import { by, browser } from 'protractor';
import { BrowserActions, Logger } from '@alfresco/adf-testing';
import { Component } from '../component';
import { waitForPresence, waitForStaleness, typeText } from '../../utilities/utils';
import { waitForPresence, waitForStaleness, typeText } from '../../utilities';
export class LibraryMetadata extends Component {
visibilityDropDown = this.component.element(by.css('.mat-select'));

View File

@@ -22,24 +22,20 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, browser } from 'protractor';
import { browser } from 'protractor';
import { BrowserActions, BrowserVisibility, Logger, TestElement } from '@alfresco/adf-testing';
import { Component } from '../component';
import { CommentsTab } from './info-drawer-comments-tab';
import { LibraryMetadata } from './info-drawer-metadata-library';
import { ContentMetadata } from './info-drawer-metadata-content';
import { waitForPresence } from '../../utilities/utils';
import { waitForPresence } from '../../utilities';
import { Toolbar } from '../toolbar/toolbar';
export class InfoDrawer extends Component {
commentsTab = new CommentsTab('adf-info-drawer');
aboutTab = new LibraryMetadata('adf-info-drawer');
propertiesTab = new ContentMetadata('adf-info-drawer');
header = this.byCss('.adf-info-drawer-layout-header');
headerTitle = this.byCss('.adf-info-drawer-layout-header-title > div');
tabLabelsList = this.allByCss('.mat-tab-label-content');
tabActiveLabel = this.byCss('.mat-tab-label-active');
tabActiveContent = this.byCss('.mat-tab-body-active .mat-tab-body-content adf-dynamic-tab');
expandDetailsButton = TestElement.byCss(`button[title='Expand panel']`);
selectedTab = TestElement.byCss(`.mat-tab-list [aria-selected='true'] div`);
expandedDetailsPermissionsTab = TestElement.byText('.aca-details-container .mat-tab-label-content', 'Permissions');
@@ -58,10 +54,6 @@ export class InfoDrawer extends Component {
return browser.isElementPresent(this.header);
}
async isEmpty() {
return !(await browser.isElementPresent(by.css('.adf-info-drawer-tabs')));
}
getTabByTitle(title: string) {
return this.byCssText('.mat-tab-label-content', title);
}
@@ -70,10 +62,6 @@ export class InfoDrawer extends Component {
return this.allByCss('.mat-tab-label-content').count();
}
async isTabPresent(title: string) {
return this.getTabByTitle(title).isPresent();
}
async isTabDisplayed(title: string): Promise<boolean> {
if (await browser.isElementPresent(this.getTabByTitle(title))) {
return this.getTabByTitle(title).isDisplayed();
@@ -82,23 +70,10 @@ export class InfoDrawer extends Component {
return false;
}
async getTabTitle(index: number): Promise<string> {
const attributeValue: string = await browser.executeScript(`return arguments[0].innerText`, this.tabLabelsList.get(index - 1));
return attributeValue || '';
}
async getActiveTabTitle(): Promise<string> {
return this.tabActiveLabel.getText();
}
async clickTab(title: string) {
await BrowserActions.click(this.getTabByTitle(title));
}
async getComponentIdOfTab(): Promise<string> {
return this.tabActiveContent.getAttribute('data-automation-id');
}
async getHeaderTitle(): Promise<string> {
return this.headerTitle.getText();
}

View File

@@ -23,7 +23,7 @@
*/
import { Component } from '../component';
import { typeText } from '../../utilities/utils';
import { typeText } from '../../utilities';
export class LoginComponent extends Component {
usernameInput = this.byCss('input#username');

View File

@@ -25,22 +25,15 @@
import { ElementFinder, by, browser } from 'protractor';
import { Logger, BrowserVisibility, BrowserActions } from '@alfresco/adf-testing';
import { Component } from '../component';
import { Utils, waitForPresence, waitForStaleness } from '../../utilities/utils';
import { waitForPresence, waitForStaleness } from '../../utilities';
export class Menu extends Component {
items = this.allByCss('.mat-menu-item');
uploadFilesInput = this.byId('app-upload-files', browser);
submenus = browser.element.all(by.css('app-context-menu-item .mat-menu-item'));
createFolderAction = this.byId('app.create.folder');
cancelEditingAction = this.byCss(`.mat-menu-item[title='Cancel Editing']`);
copyAction = this.byTitleAttr('Copy');
editFolderAction = this.byCss(`.mat-menu-item[id$='editFolder']`);
editOfflineAction = this.byCss(`.mat-menu-item[title='Edit Offline']`);
managePermissionsAction = this.byCssText('.mat-menu-item', 'Permissions');
shareAction = this.byCssText('.mat-menu-item', 'Share');
shareEditAction = this.byCssText('.mat-menu-item', 'Shared Link Settings');
constructor(ancestor?: string) {
super('.mat-menu-panel', ancestor);
@@ -55,11 +48,6 @@ export class Menu extends Component {
await waitForStaleness(browser.element(by.css('.cdk-overlay-container .mat-menu-panel')));
}
async closeMenu(): Promise<void> {
await Utils.pressEscape();
await this.waitForMenuToClose();
}
getNthItem(nth: number): ElementFinder {
return this.items.get(nth - 1);
}
@@ -68,22 +56,10 @@ export class Menu extends Component {
return this.byCssText('.mat-menu-item', menuItem);
}
getItemById(id: string): ElementFinder {
return this.byId(id);
}
async getItemIconText(menuItem: string): Promise<string> {
return this.getItemByLabel(menuItem).element(by.css('.mat-icon')).getText();
}
async getItemIdAttribute(menuItem: string): Promise<string> {
return this.getItemByLabel(menuItem).getAttribute('id');
}
async getItemsCount(): Promise<number> {
return this.items.count();
}
async clickNthItem(nth: number): Promise<void> {
try {
const elem = this.getNthItem(nth);
@@ -104,49 +80,4 @@ export class Menu extends Component {
Logger.error(`___click menu item catch : failed to click on ${menuItem}___`, e);
}
}
async mouseOverMenuItem(menuItem: string): Promise<void> {
try {
const elem = this.getItemByLabel(menuItem);
await BrowserVisibility.waitUntilElementIsClickable(elem);
await browser.actions().mouseMove(elem).perform();
await browser.sleep(500);
} catch (error) {
Logger.error(`----- mouse over error : failed to mouse over ${menuItem} : `, error);
}
}
async hasSubMenu(menuItem: string): Promise<boolean> {
try {
const elem = this.getItemByLabel(menuItem);
await BrowserVisibility.waitUntilElementIsClickable(elem);
const elemClass = await elem.getAttribute('class');
return elemClass.includes('mat-menu-item-submenu-trigger');
} catch (error) {
Logger.error('---- has submenu error: ', error);
return false;
}
}
async isMenuItemPresent(title: string): Promise<boolean> {
return browser.element(by.cssContainingText('.mat-menu-item', title)).isPresent();
}
async isSubMenuItemPresent(title: string): Promise<boolean> {
return browser.element(by.cssContainingText('app-context-menu-item .mat-menu-item', title)).isPresent();
}
async getSubmenuItemsCount(): Promise<number> {
return this.submenus.count();
}
async isMenuItemDisabled(title: string): Promise<string | null> {
try {
const item = this.getItemByLabel(title);
return await item.getAttribute('disabled');
} catch (error) {
Logger.error('----- isMenuItemDisabled catch: ', error);
return null;
}
}
}

View File

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

View File

@@ -22,8 +22,6 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { browser } from 'protractor';
import { BrowserActions, Logger } from '@alfresco/adf-testing';
import { Menu } from '../menu/menu';
import { Component } from '../component';
@@ -34,8 +32,6 @@ export class Pagination extends Component {
totalPages = this.byCss('.adf-pagination__total-pages');
previousButton = this.byCss('.adf-pagination__previous-button');
nextButton = this.byCss('.adf-pagination__next-button');
maxItemsButton = this.byCss('.adf-pagination__max-items + button[mat-icon-button]');
pagesButton = this.byCss('.adf-pagination__current-page + button[mat-icon-button]');
menu: Menu = new Menu();
@@ -43,64 +39,6 @@ export class Pagination extends Component {
super('adf-pagination', ancestor);
}
async openMaxItemsMenu() {
try {
await BrowserActions.click(this.maxItemsButton);
await this.menu.waitForMenuToOpen();
} catch (error) {
Logger.error('____ open max items catch ___', error);
}
}
async openCurrentPageMenu() {
try {
await BrowserActions.click(this.pagesButton);
await this.menu.waitForMenuToOpen();
} catch (error) {
Logger.error('____ open current page menu ___', error);
}
}
async resetToDefaultPageSize() {
try {
await this.openMaxItemsMenu();
await this.menu.clickNthItem(1);
await this.menu.waitForMenuToClose();
} catch (error) {
Logger.error('___ reset to default page size catch ___', error);
}
}
async resetToDefaultPageNumber() {
try {
await this.openCurrentPageMenu();
await this.menu.clickNthItem(1);
await this.menu.waitForMenuToClose();
} catch (error) {
Logger.error('____ reset to default page number catch ___', error);
}
}
async clickNext() {
await BrowserActions.click(this.nextButton);
}
async clickPrevious() {
await BrowserActions.click(this.previousButton);
}
async isNextEnabled() {
return this.nextButton.isEnabled();
}
async isPreviousEnabled() {
return this.previousButton.isEnabled();
}
async isPagesButtonPresent() {
return browser.isElementPresent(this.pagesButton);
}
async isRangePresent() {
return this.range.isPresent();
}
@@ -125,19 +63,7 @@ export class Pagination extends Component {
return this.nextButton.isPresent();
}
async getCurrentPage() {
return this.currentPage.getText();
}
async getRange() {
return this.range.getText();
}
async getMaxItems() {
return this.maxItems.getText();
}
async getTotalPages() {
return this.totalPages.getText();
}
}

View File

@@ -22,14 +22,13 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, element, browser, By } from 'protractor';
import { ElementFinder, by, browser } from 'protractor';
import { Logger, BrowserActions } from '@alfresco/adf-testing';
import { Menu } from '../menu/menu';
import { Component } from '../component';
export class Sidenav extends Component {
links = this.component.all(by.css('.item'));
newButton = element(By.css('[id="app.toolbar.create"]'));
personalFiles = this.byCss(`[data-automation-id='app.navbar.personalFiles']`);
fileLibraries = this.byCss(`[data-automation-id='app.navbar.libraries.menu']`);
myLibraries = this.byCss(`[data-automation-id='app.navbar.libraries.files']`, browser);
@@ -45,16 +44,6 @@ export class Sidenav extends Component {
super('app-sidenav', ancestor);
}
async openNewMenu(): Promise<void> {
await BrowserActions.click(this.newButton);
await this.menu.waitForMenuToOpen();
}
async openCreateFolderDialog(): Promise<void> {
await this.openNewMenu();
await BrowserActions.click(this.menu.createFolderAction);
}
async isActive(name: string): Promise<boolean> {
const cssClass = await this.getLinkLabel(name).getAttribute('class');
return cssClass.includes('action-button--active');

View File

@@ -22,11 +22,11 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, browser, By, element } from 'protractor';
import { by, browser, By, element } from 'protractor';
import { BrowserActions } from '@alfresco/adf-testing';
import { Menu } from '../menu/menu';
import { Component } from '../component';
import { Utils } from '../../utilities/utils';
import { Utils } from '../../utilities';
export class Toolbar extends Component {
menu = new Menu();
@@ -34,10 +34,8 @@ export class Toolbar extends Component {
buttons = this.allByCss('button');
createButton = element(By.css('[id="app.toolbar.create"]'));
uploadButton = element(By.css('[id="app.toolbar.upload"]'));
shareButton = element(By.css('button[data-automation-id="share-action-button"]'));
downloadButton = element(By.css(`.mat-icon-button[title='Download']`));
viewDetailsButton = element(By.css(`button[title='View Details']`));
printButton = element(By.css(`button[title='Print']`));
permanentlyDeleteButton = element(By.css(`button[title='Permanently Delete']`));
restoreButton = element(By.css(`button[title='Restore']`));
searchIconButton = element(By.css(`button[title='Search']`));
@@ -52,27 +50,10 @@ export class Toolbar extends Component {
return element.isPresent();
}
getButtonByTitleAttribute(title: string) {
return this.byCss(`button[title="${title}"]`);
}
getButtonById(id: string) {
return this.component.element(by.id(id));
}
async clickSearchIconButton() {
await BrowserActions.click(this.searchIconButton);
}
async openViewerMoreMenu(): Promise<void> {
const btnMoreActions = element(By.css('button[id="app.viewer.toolbar.more"]'));
await btnMoreActions.isPresent();
await BrowserActions.click(btnMoreActions);
await this.menu.waitForMenuToOpen();
await browser.sleep(500);
}
async openMoreMenu(): Promise<void> {
const btnMoreActions = element(By.css('button[id="app.toolbar.more"]'));
await btnMoreActions.isPresent();
@@ -86,18 +67,6 @@ export class Toolbar extends Component {
await Utils.pressEscape();
}
async getButtonTooltip(button: ElementFinder): Promise<string> {
return button.getAttribute('title');
}
async clickButton(title: string): Promise<void> {
await BrowserActions.click(this.getButtonByTitleAttribute(title));
}
async isPrintPresent() {
return browser.isElementPresent(this.printButton);
}
async openUploadMenu(): Promise<void> {
await BrowserActions.click(this.uploadButton);
await this.menu.waitForMenuToOpen();
@@ -128,11 +97,6 @@ export class Toolbar extends Component {
await this.menu.clickMenuItem('Manage Versions');
}
async clickMoreActionsMove(): Promise<void> {
await this.openMoreMenu();
await this.menu.clickMenuItem('Move');
}
async clickMoreActionsCopy(): Promise<void> {
await this.openMoreMenu();
await this.menu.copyAction.click();

View File

@@ -22,11 +22,10 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { browser, by, element, ElementFinder } from 'protractor';
import { BrowserActions, Logger } from '@alfresco/adf-testing';
import { browser } from 'protractor';
import { Component } from '../component';
import { Toolbar } from '../toolbar/toolbar';
import { waitForPresence } from '../../utilities/utils';
import { waitForPresence } from '../../utilities';
export class Viewer extends Component {
root = browser.$('adf-viewer');
@@ -34,8 +33,6 @@ export class Viewer extends Component {
viewerContainer = this.byCss('.adf-viewer-render-content-container');
closeButton = this.byCss('.adf-viewer-close-button');
fileTitle = this.byCss('.adf-viewer__file-title');
viewerExtensionContent = this.byCss('adf-preview-extension');
txtViewerContent = this.byCss('.adf-txt-viewer-content');
toolbar = new Toolbar('adf-viewer');
@@ -48,7 +45,7 @@ export class Viewer extends Component {
await waitForPresence(this.viewerContainer);
await waitForPresence(this.viewerLayout);
} catch (error) {
Logger.error('\n-----> catch waitForViewerToOpen <-----\n', error);
console.error('\n-----> catch waitForViewerToOpen <-----\n', error);
}
}
@@ -57,16 +54,7 @@ export class Viewer extends Component {
const fileName = this.byCssText('.adf-viewer__display-name', `${fileTitle}`);
await waitForPresence(fileName);
} catch (error) {
Logger.error('\n-----> catch waitForFileTitle <-----\n', error);
}
}
async waitForTxtViewerToLoad(): Promise<void> {
try {
await this.waitForViewerToOpen();
await waitForPresence(this.txtViewerContent);
} catch (error) {
Logger.error('\n-----> catch waitForTxtViewerToLoad <-----\n', error);
console.error('\n-----> catch waitForFileTitle <-----\n', error);
}
}
@@ -74,36 +62,7 @@ export class Viewer extends Component {
return browser.isElementPresent(this.viewerLayout);
}
async isViewerToolbarDisplayed() {
return browser.isElementPresent(this.toolbar.component);
}
async isCloseButtonDisplayed() {
return browser.isElementPresent(this.closeButton);
}
async isFileTitleDisplayed() {
return browser.isElementPresent(this.fileTitle);
}
async getFileTitle(): Promise<string> {
return this.fileTitle.getText();
}
async isCustomContentPresent() {
return browser.isElementPresent(this.viewerExtensionContent);
}
async getComponentIdOfView(): Promise<string> {
if (await this.isCustomContentPresent()) {
return this.viewerExtensionContent.getAttribute('data-automation-id');
}
return '';
}
async clickCloseButton(): Promise<void> {
const closeButton: ElementFinder = element(by.css('button.adf-viewer-close-button'));
await BrowserActions.click(closeButton);
}
}

View File

@@ -94,13 +94,3 @@ export const FILES = {
},
jpgFile: 'file-jpg.jpg'
};
export const EXTENSIBILITY_CONFIGS = {
INFO_DRAWER: 'info-drawer-ext.json',
INFO_DRAWER_EMPTY: 'info-drawer-no-tabs-ext.json',
VIEWER: 'viewer-ext.json',
HEADER: 'header-ext.json',
METADATA_PRESETS: 'metadata-ext.json',
DOCUMENT_LIST_PRESETS: 'document-presets-ext.json',
CONTEXT_SUBMENUS: 'context-submenus-ext.json'
};

View File

@@ -22,8 +22,8 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { Header, DataTable, Pagination, Toolbar, Breadcrumb, Sidenav, PageLayoutHeader } from '../components/components';
import { SIDEBAR_LABELS } from './../configs';
import { Header, DataTable, Pagination, Toolbar, Breadcrumb, Sidenav, PageLayoutHeader } from '../components';
import { SIDEBAR_LABELS } from '../configs';
import { Page } from './page';
export class BrowsingPage extends Page {
@@ -48,11 +48,6 @@ export class BrowsingPage extends Page {
await this.sidenav.clickLink(SIDEBAR_LABELS.FAVORITE_LIBRARIES);
}
async goToFavoriteLibrariesAndWait(): Promise<void> {
await this.goToFavoriteLibraries();
await this.dataTable.waitForHeader();
}
async goToMyLibraries(): Promise<void> {
await this.sidenav.clickLink(SIDEBAR_LABELS.MY_LIBRARIES);
}

View File

@@ -23,10 +23,10 @@
*/
import { browser } from 'protractor';
import { LoginComponent } from '../components/components';
import { LoginComponent } from '../components';
import { Page } from './page';
import { APP_ROUTES } from '../configs';
import { waitForPresence } from '../utilities/utils';
import { waitForPresence } from '../utilities';
import { BrowserActions, Logger } from '@alfresco/adf-testing';
export class LoginPage extends Page {

View File

@@ -36,8 +36,6 @@ export abstract class Page {
overlay = this.byCss('.cdk-overlay-container');
snackBar = this.byCss(`[data-automation-id='adf-snackbar-message-content-action-button']`);
dialogContainer = this.byCss('.mat-dialog-container');
genericError = this.byCss('aca-generic-error');
genericErrorTitle = this.byCss('.generic-error__title');
uploadFilesDialog = new UploadFilesDialog();

View File

@@ -23,8 +23,7 @@
*/
import { BrowsingPage } from './browsing-page';
import { SearchSortingPicker } from '../components/search/search-sorting-picker';
import { SearchFilters } from '../components/search/search-filters';
import { SearchSortingPicker, SearchFilters } from '../components';
export class SearchResultsPage extends BrowsingPage {
root = this.byCss('aca-search-results');

View File

@@ -86,13 +86,6 @@ export class Utils {
return crypto.getRandomValues(new Uint32Array(1))[0].toString(36).substring(0, 5).toLowerCase();
}
static async setSessionStorageFromConfig(configFileName: string): Promise<void> {
const configFile = `${browser.params.e2eRootPath}/resources/extensibility-configs/${configFileName}`;
const fileContent = JSON.stringify(fs.readFileSync(configFile, { encoding: 'utf8' }));
await browser.executeScript(`window.sessionStorage.setItem('app.extension.config', ${fileContent});`);
}
static retryCall(fn: () => Promise<any>, retry: number = 30, delay: number = 1500): Promise<any> {
const pause = (duration: number) => new Promise((res) => setTimeout(res, duration));
@@ -184,10 +177,6 @@ export class Utils {
await browser.actions().sendKeys(protractor.Key.NULL).perform();
}
static formatDate(date: string): string {
return new Date(date).toLocaleDateString('en-US');
}
static async uploadFileNewVersion(fileFromOS: string): Promise<void> {
const el = browser.element(by.id('app-upload-file-version'));
await el.sendKeys(`${browser.params.e2eRootPath}/resources/test-files/${fileFromOS}`);