playwright test

Signed-off-by: Eugenio Romano <eugenio.romano@alfresco.com>
This commit is contained in:
Eugenio Romano
2022-01-27 11:13:06 +01:00
parent 8a9a9a6fdc
commit 680a965488
46 changed files with 4862 additions and 4787 deletions

2
.gitignore vendored
View File

@@ -30,3 +30,5 @@ out-tsc
e2e-result-*
licenses.txt
.DS_Store
test-results/
playwright-report/

View File

@@ -0,0 +1,162 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
createApiService,
LocalStorageUtil,
LoginPage,
StringUtil,
UploadActions,
UserModel,
UsersActions
} from '@alfresco/adf-testing';
import { FolderModel } from '../models/ACS/folder.model';
import { ContentServicesPage } from '../core/pages/content-services.page';
import { InfinitePaginationPage } from './pages/infinite-pagination.page';
import { NavigationBarPage } from '../core/pages/navigation-bar.page';
import { test, expect } from '@playwright/test';
const testConfig = require('../../e2e/test.config');
test.describe('Enable infinite scrolling', () => {
const apiService = createApiService(testConfig.appConfig, testConfig.users);
const usersActions = new UsersActions(apiService);
const acsUser = new UserModel();
const folderModel = new FolderModel({ 'name': 'folderOne' });
let fileNames = [];
const nrOfFiles = 30;
let deleteFileNames = [];
const nrOfDeletedFiles = 22;
let deleteUploaded;
const pageSize = 20;
let emptyFolderModel;
const files = {
base: 'newFile',
extension: '.txt'
};
test.beforeAll(async () => {
const uploadActions = new UploadActions(apiService);
await apiService.loginWithProfile('admin');
await usersActions.createUser(acsUser);
fileNames = StringUtil.generateFilesNames(1, nrOfFiles, files.base, files.extension);
deleteFileNames = StringUtil.generateFilesNames(1, nrOfDeletedFiles, files.base, files.extension);
await apiService.login(acsUser.username, acsUser.password);
const folderUploadedModel = await uploadActions.createFolder(folderModel.name, '-my-');
emptyFolderModel = await uploadActions.createFolder('emptyFolder', '-my-');
await uploadActions.createEmptyFiles(fileNames, folderUploadedModel.entry.id);
deleteUploaded = await uploadActions.createFolder('deleteFolder', '-my-');
await uploadActions.createEmptyFiles(deleteFileNames, deleteUploaded.entry.id);
});
test.beforeEach(async ({ page }) => {
const loginPage = new LoginPage(page);
const navigationBarPage = new NavigationBarPage(page);
await loginPage.login(acsUser.username, acsUser.password);
await navigationBarPage.navigateToContentServices();
const contentServicesPage = new ContentServicesPage(page);
await contentServicesPage.contentList.dataTablePage().waitTillContentLoaded();
});
test('[C260484] Should be possible to enable infinite scrolling', async ({ page }) => {
const contentServicesPage = new ContentServicesPage(page);
const infinitePaginationPage = new InfinitePaginationPage(page);
await contentServicesPage.openFolder(folderModel.name);
await contentServicesPage.enableInfiniteScrolling();
await infinitePaginationPage.clickLoadMoreButton();
await contentServicesPage.contentList.dataTablePage().waitTillContentLoadedInfinitePagination();
for (let i = 0; i < nrOfFiles; i++) {
await contentServicesPage.checkContentIsDisplayed(fileNames[i]);
}
});
test('[C268165] Delete folder when infinite scrolling is enabled', async ({ page }) => {
const contentServicesPage = new ContentServicesPage(page);
const infinitePaginationPage = new InfinitePaginationPage(page);
await contentServicesPage.openFolder(deleteUploaded.entry.name);
await contentServicesPage.enableInfiniteScrolling();
await infinitePaginationPage.clickLoadMoreButton();
await contentServicesPage.contentList.dataTablePage().waitTillContentLoadedInfinitePagination();
for (let i = 0; i < nrOfDeletedFiles; i++) {
await contentServicesPage.checkContentIsDisplayed(deleteFileNames[i]);
}
await expect(await contentServicesPage.getDocumentList().dataTablePage().numberOfRows()).toEqual(nrOfDeletedFiles);
await contentServicesPage.deleteContent(deleteFileNames[nrOfDeletedFiles - 1]);
await contentServicesPage.checkContentIsNotDisplayed(deleteFileNames[nrOfDeletedFiles - 1]);
for (let i = 0; i < nrOfDeletedFiles - 1; i++) {
await contentServicesPage.checkContentIsDisplayed(deleteFileNames[i]);
}
});
test('[C299201] Should use default pagination settings for infinite pagination', async ({ page }) => {
const contentServicesPage = new ContentServicesPage(page);
const infinitePaginationPage = new InfinitePaginationPage(page);
await contentServicesPage.openFolder(folderModel.name);
await contentServicesPage.enableInfiniteScrolling();
await contentServicesPage.contentList.dataTablePage().waitTillContentLoadedInfinitePagination();
await expect(await contentServicesPage.numberOfResultsDisplayed()).toBe(pageSize);
await infinitePaginationPage.clickLoadMoreButton();
await contentServicesPage.contentList.dataTablePage().waitTillContentLoadedInfinitePagination();
await infinitePaginationPage.checkLoadMoreButtonIsNotDisplayed();
await expect(await contentServicesPage.numberOfResultsDisplayed()).toBe(nrOfFiles);
});
test('[C299202] Should not display load more button when all the files are already displayed', async ({ page }) => {
const contentServicesPage = new ContentServicesPage(page);
const infinitePaginationPage = new InfinitePaginationPage(page);
await LocalStorageUtil.setUserPreference('paginationSize', '30');
await contentServicesPage.openFolder(folderModel.name);
await contentServicesPage.enableInfiniteScrolling();
await expect(await contentServicesPage.numberOfResultsDisplayed()).toBe(nrOfFiles);
await infinitePaginationPage.checkLoadMoreButtonIsNotDisplayed();
});
test('[C299203] Should not display load more button when a folder is empty', async ({ page }) => {
const contentServicesPage = new ContentServicesPage(page);
const infinitePaginationPage = new InfinitePaginationPage(page);
await contentServicesPage.openFolder(emptyFolderModel.entry.name);
await infinitePaginationPage.checkLoadMoreButtonIsNotDisplayed();
});
});

View File

@@ -0,0 +1,253 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $, by, element } from 'protractor';
import {
BrowserVisibility,
BrowserActions,
CardTextItemPage,
DropdownPage,
CardBooleanItemPage
} from '@alfresco/adf-testing';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
export class CardViewComponentPage extends ADFPage {
addButton = element(by.className('adf-card-view__key-value-pairs__add-btn'));
nameCardTextItem = new CardTextItemPage('name');
booleanCardBooleanItem = new CardBooleanItemPage('boolean');
intField = $(`input[data-automation-id='card-textitem-editinput-int']`);
floatField = $(`input[data-automation-id='card-textitem-editinput-float']`);
valueInputField = element(by.xpath(`//*[contains(@id,'input') and @placeholder='Value']`));
nameInputField = element(by.xpath(`//*[contains(@id,'input') and @placeholder='Name']`));
consoleLog = element(by.className('app-console'));
deleteButton = element.all(by.className('adf-card-view__key-value-pairs__remove-btn'))[0];
resetButton = $(`#adf-reset-card-log`);
editableSwitch = $('#app-toggle-editable');
clearDateSwitch = $('#app-toggle-clear-date');
noneOptionSwitch = $('#app-toggle-none-option');
clickableField = $(`[data-automation-id="card-textitem-toggle-click"]`);
selectDropdown = new DropdownPage($('mat-select[data-automation-class="select-box"]'));
async clickOnAddButton(): Promise<void> {
await BrowserActions.click(this.addButton);
}
async checkNameTextLabelIsPresent(): Promise<void> {
await this.nameCardTextItem.checkLabelIsPresent();
}
async getNameTextFieldText(): Promise<string> {
return this.nameCardTextItem.getFieldValue();
}
async enterNameTextField(text: string): Promise<void> {
await this.nameCardTextItem.enterTextField(text);
}
async clickOnNameTextSaveIcon(): Promise<void> {
await this.nameCardTextItem.clickOnSaveButton();
}
async clickOnNameTextClearIcon(): Promise<void> {
await this.nameCardTextItem.clickOnClearButton();
}
async clickOnResetButton(): Promise<void> {
await BrowserActions.click(this.resetButton);
}
async clickOnIntField(): Promise<void> {
const toggleText = $('div[data-automation-id="card-textitem-toggle-int"]');
await BrowserActions.click(toggleText);
await BrowserVisibility.waitUntilElementIsVisible(this.intField);
}
async clickOnIntClearIcon(): Promise<void> {
const clearIcon = $('button[data-automation-id="card-textitem-reset-int"]');
await BrowserActions.click(clearIcon);
}
async clickOnIntSaveIcon(): Promise<void> {
const saveIcon = $('button[data-automation-id="card-textitem-update-int"]');
await BrowserActions.click(saveIcon);
}
async enterIntField(text): Promise<void> {
await BrowserActions.clearSendKeys(this.intField, text);
}
getIntFieldText(): Promise<string> {
const textField = $('span[data-automation-id="card-textitem-value-int"]');
return BrowserActions.getText(textField);
}
getErrorInt(): Promise<string> {
const errorElement = $('mat-error[data-automation-id="card-textitem-error-int"]');
return BrowserActions.getText(errorElement);
}
async clickOnFloatField(): Promise<void> {
const toggleText = $('div[data-automation-id="card-textitem-toggle-float"]');
await BrowserActions.click(toggleText);
await BrowserVisibility.waitUntilElementIsVisible(this.floatField);
}
async clickOnFloatClearIcon(): Promise<void> {
const clearIcon = $(`button[data-automation-id="card-textitem-reset-float"]`);
await BrowserActions.click(clearIcon);
}
async clickOnFloatSaveIcon(): Promise<void> {
const saveIcon = $(`button[data-automation-id="card-textitem-update-float"]`);
await BrowserActions.click(saveIcon);
}
async enterFloatField(text): Promise<void> {
await BrowserActions.clearSendKeys(this.floatField, text);
}
getFloatFieldText(): Promise<string> {
const textField = $('span[data-automation-id="card-textitem-value-float"]');
return BrowserActions.getText(textField);
}
getErrorFloat(): Promise<string> {
const errorElement = $('mat-error[data-automation-id="card-textitem-error-float"]');
return BrowserActions.getText(errorElement);
}
async setName(name: string): Promise<void> {
await BrowserActions.clearSendKeys(this.nameInputField, name);
}
async setValue(value): Promise<void> {
await BrowserActions.clearSendKeys(this.valueInputField, value);
}
async waitForOutput(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.consoleLog);
}
getOutputText(index: number): Promise<string> {
return BrowserActions.getText(this.consoleLog.this.page.$$('p').get(index));
}
async deletePairsValues(): Promise<void> {
await BrowserActions.click(this.deleteButton);
}
async clickSelectBox(): Promise<void> {
await this.selectDropdown.clickDropdown();
await this.selectDropdown.checkOptionsPanelIsDisplayed();
}
async checkboxClick(): Promise<void> {
await this.booleanCardBooleanItem.checkboxClick();
}
async checkBooleanLabelIsPresent(): Promise<void> {
await this.booleanCardBooleanItem.checkLabelIsPresent();
}
async selectValueFromComboBox(index): Promise<void> {
await this.selectDropdown.selectOptionFromIndex(index);
}
async disableEdit(): Promise<void> {
const check = await BrowserActions.getAttribute(this.editableSwitch, 'class');
if (check.indexOf('mat-checked') > -1) {
await BrowserActions.click(this.editableSwitch);
await expect(await BrowserActions.getAttribute(this.editableSwitch, 'class')).not.toContain('mat-checked');
}
}
async getDateValue(): Promise<string> {
const dateValue = $('span[data-automation-id="card-date-value-date"]');
return dateValue.getText();
}
async getDateTimeValue(): Promise<string> {
const dateTimeValue = $('span[data-automation-id="card-datetime-value-datetime"]');
return dateTimeValue.getText();
}
async clearDateField(): Promise<void> {
const clearDateButton = $('mat-icon[data-automation-id="datepicker-date-clear-date"]');
await BrowserActions.click(clearDateButton);
}
async clearDateTimeField(): Promise<void> {
const clearDateButton = $('mat-icon[data-automation-id="datepicker-date-clear-datetime"]');
await BrowserActions.click(clearDateButton);
}
async enableClearDate(): Promise<void> {
const switchClass = await BrowserActions.getAttribute(this.editableSwitch, 'class');
if (switchClass.indexOf('mat-checked') === -1) {
await this.clearDateSwitch.click();
const clearDateChecked = $('mat-slide-toggle[id="app-toggle-clear-date"][class*="mat-checked"]');
await BrowserVisibility.waitUntilElementIsVisible(clearDateChecked);
}
}
async enableNoneOption(): Promise<void> {
const switchClass = await BrowserActions.getAttribute(this.noneOptionSwitch, 'class');
if (switchClass.indexOf('mat-checked') === -1) {
await this.noneOptionSwitch.click();
const noneOptionChecked = $('mat-slide-toggle[id="app-toggle-none-option"][class*="mat-checked"]');
await BrowserVisibility.waitUntilElementIsVisible(noneOptionChecked);
}
}
async isErrorNotDisplayed(): Promise<boolean> {
const errorElement = $('mat-error[data-automation-id="card-textitem-error-int"]');
try {
await BrowserVisibility.waitUntilElementIsNotVisible(errorElement);
return true;
} catch {
return false;
}
}
async getClickableValue(): Promise<string> {
return this.clickableField.getText();
}
async updateClickableField(text: string): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.clickableField);
await BrowserActions.click(this.clickableField);
const inputField = $('input[data-automation-id="card-textitem-editinput-click"]');
await BrowserVisibility.waitUntilElementIsPresent(inputField);
await BrowserActions.clearSendKeys(inputField, text);
const save = $('[data-automation-id="card-textitem-update-click"]');
await BrowserVisibility.waitUntilElementIsVisible(save);
await BrowserActions.click(save);
}
async hasCardViewConsoleLog(text: string): Promise<string> {
const cardViewConsole = element(by.cssContainingText('.app-console', text));
await BrowserVisibility.waitUntilElementIsVisible(cardViewConsole);
return cardViewConsole.getText();
}
async clearIntField(): Promise<void> {
await this.intField.clear();
}
}

View File

@@ -0,0 +1,70 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BrowserActions, BrowserVisibility, TabsPage } from '@alfresco/adf-testing';
import { $, $$ } from 'protractor';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
export class CommentsPage extends ADFPage {
tabsPage = new TabsPage();
numberOfComments = $('#comment-header');
commentUserIcon = this.page.$$('#comment-user-icon');
commentUserName = this.page.$$('#comment-user');
commentMessage = this.page.$$('#comment-message');
commentTime = this.page.$$('#comment-time');
commentInput = $('#comment-input');
addCommentButton = $("[data-automation-id='comments-input-add']");
async getTotalNumberOfComments(text: string): Promise<void> {
await BrowserVisibility.waitUntilElementHasText(this.numberOfComments, text);
}
async checkUserIconIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.commentUserIcon[0]);
}
getUserName(position: number): Promise<string> {
return BrowserActions.getText(this.commentUserName.get(position));
}
getMessage(position: number): Promise<string> {
return BrowserActions.getText(this.commentMessage.get(position));
}
getTime(position: number): Promise<string> {
return BrowserActions.getText(this.commentTime.get(position));
}
async checkCommentInputIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.commentInput);
}
async addComment(comment: string): Promise<void> {
await BrowserActions.clearSendKeys(this.commentInput, comment);
await BrowserActions.click(this.addCommentButton);
}
async checkCommentsTabIsSelected(): Promise<void> {
await this.tabsPage.checkTabIsSelectedByTitle('Comments');
}
async checkCommentInputIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.commentInput);
}
}

View File

@@ -0,0 +1,694 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
DropActions,
BrowserActions,
BrowserVisibility,
DateUtil,
DocumentListPage,
TogglePage,
DropdownPage,
Logger
} from '@alfresco/adf-testing';
import { $$, browser, by, element, ElementFinder, protractor, $ } from 'protractor';
import { CreateLibraryDialogPage } from './dialog/create-library-dialog.page';
import { FolderDialogPage } from './dialog/folder-dialog.page';
import { NavigationBarPage } from './navigation-bar.page';
import * as path from 'path';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
export class ContentServicesPage extends ADFPage {
columns = {
name: 'Display name',
size: 'Size',
nodeId: 'Node id',
createdBy: 'Created by',
created: 'Created'
};
contentList = new DocumentListPage(this.page.$$('adf-upload-drag-area adf-document-list')[0]);
togglePage = new TogglePage();
createFolderDialog = new FolderDialogPage();
createLibraryDialog = new CreateLibraryDialogPage();
multipleFileUploadToggle = $('#adf-document-list-enable-drop-files');
uploadBorder = $('#document-list-container');
contentServices = $('.app-sidenav-link[data-automation-id="Content Services"]');
currentFolder = $('div[class*="adf-breadcrumb-item adf-active"] div');
createFolderButton = $('button[data-automation-id="create-new-folder"]');
editFolderButton = $('button[data-automation-id="edit-folder"]');
deleteNodesButton = $('button[data-automation-id="delete-toolbar-button"]');
createLibraryButton = $('button[data-automation-id="create-new-library"]');
activeBreadcrumb = $('div[class*="active"]');
uploadFileButton = $('.adf-upload-button-file-container button');
uploadFileButtonInput = $('input[data-automation-id="upload-single-file"]');
uploadMultipleFileButton = $('input[data-automation-id="upload-multiple-files"]');
uploadFolderButton = $('input[data-automation-id="uploadFolder"]');
errorSnackBar = $('simple-snack-bar[class*="mat-simple-snackbar"]');
emptyPagination = $('adf-pagination[class*="adf-pagination__empty"]');
dragAndDrop = this.page.$$('adf-upload-drag-area div')[0];
nameHeader = this.page.$$('div[data-automation-id="auto_id_name"] > span')[0];
sizeHeader = this.page.$$('div[data-automation-id="auto_id_content.sizeInBytes"] > span')[0];
createdByHeader = this.page.$$('div[data-automation-id="auto_id_createdByUser.displayName"] > span')[0];
createdHeader = this.page.$$('div[data-automation-id="auto_id_createdAt"] > span')[0];
recentFiles = $('.app-container-recent');
recentFilesExpanded = $('.app-container-recent mat-expansion-panel-header.mat-expanded');
recentFilesClosed = $('.app-container-recent mat-expansion-panel-header');
recentFileIcon = $('.app-container-recent mat-expansion-panel-header mat-icon');
emptyFolder = $('.adf-empty-folder-this-space-is-empty');
emptyFolderImage = $('.adf-empty-folder-image');
emptyRecent = $('.app-container-recent .app-empty-list__title');
gridViewButton = $('button[data-automation-id="document-list-grid-view"]');
cardViewContainer = $('div.app-document-list-container div.adf-datatable-card');
shareNodeButton = element(by.cssContainingText('mat-icon', ' share '));
nameColumnHeader = 'name';
createdByColumnHeader = 'createdByUser.displayName';
createdColumnHeader = 'createdAt';
deleteContentElement = $('button[data-automation-id*="DELETE"]');
metadataAction = $('button[data-automation-id*="METADATA"]');
versionManagerAction = $('button[data-automation-id*="VERSIONS"]');
moveContentElement = $('button[data-automation-id*="MOVE"]');
copyContentElement = $('button[data-automation-id*="COPY"]');
lockContentElement = $('button[data-automation-id="DOCUMENT_LIST.ACTIONS.LOCK"]');
downloadContent = $('button[data-automation-id*="DOWNLOAD"]');
downloadButton = $('button[title="Download"]');
favoriteButton = $('button[data-automation-id="favorite"]');
markedFavorite = element(by.cssContainingText('button[data-automation-id="favorite"] mat-icon', 'star'));
notMarkedFavorite = element(by.cssContainingText('button[data-automation-id="favorite"] mat-icon', 'star_border'));
multiSelectToggle = $('[data-automation-id="multiSelectToggle"]');
selectAllCheckbox = this.page.$$('.adf-checkbox-sr-only')[0];
selectionModeDropdown = $('.mat-select[aria-label="Selection Mode"]');
selectedNodesList = this.page.$$('.app-content-service-settings li');
siteListDropdown = new DropdownPage($(`mat-select[data-automation-id='site-my-files-option']`));
sortingDropdown = new DropdownPage($('mat-select[data-automation-id="grid-view-sorting"]'));
async pressContextMenuActionNamed(actionName): Promise<void> {
await BrowserActions.clickExecuteScript(`button[data-automation-id="context-${actionName}"]`);
}
async checkContextActionIsVisible(actionName) {
const actionButton = $(`button[data-automation-id="context-${actionName}"`);
await BrowserVisibility.waitUntilElementIsVisible(actionButton);
}
async isContextActionEnabled(actionName): Promise<boolean> {
const actionButton = $(`button[data-automation-id="context-${actionName}"`);
await BrowserVisibility.waitUntilElementIsVisible(actionButton);
return actionButton.isEnabled();
}
getDocumentList(): DocumentListPage {
return this.contentList;
}
async closeActionContext(): Promise<void> {
await BrowserActions.closeMenuAndDialogs();
}
async checkLockedIcon(content): Promise<void> {
return this.contentList.checkLockedIcon(content);
}
async checkUnlockedIcon(content): Promise<void> {
return this.contentList.checkUnlockedIcon(content);
}
async checkDeleteIsDisabled(content): Promise<void> {
await this.contentList.clickOnActionMenu(content);
const disabledDelete = $(`button[data-automation-id*='DELETE'][disabled='true']`);
await BrowserVisibility.waitUntilElementIsVisible(disabledDelete);
}
async deleteContent(content): Promise<void> {
await this.contentList.clickOnActionMenu(content);
await BrowserActions.click(this.deleteContentElement);
await this.checkContentIsNotDisplayed(content);
}
async clickDeleteOnToolbar(): Promise<void> {
await BrowserActions.click(this.deleteNodesButton);
}
async checkToolbarDeleteIsDisabled(): Promise<boolean> {
return !(await this.deleteNodesButton.isEnabled());
}
async metadataContent(content): Promise<void> {
await this.contentList.clickOnActionMenu(content);
await BrowserActions.click(this.metadataAction);
}
async versionManagerContent(content): Promise<void> {
await this.contentList.clickOnActionMenu(content);
await BrowserActions.click(this.versionManagerAction);
}
async copyContent(content): Promise<void> {
await this.contentList.clickOnActionMenu(content);
await BrowserActions.click(this.copyContentElement);
}
async moveContent(content): Promise<void> {
await this.contentList.clickOnActionMenu(content);
await BrowserActions.click(this.moveContentElement);
}
async lockContent(content): Promise<void> {
await this.contentList.clickOnActionMenu(content);
await BrowserActions.click(this.lockContentElement);
}
async clickFileHyperlink(fileName): Promise<void> {
const hyperlink = this.contentList.dataTablePage().getFileHyperlink(fileName);
await BrowserActions.click(hyperlink);
}
async checkFileHyperlinkIsEnabled(fileName): Promise<void> {
const hyperlink = this.contentList.dataTablePage().getFileHyperlink(fileName);
await BrowserVisibility.waitUntilElementIsVisible(hyperlink);
}
async clickHyperlinkNavigationToggle(): Promise<void> {
const hyperlinkToggle = element(by.cssContainingText('.mat-slide-toggle-content', 'Hyperlink navigation'));
await BrowserActions.click(hyperlinkToggle);
}
async enableDropFilesInAFolder(): Promise<void> {
await this.togglePage.enableToggle(this.multipleFileUploadToggle);
}
async disableDropFilesInAFolder(): Promise<void> {
await browser.executeScript('arguments[0].scrollIntoView()', this.multipleFileUploadToggle);
await this.togglePage.disableToggle(this.multipleFileUploadToggle);
}
async getElementsDisplayedId() {
return this.contentList.dataTablePage().getAllRowsColumnValues(this.columns.nodeId);
}
checkElementsDateSortedAsc(elements) {
let sorted = true;
let i = 0;
while (elements.length > 1 && sorted === true && i < (elements.length - 1)) {
const left = DateUtil.parse(elements[i], 'DD-MM-YY');
const right = DateUtil.parse(elements[i + 1], 'DD-MM-YY');
if (left > right) {
sorted = false;
}
i++;
}
return sorted;
}
checkElementsDateSortedDesc(elements) {
let sorted = true;
let i = 0;
while (elements.length > 1 && sorted === true && i < (elements.length - 1)) {
const left = DateUtil.parse(elements[i], 'DD-MM-YY');
const right = DateUtil.parse(elements[i + 1], 'DD-MM-YY');
if (left < right) {
sorted = false;
}
i++;
}
return sorted;
}
async checkRecentFileToBeShowed() {
await BrowserVisibility.waitUntilElementIsVisible(this.recentFiles);
}
async expandRecentFiles(): Promise<void> {
await this.checkRecentFileToBeShowed();
await this.checkRecentFileToBeClosed();
await BrowserActions.click(this.recentFilesClosed);
await this.checkRecentFileToBeOpened();
}
async closeRecentFiles(): Promise<void> {
await this.checkRecentFileToBeShowed();
await this.checkRecentFileToBeOpened();
await BrowserActions.click(this.recentFilesExpanded);
await this.checkRecentFileToBeClosed();
}
async checkRecentFileToBeClosed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.recentFilesClosed);
}
async checkRecentFileToBeOpened(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.recentFilesExpanded);
}
async getRecentFileIcon(): Promise<string> {
return BrowserActions.getText(this.recentFileIcon);
}
// @deprecated prefer waitTillContentLoaded
async checkDocumentListElementsAreDisplayed(): Promise<void> {
await this.checkAcsContainer();
await this.waitForTableBody();
}
// @deprecated prefer waitTillContentLoaded
async checkAcsContainer(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.uploadBorder);
}
// @deprecated prefer waitTillContentLoaded
async waitForTableBody(): Promise<void> {
await this.contentList.dataTablePage().waitTillContentLoaded();
}
async goToDocumentList(): Promise<void> {
const navigationBarPage = new NavigationBarPage();
await navigationBarPage.navigateToContentServices();
await this.contentList.dataTablePage().waitTillContentLoaded();
}
async clickOnContentServices(): Promise<void> {
await BrowserActions.click(this.contentServices);
}
async numberOfResultsDisplayed(): Promise<number> {
return this.contentList.dataTablePage().numberOfRows();
}
async currentFolderName(): Promise<string> {
return BrowserActions.getText(this.currentFolder);
}
async getAllRowsNameColumn(): Promise<any> {
return this.contentList.getAllRowsColumnValues(this.columns.name);
}
async sortByName(sortOrder: string): Promise<any> {
await this.contentList.dataTable.sortByColumn(sortOrder, this.nameColumnHeader);
}
async sortByAuthor(sortOrder: string): Promise<any> {
await this.contentList.dataTable.sortByColumn(sortOrder, this.createdByColumnHeader);
}
async sortByCreated(sortOrder: string): Promise<any> {
await this.contentList.dataTable.sortByColumn(sortOrder, this.createdColumnHeader);
}
async sortAndCheckListIsOrderedByName(sortOrder: string): Promise<any> {
await this.sortByName(sortOrder);
return this.checkListIsSortedByNameColumn(sortOrder);
}
async checkListIsSortedByNameColumn(sortOrder: string): Promise<any> {
return this.contentList.dataTablePage().checkListIsSorted(sortOrder, this.columns.name);
}
async checkListIsSortedByCreatedColumn(sortOrder: string): Promise<any> {
return this.contentList.dataTablePage().checkListIsSorted(sortOrder, this.columns.created);
}
async checkListIsSortedByAuthorColumn(sortOrder: string): Promise<any> {
return this.contentList.dataTablePage().checkListIsSorted(sortOrder, this.columns.createdBy);
}
async checkListIsSortedBySizeColumn(sortOrder: string): Promise<any> {
return this.contentList.dataTablePage().checkListIsSorted(sortOrder, this.columns.size);
}
async sortAndCheckListIsOrderedByAuthor(sortOrder: string): Promise<any> {
await this.sortByAuthor(sortOrder);
return this.checkListIsSortedByAuthorColumn(sortOrder);
}
async sortAndCheckListIsOrderedByCreated(sortOrder: string): Promise<any> {
await this.sortByCreated(sortOrder);
return this.checkListIsSortedByCreatedColumn(sortOrder);
}
async doubleClickRow(nodeName: string): Promise<void> {
Logger.log(`Open Folder/File ${nodeName}`);
await this.contentList.doubleClickRow(nodeName);
}
async selectRow(nodeName): Promise<void> {
await this.contentList.selectRow(nodeName);
}
async clickOnCreateNewFolder(): Promise<void> {
await BrowserActions.click(this.createFolderButton);
}
async clickOnFavoriteButton(): Promise<void> {
await BrowserActions.click(this.favoriteButton);
}
async checkIsMarkedFavorite(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.markedFavorite);
}
async checkIsNotMarkedFavorite(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.notMarkedFavorite);
}
async clickOnEditFolder(): Promise<void> {
await BrowserActions.click(this.editFolderButton);
}
async isEditFolderButtonEnabled(): Promise<boolean> {
return this.editFolderButton.isEnabled();
}
async openCreateLibraryDialog(): Promise<void> {
await BrowserActions.click(this.createLibraryButton);
await this.createLibraryDialog.libraryDialog.waitVisible();
}
async createNewFolder(folderName: string): Promise<void> {
await this.clickOnCreateNewFolder();
await this.createFolderDialog.addFolderName(folderName);
await this.createFolderDialog.clickOnCreateUpdateButton();
}
async createAndOpenNewFolder(folderName: string): Promise<void> {
await this.createNewFolder(folderName);
await this.checkContentIsDisplayed(folderName);
await this.openFolder(folderName);
}
async openFolder(folderName: string): Promise<void> {
await this.doubleClickRow(folderName);
await this.contentList.dataTablePage().waitTillContentLoaded();
}
async checkContentIsDisplayed(content): Promise<void> {
await this.contentList.dataTablePage().checkContentIsDisplayed(this.columns.name, content);
}
async checkContentsAreDisplayed(content): Promise<void> {
for (let i = 0; i < content.length; i++) {
await this.checkContentIsDisplayed(content[i]);
}
}
async checkContentIsNotDisplayed(content): Promise<void> {
await this.contentList.dataTablePage().checkContentIsNotDisplayed(this.columns.name, content);
}
async deleteAndCheckFolderNotDisplayed(folderName: string): Promise<void> {
await this.deleteContent(folderName);
await this.checkContentIsNotDisplayed(folderName);
}
async deleteSubFolderUnderRoot(folderName: string, subFolderName: string): Promise<void> {
await this.goToDocumentList();
await this.openFolder(folderName);
await this.deleteAndCheckFolderNotDisplayed(subFolderName);
}
async getActiveBreadcrumb(): Promise<string> {
return BrowserActions.getAttribute(this.activeBreadcrumb, 'title');
}
async uploadFile(fileLocation): Promise<void> {
await this.checkUploadButton();
await this.uploadFileButtonInput.sendKeys(path.resolve(path.join(browser.params.testConfig.main.rootPath, fileLocation)));
await this.checkUploadButton();
}
async uploadMultipleFile(files): Promise<void> {
await BrowserVisibility.waitUntilElementIsPresent(this.uploadMultipleFileButton);
let allFiles = path.resolve(path.join(browser.params.testConfig.main.rootPath, files[0]));
for (let i = 1; i < files.length; i++) {
allFiles = allFiles + '\n' + path.resolve(path.join(browser.params.testConfig.main.rootPath, files[i]));
}
await this.uploadMultipleFileButton.sendKeys(allFiles);
await BrowserVisibility.waitUntilElementIsPresent(this.uploadMultipleFileButton);
}
async uploadFolder(folderLocation: string): Promise<void> {
await BrowserVisibility.waitUntilElementIsPresent(this.uploadFolderButton);
await this.uploadFolderButton.sendKeys(path.resolve(path.join(browser.params.testConfig.main.rootPath, folderLocation)));
}
async getSingleFileButtonTooltip(): Promise<string> {
await BrowserVisibility.waitUntilElementIsPresent(this.uploadFileButton);
return BrowserActions.getAttribute(this.uploadFileButtonInput, 'title');
}
async getMultipleFileButtonTooltip(): Promise<string> {
await BrowserVisibility.waitUntilElementIsPresent(this.uploadMultipleFileButton);
return BrowserActions.getAttribute(this.uploadMultipleFileButton, 'title');
}
async getFolderButtonTooltip(): Promise<string> {
await BrowserVisibility.waitUntilElementIsPresent(this.uploadFolderButton);
return BrowserActions.getAttribute(this.uploadFolderButton, 'title');
}
async checkUploadButton(): Promise<void> {
await BrowserVisibility.waitUntilElementIsClickable(this.uploadFileButton);
}
async uploadButtonIsEnabled(): Promise<boolean> {
return this.uploadFileButton.isEnabled();
}
async getErrorMessage(): Promise<string> {
return BrowserActions.getText(this.errorSnackBar);
}
async enableInfiniteScrolling(): Promise<void> {
const infiniteScrollButton = element(by.cssContainingText('.mat-slide-toggle-content', 'Enable Infinite Scrolling'));
await BrowserActions.click(infiniteScrollButton);
}
async enableCustomPermissionMessage(): Promise<void> {
const customPermissionMessage = element(by.cssContainingText('.mat-slide-toggle-content', 'Enable custom permission message'));
await BrowserActions.click(customPermissionMessage);
}
async enableMediumTimeFormat(): Promise<void> {
const mediumTimeFormat = $('#enableMediumTimeFormat');
await BrowserActions.click(mediumTimeFormat);
}
async enableThumbnails(): Promise<void> {
const thumbnailSlide = $('#adf-thumbnails-upload-switch');
await BrowserActions.click(thumbnailSlide);
}
async checkPaginationIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.emptyPagination);
}
async getDocumentListRowNumber(): Promise<number> {
const documentList = $('adf-upload-drag-area adf-document-list');
await BrowserVisibility.waitUntilElementIsVisible(documentList);
return (await this.page.$$('adf-upload-drag-area adf-document-list .adf-datatable-row')).length;
}
async checkColumnNameHeader(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.nameHeader);
}
async checkColumnSizeHeader(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.sizeHeader);
}
async checkColumnCreatedByHeader(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.createdByHeader);
}
async checkColumnCreatedHeader(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.createdHeader);
}
async checkDragAndDropDIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.dragAndDrop);
}
async dragAndDropFile(file: string): Promise<void> {
await this.checkDragAndDropDIsDisplayed();
await DropActions.dropFile(this.dragAndDrop, file);
}
async dragAndDropFolder(folderName: string): Promise<void> {
await this.checkDragAndDropDIsDisplayed();
await DropActions.dropFolder(this.dragAndDrop, folderName);
}
async checkLockIsDisplayedForElement(name): Promise<void> {
const lockButton = $(`div.adf-datatable-cell[data-automation-id="${name}"] button`);
await BrowserVisibility.waitUntilElementIsVisible(lockButton);
}
async getColumnValueForRow(file, columnName): Promise<string> {
return this.contentList.dataTablePage().getColumnValueForRow(this.columns.name, file, columnName);
}
async getStyleValueForRowText(rowName, styleName): Promise<string> {
const row = $(`div.adf-datatable-cell[data-automation-id="${rowName}"] span.adf-datatable-cell-value[title="${rowName}"]`);
await BrowserVisibility.waitUntilElementIsVisible(row);
return row.getCssValue(styleName);
}
async checkEmptyFolderTextToBe(text): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.emptyFolder);
await expect(await this.emptyFolder.getText()).toContain(text);
}
async checkEmptyFolderImageUrlToContain(url): Promise<void> {
await expect(await BrowserActions.getAttribute(this.emptyFolderImage, 'src')).toContain(url);
}
async checkEmptyRecentFileIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.emptyRecent);
}
async getRowIconImageUrl(fileName): Promise<string> {
const iconRow = $(`.app-document-list-container div.adf-datatable-cell[data-automation-id="${fileName}"] img`);
return BrowserActions.getAttribute(iconRow, 'src');
}
async checkGridViewButtonIsVisible(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.gridViewButton);
}
async clickGridViewButton(): Promise<void> {
await this.checkGridViewButtonIsVisible();
await BrowserActions.click(this.gridViewButton);
}
async checkCardViewContainerIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.cardViewContainer);
}
async getCardElementShowedInPage(): Promise<number> {
await BrowserVisibility.waitUntilElementIsVisible(this.cardViewContainer);
return (await this.page.$$('div.app-document-list-container div.adf-datatable-card div.adf-cell-value img')).length;
}
async getDocumentCardIconForElement(elementName): Promise<string> {
const elementIcon = $(`.app-document-list-container div.adf-datatable-cell[data-automation-id="${elementName}"] img`);
return BrowserActions.getAttribute(elementIcon, 'src');
}
async checkDocumentCardPropertyIsShowed(elementName, propertyName): Promise<void> {
const elementProperty = $(`.app-document-list-container div.adf-datatable-cell[data-automation-id="${elementName}"][title="${propertyName}"]`);
await BrowserVisibility.waitUntilElementIsVisible(elementProperty);
}
async getAttributeValueForElement(elementName, propertyName): Promise<string> {
const elementSize = $(`.app-document-list-container div.adf-datatable-cell[data-automation-id="${elementName}"][title="${propertyName}"] span`);
return BrowserActions.getText(elementSize);
}
async checkMenuIsShowedForElementIndex(elementIndex): Promise<void> {
const elementMenu = $(`button[data-automation-id="action_menu_${elementIndex}"]`);
await BrowserVisibility.waitUntilElementIsVisible(elementMenu);
}
async navigateToCardFolder(folderName): Promise<void> {
await BrowserActions.closeMenuAndDialogs();
const folderCard = $(`.app-document-list-container div.adf-image-table-cell.adf-datatable-cell[data-automation-id="${folderName}"]`);
await BrowserActions.click(folderCard);
const folderSelected = $(`.adf-datatable-row.adf-is-selected div[data-automation-id="${folderName}"].adf-datatable-cell--image`);
await BrowserVisibility.waitUntilElementIsVisible(folderSelected);
await browser.actions().sendKeys(protractor.Key.ENTER).perform();
}
async selectGridSortingFromDropdown(sortingOption): Promise<void> {
await this.sortingDropdown.selectDropdownOption(sortingOption);
}
async checkRowIsDisplayed(rowName): Promise<void> {
const row = this.contentList.dataTablePage().getCellElementByValue(this.columns.name, rowName);
await BrowserVisibility.waitUntilElementIsVisible(row);
}
async clickShareButton(): Promise<void> {
await browser.sleep(2000);
await BrowserActions.closeMenuAndDialogs();
await BrowserActions.click(this.shareNodeButton);
}
async checkSelectedSiteIsDisplayed(siteName): Promise<void> {
await this.siteListDropdown.checkOptionIsSelected(siteName);
}
async clickDownloadButton(): Promise<void> {
await BrowserActions.closeMenuAndDialogs();
await BrowserActions.click(this.downloadButton);
}
async clickMultiSelectToggle() {
await BrowserActions.closeMenuAndDialogs();
await BrowserActions.click(this.multiSelectToggle);
}
async multiSelectToggleIsEnabled(): Promise<boolean> {
return this.multiSelectToggle.isEnabled();
}
async clickSelectAllCheckbox(): Promise<void> {
await BrowserActions.click(this.selectAllCheckbox);
}
getRowByName(rowName: string): ElementFinder {
return this.contentList.dataTable.getRow(this.columns.name, rowName);
}
async selectFolder(folderName: string): Promise<void> {
const folderSelected = $(`div[data-automation-id="${folderName}"] .adf-datatable-center-img-ie`);
await BrowserVisibility.waitUntilElementIsVisible(folderSelected);
await BrowserActions.click(folderSelected);
}
async selectFolderWithCommandKey(folderName: string): Promise<void> {
await browser.actions().sendKeys(protractor.Key.COMMAND).perform();
await this.selectRow(folderName);
await browser.actions().sendKeys(protractor.Key.NULL).perform();
}
async chooseSelectionMode(option: string): Promise<void> {
const dropdownPage = new DropdownPage(this.selectionModeDropdown);
await dropdownPage.selectDropdownOption(option);
}
async getItemSelected(): Promise<string> {
return BrowserActions.getArrayText(this.selectedNodesList);
}
async selectItemWithCheckbox(itemName: string): Promise<void> {
const item = $(`adf-datatable-row[aria-label="${itemName}"] mat-checkbox .mat-checkbox-input`);
await BrowserVisibility.waitUntilElementIsVisible(item);
await BrowserActions.click(item);
}
async unSelectItemWithCheckbox(itemName: string): Promise<void> {
const item = $(`adf-datatable-row[aria-label="${itemName} selected"] mat-checkbox .mat-checkbox-input`);
await BrowserVisibility.waitUntilElementIsVisible(item);
await BrowserActions.click(item);
}
}

View File

@@ -0,0 +1,80 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BrowserActions, BrowserVisibility, DataTableComponentPage, DropdownPage } from '@alfresco/adf-testing';
import { $ } from 'protractor';
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
const source = {
favorites: 'Favorites',
recent: 'Recent',
sharedLinks: 'Shared Links',
sites: 'Sites',
mySites: 'My Sites',
trashcan: 'Trashcan',
root: 'Root',
my: 'My',
shared: 'Shared'
};
const column = {
status: 'Status'
};
export class CustomSourcesPage extends ADFPage {
dataTable = new DataTableComponentPage(this.page);
navigationBarPage = new NavigationBarPage(this.page);
toolbar = $('app-custom-sources .adf-toolbar-title');
selectModeDropdown = new DropdownPage($('mat-select[data-automation-id="custom-sources-select"]'));
async waitForToolbarToBeVisible(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.toolbar);
}
async navigateToCustomSources(): Promise<void> {
await this.navigationBarPage.clickCustomSources();
await this.waitForToolbarToBeVisible();
}
async selectMySitesSourceType(): Promise<void> {
await this.selectModeDropdown.selectDropdownOption(source.mySites);
}
async selectFavoritesSourceType(): Promise<void> {
await this.selectModeDropdown.selectDropdownOption(source.favorites);
}
async selectSharedLinksSourceType(): Promise<void> {
await this.selectModeDropdown.selectDropdownOption(source.sharedLinks);
}
checkRowIsDisplayed(rowName: string): Promise<void> {
return this.dataTable.checkContentIsDisplayed('Name', rowName);
}
checkRowIsNotDisplayed(rowName: string): Promise<void> {
return this.dataTable.checkContentIsNotDisplayed('Name', rowName);
}
async getStatusCell(rowName: string): Promise<string> {
const cell = this.dataTable.getCellByRowContentAndColumn('Name', rowName, column.status);
return BrowserActions.getText(cell);
}
}

View File

@@ -0,0 +1,195 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BrowserActions, BrowserVisibility, DataTableComponentPage, DropdownPage } from '@alfresco/adf-testing';
import { $, $$, browser, by, element, ElementFinder, protractor } from 'protractor';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
export class DataTablePage extends ADFPage {
columns = {
id: 'Id',
name: 'Name',
createdBy: 'Created By',
json: 'Json'
};
data = {
copyClipboardDataTable: 'copyClipboard-datatable',
defaultTable: 'datatable'
};
dataTable: DataTableComponentPage;
multiSelect = $(`div[data-automation-id='multiselect'] label > .mat-checkbox-inner-container`);
reset = element(by.xpath(`//span[contains(text(),'Reset to default')]/..`));
allSelectedRows = this.page.$$(`adf-datatable-row[class*='is-selected']`);
selectedRowNumber = $(`adf-datatable-row[class*='is-selected'] div[data-automation-id*='text_']`);
selectAll = $(`div[class*='header'] label`);
addRowElement = element(by.xpath(`//span[contains(text(),'Add row')]/..`));
replaceRowsElement = element(by.xpath(`//span[contains(text(),'Replace rows')]/..`));
replaceColumnsElement = element(by.xpath(`//span[contains(text(),'Replace columns')]/..`));
createdOnColumn = $(`div[data-automation-id='auto_id_createdOn']`);
idColumnHeader = $(`div[data-automation-id='auto_id_id']`);
pasteClipboardInput = $(`input[data-automation-id='paste clipboard input']`);
selectModeDropdown = new DropdownPage($(`mat-select[data-automation-id='datatable-selection-mode']`));
constructor(data?) {
if (this.data[data]) {
this.dataTable = new DataTableComponentPage($(`div[data-automation-id='` + this.data[data] + `']`));
} else {
this.dataTable = new DataTableComponentPage($(`div[data-automation-id='` + this.data.defaultTable + `']`));
}
}
async insertFilter(filterText: string): Promise<void> {
const inputFilter = $(`#adf-datatable-filter-input`);
await BrowserActions.clearSendKeys(inputFilter, filterText);
}
async addRow(): Promise<void> {
await BrowserActions.click(this.addRowElement);
}
async replaceRows(id: string): Promise<void> {
const rowID = this.dataTable.getCellElementByValue(this.columns.id, id);
await BrowserVisibility.waitUntilElementIsVisible(rowID);
await BrowserActions.click(this.replaceRowsElement);
await BrowserVisibility.waitUntilElementIsNotVisible(rowID);
}
async replaceColumns(): Promise<void> {
await BrowserActions.click(this.replaceColumnsElement);
await BrowserVisibility.waitUntilElementIsNotVisible(this.createdOnColumn);
}
async clickMultiSelect(): Promise<void> {
await BrowserActions.click(this.multiSelect);
}
async clickReset(): Promise<void> {
await BrowserActions.click(this.reset);
}
async checkRowIsNotSelected(rowNumber: string): Promise<void> {
const isRowSelected = this.dataTable.getCellElementByValue(this.columns.id, rowNumber)
.element(by.xpath(`ancestor::adf-datatable-row[contains(@class, 'adf-datatable-row custom-row-style ng-star-inserted is-selected')]`));
await BrowserVisibility.waitUntilElementIsNotVisible(isRowSelected);
}
async checkNoRowIsSelected(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.selectedRowNumber);
}
async checkAllRows(): Promise<void> {
await BrowserActions.click(this.selectAll);
}
async checkRowIsChecked(rowNumber: string): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.getRowCheckbox(rowNumber));
}
async checkRowIsNotChecked(rowNumber: string): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.getRowCheckbox(rowNumber));
}
async getNumberOfSelectedRows(): Promise<number> {
return (await this.allSelectedRows).length;
}
async clickCheckbox(rowNumber: string): Promise<void> {
await BrowserActions.closeMenuAndDialogs();
const checkbox = this.dataTable.getCellElementByValue(this.columns.id, rowNumber)
.element(by.xpath(`ancestor::adf-datatable-row[contains(@class, 'adf-datatable-row')]//mat-checkbox/label`));
await BrowserActions.click(checkbox);
}
async selectRow(rowNumber: string): Promise<void> {
const row = this.dataTable.getCellElementByValue(this.columns.id, rowNumber);
await BrowserActions.click(row);
}
async selectRowWithKeyboard(rowNumber: string): Promise<void> {
await browser.actions().sendKeys(protractor.Key.COMMAND).perform();
await this.selectRow(rowNumber);
await browser.actions().sendKeys(protractor.Key.NULL).perform();
}
async selectSelectionMode(selectionMode: string): Promise<void> {
await this.selectModeDropdown.selectDropdownOption(selectionMode);
}
getRowCheckbox(rowNumber: string): ElementFinder {
return this.dataTable.getCellElementByValue(this.columns.id, rowNumber).element(by.xpath(`ancestor::adf-datatable-row/div/mat-checkbox[contains(@class, 'mat-checkbox-checked')]`));
}
async getCopyContentTooltip(): Promise<string> {
return this.dataTable.getCopyContentTooltip();
}
async mouseOverNameColumn(name: string): Promise<void> {
await this.dataTable.mouseOverColumn(this.columns.name, name);
}
async mouseOverCreatedByColumn(name: string): Promise<void> {
await this.dataTable.mouseOverColumn(this.columns.createdBy, name);
}
async mouseOverIdColumn(name: string): Promise<void> {
await this.dataTable.mouseOverColumn(this.columns.id, name);
}
async mouseOverJsonColumn(rowNumber: number): Promise<void> {
const cell = this.dataTable.getCellByRowNumberAndColumnName(rowNumber - 1, this.columns.json);
await BrowserVisibility.waitUntilElementIsVisible(cell);
await browser.actions().mouseMove(cell).perform();
}
getDropTargetIdColumnCell(rowNumber: number): ElementFinder {
return this.dataTable.getCellByRowNumberAndColumnName(rowNumber - 1, this.columns.id);
}
getDropTargetIdColumnHeader(): ElementFinder {
return this.idColumnHeader;
}
async clickOnIdColumn(name: string): Promise<void> {
await this.dataTable.clickColumn(this.columns.id, name);
}
async clickOnJsonColumn(rowNumber: number): Promise<void> {
await BrowserActions.click(this.dataTable.getCellByRowNumberAndColumnName(rowNumber - 1, this.columns.json));
}
async clickOnNameColumn(name: string): Promise<void> {
await this.dataTable.clickColumn(this.columns.name, name);
}
async clickOnCreatedByColumn(name: string): Promise<void> {
await this.dataTable.clickColumn(this.columns.createdBy, name);
}
async pasteClipboard(): Promise<void> {
await this.pasteClipboardInput.clear();
await BrowserActions.click(this.pasteClipboardInput);
await this.pasteClipboardInput.sendKeys(protractor.Key.chord(protractor.Key.SHIFT, protractor.Key.INSERT));
}
async getClipboardInputText(): Promise<string> {
return BrowserActions.getInputValue(this.pasteClipboardInput);
}
}

View File

@@ -0,0 +1,45 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $, $$ } from 'protractor';
import { BrowserActions, TestElement } from '@alfresco/adf-testing';
import { ADFPage } from '../../../../lib/testing/src/lib/protractor/page';
export class CreateLibraryDialogPage extends ADFPage {
libraryDialog = TestElement.byCss('[role="dialog"]');
libraryTitle = TestElement.byCss('.adf-library-dialog>h2');
libraryNameField = TestElement.byCss('input[formcontrolname="title"]');
libraryIdField = TestElement.byCss('input[formcontrolname="id"]');
libraryDescriptionField = TestElement.byCss('textarea[formcontrolname="description"]');
publicRadioButton = TestElement.byCss('[data-automation-id="PUBLIC"]>label');
privateRadioButton = TestElement.byCss('[data-automation-id="PRIVATE"]>label');
moderatedRadioButton = TestElement.byCss('[data-automation-id="MODERATED"]>label');
cancelButton = TestElement.byCss('button[data-automation-id="cancel-library-id"]');
createButton = TestElement.byCss('button[data-automation-id="create-library-id"]');
errorMessage = TestElement.byCss('.mat-dialog-content .mat-error');
errorMessages = this.page.$$('.mat-dialog-content .mat-error');
libraryNameHint = TestElement.byCss('adf-library-dialog .mat-hint');
async getSelectedRadio(): Promise<string> {
const radio = $('.mat-radio-button[class*="checked"]');
return BrowserActions.getText(radio);
}
async getErrorMessages(position: number): Promise<string> {
return BrowserActions.getText(this.errorMessages.get(position));
}
}

View File

@@ -0,0 +1,88 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $$, ElementFinder } from 'protractor';
import { BrowserVisibility, BrowserActions } from '@alfresco/adf-testing';
import { ADFPage } from '../../../../lib/testing/src/lib/protractor/page';
export class FolderDialogPage extends ADFPage {
folderDialog = this.page.$$('adf-folder-dialog')[0];
folderNameField = this.folderDialog.$('#adf-folder-name-input');
folderDescriptionField = this.folderDialog.$('#adf-folder-description-input');
createUpdateButton = this.folderDialog.$('#adf-folder-create-button');
cancelButton = this.folderDialog.$('#adf-folder-cancel-button');
folderTitle = this.folderDialog.$('h2.mat-dialog-title');
validationMessage = this.folderDialog.$('div.mat-form-field-subscript-wrapper mat-hint span');
async getDialogTitle(): Promise<string> {
return BrowserActions.getText(this.folderTitle);
}
async checkFolderDialogIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.folderDialog);
}
async checkFolderDialogIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.folderDialog);
}
async clickOnCreateUpdateButton(): Promise<void> {
await BrowserActions.click(this.createUpdateButton);
}
async clickOnCancelButton(): Promise<void> {
await BrowserActions.click(this.cancelButton);
}
async addFolderName(folderName): Promise<void> {
await BrowserActions.clearSendKeys(this.folderNameField, folderName);
}
async addFolderDescription(folderDescription): Promise<void> {
await BrowserActions.clearSendKeys(this.folderDescriptionField, folderDescription);
}
async getFolderName(): Promise<string> {
return BrowserActions.getInputValue(this.folderNameField);
}
async getValidationMessage(): Promise<string> {
return BrowserActions.getText(this.validationMessage);
}
async checkValidationMessageIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.validationMessage);
}
getFolderNameField(): ElementFinder {
return this.folderNameField;
}
getFolderDescriptionField(): ElementFinder {
return this.folderDescriptionField;
}
async checkCreateUpdateBtnIsEnabled(): Promise<boolean> {
return this.createUpdateButton.isEnabled();
}
async checkCancelBtnIsEnabled(): Promise<void> {
await this.cancelButton.isEnabled();
}
}

View File

@@ -0,0 +1,124 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $$, $ } from 'protractor';
import { BrowserVisibility, TogglePage, BrowserActions, DateTimePickerPage } from '@alfresco/adf-testing';
import moment = require('moment');
import { ADFPage } from '../../../../lib/testing/src/lib/protractor/page';
export class ShareDialogPage extends ADFPage {
togglePage = new TogglePage();
dateTimePickerPage = new DateTimePickerPage();
shareDialog = $('adf-share-dialog');
dialogTitle = this.page.$$('[data-automation-id="adf-share-dialog-title"]')[0];
shareToggle = $('[data-automation-id="adf-share-toggle"] label');
expireToggle = $(`[data-automation-id="adf-expire-toggle"] label`);
shareToggleChecked = $('mat-dialog-container mat-slide-toggle.mat-checked');
shareLink = $('[data-automation-id="adf-share-link"]');
closeButton = $('button[data-automation-id="adf-share-dialog-close"]');
copySharedLinkButton = $('.adf-input-action');
expirationDateInput = $('input[formcontrolname="time"]');
confirmationDialog = $('adf-confirm-dialog');
confirmationCancelButton = $('#adf-confirm-cancel');
confirmationRemoveButton = $('#adf-confirm-accept');
async checkDialogIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.dialogTitle);
}
async clickUnShareFile() {
await this.togglePage.enableToggle(this.shareToggle);
}
async clickExpireToggle() {
await this.togglePage.enableToggle(this.expireToggle);
}
async clickConfirmationDialogCancelButton(): Promise<void> {
await BrowserActions.click(this.confirmationCancelButton);
}
async clickConfirmationDialogRemoveButton(): Promise<void> {
await BrowserActions.click(this.confirmationRemoveButton);
}
async checkShareLinkIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.shareLink);
}
async getShareLink(): Promise<string> {
return BrowserActions.getInputValue(this.shareLink);
}
async clickCloseButton(): Promise<void> {
await BrowserActions.click(this.closeButton);
}
async clickShareLinkButton(): Promise<void> {
await BrowserActions.click(this.copySharedLinkButton);
}
async shareToggleButtonIsChecked(): Promise<void> {
await BrowserVisibility.waitUntilElementIsPresent(this.shareToggleChecked);
}
async dialogIsClosed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsStale(this.shareDialog);
}
async clickDateTimePickerButton(): Promise<void> {
await this.dateTimePickerPage.clickDateTimePicker();
}
async calendarTodayDayIsDisabled(): Promise<void> {
const tomorrow = moment().add(1, 'days').format('D');
if (tomorrow !== '1') {
await this.dateTimePickerPage.checkCalendarTodayDayIsDisabled();
}
}
async setDefaultDay(): Promise<void> {
const tomorrow = moment().add(1, 'days').format('D');
await this.dateTimePickerPage.setDate(tomorrow);
}
async setDefaultHour(): Promise<void> {
await this.dateTimePickerPage.dateTime.setDefaultEnabledHour();
}
async setDefaultMinutes() {
await this.dateTimePickerPage.dateTime.setDefaultEnabledMinutes();
}
async dateTimePickerDialogIsClosed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsStale($('mat-datetimepicker-content'));
}
async getExpirationDate(): Promise<string> {
return BrowserActions.getInputValue(this.expirationDateInput);
}
async expirationDateInputHasValue(value): Promise<void> {
await BrowserVisibility.waitUntilElementHasValue(this.expirationDateInput, value);
}
async confirmationDialogIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.confirmationDialog);
}
}

View File

@@ -0,0 +1,163 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { element, by, browser, ElementFinder, $, $$ } from 'protractor';
import { BrowserVisibility, BrowserActions } from '@alfresco/adf-testing';
import { ADFPage } from '../../../../lib/testing/src/lib/protractor/page';
export class UploadDialogPage extends ADFPage {
closeButton = $('footer[class*="upload-dialog__actions"] button[id="adf-upload-dialog-close"]');
dialog = $('div[id="upload-dialog"]');
minimizedDialog = $('div[class*="upload-dialog--minimized"]');
uploadedStatusIcon = 'mat-icon[class*="status--done"]';
cancelledStatusIcon = 'div[class*="status--cancelled"]';
errorStatusIcon = 'div[class*="status--error"] mat-icon';
errorTooltip = $('div.mat-tooltip');
rowByRowName = by.xpath('ancestor::adf-file-uploading-list-row');
title = $('span[class*="upload-dialog__title"]');
minimizeButton = $('mat-icon[title="Minimize"]');
maximizeButton = $('mat-icon[title="Maximize"]');
canUploadConfirmationTitle = $('.upload-dialog__confirmation--title');
canUploadConfirmationDescription = $('.upload-dialog__confirmation--text');
confirmationDialogNoButton = element(by.partialButtonText('No'));
confirmationDialogYesButton = element(by.partialButtonText('Yes'));
cancelUploadsElement = $('footer[class*="upload-dialog__actions"] button[id="adf-upload-dialog-cancel-all"]');
cancelUploadInProgressButton = $('div[data-automation-id="cancel-upload-progress"]');
async clickOnCloseButton(): Promise<void> {
await this.checkCloseButtonIsDisplayed();
await BrowserActions.clickExecuteScript('footer[class*="upload-dialog__actions"] button[id="adf-upload-dialog-close"]');
}
async checkCloseButtonIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.closeButton);
}
async dialogIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.dialog);
}
async dialogIsMinimized(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.minimizedDialog);
}
async dialogIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.dialog);
}
async getRowByRowName(content: string): Promise<ElementFinder> {
const row = await this.page.$$(`div[class*='uploading-row'] span[title="${content}"]`).last();
await BrowserVisibility.waitUntilElementIsVisible(row);
return row.element(this.rowByRowName);
}
async fileIsUploaded(content: string): Promise<void> {
const row: ElementFinder = await this.getRowByRowName(content);
await BrowserVisibility.waitUntilElementIsVisible(row.$(this.uploadedStatusIcon), 10000);
}
async fileIsError(content: string) {
const row: ElementFinder = await this.getRowByRowName(content);
await BrowserVisibility.waitUntilElementIsVisible(row.$(this.errorStatusIcon));
}
async filesAreUploaded(content: string[]): Promise<void> {
for (let i = 0; i < content.length; i++) {
await this.fileIsUploaded(content[i]);
}
}
async fileIsNotDisplayedInDialog(content: string): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible($(`div[class*='uploading-row'] span[title="${content}"]`));
}
async cancelUploads(): Promise<void> {
await BrowserActions.click(this.cancelUploadsElement);
}
async cancelProgress(): Promise<void> {
await BrowserActions.click(this.cancelUploadInProgressButton);
}
async checkCancelProgressIsVisible(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.cancelUploadInProgressButton);
}
async fileIsCancelled(content: string): Promise<void> {
const row: ElementFinder = await this.getRowByRowName(content);
await BrowserVisibility.waitUntilElementIsVisible(row);
await BrowserVisibility.waitUntilElementIsVisible(row.$(this.cancelledStatusIcon), 10000);
}
async removeUploadedFile(content: string): Promise<void> {
const row: ElementFinder = await this.getRowByRowName(content);
await BrowserVisibility.waitUntilElementIsVisible(row.$(this.uploadedStatusIcon));
const elementRow = await this.getRowByRowName(content);
await BrowserActions.click(elementRow.$(this.uploadedStatusIcon));
}
async getTitleText(): Promise<string> {
await BrowserVisibility.waitUntilElementIsVisible(this.title);
return this.title.getText();
}
async getConfirmationDialogTitleText(): Promise<string> {
await BrowserVisibility.waitUntilElementIsVisible(this.canUploadConfirmationTitle);
return this.canUploadConfirmationTitle.getText();
}
async getConfirmationDialogDescriptionText(): Promise<string> {
await BrowserVisibility.waitUntilElementIsVisible(this.canUploadConfirmationDescription);
return this.canUploadConfirmationDescription.getText();
}
async clickOnConfirmationDialogYesButton(): Promise<void> {
await BrowserActions.click(this.confirmationDialogYesButton);
}
async clickOnConfirmationDialogNoButton(): Promise<void> {
await BrowserActions.click(this.confirmationDialogNoButton);
}
async numberOfCurrentFilesUploaded(): Promise<string> {
const text = await this.getTitleText();
return text.split('Uploaded ')[1].split(' / ')[0];
}
async numberOfInitialFilesUploaded(): Promise<string> {
const text = await this.getTitleText();
return text.split('Uploaded ')[1].split(' / ')[1];
}
async minimizeUploadDialog(): Promise<void> {
await BrowserActions.click(this.minimizeButton);
}
async maximizeUploadDialog(): Promise<void> {
await BrowserActions.click(this.maximizeButton);
}
async displayTooltip(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible($(this.errorStatusIcon));
await browser.actions().mouseMove($(this.errorStatusIcon)).perform();
}
async getTooltip(): Promise<string> {
return BrowserActions.getText(this.errorTooltip);
}
}

View File

@@ -0,0 +1,131 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $, browser } from 'protractor';
import { BrowserActions, BrowserVisibility, TogglePage } from '@alfresco/adf-testing';
import { ADFPage } from '../../../../lib/testing/src/lib/protractor/page';
export class UploadTogglesPage extends ADFPage {
togglePage = new TogglePage();
multipleFileUploadToggle = $('#adf-multiple-upload-switch');
uploadFolderToggle = $('#adf-folder-upload-switch');
extensionFilterToggle = $('#adf-extension-filter-upload-switch');
maxSizeToggle = $('#adf-max-size-filter-upload-switch');
versioningToggle = $('#adf-version-upload-switch');
extensionAcceptedField = $('input[data-automation-id="accepted-files-type"]');
maxSizeField = $('input[data-automation-id="max-files-size"]');
disableUploadCheckbox = $('[id="adf-disable-upload"]');
async enableMultipleFileUpload(): Promise<void> {
await browser.executeScript('arguments[0].scrollIntoView()', this.multipleFileUploadToggle);
await this.togglePage.enableToggle(this.multipleFileUploadToggle);
}
async disableMultipleFileUpload(): Promise<void> {
await browser.executeScript('arguments[0].scrollIntoView()', this.multipleFileUploadToggle);
await this.togglePage.disableToggle(this.multipleFileUploadToggle);
}
async enableFolderUpload(): Promise<void> {
await this.togglePage.enableToggle(this.uploadFolderToggle);
}
async checkFolderUploadToggleIsEnabled(): Promise<boolean> {
try {
const enabledFolderUpload = $('mat-slide-toggle[id="adf-folder-upload-switch"][class*="mat-checked"]');
await BrowserVisibility.waitUntilElementIsVisible(enabledFolderUpload);
return true;
} catch {
return false;
}
}
async checkMultipleFileUploadToggleIsEnabled(): Promise<void> {
const enabledToggle = $('mat-slide-toggle[id="adf-multiple-upload-switch"][class*="mat-checked"]');
await BrowserVisibility.waitUntilElementIsVisible(enabledToggle);
}
async checkMaxSizeToggleIsEnabled(): Promise<void> {
const enabledToggle = $('mat-slide-toggle[id="adf-max-size-filter-upload-switch"][class*="mat-checked"]');
await BrowserVisibility.waitUntilElementIsVisible(enabledToggle);
}
async checkVersioningToggleIsEnabled(): Promise<void> {
const enabledToggle = $('mat-slide-toggle[id="adf-version-upload-switch"][class*="mat-checked"]');
await BrowserVisibility.waitUntilElementIsVisible(enabledToggle);
}
async disableFolderUpload(): Promise<void> {
await this.togglePage.disableToggle(this.uploadFolderToggle);
}
async checkFolderUploadToggleIsNotEnabled(): Promise<boolean> {
try {
const inactiveToggleFolder = $('#adf-folder-upload-switch .mat-slide-toggle-label');
await BrowserVisibility.waitUntilElementIsVisible(inactiveToggleFolder);
return true;
} catch {
return false;
}
}
async enableExtensionFilter(): Promise<void> {
await browser.executeScript('arguments[0].scrollIntoView()', this.extensionFilterToggle);
await this.togglePage.enableToggle(this.extensionFilterToggle);
}
async disableExtensionFilter(): Promise<void> {
await browser.executeScript('arguments[0].scrollIntoView()', this.extensionFilterToggle);
await this.togglePage.disableToggle(this.extensionFilterToggle);
}
async enableMaxSize(): Promise<void> {
await this.togglePage.enableToggle(this.maxSizeToggle);
}
async disableMaxSize(): Promise<void> {
await this.togglePage.disableToggle(this.maxSizeToggle);
}
async enableVersioning(): Promise<void> {
await this.togglePage.enableToggle(this.versioningToggle);
}
async disableVersioning(): Promise<void> {
await this.togglePage.disableToggle(this.versioningToggle);
}
async clickCheckboxDisableUpload(): Promise<void> {
await BrowserActions.click(this.disableUploadCheckbox);
}
async addExtension(extension: string): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.extensionAcceptedField);
await this.extensionAcceptedField.sendKeys(',' + extension);
}
async addMaxSize(size): Promise<void> {
await this.clearText();
await this.maxSizeField.sendKeys(size);
}
async clearText(): Promise<void> {
await BrowserActions.clearSendKeys(this.maxSizeField, '');
}
}

View File

@@ -0,0 +1,44 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $, ElementFinder } from 'protractor';
import { BrowserVisibility } from '@alfresco/adf-testing';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
export class IconsPage extends ADFPage {
locateCustomIcon = (name: string): ElementFinder => $(`adf-icon[value='${name}'] svg`);
locateLigatureIcon = (name: string): ElementFinder => $(`adf-icon[value='${name}'] .material-icons`);
async isCustomIconDisplayed(name: string) {
const present = await BrowserVisibility.waitUntilElementIsVisible(this.locateCustomIcon(name));
if (present) {
return this.locateCustomIcon(name).isDisplayed();
} else {
return false;
}
}
async isLigatureIconDisplayed(name: string) {
const present = await BrowserVisibility.waitUntilElementIsVisible(this.locateLigatureIcon(name));
if (present) {
return this.locateLigatureIcon(name).isDisplayed();
} else {
return false;
}
}
}

View File

@@ -0,0 +1,44 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ElementFinder, $, $$ } from 'protractor';
import { BrowserVisibility, BrowserActions } from '@alfresco/adf-testing';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
import { Page } from '@playwright/test';
export class InfinitePaginationPage extends ADFPage {
rootElement: ElementFinder;
loadMoreButton: ElementFinder;
loading = $('[data-automation-id="adf-infinite-pagination-spinner"]');
constructor(public readonly page: Page) {
super(page);
this.rootElement = this.page.$$('adf-infinite-pagination')[0]
this.loadMoreButton = this.rootElement.$('button[data-automation-id="adf-infinite-pagination-button"]');
}
async clickLoadMoreButton(): Promise<void> {
await BrowserActions.click(this.loadMoreButton);
await BrowserVisibility.waitUntilElementIsNotVisible(this.loading);
}
async checkLoadMoreButtonIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.loadMoreButton);
}
}

View File

@@ -0,0 +1,218 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $, browser, by, element } from 'protractor';
import { TogglePage, BrowserActions, BrowserVisibility, LoginPage } from '@alfresco/adf-testing';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
export class LoginShellPage extends ADFPage {
loginURL = browser.baseUrl + '/login';
loginSSOPage = new LoginPage(this.page);
togglePage = new TogglePage(this.page);
txtUsername = $('input[id="username"]');
txtPassword = $('input[id="password"]');
logoImg = $('img[id="adf-login-img-logo"]');
successRouteTxt = $('input[data-automation-id="adf-success-route"]');
logoTxt = $('input[data-automation-id="adf-url-logo"]');
usernameError = $('span[data-automation-id="username-error"]');
passwordError = $('span[data-automation-id="password-required"]');
loginError = $('.adf-login-error-message');
usernameInactive = $('input[id="username"][aria-invalid="false"]');
passwordInactive = $('input[id="password"][aria-invalid="false"]');
adfLogo = $('.adf-img-logo');
usernameHighlighted = $('input[id="username"][aria-invalid="true"]');
passwordHighlighted = $('input[id="password"][aria-invalid="true"]');
signInButton = $('#login-button');
showPasswordElement = $('button[data-automation-id="show_password"]');
hidePasswordElement = $('button[data-automation-id="hide_password"]');
rememberMe = $('mat-checkbox[id="adf-login-remember"]');
needHelp = $('#adf-login-action-left');
register = $('#adf-login-action-right');
footerSwitch = $('#switch4');
rememberMeSwitch = $('#adf-toggle-show-rememberme');
successRouteSwitch = $('#adf-toggle-show-successRoute');
logoSwitch = $('#adf-toggle-logo');
header = $('#adf-header');
settingsIcon = element(by.cssContainingText('a[data-automation-id="settings"] mat-icon', 'settings'));
sidenavLayout = $(`[data-automation-id="sidenav-layout"]`);
async goToLoginPage(): Promise<void> {
await BrowserActions.getUrl(this.loginURL);
await this.waitForElements();
}
async waitForElements(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.txtUsername);
await BrowserVisibility.waitUntilElementIsVisible(this.txtPassword);
}
async enterUsername(username: string): Promise<void> {
await BrowserActions.clearSendKeys(this.txtUsername, username);
}
async enterPassword(password: string): Promise<void> {
await BrowserActions.clearSendKeys(this.txtPassword, password);
}
async clearUsername(): Promise<void> {
await BrowserActions.click(this.txtUsername);
await BrowserActions.clearWithBackSpace(this.txtUsername);
}
async clearPassword(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.txtPassword);
await BrowserActions.clearWithBackSpace(this.txtPassword);
}
async getUsernameTooltip(): Promise<string> {
return BrowserActions.getText(this.usernameError);
}
async getPasswordTooltip(): Promise<string> {
return BrowserActions.getText(this.passwordError);
}
async getLoginError(): Promise<string> {
return BrowserActions.getText(this.loginError);
}
async checkLoginErrorIsDisplayed(loginError: string): Promise<void> {
await BrowserVisibility.waitUntilElementHasText(this.loginError, loginError);
}
async checkLoginImgURL(): Promise<string> {
return BrowserActions.getAttribute(this.logoImg, 'src');
}
async checkUsernameInactive(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.usernameInactive);
}
async checkPasswordInactive(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.passwordInactive);
}
async checkUsernameHighlighted(): Promise<void> {
await BrowserActions.click(this.adfLogo);
await BrowserVisibility.waitUntilElementIsVisible(this.usernameHighlighted);
}
async checkPasswordHighlighted(): Promise<void> {
await BrowserActions.click(this.adfLogo);
await BrowserVisibility.waitUntilElementIsVisible(this.passwordHighlighted);
}
async checkUsernameTooltipIsNotVisible(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.usernameError);
}
async checkPasswordTooltipIsNotVisible(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.passwordError);
}
async getSignInButtonIsEnabled(): Promise<boolean> {
return this.signInButton.isEnabled();
}
async clickSignInButton(): Promise<void> {
await BrowserActions.click(this.signInButton);
}
async clickSettingsIcon(): Promise<void> {
await BrowserActions.click(this.settingsIcon);
}
async showPassword(): Promise<void> {
await BrowserActions.click(this.showPasswordElement);
}
async hidePassword(): Promise<void> {
await BrowserActions.click(this.hidePasswordElement);
}
async getShownPassword(): Promise<string> {
return BrowserActions.getInputValue(this.txtPassword);
}
async checkPasswordIsHidden(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.txtPassword);
}
async checkRememberIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.rememberMe);
}
async checkRememberIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.rememberMe);
}
async checkNeedHelpIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.needHelp);
}
async checkNeedHelpIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.needHelp);
}
async checkRegisterDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.register);
}
async checkRegisterIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.register);
}
async enableFooter(): Promise<void> {
await this.togglePage.enableToggle(this.footerSwitch);
}
async disableFooter(): Promise<void> {
await this.togglePage.disableToggle(this.footerSwitch);
}
async disableRememberMe(): Promise<void> {
await this.togglePage.disableToggle(this.rememberMeSwitch);
}
async enableSuccessRouteSwitch(): Promise<void> {
await this.togglePage.enableToggle(this.successRouteSwitch);
}
async enableLogoSwitch(): Promise<void> {
await this.togglePage.enableToggle(this.logoSwitch);
}
async enterSuccessRoute(route: string): Promise<void> {
await BrowserActions.clearSendKeys(this.successRouteTxt, route);
}
async enterLogo(logo: string): Promise<void> {
await BrowserActions.clearSendKeys(this.logoTxt, logo);
}
async login(username: string, password: string): Promise<void> {
await this.loginSSOPage.login(username, password);
}
async loginWithProfile(profile: string): Promise<void> {
await this.loginSSOPage.loginWithProfile(profile);
}
}

View File

@@ -0,0 +1,29 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $ } from 'protractor';
import { BrowserVisibility } from '@alfresco/adf-testing';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
export class LogoutPage extends ADFPage {
logoutSection = this.page.$('div[data-automation-id="adf-logout-section"]');
async checkLogoutSectionIsDisplayed() {
await BrowserVisibility.waitUntilElementIsVisible(this.logoutSection);
}
}

View File

@@ -0,0 +1,315 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $, by, element, Key, protractor, ElementFinder } from 'protractor';
import { BrowserActions, BrowserVisibility, DropdownPage, TestElement, Logger } from '@alfresco/adf-testing';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
export class MetadataViewPage extends ADFPage {
title = $(`div[info-drawer-title]`);
expandedAspect = $(`mat-expansion-panel-header[aria-expanded='true']`);
aspectTitle = `mat-panel-title`;
name = $(`[data-automation-id='card-textitem-value-properties.cm:name']`);
creator = $(`[data-automation-id='card-textitem-value-createdByUser.displayName']`);
createdDate = $(`span[data-automation-id='card-dateitem-createdAt']`);
modifier = $(`[data-automation-id='card-textitem-value-modifiedByUser.displayName']`);
modifiedDate = $(`span[data-automation-id='card-dateitem-modifiedAt']`);
mimetypeName = $(`[data-automation-id='card-textitem-value-content.mimeTypeName']`);
size = $(`[data-automation-id='card-textitem-value-content.sizeInBytes']`);
description = $(`span[data-automation-id='card-textitem-value-properties.cm:description']`);
author = $(`[data-automation-id='card-textitem-value-properties.cm:author']`);
titleProperty = $(`span[data-automation-id='card-textitem-value-properties.cm:title'] span`);
editIcon = $(`button[data-automation-id='meta-data-card-toggle-edit']`);
informationButton = $(`button[data-automation-id='meta-data-card-toggle-expand']`);
informationSpan = $(`span[data-automation-id='meta-data-card-toggle-expand-label']`);
informationIcon = $(`span[data-automation-id='meta-data-card-toggle-expand-label'] ~ mat-icon`);
displayEmptySwitch = $(`#adf-metadata-empty`);
readonlySwitch = $(`#adf-metadata-readonly`);
multiSwitch = $(`#adf-metadata-multi`);
presetSwitch = $('#adf-toggle-custom-preset');
defaultPropertiesSwitch = $('#adf-metadata-default-properties');
closeButton = element(by.cssContainingText('button.mat-button span', 'Close'));
displayAspect = $(`input[data-placeholder='Display Aspect']`);
applyAspect = element(by.cssContainingText(`button span.mat-button-wrapper`, 'Apply Aspect'));
saveMetadataButton = $(`[data-automation-id='save-metadata']`);
resetMetadataButton = $(`[data-automation-id='reset-metadata']`);
private getMetadataGroupLocator = async (groupName: string): Promise<ElementFinder> => $(`mat-expansion-panel[data-automation-id="adf-metadata-group-${groupName}"]`);
private getExpandedMetadataGroupLocator = async (groupName: string): Promise<ElementFinder> => $(`mat-expansion-panel[data-automation-id="adf-metadata-group-${groupName}"] > mat-expansion-panel-header`);
async getTitle(): Promise<string> {
return BrowserActions.getText(this.title);
}
async getExpandedAspectName(): Promise<string> {
return BrowserActions.getText(this.expandedAspect.$(this.aspectTitle));
}
async getName(): Promise<string> {
return BrowserActions.getInputValue(this.name);
}
async getCreator(): Promise<string> {
return BrowserActions.getInputValue(this.creator);
}
async getCreatedDate(): Promise<string> {
return BrowserActions.getText(this.createdDate);
}
async getModifier(): Promise<string> {
return BrowserActions.getInputValue(this.modifier);
}
async getModifiedDate(): Promise<string> {
return BrowserActions.getText(this.modifiedDate);
}
async getMimetypeName(): Promise<string> {
return BrowserActions.getInputValue(this.mimetypeName);
}
async getSize(): Promise<string> {
return BrowserActions.getInputValue(this.size);
}
async getDescription(): Promise<string> {
return BrowserActions.getInputValue(this.description);
}
async getAuthor(): Promise<string> {
return BrowserActions.getInputValue(this.author);
}
async getTitleProperty(): Promise<string> {
return BrowserActions.getText(this.titleProperty);
}
async editIconIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.editIcon);
}
async editIconIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.editIcon);
}
async editIconClick(): Promise<void> {
await BrowserActions.clickExecuteScript('button[data-automation-id="meta-data-card-toggle-edit"]');
}
async informationButtonIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsClickable(this.informationButton);
}
async informationButtonIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.informationButton);
}
async clickOnInformationButton(): Promise<void> {
await BrowserActions.click(this.informationButton);
}
async getInformationButtonText(): Promise<string> {
return BrowserActions.getText(this.informationSpan);
}
async getInformationIconText(): Promise<string> {
return BrowserActions.getText(this.informationIcon);
}
async clickOnPropertiesTab(): Promise<void> {
const propertiesTab = element(by.cssContainingText(`.adf-info-drawer-layout-content div.mat-tab-labels div .mat-tab-label-content`, `Properties`));
await BrowserActions.click(propertiesTab);
}
async getEditIconTooltip(): Promise<string> {
return BrowserActions.getAttribute(this.editIcon, 'title');
}
async editPropertyIconIsDisplayed(propertyName: string) {
const editPropertyIcon = $('[data-automation-id="header-' + propertyName + '"] .adf-textitem-edit-icon');
await BrowserVisibility.waitUntilElementIsPresent(editPropertyIcon);
}
async clickResetButton(): Promise<void> {
const clearPropertyIcon = $('button[data-automation-id="reset-metadata"]');
await BrowserActions.click(clearPropertyIcon);
}
async enterPropertyText(propertyName: string, text: string | number): Promise<void> {
const textField = $('input[data-automation-id="card-textitem-value-' + propertyName + '"]');
await BrowserActions.clearSendKeys(textField, text.toString());
await textField.sendKeys(protractor.Key.ENTER);
}
async enterPresetText(text: string): Promise<void> {
const presetField = $('input[data-automation-id="adf-text-custom-preset"]');
await BrowserActions.clearSendKeys(presetField, text.toString());
await presetField.sendKeys(protractor.Key.ENTER);
const applyButton = $('button[id="adf-metadata-aplly"]');
await BrowserActions.click(applyButton);
}
async enterDescriptionText(text: string): Promise<void> {
const textField = $('textarea[data-automation-id="card-textitem-value-properties.cm:description"]');
await BrowserActions.clearSendKeys(textField, text);
await textField.sendKeys(Key.TAB);
}
async getPropertyText(propertyName: string, type?: string): Promise<string> {
const propertyType = type || 'textitem';
const textField = $('[data-automation-id="card-' + propertyType + '-value-' + propertyName + '"]');
return BrowserActions.getInputValue(textField);
}
async getPropertyIconTooltip(propertyName: string): Promise<string> {
const editPropertyIcon = $('[data-automation-id="header-' + propertyName + '"] .adf-textitem-edit-icon');
return BrowserActions.getAttribute(editPropertyIcon, 'title');
}
async clickMetadataGroup(groupName: string): Promise<void> {
const group = await this.getMetadataGroupLocator(groupName);
await BrowserActions.click(group);
}
async checkMetadataGroupIsPresent(groupName: string): Promise<void> {
const group = await this.getMetadataGroupLocator(groupName);
await BrowserVisibility.waitUntilElementIsVisible(group);
}
async checkMetadataGroupIsNotPresent(groupName: string): Promise<void> {
const group = await this.getMetadataGroupLocator(groupName);
await BrowserVisibility.waitUntilElementIsNotVisible(group);
}
async checkMetadataGroupIsExpand(groupName: string): Promise<void> {
const group = await this.getExpandedMetadataGroupLocator(groupName);
await expect(await BrowserActions.getAttribute(group, 'class')).toContain('mat-expanded');
}
async checkMetadataGroupIsNotExpand(groupName: string): Promise<void> {
const group = await this.getExpandedMetadataGroupLocator(groupName);
await expect(await BrowserActions.getAttribute(group, 'class')).not.toContain('mat-expanded');
}
async getMetadataGroupTitle(groupName: string): Promise<string> {
const group = $('mat-expansion-panel[data-automation-id="adf-metadata-group-' + groupName + '"] > mat-expansion-panel-header > span > mat-panel-title');
return BrowserActions.getText(group);
}
async checkPropertyIsVisible(propertyName: string, type: string): Promise<void> {
const property = $('div[data-automation-id="card-' + type + '-label-' + propertyName + '"]');
await BrowserVisibility.waitUntilElementIsVisible(property);
}
async hasContentType(contentType: string, attempt = 0, maxAttempt = 3): Promise<boolean> {
const contentTypeSelector = '[data-automation-id="select-readonly-value-nodeType"]';
const type = TestElement.byText(contentTypeSelector, contentType);
try {
if (attempt > maxAttempt) {
return false;
}
await type.waitVisible();
const isPresent = type.isPresent();
if (isPresent) {
return true;
}
return this.hasContentType(contentType, attempt + 1, maxAttempt);
} catch (e) {
Logger.log(`re trying content type attempt :: ${attempt}`);
return this.hasContentType(contentType, attempt + 1, maxAttempt);
}
}
async checkPropertyDisplayed(propertyName: string, type?: string, attempt = 0, maxAttempt = 3): Promise<string> {
try {
if (attempt > maxAttempt) {
return '';
}
const propertyType = type || 'textitem';
await TestElement.byCss('[data-automation-id="card-' + propertyType + '-value-' + propertyName + '"]').waitVisible();
return this.getPropertyText(propertyName);
} catch (e) {
Logger.log(`re trying custom property attempt :: ${attempt}`);
return this.checkPropertyDisplayed(propertyName, type, attempt + 1, maxAttempt);
}
}
async changeContentType(option: string, attempt = 0, maxAttempt = 3): Promise<boolean> {
const nodeType = TestElement.byCss('div[data-automation-id="header-nodeType"] .mat-select-trigger');
if (attempt > maxAttempt) {
Logger.error(`content type select option not found. check acs version may be lesser than 7.0.0`);
return false;
}
try {
await nodeType.waitVisible();
if (await nodeType.isPresent()) {
await nodeType.click();
const typesDropDownPage = new DropdownPage(nodeType.elementFinder);
await typesDropDownPage.checkOptionIsDisplayed(option);
await typesDropDownPage.selectOption(option);
return true;
}
return this.changeContentType(option, attempt + 1, maxAttempt);
} catch (error) {
Logger.log(`re trying content type options attempt :: ${attempt}`);
await BrowserActions.closeMenuAndDialogs();
return this.changeContentType(option, attempt + 1, maxAttempt);
}
}
async checkConfirmDialogDisplayed(): Promise<void> {
const confirmButton = TestElement.byCss('adf-content-type-dialog');
await confirmButton.waitPresent();
}
async applyNodeProperties(): Promise<void> {
const confirmButton = TestElement.byId('content-type-dialog-apply-button');
await confirmButton.click();
}
async cancelNodeProperties(): Promise<void> {
const cancelButton = TestElement.byId('content-type-dialog-actions-cancel');
await cancelButton.click();
}
async checkPropertyIsNotVisible(propertyName: string, type: string): Promise<void> {
await TestElement.byCss('div[data-automation-id="card-' + type + '-label-' + propertyName + '"]').waitNotVisible();
}
async clickCloseButton(): Promise<void> {
await BrowserActions.click(this.closeButton);
}
async typeAspectName(aspectName): Promise<void> {
await BrowserActions.clearSendKeys(this.displayAspect, aspectName);
}
async clickApplyAspect(): Promise<void> {
await BrowserActions.click(this.applyAspect);
}
async clickSaveMetadata(): Promise<void> {
await BrowserActions.click(this.saveMetadataButton);
}
async clickResetMetadata(): Promise<void> {
await BrowserActions.click(this.resetMetadataButton);
}
}

View File

@@ -0,0 +1,252 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AppListCloudPage, BrowserActions, BrowserVisibility, Logger } from '@alfresco/adf-testing';
import { $, browser, ElementFinder } from 'protractor';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
export class NavigationBarPage extends ADFPage {
linkListContainer = this.page.$('.app-sidenav-linklist');
linkMenuChildrenContainer = this.page.$('.nestedMenu');
dataTableNestedButton = this.page.$('.app-sidenav-link[data-automation-id="Datatable"]');
dataTableCopyContentButton = this.page.$('.app-sidenav-link[data-automation-id="Copy Content"]');
dataTableDragAndDropButton = this.page.$('.app-sidenav-link[data-automation-id="Drag and Drop"]');
processServicesNestedButton = this.page.$('.app-sidenav-link[data-automation-id="App"]');
processServicesCloudHomeButton = this.page.$('.app-sidenav-link[data-automation-id="Home"]');
themeButton = this.page.$('button[data-automation-id="theme menu"]');
themeMenuContent = this.page.$('div[class*="mat-menu-panel"]');
appTitle = this.page.$('.adf-app-title');
menuButton = this.page.$('button[data-automation-id="adf-menu-icon"]');
formButton = this.page.$('.app-sidenav-link[data-automation-id="Form"]');
peopleGroupCloudButton = this.page.$('.app-sidenav-link[data-automation-id="People/Group Cloud"]');
serviceTaskListButton = this.page.$('.app-sidenav-link[data-automation-id="Service Task List"]');
logoutSection = this.page.$('div[data-automation-id="adf-logout-section"]');
personalFiles = this.page.$('div [title="Personal Files"]');
getMenuItemLocator = (title: string) => $(`.app-sidenav-link[data-automation-id="${title}"]`);
async clickNavigationBarItem(title: string, untilElementIsVisible?: ElementFinder): Promise<void> {
Logger.log(`clickNavigationBarItem ${title}`);
const menu = this.page.$(`.app-sidenav-link[data-automation-id="${title}"]`);
await BrowserActions.closeMenuAndDialogs();
if (untilElementIsVisible) {
await BrowserActions.clickUntilIsNotVisible(menu, untilElementIsVisible);
} else {
await BrowserActions.click(menu);
}
}
async clickHomeButton(): Promise<void> {
await this.clickNavigationBarItem('Home');
}
async navigateToContentServices(): Promise<void> {
await this.clickNavigationBarItem('Content Services', this.personalFiles);
}
async clickHeaderDataButton(): Promise<void> {
await this.clickNavigationBarItem('Header Data');
}
async clickTaskListButton(): Promise<void> {
await this.clickNavigationBarItem('Task List');
}
async clickProcessCloudButton() {
await BrowserActions.closeMenuAndDialogs();
await BrowserActions.clickUntilIsNotVisible(this.getMenuItemLocator('Process Cloud'), this.linkMenuChildrenContainer);
}
async navigateToProcessServicesCloudPage(): Promise<AppListCloudPage> {
await this.clickProcessCloudButton();
await BrowserActions.click(this.processServicesCloudHomeButton);
await BrowserVisibility.waitUntilElementIsNotPresent(this.linkMenuChildrenContainer);
return new AppListCloudPage();
}
async navigateToFormCloudPage(): Promise<void> {
await this.clickProcessCloudButton();
await BrowserActions.click(this.formButton);
await BrowserVisibility.waitUntilElementIsNotPresent(this.linkMenuChildrenContainer);
}
async navigateToPeopleGroupCloudPage(): Promise<void> {
await this.clickProcessCloudButton();
await BrowserActions.click(this.peopleGroupCloudButton);
await BrowserVisibility.waitUntilElementIsNotPresent(this.linkMenuChildrenContainer);
}
async navigateToServiceTaskListCloudPage(): Promise<void> {
await this.clickProcessCloudButton();
await BrowserActions.click(this.serviceTaskListButton);
await BrowserVisibility.waitUntilElementIsNotPresent(this.linkMenuChildrenContainer);
}
private async clickProcessServicesButton() {
await BrowserActions.closeMenuAndDialogs();
await BrowserActions.clickUntilIsNotVisible(this.getMenuItemLocator('Process Services'), this.linkMenuChildrenContainer);
}
async navigateToProcessServicesPage(): Promise<void> {
await this.clickProcessServicesButton();
await BrowserActions.click(this.processServicesNestedButton);
await BrowserVisibility.waitUntilElementIsNotPresent(this.linkMenuChildrenContainer);
}
async navigateToProcessServicesFormPage(): Promise<void> {
await this.clickProcessServicesButton();
await BrowserActions.click(this.formButton);
await BrowserVisibility.waitUntilElementIsNotPresent(this.linkMenuChildrenContainer);
}
async clickLoginButton(): Promise<void> {
await this.clickNavigationBarItem('Login');
}
async clickTrashcanButton(): Promise<void> {
await this.clickNavigationBarItem('Trashcan');
}
async clickCustomSources(): Promise<void> {
await this.clickNavigationBarItem('Custom Sources');
}
async clickDataTable(): Promise<void> {
await this.clickNavigationBarItem('Datatable');
await BrowserVisibility.waitUntilElementIsVisible(this.linkMenuChildrenContainer);
}
async navigateToDatatable(): Promise<void> {
await this.clickDataTable();
await BrowserActions.click(this.dataTableNestedButton);
await BrowserVisibility.waitUntilElementIsNotPresent(this.linkMenuChildrenContainer);
}
async navigateToDragAndDropDatatable(): Promise<void> {
await this.clickDataTable();
await BrowserActions.click(this.dataTableDragAndDropButton);
await BrowserVisibility.waitUntilElementIsNotPresent(this.linkMenuChildrenContainer);
}
async navigateToCopyContentDatatable(): Promise<void> {
await this.clickDataTable();
await BrowserActions.click(this.dataTableCopyContentButton);
await BrowserVisibility.waitUntilElementIsNotPresent(this.linkMenuChildrenContainer);
}
async clickTagButton(): Promise<void> {
await this.clickNavigationBarItem('Tag');
}
async clickSocialButton(): Promise<void> {
await this.clickNavigationBarItem('Social');
}
async clickSettingsButton(): Promise<void> {
await this.clickNavigationBarItem('Settings');
}
async clickConfigEditorButton(): Promise<void> {
await this.clickNavigationBarItem('Configuration Editor');
}
async clickOverlayViewerButton(): Promise<void> {
await this.clickNavigationBarItem('Overlay Viewer');
}
async clickTreeViewButton(): Promise<void> {
await this.clickNavigationBarItem('Tree View');
}
async clickIconsButton(): Promise<void> {
await this.clickNavigationBarItem('Icons');
}
async clickAboutButton(): Promise<void> {
await this.clickNavigationBarItem('About');
}
async clickLogoutButton(): Promise<void> {
Logger.log('Logout');
try {
await BrowserActions.closeMenuAndDialogs();
await BrowserActions.clickExecuteScript('.app-sidenav-link[adf-logout]');
await BrowserVisibility.waitUntilElementIsPresent(this.logoutSection);
} catch (error) {
Logger.log('Logout section NOT found');
}
}
async clickThemeButton(): Promise<void> {
await BrowserActions.closeMenuAndDialogs();
await BrowserActions.click(this.themeButton);
await BrowserVisibility.waitUntilElementIsVisible(this.themeMenuContent);
}
async clickOnSpecificThemeButton(themeName): Promise<void> {
const themeElement = this.page.$(`button[data-automation-id="${themeName}"]`);
await BrowserActions.click(themeElement);
await BrowserVisibility.waitUntilElementIsNotPresent(this.linkMenuChildrenContainer);
}
async openContentServicesFolder(folderId): Promise<void> {
await BrowserActions.getUrl(`${browser.baseUrl}/files/${folderId}`);
}
async checkMenuButtonIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.menuButton);
}
async checkMenuButtonIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.menuButton);
}
async checkToolbarColor(color: string): Promise<void> {
const toolbarColor = this.page.$(`mat-toolbar[class*="mat-${color}"]`);
await BrowserVisibility.waitUntilElementIsVisible(toolbarColor);
}
async clickAppLogo(logoTitle: string): Promise<void> {
const appLogo = this.page.$('a[title="' + logoTitle + '"]');
await BrowserActions.click(appLogo);
}
async clickAppLogoText(): Promise<void> {
await BrowserActions.click(this.appTitle);
}
async checkLogoTooltip(logoTooltipTitle: string): Promise<void> {
const logoTooltip = this.page.$('a[title="' + logoTooltipTitle + '"]');
await BrowserVisibility.waitUntilElementIsVisible(logoTooltip);
}
async openViewer(nodeId: string): Promise<void> {
await BrowserActions.getUrl(browser.baseUrl + `/files(overlay:files/${nodeId}/view`);
}
async goToSite(site): Promise<void> {
await BrowserActions.getUrl(browser.baseUrl + `/files/${site.entry.guid}/display/list`);
}
async scrollTo(el: ElementFinder): Promise<void> {
await browser.executeScript(`return arguments[0].scrollTop = arguments[1].offsetTop`, this.linkListContainer.getWebElement(), el.getWebElement());
}
}

View File

@@ -0,0 +1,103 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { element, by, browser, $, $$ } from 'protractor';
import { BrowserVisibility, BrowserActions, DropdownPage, SnackbarPage } from '@alfresco/adf-testing';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
export class NotificationDemoPage extends ADFPage {
snackbarPage = new SnackbarPage();
messageField = $('input[data-automation-id="notification-message"]');
durationField = $('input[data-automation-id="notification-duration"]');
actionToggle = $('mat-slide-toggle[data-automation-id="notification-action-toggle"]');
notificationSnackBar = this.page.$$('simple-snack-bar')[0];
actionOutput = $('div[data-automation-id="notification-action-output"]');
notificationsPage = $('.app-sidenav-link[data-automation-id="Notifications"]');
notificationConfig = $('p[data-automation-id="notification-custom-object"]');
horizontalPositionDropdown = new DropdownPage($('mat-select[data-automation-id="notification-horizontal-position"]'));
verticalPositionDropdown = new DropdownPage($('mat-select[data-automation-id="notification-vertical-position"]'));
directionDropdown = new DropdownPage($('mat-select[data-automation-id="notification-direction"]'));
async checkNotifyContains(message): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(element.all(by.cssContainingText('simple-snack-bar', message))[0]);
}
async goToNotificationsPage(): Promise<void> {
await BrowserActions.click(this.notificationsPage);
}
getConfigObject(): Promise<string> {
return BrowserActions.getText(this.notificationConfig);
}
async isNotificationSnackBarDisplayed(): Promise<boolean> {
return this.snackbarPage.isNotificationSnackBarDisplayed();
}
async getSnackBarMessage(): Promise<string> {
return this.snackbarPage.getSnackBarMessage();
}
async waitForSnackBarToClose(): Promise<void> {
await this.snackbarPage.waitForSnackBarToClose(15000);
}
async enterMessageField(text: string): Promise<void> {
await BrowserActions.clearSendKeys(this.messageField, text);
}
async enterDurationField(time: number): Promise<void> {
await BrowserActions.clearSendKeys(this.durationField, time.toString());
}
async selectHorizontalPosition(selectItem: string): Promise<void> {
await this.horizontalPositionDropdown.selectDropdownOption(selectItem);
}
async selectVerticalPosition(selectItem: string): Promise<void> {
await this.verticalPositionDropdown.selectDropdownOption(selectItem);
}
async selectDirection(selectItem: string): Promise<void> {
await this.directionDropdown.selectDropdownOption(selectItem);
}
async clickNotificationButton(): Promise<void> {
const button = $('button[data-automation-id="notification-custom-config-button"]');
await BrowserActions.click(button);
}
async checkActionEvent(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.actionOutput);
}
async clickActionToggle(): Promise<void> {
await BrowserActions.click(this.actionToggle);
}
async clickActionButton(): Promise<void> {
await browser.executeScript(`document.querySelector("simple-snack-bar > div > button").click();`);
}
async clearMessage(): Promise<void> {
await BrowserActions.click(this.messageField);
await BrowserActions.clearWithBackSpace(this.messageField);
}
}

View File

@@ -0,0 +1,64 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BrowserActions, BrowserVisibility, DocumentListPage } from '@alfresco/adf-testing';
import { browser, $$, $ } from 'protractor';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
export class TrashcanPage extends ADFPage {
contentList = new DocumentListPage($('adf-document-list'));
rows = this.page.$$('adf-document-list div[class*="adf-datatable-body"] adf-datatable-row[class*="adf-datatable-row"]');
tableBody = this.page.$$('adf-document-list .adf-datatable-body')[0];
pagination = $('adf-pagination');
emptyTrashcan = $('adf-empty-content');
restoreButton = $(`button[title='Restore']`);
async numberOfResultsDisplayed(): Promise<number> {
return this.rows.length;
}
async waitForTableBody(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.tableBody);
}
async waitForPagination(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.pagination);
}
async checkTrashcanIsEmpty(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.emptyTrashcan);
}
getDocumentList(): DocumentListPage {
return this.contentList;
}
async clickRestore(): Promise<void> {
await BrowserActions.click(this.restoreButton);
await browser.sleep(2000);
}
async checkRestoreButtonIsNotDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.restoreButton);
}
async checkRestoreButtonIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.restoreButton);
}
}

View File

@@ -0,0 +1,166 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as path from 'path';
import { BrowserActions, TestElement, TogglePage } from '@alfresco/adf-testing';
import { $, browser } from 'protractor';
import { ADFPage } from '../../../lib/testing/src/lib/protractor/page';
export class VersionManagePage extends ADFPage {
togglePage = new TogglePage();
showNewVersionButton = TestElement.byId('adf-show-version-upload-button');
uploadNewVersionInput = TestElement.byCss('.adf-upload-version-button input[data-automation-id="upload-single-file"]');
uploadNewVersionButton = TestElement.byCss('.adf-upload-version-button');
uploadNewVersionContainer = TestElement.byId('adf-new-version-uploader-container');
cancelButton = TestElement.byId('adf-new-version-cancel');
majorRadio = TestElement.byId('adf-new-version-major');
minorRadio = TestElement.byId('adf-new-version-minor');
commentText = TestElement.byId('adf-new-version-text-area');
readOnlySwitch = $('#adf-version-manager-switch-readonly');
downloadSwitch = $('#adf-version-manager-switch-download');
commentsSwitch = $('#adf-version-manager-switch-comments');
confirmAccept = TestElement.byId('adf-confirm-accept');
confirmCancel = TestElement.byId('adf-confirm-cancel');
async uploadNewVersionFile(fileLocation: string): Promise<void> {
const filePath = path.resolve(path.join(browser.params.testConfig.main.rootPath, fileLocation));
await this.uploadNewVersionInput.waitPresent();
await this.uploadNewVersionInput.elementFinder.sendKeys(filePath);
await this.showNewVersionButton.waitVisible();
}
getFileVersionName(version: string): Promise<string> {
return TestElement.byCss(`[id="adf-version-list-item-name-${version}"]`).getText();
}
checkFileVersionExist(version: string): Promise<void> {
return TestElement.byId(`adf-version-list-item-version-${version}`).waitVisible();
}
checkFileVersionNotExist(version: string): Promise<void> {
return TestElement.byId(`adf-version-list-item-version-${version}`).waitNotVisible();
}
getFileVersionComment(version: string): Promise<string> {
return TestElement.byId(`adf-version-list-item-comment-${version}`).getText();
}
getFileVersionDate(version: string): Promise<string> {
return TestElement.byId(`adf-version-list-item-date-${version}`).getText();
}
/**
* disables readOnly
*/
async disableReadOnly(): Promise<void> {
await this.togglePage.disableToggle(this.readOnlySwitch);
}
/**
* enables readOnly
*/
async enableReadOnly(): Promise<void> {
await this.togglePage.enableToggle(this.readOnlySwitch);
}
/**
* disables download
*/
async disableDownload(): Promise<void> {
await this.togglePage.disableToggle(this.downloadSwitch);
}
/**
* enables download
*/
async enableDownload(): Promise<void> {
await this.togglePage.enableToggle(this.downloadSwitch);
}
/**
*
* disables comments
*/
async disableComments(): Promise<void> {
await this.togglePage.disableToggle(this.commentsSwitch);
}
/**
* enables comments
*/
async enableComments(): Promise<void> {
await this.togglePage.enableToggle(this.commentsSwitch);
}
async clickActionButton(version: string): Promise<void> {
await TestElement.byId(`adf-version-list-action-menu-button-${version}`).click();
await TestElement.byCss('.cdk-overlay-container .mat-menu-content').waitVisible();
}
async closeActionsMenu(): Promise<void> {
await BrowserActions.closeMenuAndDialogs();
}
async closeDisabledActionsMenu(): Promise<void> {
const container = TestElement.byCss('div.cdk-overlay-backdrop.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing');
await BrowserActions.closeDisabledMenu();
await container.waitNotVisible();
}
async downloadFileVersion(version: string): Promise<void> {
await this.clickActionButton(version);
const downloadButton = TestElement.byId(`adf-version-list-action-download-${version}`);
await downloadButton.click();
await downloadButton.waitNotVisible();
}
async deleteFileVersion(version: string): Promise<void> {
await this.clickActionButton(version);
const deleteButton = TestElement.byId(`adf-version-list-action-delete-${version}`);
await deleteButton.click();
}
async restoreFileVersion(version: string): Promise<void> {
await this.clickActionButton(version);
const restoreButton = TestElement.byId(`adf-version-list-action-restore-${version}`);
await restoreButton.click();
}
async viewFileVersion(version): Promise<void> {
await this.clickActionButton(version);
const viewButton = TestElement.byId(`adf-version-list-action-view-${version}`);
await viewButton.click();
}
async checkActionsArePresent(version: string): Promise<void> {
await TestElement.byId(`adf-version-list-action-download-${version}`).waitVisible();
await TestElement.byId(`adf-version-list-action-delete-${version}`).waitVisible();
await TestElement.byId(`adf-version-list-action-restore-${version}`).waitVisible();
}
async closeVersionDialog(): Promise<void> {
await BrowserActions.closeMenuAndDialogs();
await this.uploadNewVersionContainer.waitNotVisible();
}
}

View File

@@ -0,0 +1,49 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var ContentModel = function (details) {
this.mimeType = '';
this.mimeTypeName = '';
this.sizeInBytes = '';
this.encoding = '';
this.getMimeType = function () {
return this.mimeType;
};
this.getMimeTypeName = function () {
return this.mimeTypeName;
};
this.getSizeInBytes = function () {
if (this.sizeInBytes >= 1024) {
return (this.sizeInBytes / 1024).toFixed(2) + ' KB';
}
else {
return this.sizeInBytes;
}
};
this.getEncoding = function () {
return this.encoding;
};
Object.assign(this, details);
};
module.exports = ContentModel;

View File

@@ -0,0 +1,38 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var ContentPropertiesModel = function (details) {
this['cm:author'] = '';
this['cm:description'] = '';
this['cm:title'] = '';
this.getAuthor = function () {
return this['cm:author'];
};
this.getDescription = function () {
return this['cm:description'];
};
this.getTitle = function () {
return this['cm:title'];
};
Object.assign(this, details);
};
module.exports = ContentPropertiesModel;

View File

@@ -0,0 +1,36 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { StringUtil } from '@alfresco/adf-testing';
export class CreatedByModel {
displayName = StringUtil.generateRandomString();
id = StringUtil.generateRandomString();
constructor(details?: any) {
Object.assign(this, details);
}
getId() {
return this.id;
}
getDisplayName() {
return this.displayName;
}
}

View File

@@ -0,0 +1,117 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { browser } from 'protractor';
import ContentModel = require('./contentModel');
import ContentPropertiesModel = require('./contentProperties');
import { CreatedByModel } from './created-by-model';
import { StringUtil } from '@alfresco/adf-testing';
export class FileModel {
id = StringUtil.generateRandomString();
name = StringUtil.generateRandomString();
shortName = this.name;
location = browser.params.resources.Files.ADF_DOCUMENTS.PDF.file_path;
tooltip = this.name;
version = '';
firstPageText = browser.params.resources.Files.ADF_DOCUMENTS.PDF.first_page_text;
lastPageText = browser.params.resources.Files.ADF_DOCUMENTS.PDF.last_page_text;
secondPageText = browser.params.resources.Files.ADF_DOCUMENTS.PDF.second_page_text;
lastPageNumber = browser.params.resources.Files.ADF_DOCUMENTS.PDF.last_page_number;
createdAt = '';
password = '';
createdByUser = new CreatedByModel();
modifiedByUser = new CreatedByModel();
content: ContentModel = {};
properties: ContentPropertiesModel = {};
constructor(details?: any) {
Object.assign(this, details);
}
getName() {
return this.name;
}
setVersion(ver) {
this.version = '-' + ver;
}
getVersionName() {
const extension = this.name.split('.')[1];
const name = this.name.split('.')[0];
return name + this.version + '.' + extension;
}
getShortName() {
return this.shortName;
}
getLocation() {
return this.location;
}
getTooltip() {
return this.tooltip;
}
getId() {
return this.id;
}
getFirstPageText() {
return this.firstPageText;
}
getLastPageText() {
return this.lastPageText;
}
getSecondPageText() {
return this.secondPageText;
}
getLastPageNumber() {
return this.lastPageNumber;
}
getCreatedByUser(): CreatedByModel {
return this.createdByUser;
}
getModifiedByUser(): CreatedByModel {
return this.modifiedByUser;
}
getContent(): ContentModel {
return this.content;
}
getProperties(): ContentPropertiesModel {
return this.properties;
}
update(details) {
Object.assign(this, {
createdByUser: new CreatedByModel(details.createdByUser),
modifiedByUser: new CreatedByModel(details.modifiedByUser),
content: new ContentModel(details.content),
properties: new ContentPropertiesModel(details.properties)
});
}
}

View File

@@ -0,0 +1,53 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { StringUtil } from '@alfresco/adf-testing';
export class FolderModel {
id = StringUtil.generateRandomString();
name = StringUtil.generateRandomString();
shortName = this.name;
tooltip = this.name;
location = '';
description = '';
constructor(details?: any) {
Object.assign(this, details);
}
getName() {
return this.name;
}
getShortName() {
return this.shortName;
}
getTooltip() {
return this.tooltip;
}
getId() {
return this.id;
}
getLocation() {
return this.location;
}
}

View File

@@ -0,0 +1,31 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* App definition publish representation JSON Object
*
* @param details - JSON object used to overwrite the default values
* @constructor
*/
var AppPublish = function (details) {
this.comment = '';
this.force = true;
Object.assign(this, details);
};
module.exports = AppPublish;

View File

@@ -0,0 +1,58 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var FormDefinitionFieldModel = function (details) {
this.fieldType;
this.id;
this.name;
this.value;
this.type;
this.required;
this.readOnly;
this.overrideId;
this.colspan;
this.placeholder;
this.minLength;
this.maxLength;
this.minValue;
this.maxValue;
this.regexPattern;
this.optionType;
this.hasEmptyValue;
this.options;
this.restUrl;
this.restResponsePath;
this.restIdProperty;
this.setRestLabelProperty;
this.tab;
this.className;
this.dateDisplayFormat;
this.layout = {};
this.sizeX;
this.sizeY;
this.row;
this.col;
this.columnDefinitions;
this.visibilityCondition;
this.numberOfColumns;
this.fields = {};
Object.assign(this, details);
};
module.exports = FormDefinitionFieldModel;

View File

@@ -0,0 +1,61 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var FormDefinitionFieldModel = require('./FormDefinitionFieldModel');
var FormDefinitionModel = function (fields) {
var fields = null;
var widgets = null;
this.setFields = function (arr) {
fields = arr.map(function(item) {
return new FormDefinitionFieldModel(item);
})
};
this.setAllWidgets = function (arr) {
widgets = arr.reduce(function(acc, item) {
if(item.type === 'container') {
var children = Object.keys(item.fields).map(function(key) {
return item.fields[key][0];
});
return acc.concat(children);
}
return acc.concat(item);
}, []);
};
this.getWidgets = function () {
return widgets;
};
this.getWidgetBy = function (key, value) {
return widgets.find(function(widget) {
return widget[key]===value;
})
};
this.findFieldBy = function(key, value) {
return fields.find(function(field) {
return field[key]===value;
})
};
};
module.exports = FormDefinitionModel;

View File

@@ -0,0 +1,58 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var FormModel = function (details) {
this.id;
this.name;
this.description;
this.modelId;
this.appDefinitionId;
this.appDeploymentId;
this.tenantId;
this.getName = function () {
return this.name;
};
this.getId = function () {
return this.id;
};
this.getDescription = function () {
return this.description;
};
this.getModelId = function () {
return this.modelId;
};
this.getAppDefinitionId = function () {
return this.appDefinitionId;
};
this.getAppDeploymentId = function () {
return this.appDeploymentId;
};
this.getTenantId = function () {
return this.tenantId;
};
Object.assign(this, details);
};
module.exports = FormModel;

View File

@@ -0,0 +1,32 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Create and manage task JSON Object
*
* @param details - JSON object used to overwrite the default values
* @constructor
*/
var Task = function (details) {
this.processInstanceId;
this.sort;
Object.assign(this, details);
};
module.exports = Task;

View File

@@ -0,0 +1,49 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var TaskAssigneeModel = function (details) {
this.id;
this.firstName;
this.lastName;
this.email;
this.getFirstName = function () {
return this.firstName;
};
this.getId = function () {
return this.id;
};
this.getLastName = function () {
return this.lastName;
};
this.getEmail = function () {
return this.email;
};
this.getEntireName = function() {
return this.firstName + " " + this.getLastName();
};
Object.assign(this, details);
};
module.exports = TaskAssigneeModel;

View File

@@ -0,0 +1,91 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var TaskAssigneeModel = require('./TaskAssigneeModel');
var TaskModel = function (details) {
this.id;
this.name;
this.description;
this.category;
this.created;
this.dueDate;
this.priority;
this.parentTaskName;
this.parentTaskId;
this.formKey;
this.duration;
this.endDate;
this.assignee = {};
this.getName = function () {
return this.name;
};
this.getId = function () {
return this.id;
};
this.getDescription = function () {
return this.description;
};
this.getCategory = function () {
return this.category;
};
this.getCreated = function () {
return this.created;
};
this.getDueDate = function () {
return this.dueDate;
};
this.getPriority = function () {
return this.priority;
};
this.getDuration = function () {
return this.duration;
};
this.getEndDate = function () {
return this.endDate;
};
this.getParentTaskName = function () {
return this.parentTaskName;
};
this.getParentTaskId = function () {
return this.parentTaskId;
};
this.getFormKey = function () {
return this.formKey;
};
this.getAssignee = function () {
return this.assignee;
};
Object.assign(this, details);
Object.assign(this.assignee, new TaskAssigneeModel(details.assignee));
};
module.exports = TaskModel;

View File

@@ -0,0 +1,29 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"noEmit": true,
"outDir": "../out-tsc/e2e",
"baseUrl": ".",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"jasminewd2",
"node"
],
"paths": {
"@alfresco/adf-testing": [
"../lib/testing"
],
"@alfresco/adf-process-services-cloud": [
"../lib/process-services-cloud"
]
}
},
"include": [
"**/*.ts"
],
"exclude": [
"node_modules"
]
}

View File

@@ -38,6 +38,8 @@ const E2E_LOG_LEVEL = process.env.E2E_LOG_LEVEL || 'ERROR';
const appConfig = {
"log": E2E_LOG_LEVEL,
"hostEcm": HOST_ECM,
"hostBpm": HOST_ECM,
"ecmHost": HOST_ECM,
"bpmHost": HOST_BPM,
"identityHost": `${HOST_SSO}/auth/admin/realms/alfresco`,
@@ -61,6 +63,34 @@ const appConfig = {
}
};
const users = {
admin: {
username: USERNAME_ADF,
password: PASSWORD_ADF
},
superadmin: {
username: USERNAME_SUPER_ADMIN_ADF,
password: PASSWORD_SUPER_ADMIN_ADF
},
identityAdmin: {
username: IDENTITY_ADMIN_EMAIL,
password: IDENTITY_ADMIN_PASSWORD
},
hrUser: {
username: HR_USER,
password: HR_USER_PASSWORD
},
screenshot: {
username: USERNAME_ADF,
password: PASSWORD_ADF
},
};
if (LOG) {
console.log('======= test.config.js hostBPM ====== ');
console.log('hostBPM : ' + HOST_ECM);
@@ -82,33 +112,7 @@ module.exports = {
rootPath: __dirname
},
users: {
admin: {
username: USERNAME_ADF,
password: PASSWORD_ADF
},
superadmin: {
username: USERNAME_SUPER_ADMIN_ADF,
password: PASSWORD_SUPER_ADMIN_ADF
},
identityAdmin: {
username: IDENTITY_ADMIN_EMAIL,
password: IDENTITY_ADMIN_PASSWORD
},
hrUser: {
username: HR_USER,
password: HR_USER_PASSWORD
},
screenshot: {
username: USERNAME_ADF,
password: PASSWORD_ADF
},
},
users: users,
screenshot: {
url: HOST_ECM,

View File

@@ -18,29 +18,16 @@
import { AlfrescoApiConfig } from '@alfresco/js-api';
import { ApiService } from '../../../shared/api/api.service';
import { Logger } from '../utils/logger';
import { browser } from 'protractor';
export function createApiService(
/** @deprecated */
appConfigOverride: Partial<AlfrescoApiConfig> = {}
appConfigOverride: Partial<AlfrescoApiConfig> = {}, users
) {
const patchedAppConfig = {
...browser.params.testConfig.appConfig,
oauth2: {
...browser.params.testConfig.appConfig.oauth2,
// For some reason protractor e2es must have this value hardcoded
implicitFlow: false
},
// Legacy debt...
hostEcm: browser.params.testConfig.appConfig.ecmHost,
hostBpm: browser.params.testConfig.appConfig.bpmHost,
...appConfigOverride
};
return new ApiService(
{
appConfig: new AlfrescoApiConfig(patchedAppConfig),
users: browser.params.testConfig.users
appConfig: new AlfrescoApiConfig(appConfigOverride),
users: users
},
Logger
);

View File

@@ -16,7 +16,6 @@
*/
import { StringUtil } from '../../../shared/utils/string.util';
import { browser } from 'protractor';
import { UserRepresentation } from '@alfresco/js-api';
export class UserModel {
@@ -33,7 +32,7 @@ export class UserModel {
id: number;
constructor(details: any = {}) {
const EMAIL_DOMAIN = browser.params?.testConfig?.projectName ? browser.params.testConfig.projectName : 'alfresco';
const EMAIL_DOMAIN = 'alfresco';
this.firstName = details.firstName ? details.firstName : this.firstName;
this.lastName = details.lastName ? details.lastName : this.lastName;

View File

@@ -15,27 +15,28 @@
* limitations under the License.
*/
import { element, by, browser, protractor, $ } from 'protractor';
import { browser, protractor } from 'protractor';
import { BrowserVisibility } from '../utils/browser-visibility';
import { BrowserActions } from '../utils/browser-actions';
import { LocalStorageUtil } from '../utils/local-storage.util';
import { Logger } from '../utils/logger';
import { ADFPage } from '../../page';
export class LoginPage {
export class LoginPage extends ADFPage {
loginUrl = `${browser.baseUrl}/login`;
loginUrl = `/login`;
ssoButton = $(`[data-automation-id="login-button-sso"]`);
usernameField = $('#username');
passwordField = $('#password');
loginButton = $('input[type="submit"]');
header = element(by.tagName('adf-layout-header'));
loginError = $(`div[data-automation-id="login-error"]`);
visibilityLabel = $('#v');
ssoButton = this.page.$(`[data-automation-id="login-button-sso"]`);
usernameField = this.page.$('#username');
passwordField = this.page.$('#password');
loginButton = this.page.$('input[type="submit"]');
header = this.page.$('adf-layout-header');
loginError = this.page.$(`div[data-automation-id="login-error"]`);
visibilityLabel = this.page.$('#v');
txtUsernameBasicAuth = $('input[id="username"]');
txtPasswordBasicAuth = $('input[id="password"]');
signInButtonBasicAuth = $('#login-button');
txtUsernameBasicAuth = this.page.$('input[id="username"]');
txtPasswordBasicAuth = this.page.$('input[id="password"]');
signInButtonBasicAuth = this.page.$('#login-button');
async goToLoginPage(): Promise<void> {
let currentUrl;
@@ -65,7 +66,8 @@ export class LoginPage {
async login(username: string, password: string) {
Logger.log('Login With ' + username);
const authType = await LocalStorageUtil.getConfigField('authType');
const localStorageUtil = new LocalStorageUtil(this.page);
const authType = await localStorageUtil.getConfigField('authType');
if (!authType || authType === 'OAUTH') {
await this.loginSSOIdentityService(username, password);
@@ -77,24 +79,20 @@ export class LoginPage {
}
async loginSSOIdentityService(username: string, password: string) {
browser.ignoreSynchronization = true;
const localStorageUtil = new LocalStorageUtil(this.page);
const oauth2 = await localStorageUtil.getConfigField('oauth2');
const loginURL: string = browser.baseUrl + (browser.params.loginRoute ? browser.params.loginRoute : '');
const oauth2 = await LocalStorageUtil.getConfigField('oauth2');
await BrowserActions.getUrl(loginURL);
await this.page.goto('https://adfdev.envalfresco.com/adf');
if (oauth2 && oauth2.silentLogin === false) {
await this.clickOnSSOButton();
}
await BrowserVisibility.waitUntilElementIsVisible(this.usernameField);
await this.displayPassword();
await this.enterUsername(username);
await this.enterPassword(password);
await this.clickLoginButton();
await browser.actions().sendKeys(protractor.Key.ENTER).perform();
await BrowserVisibility.waitUntilElementIsVisible(this.header, BrowserVisibility.DEFAULT_TIMEOUT * 2);
await this.page.keyboard.press(protractor.Key.ENTER);
}
async loginBasicAuth(username: string, password: string): Promise<void> {
@@ -143,8 +141,9 @@ export class LoginPage {
}
async displayPassword(): Promise<void> {
(await this.visibilityLabel).isVisible();
await BrowserActions.click(this.visibilityLabel);
const passwordInputTypeText = $(`input[name="password"][type="text"]`);
const passwordInputTypeText = this.page.$(`input[name="password"][type="text"]`);
await BrowserVisibility.waitUntilElementIsVisible(passwordInputTypeText);
}

View File

@@ -22,9 +22,16 @@ import { Logger } from './logger';
import * as path from 'path';
import * as fs from 'fs';
import { ApiUtil } from '../../../shared/api/api.util';
import { Page } from '@playwright/test';
export class BrowserActions {
readonly page: Page;
constructor(private page: Page) {
this.page = page;
}
static async clickUntilIsNotVisible(elementToClick: ElementFinder, elementToFind: ElementFinder): Promise<void> {
Logger.info(`Click until element is not present: ${elementToClick.locator().toString()}`);
@@ -46,19 +53,11 @@ export class BrowserActions {
return ApiUtil.waitForApi(apiCall, predicate, 10, 2000);
}
static async click(elementToClick: ElementFinder): Promise<void> {
try {
Logger.info(`Click element: ${elementToClick.locator().toString()}`);
await BrowserVisibility.waitUntilElementIsVisible(elementToClick);
await BrowserVisibility.waitUntilElementIsClickable(elementToClick);
await elementToClick.click();
} catch (clickErr) {
Logger.warn(`click error element ${elementToClick.locator().toString()} consider to use directly clickScript`);
await this.clickScript(elementToClick);
}
static async click(elementToClick: any): Promise<void> {
await elementToClick.click();
}
static async clickScript(elementToClick: ElementFinder): Promise<void> {
static async clickScript(elementToClick: any): Promise<void> {
Logger.info(`Click script ${elementToClick.locator().toString()}`);
await browser.executeScript(`arguments[0].scrollIntoView();`, elementToClick);
@@ -86,9 +85,9 @@ export class BrowserActions {
await BrowserVisibility.waitUntilElementIsNotVisible(actionMenu);
}
static async getUrl(url: string, timeout: number = 10000): Promise<any> {
static async getUrl(url: string, timeout: number = 10000): Promise<void> {
Logger.info(`Get URL ${url}`);
return browser.get(url, timeout);
await this.page.goto(url, { timeout: timeout });
}
static async getAttribute(elementFinder: ElementFinder, attribute: string): Promise<string> {
@@ -97,7 +96,7 @@ export class BrowserActions {
return attributeValue || '';
}
static async getText(elementFinder: ElementFinder): Promise<string> {
static async getText(elementFinder: any): Promise<string> {
Logger.info(`Get Text ${elementFinder.locator().toString()}`);
const present = await BrowserVisibility.waitUntilElementIsVisible(elementFinder);
@@ -136,17 +135,17 @@ export class BrowserActions {
}
}
static async getArrayText(elementFinders: ElementArrayFinder): Promise<string> {
static async getArrayText(elementFinders: any): Promise<string> {
return elementFinders.getText();
}
static async getColor(elementFinder: ElementFinder): Promise<string> {
static async getColor(elementFinder: any): Promise<string> {
await BrowserVisibility.waitUntilElementIsVisible(elementFinder);
const webElem = await elementFinder.getWebElement();
return webElem.getCssValue('color');
}
static async clearWithBackSpace(elementFinder: ElementFinder, sleepTime: number = 0) {
static async clearWithBackSpace(elementFinder: any, sleepTime: number = 0) {
await BrowserVisibility.waitUntilElementIsVisible(elementFinder);
await elementFinder.click();
await elementFinder.sendKeys(protractor.Key.END);
@@ -160,7 +159,7 @@ export class BrowserActions {
}
}
static async clearSendKeys(elementFinder: ElementFinder, text: string = '', sleepTime: number = 0): Promise<void> {
static async clearSendKeys(elementFinder: any, text: string = '', sleepTime: number = 0): Promise<void> {
Logger.info(`Clear and sendKeys text:${text} locator:${elementFinder.locator().toString()}`);
await this.click(elementFinder);

View File

@@ -51,7 +51,7 @@ export class BrowserVisibility {
/*
* Wait for element to be visible
*/
static async waitUntilElementIsVisible(elementToCheck: ElementFinder, waitTimeout: number = BrowserVisibility.DEFAULT_TIMEOUT, message: string = 'Element is not visible'): Promise<any> {
static async waitUntilElementIsVisible(elementToCheck: any, waitTimeout: number = BrowserVisibility.DEFAULT_TIMEOUT, message: string = 'Element is not visible'): Promise<any> {
Logger.info(`Wait Until Element Is Visible ${elementToCheck.locator().toString()} for ${waitTimeout}`);
return browser.wait(protractor.ExpectedConditions.visibilityOf(elementToCheck), waitTimeout, message + elementToCheck.locator());

View File

@@ -15,55 +15,55 @@
* limitations under the License.
*/
import { browser } from 'protractor';
import { ADFPage } from '../../page';
export class LocalStorageUtil {
export class LocalStorageUtil extends ADFPage {
static async getConfigField(field: string): Promise<any> {
return browser.executeScript(
'return window.adf ? window.adf.getConfigField(`' + field + '`) : null;'
async getConfigField(field: string): Promise<any> {
return this.page.evaluate(() =>
window.adf ? window.adf.getConfigField(field) : null
);
}
static async setConfigField(field: string, value: string): Promise<void> {
await browser.executeScript(
'window.adf.setConfigField(`' + field + '`, `' + value + '`);'
async setConfigField(field: string, value: string): Promise<void> {
await this.page.evaluate(() =>
window.adf.setConfigField(field, value)
);
}
static async setStorageItem(field: string, value: string): Promise<void> {
await browser.executeScript(
'window.adf.setStorageItem(`' + field + '`, `' + value + '`);'
async setStorageItem(field: string, value: string): Promise<void> {
await this.page.evaluate(() =>
window.adf.setStorageItem(field, value)
);
}
static async removeStorageItem(field: string): Promise<void> {
await browser.executeScript(
'window.adf.removeStorageItem(`' + field + '`);'
async removeStorageItem(field: string): Promise<void> {
await this.page.evaluate(() =>
window.adf.removeStorageItem(field)
);
}
static async getStorageItem(field: string): Promise<any> {
return browser.executeScript(
'return window.adf ? window.adf.getStorageItem(`' + field + '`) : null;'
async getStorageItem(field: string): Promise<any> {
return this.page.evaluate(() =>
window.adf ? window.adf.getStorageItem(field) : null
);
}
static async setUserPreference(field: string, value: any): Promise<void> {
await browser.executeScript(
'window.adf.setUserPreference(`' + field + '`, `' + value + '`);'
async setUserPreference(field: string, value: any): Promise<void> {
await this.page.evaluate(() =>
window.adf.setUserPreference(field, value)
);
}
static async clearStorage(): Promise<void> {
await browser.executeScript(
'window.adf.clearStorage();'
async clearStorage(): Promise<void> {
await this.page.evaluate(() =>
window.adf.clearStorage()
);
}
static async apiReset(): Promise<void> {
await browser.executeScript(
`window.adf.apiReset();`
async apiReset(): Promise<void> {
await this.page.evaluate(() =>
window.adf.apiReset()
);
}

View File

@@ -21,4 +21,4 @@ import { browser } from 'protractor';
// This was previously a static class, that is why we need this constant starting with uppercase
// Otherwise, feel free to update everywhere in the codebase, where we were using it :)
/* tslint:disable:variable-name */
export const Logger = new GenericLogger(browser?.params?.testConfig?.appConfig?.log);
export const Logger = new GenericLogger('TRACE');

View File

@@ -0,0 +1,9 @@
import { Page } from '@playwright/test';
export abstract class ADFPage {
constructor(public readonly page?: Page) {}
async close() {
await this.page.close();
}
}

5368
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -114,6 +114,7 @@
"@nrwl/storybook": "^12.9.0",
"@nrwl/workspace": "^11.2.11",
"@paperist/types-remark": "0.1.3",
"@playwright/test": "^1.18.0",
"@storybook/addon-essentials": "~6.3.0",
"@storybook/angular": "~6.3.0",
"@storybook/builder-webpack5": "~6.3.0",

111
playwright.config.ts Normal file
View File

@@ -0,0 +1,111 @@
import { PlaywrightTestConfig, devices } from '@playwright/test';
/**
* See https://playwright.dev/docs/test-configuration.
*/
const config: PlaywrightTestConfig = {
testDir: './e2e-play',
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000
},
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://localhost:3000',
baseURL: 'https://apadev.envalfresco.com',
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
},
/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
/* Project-specific settings. */
use: {
...devices['Desktop Chrome'],
},
},
// {
// name: 'firefox',
// use: {
// ...devices['Desktop Firefox'],
// },
// },
//
// {
// name: 'webkit',
// use: {
// ...devices['Desktop Safari'],
// },
// },
/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: {
// ...devices['Pixel 5'],
// },
// },
// {
// name: 'Mobile Safari',
// use: {
// ...devices['iPhone 12'],
// },
// },
/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: {
// channel: 'msedge',
// },
// },
// {
// name: 'Google Chrome',
// use: {
// channel: 'chrome',
// },
// },
],
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
// outputDir: 'test-results/',
/* Run your local dev server before starting the tests */
// webServer: {
// command: 'npm run start',
// port: 3000,
// },
};
export default config;