[ACS-259] refactor login page (#5733)

* refator login page

* refator login page

* remove obsolete classes and move what is needed in the test pck

* fix const

* revert modify

* remove duplicate browser property

* fix build

* fix

* fix

* fix lint

* move drop action in testing
remove not necessary space
js-api centralize content

* first refactor use js-api

* fix protractor

* refactor test config

* simplify properties
fix namings

* ps cloud simplify
remove unused js files

* id fix

* fix search test
simplify environment var step 1

* fix lint

* first user iteration fix

* fix model

* unify use of apiService

* first step automatic user creation Identity

* refactor creation user content-services

* refactor creation user search

* refactor creation user core

* process service refactoring 1

* process service refactoring 1

* process service refactoring 2

* fix process

* appconfig

* fix process util

* fix gallery

* fix "this" reference issues

* fix incorrect import paths

* fix core

* some fixes

* allign

* fix some test
remove structure folder and move in actions

* fixes

* move folders in the right place

* fix

* fix rebase

* solve build issue

* fix e2e

* change init aae

* order api and some fixes

* fix possible not valid password

* fix some ps test

* replace host port also in objects

* Update app-config.service.ts

* fix process

* fix process test

* process service cloud fix

* fiexs

* modify init script

* fix two test

* remove unused property

* host issue

* not use npx

* fix ps cloud test

Co-authored-by: Denys Vuika <denys.vuika@gmail.com>
This commit is contained in:
Eugenio Romano
2020-06-04 14:41:30 +01:00
committed by GitHub
parent f0df6b3a5f
commit a78f24ada1
297 changed files with 5130 additions and 9622 deletions

View File

@@ -5,8 +5,8 @@ Contains the reusable pages for e2e tests
## Run e2e against a remote env using the .env.cloud file
Create a file `.env.cloud` under the `e2e` folder
```
URL_HOST_BPM_ADF="https://gateway.example.com"
URL_HOST_SSO_ADF="https://identity.example.com/auth/realms/alfresco"
HOST_BPM="https://gateway.example.com"
HOST_SSO="https://identity.example.com/auth/realms/alfresco"
URL_HOST_IDENTITY="https://identity.example.com/auth/admin/realms/alfresco"
IDENTITY_USERNAME_ADF="username"
IDENTITY_PASSWORD_ADF="password"
@@ -45,8 +45,8 @@ or `./scripts/test-e2e-lib.sh -host http://myadf.example.com -s process-services
## Run e2e against a local env (use dist) using the .env.cloud file
Create a file `.env.cloud` under the `e2e` folder
```
URL_HOST_BPM_ADF="https://gateway.example.com"
URL_HOST_SSO_ADF="https://identity.example.com/auth/realms/alfresco"
HOST_BPM="https://gateway.example.com"
HOST_SSO="https://identity.example.com/auth/realms/alfresco"
URL_HOST_IDENTITY="https://identity.example.com/auth/admin/realms/alfresco"
IDENTITY_USERNAME_ADF="username"
IDENTITY_PASSWORD_ADF="password"

View File

@@ -15,13 +15,14 @@
* limitations under the License.
*/
import { AlfrescoApiCompatibility as AlfrescoApi, NodeEntry, NodeBodyUpdate } from '@alfresco/js-api';
import { NodeEntry, NodeBodyUpdate } from '@alfresco/js-api';
import { ApiService } from '../../core/actions/api.service';
export class PermissionActions {
alfrescoJsApi: AlfrescoApi = null;
api: ApiService;
constructor(alfrescoJsApi: AlfrescoApi) {
this.alfrescoJsApi = alfrescoJsApi;
constructor(apiService: ApiService) {
this.api = apiService;
}
addRoleForUser(userName: string, role: string, nodeToUpdate: NodeEntry): Promise<NodeEntry> {
@@ -36,17 +37,17 @@ export class PermissionActions {
]
}
};
return this.alfrescoJsApi.nodes.updateNode(nodeToUpdate.entry.id, payload);
return this.api.apiService.nodes.updateNode(nodeToUpdate.entry.id, payload);
}
disableInheritedPermissionsForNode(nodeId: string): Promise<NodeEntry> {
const nodeBody = { permissions: { isInheritanceEnabled: false } };
return this.alfrescoJsApi.nodes.updateNode(nodeId, nodeBody, { include: ['permissions'] });
return this.api.apiService.nodes.updateNode(nodeId, nodeBody, { include: ['permissions'] });
}
enableInheritedPermissionsForNode(nodeId: string): Promise<NodeEntry> {
const nodeBody = { permissions: { isInheritanceEnabled: true } };
return this.alfrescoJsApi.nodes.updateNode(nodeId, nodeBody, { include: ['permissions'] });
return this.api.apiService.nodes.updateNode(nodeId, nodeBody, { include: ['permissions'] });
}
}

View File

@@ -17,22 +17,23 @@
import * as path from 'path';
import * as fs from 'fs';
import { AlfrescoApiCompatibility as AlfrescoApi } from '@alfresco/js-api';
import { NodeEntry } from '@alfresco/js-api/src/api/content-rest-api/model/nodeEntry';
import { ApiUtil } from '../../core/structure/api.util';
import { NodeEntry } from '@alfresco/js-api';
import { ApiUtil } from '../../core/actions/api.util';
import { Logger } from '../../core/utils/logger';
import { ApiService } from '../../core/actions/api.service';
export class UploadActions {
alfrescoJsApi: AlfrescoApi = null;
constructor(alfrescoJsApi: AlfrescoApi) {
this.alfrescoJsApi = alfrescoJsApi;
api: ApiService;
constructor(alfrescoJsApi: ApiService) {
this.api = alfrescoJsApi;
}
async uploadFile(fileLocation, fileName, parentFolderId): Promise<any> {
const file = fs.createReadStream(fileLocation);
return this.alfrescoJsApi.upload.uploadFile(
return this.api.apiService.upload.uploadFile(
file,
'',
parentFolderId,
@@ -55,11 +56,11 @@ export class UploadActions {
filesRequest.push(jsonItem);
}
return this.alfrescoJsApi.nodes.addNode(parentFolderId, <any> filesRequest, {});
return this.api.apiService.nodes.addNode(parentFolderId, <any> filesRequest, {});
}
async createFolder(folderName, parentFolderId): Promise<NodeEntry> {
return this.alfrescoJsApi.node.addNode(parentFolderId, {
return this.api.apiService.node.addNode(parentFolderId, {
name: folderName,
nodeType: 'cm:folder'
}, {});
@@ -68,7 +69,7 @@ export class UploadActions {
async deleteFileOrFolder(nodeId) {
const apiCall = async () => {
try {
return this.alfrescoJsApi.node.deleteNode(nodeId, { permanent: true });
return this.api.apiService.node.deleteNode(nodeId, { permanent: true });
} catch (error) {
Logger.error('Error delete file or folder');
}

View File

@@ -19,7 +19,7 @@ import { by, element, ElementFinder } from 'protractor';
import { DocumentListPage } from '../pages/document-list.page';
import { BrowserVisibility } from '../../core/utils/browser-visibility';
import { BrowserActions } from '../../core/utils/browser-actions';
import { DropdownPage } from '../../material/pages/dropdown.page';
import { DropdownPage } from '../../core/pages/material/dropdown.page';
import { DataTableComponentPage } from '../../core/pages/data-table-component.page';
export class ContentNodeSelectorDialogPage {

View File

@@ -16,7 +16,7 @@
*/
import { by, protractor, ElementFinder, Locator, element } from 'protractor';
import { DatePickerCalendarPage } from '../../../material/pages/date-picker-calendar.page';
import { DatePickerCalendarPage } from '../../../core/pages/material/date-picker-calendar.page';
import { BrowserVisibility } from '../../../core/utils/browser-visibility';
import { BrowserActions } from '../../../core/utils/browser-actions';

View File

@@ -18,7 +18,7 @@
import { browser, by, element, ElementFinder } from 'protractor';
import { BrowserActions } from '../../../core/utils/browser-actions';
import { BrowserVisibility } from '../../../core/utils/browser-visibility';
import { DropdownPage } from '../../../material/pages/dropdown.page';
import { DropdownPage } from '../../../core/pages/material/dropdown.page';
export class SearchSortingPickerPage {

View File

@@ -1,69 +0,0 @@
/*!
* @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 { AlfrescoApiCompatibility as AlfrescoApi } from '@alfresco/js-api';
import { Logger } from '../../utils/logger';
import * as remote from 'selenium-webdriver/remote';
import { browser } from 'protractor';
import * as fs from 'fs';
export class AppPublish {
comment: string = '';
force: boolean = true;
}
export class ApplicationsUtil {
api: AlfrescoApi;
constructor(api: AlfrescoApi) {
this.api = api;
}
async importPublishDeployApp(appFileLocation, option = {}) {
try {
const appCreated = await this.importApplication(appFileLocation, option);
const publishApp = await this.api.activiti.appsApi.publishAppDefinition(appCreated.id, new AppPublish());
await this.api.activiti.appsApi.deployAppDefinitions({ appDefinitions: [{ id: publishApp.appDefinition.id }] });
return appCreated;
} catch (error) {
Logger.error('Import Publish Deploy Application - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
}
}
async importApplication(appFileLocation, options = {}): Promise<any> {
try {
browser.setFileDetector(new remote.FileDetector());
const file = fs.createReadStream(appFileLocation);
return await this.api.activiti.appsDefinitionApi.importAppDefinition(file, options);
} catch (error) {
Logger.error('Import Application - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
}
}
async getAppDefinitionByName(appName): Promise<any> {
try {
const appDefinitionsList = await this.api.activiti.appsApi.getAppDefinitions();
const appDefinition = appDefinitionsList.data.filter((currentApp) => {
return currentApp.name === appName;
});
return appDefinition;
} catch (error) {
Logger.error('Get AppDefinitions - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
}
}
}

View File

@@ -16,6 +16,7 @@
*/
import { AlfrescoApiCompatibility as AlfrescoApi, AlfrescoApiConfig } from '@alfresco/js-api';
import { browser } from 'protractor';
export class ApiService {
@@ -23,28 +24,44 @@ export class ApiService {
config: AlfrescoApiConfig;
constructor(clientId: string, host: string, hostSso: string, provider: string) {
this.config = {
provider,
hostBpm: host,
hostEcm: host,
authType: 'OAUTH',
oauth2: {
host: hostSso,
clientId,
scope: 'openid',
secret: '',
implicitFlow: false,
silentLogin: false,
redirectUri: '/',
redirectUriLogout: '/logout'
}
constructor(clientIdOrAppConfig?: AlfrescoApiConfig | string, host?: string, hostSso?: string, provider?: string) {
};
if (browser.params.testConfig && browser.params.testConfig.appConfig) {
this.config = { ...browser.params.testConfig.appConfig };
this.config.hostEcm = browser.params.testConfig.appConfig.ecmHost;
this.config.hostBpm = browser.params.testConfig.appConfig.bpmHost;
}
if (clientIdOrAppConfig && typeof clientIdOrAppConfig !== 'string') {
this.config = { ...browser.params.testConfig.appConfig, ...clientIdOrAppConfig };
this.config.hostEcm = clientIdOrAppConfig.hostEcm ? clientIdOrAppConfig.hostEcm : browser.params.testConfig.appConfig.ecmHost;
this.config.hostBpm = clientIdOrAppConfig.hostBpm ? clientIdOrAppConfig.hostBpm : browser.params.testConfig.appConfig.bpmHost;
} else if (clientIdOrAppConfig && typeof clientIdOrAppConfig === 'string') {
this.config.oauth2.clientId = clientIdOrAppConfig;
}
if (hostSso) {
this.config.oauth2.host = hostSso;
}
if (host) {
this.config.hostBpm = host;
this.config.hostEcm = host;
}
if (provider) {
this.config.provider = provider;
}
this.config.oauth2.implicitFlow = false;
this.apiService = new AlfrescoApi(this.config);
}
getInstance(): AlfrescoApi {
return this.apiService;
}
async login(username: string, password: string): Promise<void> {
await this.apiService.login(username, password);
}

View File

@@ -19,24 +19,24 @@ import { AlfrescoApi } from '@alfresco/js-api';
import { browser } from 'protractor';
export abstract class Api {
public api: AlfrescoApi;
testConfig = browser.params;
public api: AlfrescoApi;
constructor(root: string) {
this.api = this.configureApi(root);
}
constructor(root: string) {
this.api = this.configureApi(root);
}
private configureApi(root: string): AlfrescoApi {
const config = browser.params.adminapp.apiConfig;
return new AlfrescoApi({
provider: 'BPM',
authType: config.authType,
oauth2: config.oauth2,
hostBpm: config.bpmHost + '/' + root
});
}
private configureApi(root: string): AlfrescoApi {
const config = browser.params.adminapp.apiConfig;
abstract setUp(): Promise<Api>;
return new AlfrescoApi({
provider: 'BPM',
authType: config.authType,
oauth2: config.oauth2,
hostBpm: config.bpmHost + '/' + root
});
}
abstract tearDown();
abstract setUp(): Promise<Api>;
abstract tearDown();
}

View File

@@ -0,0 +1,100 @@
/*!
* @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 * as path from 'path';
import * as fs from 'fs';
import * as remote from 'selenium-webdriver/remote';
const JS_BIND_INPUT = function(target) {
const input = document.createElement('input');
input.type = 'file';
input.style.display = 'none';
input.addEventListener('change', function() {
target.scrollIntoView(true);
const rect = target.getBoundingClientRect();
const x = rect.left + (rect.width >> 1);
const y = rect.top + (rect.height >> 1);
const data = { files: input.files };
['dragenter', 'dragover', 'drop'].forEach(function(name) {
const mouseEvent: any = document.createEvent('MouseEvent');
mouseEvent.initMouseEvent(name, !0, !0, window, 0, 0, 0, x, y, !1, !1, !1, !1, 0, null);
mouseEvent.dataTransfer = data;
target.dispatchEvent(mouseEvent);
});
document.body.removeChild(input);
}, false);
document.body.appendChild(input);
return input;
};
const JS_BIND_INPUT_FOLDER = function(target) {
const input: any = document.createElement('input');
input.type = 'file';
input.style.display = 'none';
input.multiple = true;
input.webkitdirectory = true;
input.addEventListener('change', function() {
target.scrollIntoView(true);
const rect = target.getBoundingClientRect();
const x = rect.left + (rect.width >> 1);
const y = rect.top + (rect.height >> 1);
const data = { files: input.files };
['dragenter', 'dragover', 'drop'].forEach(function(name) {
const mouseEvent: any = document.createEvent('MouseEvent');
mouseEvent.initMouseEvent(name, !0, !0, window, 0, 0, 0, x, y, !1, !1, !1, !1, 0, null);
mouseEvent.dataTransfer = data;
target.dispatchEvent(mouseEvent);
});
document.body.removeChild(input);
}, false);
document.body.appendChild(input);
return input;
};
export class DropActions {
async dropFile(dropArea, filePath) {
browser.setFileDetector(new remote.FileDetector());
const absolutePath = path.resolve(path.join(browser.params.testConfig.main.rootPath, filePath));
fs.accessSync(absolutePath, fs.constants.F_OK);
const elem = await dropArea.getWebElement();
const input: any = await browser.executeScript(JS_BIND_INPUT, elem);
return input.sendKeys(absolutePath);
}
async dropFolder(dropArea, folderPath) {
browser.setFileDetector(new remote.FileDetector());
const absolutePath = path.resolve(path.join(browser.params.testConfig.main.rootPath, folderPath));
fs.accessSync(absolutePath, fs.constants.F_OK);
const elem = await dropArea.getWebElement();
const input: any = await browser.executeScript(JS_BIND_INPUT_FOLDER, elem);
return input.sendKeys(absolutePath);
}
}

View File

@@ -0,0 +1,121 @@
/*!
* @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 { Api } from './api';
import { ApiService } from './api.service';
import { AlfrescoApiCompatibility as AlfrescoApi } from '@alfresco/js-api';
export interface E2eRequestApiHelperOptions {
pathParams?: { [key: string]: any };
queryParams?: { [key: string]: any };
headerParams?: { [key: string]: any };
formParams?: { [key: string]: any };
bodyParam?: { [key: string]: any };
contentTypes?: string[];
accepts?: string[];
returnType?: any;
contextRoot?: string;
responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text';
}
function getDefaultOptions(): E2eRequestApiHelperOptions {
return {
pathParams: {},
queryParams: {},
headerParams: {},
formParams: {},
bodyParam: {},
contentTypes: ['application/json'],
accepts: ['application/json'],
returnType: undefined
};
}
export class E2eRequestApiHelper {
api: AlfrescoApi;
// @ts-ignore
constructor(private backend: Api | ApiService) {
if (backend.constructor === Api) {
// @ts-ignore
this.api = backend.api;
} else {
// @ts-ignore
this.api = backend.apiService;
}
}
private buildUrl(endPoint: string): string {
const trimSlash = (str: string) => str.replace(/^\/|\/$/g, '');
const host = this.api.config.hostBpm;
const path = '/' + trimSlash(endPoint);
return `${host}${path}`;
}
public get<T>(endPoint: string, overriddenOptions?: E2eRequestApiHelperOptions): PromiseLike<T> {
return this.request<T>('GET', endPoint, overriddenOptions);
}
public post<T>(endPoint: string, overriddenOptions?: E2eRequestApiHelperOptions): PromiseLike<T> {
return this.request<T>('POST', endPoint, overriddenOptions);
}
public put<T>(endPoint: string, overriddenOptions?: E2eRequestApiHelperOptions): PromiseLike<T> {
return this.request<T>('PUT', endPoint, overriddenOptions);
}
public delete<T>(endPoint: string, overriddenOptions?: E2eRequestApiHelperOptions): PromiseLike<T> {
return this.request<T>('DELETE', endPoint, overriddenOptions);
}
private request<T>(httpMethod: string, endPoint: string, overriddenOptions?: E2eRequestApiHelperOptions): PromiseLike<T> {
const options = {
...getDefaultOptions(),
...overriddenOptions
};
const {
pathParams,
queryParams,
headerParams,
formParams,
bodyParam,
contentTypes,
accepts,
returnType,
contextRoot,
responseType
} = options;
return this.api.oauth2Auth.callCustomApi(
this.buildUrl(endPoint),
httpMethod,
pathParams,
queryParams,
headerParams,
formParams,
bodyParam,
contentTypes,
accepts,
returnType,
contextRoot,
responseType
);
}
}

View File

@@ -1,42 +0,0 @@
/*!
* @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 { ApiService } from '../api.service';
import { Logger } from '../../utils/logger';
export class ApplicationsService {
api: ApiService;
constructor(api: ApiService) {
this.api = api;
}
async getApplicationsByStatus(status): Promise<any> {
try {
const path = '/deployment-service/v1/applications';
const method = 'GET';
const queryParams = { status: status, sort: 'name' }, postBody = {};
return this.api.performBpmOperation(path, method, queryParams, postBody);
} catch (error) {
Logger.error('Get Applications - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
}
}
}

View File

@@ -17,7 +17,7 @@
import { ApiService } from '../api.service';
import { StringUtil } from '../../utils/string.util';
import { ApiUtil } from '../../structure/api.util';
import { ApiUtil } from '../../actions/api.util';
import { Logger } from '../../utils/logger';
import { browser } from 'protractor';

View File

@@ -17,7 +17,6 @@
import { ApiService } from '../api.service';
import { UserModel } from '../../models/user.model';
import { PersonBodyCreate } from '@alfresco/js-api';
import { RolesService } from './roles.service';
import { Logger } from '../../utils/logger';
@@ -36,8 +35,8 @@ export class IdentityService {
ACTIVITI_IDENTITY: 'ACTIVITI_IDENTITY'
};
async createIdentityUserWithRole(apiService: ApiService, roles: string[]): Promise<any> {
const rolesService = new RolesService(apiService);
async createIdentityUserWithRole(roles: string[]): Promise<any> {
const rolesService = new RolesService(this.api);
const user = await this.createIdentityUser();
for (let i = 0; i < roles.length; i++) {
const roleId = await rolesService.getRoleIdByRoleName(roles[i]);
@@ -55,33 +54,6 @@ export class IdentityService {
return user;
}
async createIdentityUserAndSyncECMBPM(user: UserModel): Promise<void> {
if (this.api.config.provider === 'ECM' || this.api.config.provider === 'ALL') {
const createUser: PersonBodyCreate = {
firstName: user.firstName,
lastName: user.lastName,
password: user.password,
email: user.email,
id: user.email
} as PersonBodyCreate;
await this.api.apiService.core.peopleApi.addPerson(createUser);
}
if (this.api.config.provider === 'BPM' || this.api.config.provider === 'ALL') {
await this.api.apiService.activiti.adminUsersApi.createNewUser({
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
password: user.password,
type: 'enterprise',
tenantId: 1,
company: null
});
}
await this.createIdentityUser(user);
}
async deleteIdentityUser(userId: string): Promise<void> {
await this.deleteUser(userId);
}

View File

@@ -15,9 +15,7 @@
* limitations under the License.
*/
export * from './applications.service';
export * from './identity.service';
export * from './group-identity.service';
export * from './roles.service';
export * from './tasks.service';
export * from './query.service';

View File

@@ -17,7 +17,7 @@
import { ApiService } from '../api.service';
import { Logger } from '../../utils/logger';
import { ApiUtil } from '../../structure/api.util';
import { ApiUtil } from '../../actions/api.util';
export type TaskStatus = 'COMPLETED' | 'CREATED' | 'ASSIGNED' | 'SUSPENDED' | 'CANCELLED' | 'COMPLETED';

View File

@@ -16,5 +16,8 @@
*/
export * from './identity/public-api';
export * from './APS/public-api';
export * from './api.service';
export * from './drop.actions';
export * from './api';
export * from './api.util';
export * from './e2e-request-api.helper';

View File

@@ -17,24 +17,49 @@
import { StringUtil } from '../utils/string.util';
import { browser } from 'protractor';
import { UserRepresentation } from '@alfresco/js-api';
export class UserModel {
EMAIL_DOMAIN = browser.params.testConfig ? browser.params.testConfig.projectName : 'alfresco';
firstName?: string = StringUtil.generateRandomLowercaseString();
lastName?: string = StringUtil.generateRandomLowercaseString();
password?: string = StringUtil.generateRandomLowercaseString(4) + StringUtil.generateRandomString(4).toUpperCase();
email?: string;
username?: string;
idIdentityService?: string;
type = 'enterprise';
tenantId;
company;
id: number;
firstName: string = StringUtil.generateRandomString();
lastName: string = StringUtil.generateRandomString();
password: string = StringUtil.generateRandomString();
email: string = StringUtil.generateRandomEmail(`@${this.EMAIL_DOMAIN}.com`);
username: string = StringUtil.generateRandomString().toLowerCase();
idIdentityService: string;
constructor(details: any = {}) {
const EMAIL_DOMAIN = browser.params.testConfig ? browser.params.testConfig.projectName : 'alfresco';
this.firstName = details.firstName ? details.firstName : this.firstName;
this.lastName = details.lastName ? details.lastName : this.lastName;
constructor(details?: any) {
Object.assign(this, details);
const USER_IDENTIFY = `${this.firstName}${this.lastName}.${StringUtil.generateRandomLowercaseString(5)}`;
this.password = details.password ? details.password : this.password;
this.email = details.email ? details.email : `${USER_IDENTIFY}@${EMAIL_DOMAIN}.com`;
this.username = details.username ? details.username : USER_IDENTIFY;
this.idIdentityService = details.idIdentityService ? details.idIdentityService : this.idIdentityService;
this.type = details.type ? details.type : this.type;
this.tenantId = details.tenantId ? details.tenantId : this.tenantId;
this.company = details.company ? details.company : this.company;
this.id = details.id ? details.id : this.id;
}
get id() {
return this.email;
getAPSModel() {
return new UserRepresentation({
firstName: this.firstName,
lastName: this.lastName,
password: this.password,
email: this.email,
type: this.type,
tenantId: this.tenantId,
company: this.company,
id: this.id
});
}
}

View File

@@ -16,8 +16,8 @@
*/
import { element, by, ElementFinder, Locator } from 'protractor';
import { DateTimePickerPage } from '../../../material/pages/date-time-picker.page';
import { DatePickerPage } from '../../../material/pages/date-picker.page';
import { DateTimePickerPage } from '../material/date-time-picker.page';
import { DatePickerPage } from '../material/date-picker.page';
export class CardDateItemPage {

View File

@@ -17,7 +17,7 @@
import { element, by, ElementFinder, Locator } from 'protractor';
import { BrowserVisibility } from '../../utils/public-api';
import { DropdownPage } from '../../../material/pages/dropdown.page';
import { DropdownPage } from '../material/dropdown.page';
export class CardSelectItemPage {

View File

@@ -17,7 +17,7 @@
import { by, element, Locator, ElementFinder } from 'protractor';
import { BrowserVisibility, BrowserActions } from '../../utils/public-api';
import { DropdownPage } from '../../../material/pages/dropdown.page';
import { DropdownPage } from '../material/dropdown.page';
export class FormFields {
@@ -36,27 +36,27 @@ export class FormFields {
selectFormDropdown = new DropdownPage(element.all(by.css('adf-attach-form div[class*="mat-select-arrow"]')).first());
async setFieldValue(locator, field, value): Promise<void> {
async setFieldValue(locator, field, value: string): Promise<void> {
const fieldElement = element(locator(field));
await BrowserActions.clearSendKeys(fieldElement, value);
}
async clickField(locator, field, fieldtext?): Promise<void> {
async clickField(locator, field: string, fieldtext?: string): Promise<void> {
const fieldElement = fieldtext ? element(locator(field, fieldtext)) : element(locator(field));
await BrowserActions.click(fieldElement);
}
async checkWidgetIsVisible(fieldId): Promise<void> {
async checkWidgetIsVisible(fieldId: string): Promise<void> {
const fieldElement = element.all(by.css(`adf-form-field div[id='field-${fieldId}-container']`)).first();
await BrowserVisibility.waitUntilElementIsVisible(fieldElement);
}
async checkWidgetIsClickable(fieldId): Promise<void> {
async checkWidgetIsClickable(fieldId: string): Promise<void> {
const fieldElement = element.all(by.css(`adf-form-field div[id='field-${fieldId}-container']`)).first();
await BrowserVisibility.waitUntilElementIsClickable(fieldElement);
}
async checkWidgetIsHidden(fieldId): Promise<void> {
async checkWidgetIsHidden(fieldId: string): Promise<void> {
const hiddenElement = element(by.css(`adf-form-field div[id='field-${fieldId}-container']`));
await BrowserVisibility.waitUntilElementIsNotVisible(hiddenElement, 6000);
}
@@ -65,30 +65,30 @@ export class FormFields {
return element(by.css(`adf-form-field div[id='field-${fieldId}-container']`));
}
async getFieldValue(fieldId, valueLocatorParam?: any): Promise<string> {
async getFieldValue(fieldId: string, valueLocatorParam?: any): Promise<string> {
const valueWidget: ElementFinder = await (await this.getWidget(fieldId)).element(valueLocatorParam || this.valueLocator);
await BrowserVisibility.waitUntilElementIsVisible(valueWidget);
return valueWidget.getAttribute('value');
}
async getFieldLabel(fieldId, labelLocatorParam?: any) {
async getFieldLabel(fieldId: string, labelLocatorParam?: any) {
const label = await (await this.getWidget(fieldId)).all(labelLocatorParam || this.labelLocator).first();
return BrowserActions.getText(label);
}
async getFieldErrorMessage(fieldId): Promise<string> {
async getFieldErrorMessage(fieldId: string): Promise<string> {
const error = await this.getWidget(fieldId);
error.element(this.errorMessage);
return BrowserActions.getText(error);
}
async getFieldText(fieldId, labelLocatorParam?: any) {
async getFieldText(fieldId: string, labelLocatorParam?: any) {
const label = await (await this.getWidget(fieldId)).element(labelLocatorParam || this.labelLocator);
return BrowserActions.getText(label);
}
async getFieldPlaceHolder(fieldId, locator = 'input'): Promise<string> {
async getFieldPlaceHolder(fieldId: string, locator = 'input'): Promise<string> {
const placeHolderLocator: ElementFinder = element(by.css(`${locator}#${fieldId}`));
await BrowserVisibility.waitUntilElementIsVisible(placeHolderLocator);
return placeHolderLocator.getAttribute('placeholder');
@@ -137,11 +137,11 @@ export class FormFields {
await BrowserActions.click(this.attachFormButton);
}
async selectForm(formName): Promise<void> {
async selectForm(formName: string): Promise<void> {
await this.selectFormDropdown.selectDropdownOption(formName);
}
async selectFormFromDropDown(formName): Promise<void> {
async selectFormFromDropDown(formName: string): Promise<void> {
const formNameElement = element(by.cssContainingText('span', formName));
await BrowserActions.click(formNameElement);
}
@@ -157,7 +157,7 @@ export class FormFields {
await BrowserActions.click(this.completeButton);
}
async setValueInInputById(fieldId, value): Promise<void> {
async setValueInInputById(fieldId: string, value: string): Promise<void> {
const input = element(by.id(fieldId));
await BrowserActions.clearSendKeys(input, value);
}

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { element, by, browser, protractor } from 'protractor';
import { element, by, browser, protractor, ElementFinder } from 'protractor';
import { BrowserVisibility } from '../utils/browser-visibility';
import { BrowserActions } from '../utils/browser-actions';
@@ -28,7 +28,35 @@ export class LoginSSOPage {
header = element(by.tagName('adf-layout-header'));
loginError = element(by.css(`div[data-automation-id="login-error"]`));
async loginSSOIdentityService(username, password) {
txtUsernameBasicAuth: ElementFinder = element(by.css('input[id="username"]'));
txtPasswordBasicAuth: ElementFinder = element(by.css('input[id="password"]'));
signInButtonBasicAuth: ElementFinder = element(by.id('login-button'));
async goToLoginPage(): Promise<void> {
let currentUrl;
try {
currentUrl = await browser.getCurrentUrl();
} catch (e) {
}
if (!currentUrl || currentUrl.indexOf(`${browser.baseUrl}/login`) === -1) {
await BrowserActions.getUrl(browser.baseUrl + '/login');
}
await BrowserVisibility.waitUntilElementIsVisible(this.txtUsernameBasicAuth);
await BrowserVisibility.waitUntilElementIsVisible(this.txtPasswordBasicAuth);
}
async login(username: string, password: string) {
if (browser.params.testConfig.appConfig.authType === 'OAUTH') {
await this.loginSSOIdentityService(username, password);
} else {
await this.loginBasicAuth(username, password);
}
}
async loginSSOIdentityService(username: string, password: string) {
browser.ignoreSynchronization = true;
let currentUrl;
@@ -53,15 +81,36 @@ export class LoginSSOPage {
await browser.waitForAngular();
}
async clickOnSSOButton() {
await BrowserActions.clickExecuteScript('[data-automation-id="login-button-sso"]');
async loginBasicAuth(username: string, password: string): Promise<void> {
await this.goToLoginPage();
await this.enterUsernameBasicAuth(username);
await this.enterPasswordBasicAuth(password);
await this.clickSignInBasicAuthButton();
await BrowserVisibility.waitUntilElementIsVisible(this.header);
}
async enterUsername(username) {
async clickSignInBasicAuthButton(): Promise<void> {
await BrowserActions.click(this.signInButtonBasicAuth);
}
async enterUsernameBasicAuth(username): Promise<void> {
await BrowserActions.clearSendKeys(this.txtUsernameBasicAuth, username);
}
async enterPasswordBasicAuth(password): Promise<void> {
await BrowserActions.clearSendKeys(this.txtPasswordBasicAuth, password);
}
async clickOnSSOButton() {
await BrowserActions.click(this.ssoButton);
}
async enterUsername(username: string) {
await BrowserActions.clearSendKeys(this.usernameField, username);
}
async enterPassword(password) {
async enterPassword(password: string) {
await BrowserActions.clearSendKeys(this.passwordField, password);
}

View File

@@ -1,246 +0,0 @@
/*!
* @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 { TogglePage } from '../../material/pages/toggle.page';
import { browser, by, element, ElementFinder } from 'protractor';
import { BrowserVisibility } from '../utils/browser-visibility';
import { LocalStorageUtil } from '../utils/local-storage.util';
import { BrowserActions } from '../utils/browser-actions';
export class LoginPage {
loginURL: string = browser.baseUrl + '/login';
togglePage: TogglePage = new TogglePage();
txtUsername: ElementFinder = element(by.css('input[id="username"]'));
txtPassword: ElementFinder = element(by.css('input[id="password"]'));
logoImg: ElementFinder = element(by.css('img[id="adf-login-img-logo"]'));
successRouteTxt: ElementFinder = element(by.css('input[data-automation-id="adf-success-route"]'));
logoTxt: ElementFinder = element(by.css('input[data-automation-id="adf-url-logo"]'));
usernameTooltip: ElementFinder = element(by.css('span[data-automation-id="username-error"]'));
passwordTooltip: ElementFinder = element(by.css('span[data-automation-id="password-required"]'));
loginTooltip: ElementFinder = element(by.css('span[class="adf-login-error-message"]'));
usernameInactive: ElementFinder = element(by.css('input[id="username"][aria-invalid="false"]'));
passwordInactive: ElementFinder = element(by.css('input[id="password"][aria-invalid="false"]'));
adfLogo: ElementFinder = element(by.css('img[class="adf-img-logo ng-star-inserted"]'));
usernameHighlighted: ElementFinder = element(by.css('input[id="username"][aria-invalid="true"]'));
passwordHighlighted: ElementFinder = element(by.css('input[id="password"][aria-invalid="true"]'));
signInButton: ElementFinder = element(by.id('login-button'));
showPasswordElement: ElementFinder = element(by.css('button[data-automation-id="show_password"]'));
hidePasswordElement: ElementFinder = element(by.css('button[data-automation-id="hide_password"]'));
rememberMe: ElementFinder = element(by.css('mat-checkbox[id="adf-login-remember"]'));
needHelp: ElementFinder = element(by.css('div[id="adf-login-action-left"]'));
register: ElementFinder = element(by.css('div[id="adf-login-action-right"]'));
footerSwitch: ElementFinder = element(by.id('switch4'));
rememberMeSwitch: ElementFinder = element(by.id('adf-toggle-show-rememberme'));
successRouteSwitch: ElementFinder = element(by.id('adf-toggle-show-successRoute'));
logoSwitch: ElementFinder = element(by.id('adf-toggle-logo'));
header: ElementFinder = element(by.id('adf-header'));
settingsIcon: ElementFinder = element(by.cssContainingText('a[data-automation-id="settings"] mat-icon', 'settings'));
sidenavLayout = element(by.css(`[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): Promise<void> {
await BrowserActions.clearSendKeys(this.txtUsername, username);
}
async enterPassword(password): 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.usernameTooltip);
}
async getPasswordTooltip(): Promise<string> {
return BrowserActions.getText(this.passwordTooltip);
}
async getLoginError(): Promise<string> {
return BrowserActions.getText(this.loginTooltip);
}
async checkLoginImgURL(): Promise<string> {
await BrowserVisibility.waitUntilElementIsVisible(this.logoImg);
return this.logoImg.getAttribute('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.usernameTooltip);
}
async checkPasswordTooltipIsNotVisible(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.passwordTooltip);
}
async getSignInButtonIsEnabled(): Promise<boolean> {
await BrowserVisibility.waitUntilElementIsVisible(this.signInButton);
return this.signInButton.isEnabled();
}
async loginToAllUsingUserModel(userModel): Promise<void> {
await this.goToLoginPage();
await LocalStorageUtil.clearStorage();
await LocalStorageUtil.setStorageItem('providers', 'ALL');
await LocalStorageUtil.apiReset();
await this.login(userModel.email, userModel.password);
}
async loginToProcessServicesUsingUserModel(userModel): Promise<void> {
await this.goToLoginPage();
await LocalStorageUtil.clearStorage();
await LocalStorageUtil.setStorageItem('providers', 'BPM');
await LocalStorageUtil.apiReset();
await this.login(userModel.email, userModel.password);
}
async loginToContentServicesUsingUserModel(userModel): Promise<void> {
await this.goToLoginPage();
await LocalStorageUtil.clearStorage();
await LocalStorageUtil.setStorageItem('providers', 'ECM');
await LocalStorageUtil.apiReset();
await this.login(userModel.getId(), userModel.getPassword());
}
async loginToContentServices(username, password): Promise<void> {
await this.goToLoginPage();
await LocalStorageUtil.clearStorage();
await LocalStorageUtil.setStorageItem('providers', 'ECM');
await LocalStorageUtil.apiReset();
await this.login(username, password);
}
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 this.txtPassword.getAttribute('value');
}
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): Promise<void> {
await BrowserActions.clearSendKeys(this.successRouteTxt, route);
}
async enterLogo(logo): Promise<void> {
await BrowserActions.clearSendKeys(this.logoTxt, logo);
}
async login(username, password): Promise<void> {
await this.enterUsername(username);
await this.enterPassword(password);
await this.clickSignInButton();
await BrowserVisibility.waitUntilElementIsVisible(this.sidenavLayout);
}
}

View File

@@ -0,0 +1,39 @@
/*!
* @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 { BrowserActions } from '../../utils/browser-actions';
import { BrowserVisibility } from '../../utils/browser-visibility';
export class CheckboxPage {
static async uncheck(el: ElementFinder) {
await BrowserVisibility.waitUntilElementIsVisible(el);
const classList = await el.getAttribute('class');
if (classList && classList.indexOf('mat-checked') > -1) {
await BrowserActions.click(el);
}
}
static async check(el: ElementFinder) {
await BrowserVisibility.waitUntilElementIsVisible(el);
const classList = await el.getAttribute('class');
if (classList && classList.indexOf('mat-checked') === -1) {
await BrowserActions.click(el);
}
}
}

View File

@@ -16,9 +16,9 @@
*/
import { element, by, ElementFinder } from 'protractor';
import { DateUtil } from '../../core/utils/date-util';
import { BrowserVisibility } from '../../core/utils/browser-visibility';
import { BrowserActions } from '../../core/utils/browser-actions';
import { DateUtil } from '../../utils/date-util';
import { BrowserVisibility } from '../../utils/browser-visibility';
import { BrowserActions } from '../../utils/browser-actions';
export class DatePickerCalendarPage {

View File

@@ -16,7 +16,7 @@
*/
import { element, by, ElementFinder } from 'protractor';
import { BrowserActions } from '../../core/utils/browser-actions';
import { BrowserActions } from '../../utils/browser-actions';
import { DatePickerCalendarPage } from './date-picker-calendar.page';
export class DatePickerPage {

View File

@@ -16,8 +16,8 @@
*/
import { element, by, ElementFinder, Locator } from 'protractor';
import { BrowserVisibility } from '../../core/utils/browser-visibility';
import { BrowserActions } from '../../core/utils/browser-actions';
import { BrowserVisibility } from '../../utils/browser-visibility';
import { BrowserActions } from '../../utils/browser-actions';
export class DateTimePickerCalendarPage {

View File

@@ -16,7 +16,7 @@
*/
import { element, by, ElementFinder } from 'protractor';
import { BrowserActions } from '../../core/utils/browser-actions';
import { BrowserActions } from '../../utils/browser-actions';
import { DateTimePickerCalendarPage } from './date-time-picker-calendar.page';
export class DateTimePickerPage {

View File

@@ -16,8 +16,8 @@
*/
import { element, by, ElementFinder } from 'protractor';
import { BrowserVisibility } from '../../core/utils/browser-visibility';
import { BrowserActions } from '../../core/utils/browser-actions';
import { BrowserVisibility } from '../../utils/browser-visibility';
import { BrowserActions } from '../../utils/browser-actions';
export class DropdownPage {

View File

@@ -22,3 +22,4 @@ export * from './date-picker.page';
export * from './date-time-picker-calendar.page';
export * from './dropdown.page';
export * from './toggle.page';
export * from './checkbox.page';

View File

@@ -16,7 +16,7 @@
*/
import { element, by } from 'protractor';
import { BrowserActions } from '../../core/utils/browser-actions';
import { BrowserActions } from '../../utils/browser-actions';
export class TabsPage {

View File

@@ -16,8 +16,8 @@
*/
import { by, ElementFinder } from 'protractor';
import { BrowserVisibility } from '../../core/utils/browser-visibility';
import { BrowserActions } from '../../core/utils/browser-actions';
import { BrowserVisibility } from '../../utils/browser-visibility';
import { BrowserActions } from '../../utils/browser-actions';
export class TogglePage {

View File

@@ -18,7 +18,6 @@
export * from './bread-crumb.page';
export * from './header.page';
export * from './user-info.page';
export * from './login.page';
export * from './settings.page';
export * from './login-sso.page';
export * from './data-table-component.page';
@@ -26,6 +25,7 @@ export * from './pagination.page';
export * from './error.page';
export * from './notification-history.page';
export * from './form/public-api';
export * from './material/public-api';
export * from './card-view/public-api';
export * from './viewer.page';
export * from './config-editor-page';

View File

@@ -18,7 +18,7 @@
import { browser, by, element, ElementFinder } from 'protractor';
import { BrowserVisibility } from '../utils/browser-visibility';
import { BrowserActions } from '../utils/browser-actions';
import { DropdownPage } from '../../material/pages/dropdown.page';
import { DropdownPage } from '../../core/pages/material/dropdown.page';
export class SettingsPage {
@@ -42,7 +42,16 @@ export class SettingsPage {
providerDropdown = new DropdownPage(element(by.css('mat-select[id="adf-provider-selector"]')));
async goToSettingsPage(): Promise<void> {
await browser.get(this.settingsURL);
let currentUrl;
try {
currentUrl = await browser.getCurrentUrl();
} catch (e) {
}
if (!currentUrl || currentUrl.indexOf(this.settingsURL) === -1) {
await browser.get(this.settingsURL);
}
await this.providerDropdown.checkDropdownIsVisible();
}
@@ -93,6 +102,7 @@ export class SettingsPage {
}
async setProviderEcmSso(contentServiceURL, authHost, identityHost, silentLogin = true, implicitFlow = true, clientId?: string, logoutUrl: string = '/logout') {
await this.goToSettingsPage();
await this.setProvider('ECM');
await this.clickSsoRadioButton();
@@ -149,7 +159,7 @@ export class SettingsPage {
await BrowserActions.clearSendKeys(this.bpmText, processServiceURL);
}
async setClientId(clientId: string = browser.params.config.oauth2.clientId) {
async setClientId(clientId: string = browser.params.testConfig.appConfig.oauth2.clientId) {
await BrowserActions.clearSendKeys(this.clientIdText, clientId);
}

View File

@@ -17,21 +17,20 @@
import { element, by, ElementFinder } from 'protractor';
import { BrowserVisibility } from '../utils/browser-visibility';
import { Logger } from '../utils/logger';
export class SnackbarPage {
notificationSnackBar: ElementFinder = element(by.css('simple-snack-bar span'));
notificationSnackBar: ElementFinder = element.all(by.css('simple-snack-bar span')).first();
snackBarContainerCss = by.css('.mat-snack-bar-container');
async waitForSnackBarToAppear() {
return BrowserVisibility.waitUntilElementIsVisible(element(this.snackBarContainerCss), 20000,
return BrowserVisibility.waitUntilElementIsVisible(element.all(this.snackBarContainerCss).first(), 5000,
'snackbar did not appear'
);
}
async waitForSnackBarToClose() {
return BrowserVisibility.waitUntilElementIsNotVisible(element(this.snackBarContainerCss), 20000);
return BrowserVisibility.waitUntilElementIsNotVisible(element.all(this.snackBarContainerCss).first(), 5000);
}
async getSnackBarMessage(): Promise<string> {
@@ -41,10 +40,9 @@ export class SnackbarPage {
async isNotificationSnackBarDisplayed(): Promise<boolean> {
try {
await BrowserVisibility.waitUntilElementIsVisible(this.notificationSnackBar);
await BrowserVisibility.waitUntilElementIsVisible(this.notificationSnackBar, 2000);
return true;
} catch {
Logger.error(`Snackbar is not displayed `);
return false;
}
}

View File

@@ -17,7 +17,7 @@
import { element, by, ElementFinder } from 'protractor';
import { BrowserVisibility } from '../utils/browser-visibility';
import { TabsPage } from '../../material/pages/tabs.page';
import { TabsPage } from '../../core/pages/material/tabs.page';
import { BrowserActions } from '../utils/browser-actions';
export class UserInfoPage {

View File

@@ -16,8 +16,8 @@
*/
import { BrowserActions } from '../utils/browser-actions';
import { TabsPage } from '../../../lib/material/pages/tabs.page';
import { TogglePage } from '../../material/pages/toggle.page';
import { TabsPage } from './material/tabs.page';
import { TogglePage } from './material/toggle.page';
import { BrowserVisibility } from '../utils/browser-visibility';
import { element, by, ElementFinder, browser, protractor } from 'protractor';

View File

@@ -20,4 +20,3 @@ export * from './pages/public-api';
export * from './models/public-api';
export * from './dialog/public-api';
export * from './utils/public-api';
export * from './structure/public-api';

View File

@@ -1,58 +0,0 @@
/*!
* @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 { E2eRequestApiHelper } from './e2e-request-api.helper';
import { Api } from './api';
import { Logger } from '../utils/logger';
import { ResultSetPaging } from '@alfresco/js-api';
export class Application {
requestApiHelper: E2eRequestApiHelper;
endPoint = `/v1/applications/`;
constructor(api: Api) {
this.requestApiHelper = new E2eRequestApiHelper(api);
}
async deploy(model: any): Promise<any> {
await this.requestApiHelper.post(`${this.endPoint}`, { bodyParam: model});
Logger.info(`[Application] Application '${model.name}' was deployed successfully.`);
}
async delete(applicationId: string): Promise<void> {
await this.requestApiHelper.delete(`${this.endPoint}${applicationId}`);
Logger.info(`[Application] Application: '${applicationId}' was deleted successfully.`);
}
async deleteDescriptor(name: string): Promise<void> {
await this.requestApiHelper.delete(`v1/descriptors/${name}`);
Logger.info(`[Descriptor] Descriptor: '${name}' was deleted successfully.`);
}
async getDescriptors(): Promise<ResultSetPaging> {
Logger.info(`[Descriptor] Return descriptors`);
return this.requestApiHelper.get<ResultSetPaging>(`v1/descriptors`, {});
}
async getApplicationsByStatus(status: string): Promise<ResultSetPaging> {
Logger.info(`[Application] Return application by status: ${status}`);
return this.requestApiHelper.get<ResultSetPaging>(this.endPoint, {
queryParams: { status: status }
});
}
}

View File

@@ -1,112 +0,0 @@
/*!
* @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 { Oauth2Auth } from '@alfresco/js-api/src/authentication/oauth2Auth';
export interface E2eRequestApiHelperOptions {
pathParams?: { [key: string]: any };
queryParams?: { [key: string]: any };
headerParams?: { [key: string]: any };
formParams?: { [key: string]: any };
bodyParam?: { [key: string]: any };
contentTypes?: string[];
accepts?: string[];
returnType?: any;
contextRoot?: string;
responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text';
}
function getDefaultOptions(): E2eRequestApiHelperOptions {
return {
pathParams: {},
queryParams: {},
headerParams: {},
formParams: {},
bodyParam: {},
contentTypes: ['application/json'],
accepts: ['application/json'],
returnType: undefined
};
}
export class E2eRequestApiHelper {
api: Oauth2Auth;
constructor(private backend) {
this.api = backend.api.oauth2Auth;
}
private buildUrl(endPoint: string): string {
const trimSlash = (str: string) => str.replace(/^\/|\/$/g, '');
const host = this.backend.api.config.hostBpm;
const path = '/' + trimSlash(endPoint);
return `${host}${path}`;
}
public get<T>(endPoint: string, overriddenOptions?: E2eRequestApiHelperOptions): PromiseLike<T> {
return this.request<T>('GET', endPoint, overriddenOptions);
}
public post<T>(endPoint: string, overriddenOptions?: E2eRequestApiHelperOptions): PromiseLike<T> {
return this.request<T>('POST', endPoint, overriddenOptions);
}
public put<T>(endPoint: string, overriddenOptions?: E2eRequestApiHelperOptions): PromiseLike<T> {
return this.request<T>('PUT', endPoint, overriddenOptions);
}
public delete<T>(endPoint: string, overriddenOptions?: E2eRequestApiHelperOptions): PromiseLike<T> {
return this.request<T>('DELETE', endPoint, overriddenOptions);
}
private request<T>(httpMethod: string, endPoint: string, overriddenOptions?: E2eRequestApiHelperOptions): PromiseLike<T> {
const options = {
...getDefaultOptions(),
...overriddenOptions
};
const {
pathParams,
queryParams,
headerParams,
formParams,
bodyParam,
contentTypes,
accepts,
returnType,
contextRoot,
responseType
} = options;
return this.api.callCustomApi(
this.buildUrl(endPoint),
httpMethod,
pathParams,
queryParams,
headerParams,
formParams,
bodyParam,
contentTypes,
accepts,
returnType,
contextRoot,
responseType
);
}
}

View File

@@ -1,21 +0,0 @@
/*!
* @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.
*/
export * from './api';
export * from './api.util';
export * from './deployment-api';
export * from './modeling-api';

View File

@@ -15,4 +15,21 @@
* limitations under the License.
*/
export * from './form-cloud.service';
export class ArrayUtil {
/**
* Returns TRUE if the first array contains all elements from the second one.
*
* @param superset
* @param subset
*
*/
static arrayContainsArray(superset: any[], subset: any[]): boolean {
if (0 === subset.length) {
return false;
}
return subset.every(function (value) {
return (superset.indexOf(value) >= 0);
});
}
}

View File

@@ -38,12 +38,12 @@ export class BrowserActions {
}
static async waitUntilActionMenuIsVisible(): Promise<void> {
const actionMenu = element(by.css('div[role="menu"]'));
const actionMenu = element.all(by.css('div[role="menu"]')).first();
await BrowserVisibility.waitUntilElementIsVisible(actionMenu);
}
static async waitUntilActionMenuIsNotVisible(): Promise<void> {
const actionMenu = element(by.css('div[role="menu"]'));
const actionMenu = element.all(by.css('div[role="menu"]')).first();
await BrowserVisibility.waitUntilElementIsNotVisible(actionMenu);
}
@@ -87,6 +87,8 @@ export class BrowserActions {
static async clearWithBackSpace(elementFinder: ElementFinder, sleepTime: number = 0) {
await BrowserVisibility.waitUntilElementIsVisible(elementFinder);
await elementFinder.click();
await elementFinder.sendKeys(protractor.Key.END);
const value = await elementFinder.getAttribute('value');
for (let i = value.length; i >= 0; i--) {
await elementFinder.sendKeys(protractor.Key.BACK_SPACE);

View File

@@ -18,7 +18,7 @@
import { browser, by, element, ElementFinder, protractor } from 'protractor';
const DEFAULT_TIMEOUT = global['TestConfig'] ? global['TestConfig'].main.timeout : 20000;
const NOT_VISIBLE_DEFAULT_TIMEOUT = global['TestConfig'] ? global['TestConfig'].main.timeout : 5000;
const NOT_VISIBLE_DEFAULT_TIMEOUT = global['TestConfig'] ? global['TestConfig'].main.timeout : 2000;
export class BrowserVisibility {

View File

@@ -22,22 +22,40 @@ const infoColor = '\x1b[36m%s\x1b[0m',
warnColor = '\x1b[33m%s\x1b[0m',
errorColor = '\x1b[31m%s\x1b[0m';
export class LogLevelsEnum extends Number {
static TRACE: number = 5;
static DEBUG: number = 4;
static INFO: number = 3;
static WARN: number = 2;
static ERROR: number = 1;
static SILENT: number = 0;
}
export let logLevels: any[] = [
{level: LogLevelsEnum.TRACE, name: 'TRACE'},
{level: LogLevelsEnum.DEBUG, name: 'DEBUG'},
{level: LogLevelsEnum.INFO, name: 'INFO'},
{level: LogLevelsEnum.WARN, name: 'WARN'},
{level: LogLevelsEnum.ERROR, name: 'ERROR'},
{level: LogLevelsEnum.SILENT, name: 'SILENT'}
];
/* tslint:disable:no-console */
export class Logger {
static info(...messages: string[]): void {
if (browser.params.config && browser.params.config.log) {
if (browser.params.config && browser.params.testConfig.appConfig.log >= LogLevelsEnum.INFO) {
console.log(infoColor, messages.join(''));
}
}
static log(...messages: string[]): void {
if (browser.params.config && browser.params.config.log) {
if (browser.params.config && browser.params.testConfig.appConfig.log >= LogLevelsEnum.TRACE) {
console.log(logColor, messages.join(''));
}
}
static warn(...messages: string[]): void {
if (browser.params.config && browser.params.config.log) {
if (browser.params.config && browser.params.testConfig.appConfig.log >= LogLevelsEnum.WARN) {
console.log(warnColor, messages.join(''));
}
}

View File

@@ -18,6 +18,7 @@
export * from './browser-visibility';
export * from './browser-actions';
export * from './string.util';
export * from './array.util';
export * from './protractor.util';
export * from './local-storage.util';
export * from './file-browser.util';

View File

@@ -71,7 +71,7 @@ export class StringUtil {
* @param length {int} If this parameter is not provided the length is set to 3 by default.
*/
static generateRandomStringNonLatin(length: number = 3): string {
return StringUtil.generateRandomCharset(length, '密码你好𠮷');
return StringUtil.generateRandomCharset(length, '密码你好𠮷');
}
/**
@@ -90,4 +90,21 @@ export class StringUtil {
return text;
}
/**
* Generates a sequence of files with name: baseName + index + extension (e.g.) baseName1.txt, baseName2.txt, ...
*
* @param startIndex
* @param endIndex
* @param baseName the base name of all files
* @param extension the extension of the file
* @return fileNames
*/
static generateFilesNames(startIndex: number, endIndex: number, baseName: string, extension: string): string [] {
const fileNames: string[] = [];
for (let i = startIndex; i <= endIndex; i++) {
fileNames.push(baseName + i + extension);
}
return fileNames;
}
}

View File

@@ -1,18 +0,0 @@
/*!
* @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.
*/
export * from './actions/public-api';

View File

@@ -1,18 +0,0 @@
/*!
* @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.
*/
export * from './pages/public-api';

View File

@@ -0,0 +1,59 @@
/*!
* @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 { E2eRequestApiHelper } from '../../core/actions/e2e-request-api.helper';
import { Api } from '../../core/actions/api';
import { Logger } from '../../core/utils/logger';
import { ResultSetPaging } from '@alfresco/js-api';
import { ApiService } from '../../core/actions/api.service';
export class Application {
requestApiHelper: E2eRequestApiHelper;
endPoint = `/deployment-service/v1/applications/`;
constructor(api: Api | ApiService) {
this.requestApiHelper = new E2eRequestApiHelper(api);
}
async deploy(model: any): Promise<any> {
await this.requestApiHelper.post(`${this.endPoint}`, { bodyParam: model });
Logger.info(`[Application] Application '${model.name}' was deployed successfully.`);
}
async delete(applicationId: string): Promise<void> {
await this.requestApiHelper.delete(`${this.endPoint}${applicationId}`);
Logger.info(`[Application] Application: '${applicationId}' was deleted successfully.`);
}
async deleteDescriptor(name: string): Promise<void> {
await this.requestApiHelper.delete(`v1/descriptors/${name}`);
Logger.info(`[Descriptor] Descriptor: '${name}' was deleted successfully.`);
}
async getDescriptors(): Promise<ResultSetPaging> {
Logger.info(`[Descriptor] Return descriptors`);
return this.requestApiHelper.get<ResultSetPaging>(`v1/descriptors`, {});
}
async getApplicationsByStatus(status: string): Promise<ResultSetPaging> {
Logger.info(`[Application] Return application by status: ${status}`);
return this.requestApiHelper.get<ResultSetPaging>(this.endPoint, {
queryParams: { status: status, sort: 'name' }
});
}
}

View File

@@ -15,9 +15,9 @@
* limitations under the License.
*/
import { Api } from './api';
import { Api } from '../../core/actions/api';
import { Application } from './application';
import { Logger } from '../utils/logger';
import { Logger } from '../../core/utils/logger';
import { browser } from 'protractor';
import { ResultSetPaging } from '@alfresco/js-api';
@@ -63,7 +63,7 @@ export class DeploymentAPI extends Api {
}
async getApplicationByStatus(status: string): Promise<ResultSetPaging> {
const applications = this.application.getApplicationsByStatus(status);
const applications = this.application.getApplicationsByStatus(status);
return applications;
}
}

View File

@@ -15,9 +15,9 @@
* limitations under the License.
*/
import { Api } from './api';
import { Api } from '../../core/actions/api';
import { Project } from './project';
import { Logger } from '../utils/logger';
import { Logger } from '../../core/utils/logger';
import { browser } from 'protractor';
import { NodeEntry, ResultSetPaging } from '@alfresco/js-api';

View File

@@ -18,11 +18,11 @@
import { browser } from 'protractor';
import { ModelingAPI } from './modeling-api';
import { NodeEntry, ResultSetPaging } from '@alfresco/js-api';
import { ApiUtil } from './api.util';
import { E2eRequestApiHelper, E2eRequestApiHelperOptions } from './e2e-request-api.helper';
import { ApiUtil } from '../../core/actions/api.util';
import { E2eRequestApiHelper, E2eRequestApiHelperOptions } from '../../core/actions/e2e-request-api.helper';
import * as fs from 'fs';
import { StringUtil } from '../utils/string.util';
import { Logger } from '../utils/logger';
import { StringUtil } from '../../core/utils/string.util';
import { Logger } from '../../core/utils/logger';
export class Project {
requestApiHelper: E2eRequestApiHelper;

View File

@@ -20,3 +20,9 @@ export * from './testing-app-config.service';
export * from './process-definitions.service';
export * from './process-instances.service';
export * from './message-events.service';
export * from './form-cloud.service';
export * from './tasks.service';
export * from './deployment-api';
export * from './modeling-api';
export * from './application';
export * from './project';

View File

@@ -15,8 +15,8 @@
* limitations under the License.
*/
import { ApiService } from '../api.service';
import { Logger } from '../../utils/logger';
import { ApiService } from '../../core/actions/api.service';
import { Logger } from '../../core/utils/logger';
export class TasksService {

View File

@@ -18,7 +18,7 @@ import { browser, by, element, protractor, ElementFinder } from 'protractor';
import { EditProcessFilterDialogPage } from './dialog/edit-process-filter-dialog.page';
import { BrowserVisibility } from '../../core/utils/browser-visibility';
import { BrowserActions } from '../../core/utils/browser-actions';
import { DropdownPage } from '../../material/pages/dropdown.page';
import { DropdownPage } from '../../core/pages/material/dropdown.page';
export class EditProcessFilterCloudComponentPage {

View File

@@ -19,7 +19,7 @@ import { browser, by, element, protractor, ElementFinder } from 'protractor';
import { EditTaskFilterDialogPage } from './dialog/edit-task-filter-dialog.page';
import { BrowserVisibility } from '../../core/utils/browser-visibility';
import { BrowserActions } from '../../core/utils/browser-actions';
import { DropdownPage } from '../../material/pages/dropdown.page';
import { DropdownPage } from '../../core/pages/material/dropdown.page';
export class EditTaskFilterCloudComponentPage {
@@ -183,7 +183,7 @@ export class EditTaskFilterCloudComponentPage {
}
async clearAssignee(): Promise<void> {
await BrowserActions.clearWithBackSpace(this.assignee, 200);
await BrowserActions.clearWithBackSpace(this.assignee, 250);
await browser.driver.sleep(1000);
}

View File

@@ -0,0 +1,110 @@
/*!
* @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 { Logger } from '../../core/utils/logger';
import * as remote from 'selenium-webdriver/remote';
import { browser } from 'protractor';
import { ApiService } from '../../core/actions/api.service';
import { AppDefinitionUpdateResultRepresentation } from '@alfresco/js-api';
import * as path from 'path';
import * as fs from 'fs';
export class AppPublish {
comment: string = '';
force: boolean = true;
}
export class ApplicationsUtil {
api: ApiService;
constructor(api: ApiService) {
this.api = api;
}
async getAppDefinitionId(appModelId: number): Promise<number> {
const appDefinitions = await this.api.getInstance().activiti.appsApi.getAppDefinitions();
let appDefinitionId = -1;
appDefinitions.data.forEach((appDefinition) => {
if (appDefinition.modelId === appModelId) {
appDefinitionId = appDefinition.id;
}
});
return appDefinitionId;
}
async publishDeployApp(appId: number): Promise<AppDefinitionUpdateResultRepresentation> {
browser.setFileDetector(new remote.FileDetector());
const publishApp = await this.api.getInstance().activiti.appsApi.publishAppDefinition(appId, new AppPublish());
await this.api.getInstance().activiti.appsApi.deployAppDefinitions({ appDefinitions: [{ id: publishApp.appDefinition.id }] });
return publishApp;
}
async importPublishDeployApp(appFileLocation: string, option = {}) {
try {
const appCreated = await this.importApplication(appFileLocation, option);
const publishApp = await this.publishDeployApp(appCreated.id);
await this.api.getInstance().activiti.appsApi.deployAppDefinitions({ appDefinitions: [{ id: publishApp.appDefinition.id }] });
return appCreated;
} catch (error) {
Logger.error('Import Publish Deploy Application - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
}
}
async importNewVersionAppDefinitionPublishDeployApp(appFileLocation: string, modelId: number) {
browser.setFileDetector(new remote.FileDetector());
const pathFile = path.join(browser.params.testConfig.main.rootPath + appFileLocation);
const file = fs.createReadStream(pathFile);
const appCreated = await this.api.getInstance().activiti.appsApi.importNewAppDefinition(modelId, file);
const publishApp = await this.api.getInstance().activiti.appsApi.publishAppDefinition(appCreated.id, new AppPublish());
await this.api.getInstance().activiti.appsApi.deployAppDefinitions({ appDefinitions: [{ id: publishApp.appDefinition.id }] });
return appCreated;
}
async importApplication(appFileLocation: string, options = {}): Promise<any> {
try {
browser.setFileDetector(new remote.FileDetector());
const file = fs.createReadStream(appFileLocation);
return await this.api.getInstance().activiti.appsDefinitionApi.importAppDefinition(file, options);
} catch (error) {
Logger.error('Import Application - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
}
}
async getAppDefinitionByName(appName: string): Promise<any> {
try {
const appDefinitionsList = await this.api.getInstance().activiti.appsApi.getAppDefinitions();
const appDefinition = appDefinitionsList.data.filter((currentApp) => {
return currentApp.name === appName;
});
return appDefinition;
} catch (error) {
Logger.error('Get AppDefinitions - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
}
}
}

View File

@@ -15,12 +15,12 @@
* limitations under the License.
*/
import { AlfrescoApiCompatibility as AlfrescoApi } from '@alfresco/js-api';
import { ApiService } from '../../core/actions/api.service';
export class IntegrationService {
api: AlfrescoApi;
api: ApiService;
constructor(api: AlfrescoApi) {
constructor(api: ApiService) {
this.api = api;
}
@@ -34,12 +34,12 @@ export class IntegrationService {
version: '6.1.1',
authenticationType: 'basic'
};
return this.api.activiti.integrationAccountApi.apiClient.callApi('app/rest/integration/alfresco', 'POST',
return this.api.apiService.activiti.integrationAccountApi.apiClient.callApi('app/rest/integration/alfresco', 'POST',
{}, {}, {}, {}, repository, [], [], Object);
}
authenticateRepository(id: number, body: { username: string, password: string }): Promise<any> {
return this.api.activiti.integrationAccountApi.apiClient.callApi(`app/rest/integration/alfresco/${id}/account`, 'POST',
return this.api.apiService.activiti.integrationAccountApi.apiClient.callApi(`app/rest/integration/alfresco/${id}/account`, 'POST',
{}, {}, {}, body, {}, [], []);
}
}

View File

@@ -14,20 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AlfrescoApiCompatibility as AlfrescoApi } from '@alfresco/js-api';
import { Logger } from '../../utils/logger';
import { Logger } from '../../core/utils/logger';
import { ApiService } from '../../core/actions/api.service';
export class ModelsActions {
api: AlfrescoApi;
api: ApiService;
constructor(api: AlfrescoApi) {
constructor(api: ApiService) {
this.api = api;
}
async deleteVersionModel(modelId) {
try {
return await this.api.activiti.modelsApi.deleteModel(modelId, { cascade: false, deleteRuntimeApp : true });
return await this.api.apiService.activiti.modelsApi.deleteModel(modelId, { cascade: false, deleteRuntimeApp : true });
} catch (error) {
Logger.error('Delete Model Version - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
}
@@ -35,7 +35,7 @@ export class ModelsActions {
async deleteEntireModel(modelId) {
try {
return await this.api.activiti.modelsApi.deleteModel(modelId, { cascade: true, deleteRuntimeApp : true });
return await this.api.apiService.activiti.modelsApi.deleteModel(modelId, { cascade: true, deleteRuntimeApp : true });
} catch (error) {
Logger.error('Delete Model - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
}
@@ -45,7 +45,7 @@ export class ModelsActions {
const options = opts || {};
let models;
try {
models = await this.api.activiti.modelsApi.getModels(options);
models = await this.api.apiService.activiti.modelsApi.getModels(options);
} catch (error) {
Logger.error('Get Models - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
}

View File

@@ -15,16 +15,17 @@
* limitations under the License.
*/
import { AlfrescoApiCompatibility as AlfrescoApi } from '@alfresco/js-api';
import { ApplicationsUtil } from './applications.util';
import { Logger } from '../../utils/logger';
import { StringUtil } from '../../utils/string.util';
import { Logger } from '../../core/utils/logger';
import { StringUtil } from '../../core/utils/string.util';
import { ApiService } from '../../core/actions/api.service';
import { TaskRepresentation } from '@alfresco/js-api';
export class ProcessUtil {
api: AlfrescoApi;
api: ApiService;
constructor(api: AlfrescoApi) {
constructor(api: ApiService) {
this.api = api;
}
@@ -36,45 +37,45 @@ export class ProcessUtil {
const startProcessOptions: any = { processDefinitionId: processDefinition.id, name: processDefinitionName };
return this.api.activiti.processApi.startNewProcessInstance(startProcessOptions);
return this.api.apiService.activiti.processApi.startNewProcessInstance(startProcessOptions);
} catch (error) {
Logger.error('Start Process - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
Logger.error('Start Process - Service error, Response: ', JSON.parse(JSON.stringify(error)));
}
}
async startProcessOfApp(appName: string, processName?: string): Promise<any> {
try {
const appDefinition = await new ApplicationsUtil(this.api).getAppDefinitionByName(appName);
const processDefinitionList = await this.api.activiti.processApi.getProcessDefinitions({ deploymentId: appDefinition[0].deploymentId });
const processDefinitionList = await this.api.apiService.activiti.processApi.getProcessDefinitions({ deploymentId: appDefinition[0].deploymentId });
const startProcessOptions: any = { processDefinitionId: processDefinitionList.data[0].id, name: processName ? processName : StringUtil.generateRandomString(5).toLowerCase() };
return this.api.activiti.processApi.startNewProcessInstance(startProcessOptions);
return this.api.apiService.activiti.processApi.startNewProcessInstance(startProcessOptions);
} catch (error) {
Logger.error('Start Process - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
Logger.error('Start Process - Service error, Response: ', JSON.parse(JSON.stringify(error)));
}
}
async cancelProcessInstance(processInstance: string): Promise<any> {
try {
return this.api.activiti.processApi.deleteProcessInstance(processInstance);
return this.api.apiService.activiti.processApi.deleteProcessInstance(processInstance);
} catch (error) {
Logger.error('Cancel Process - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
Logger.error('Cancel Process - Service error, Response: ', JSON.parse(JSON.stringify(error)));
}
}
async getProcessDefinitionByName(deploymentId: string, processName: string): Promise<any> {
try {
const processDefinitionList = await this.api.activiti.processApi.getProcessDefinitions({ deploymentId: deploymentId });
const processDefinitionList = await this.api.apiService.activiti.processApi.getProcessDefinitions({ deploymentId: deploymentId });
const chosenProcess = processDefinitionList.data.find( (processDefinition) => {
return processDefinition.name === processName;
});
return chosenProcess;
} catch (error) {
Logger.error('Get ProcessDefinitions - Service error, Response: ', JSON.parse(JSON.stringify(error)).response.text);
Logger.error('Get ProcessDefinitions - Service error, Response: ', JSON.parse(JSON.stringify(error)));
}
}
async getProcessTaskId(processId: string): Promise<string> {
const taskList = await this.api.activiti.taskApi.listTasks({});
async getProcessTaskId(processId: string): Promise<TaskRepresentation> {
const taskList = await this.api.apiService.activiti.taskApi.listTasks({});
let wantedtask;
taskList.data.forEach((task) => {
@@ -84,4 +85,5 @@ export class ProcessUtil {
});
return wantedtask ? wantedtask : 'null';
}
}

View File

@@ -16,6 +16,6 @@
*/
export * from './applications.util';
export * from './process.util';
export * from './models.service';
export * from './integration.service';
export * from './models.service';
export * from './process.util';

View File

@@ -34,7 +34,7 @@ export class FiltersPage {
}
async isFilterHighlighted(filterName): Promise<boolean> {
const processNameHighlighted: ElementFinder = element(by.css(`.adf-active button[data-automation-id='${filterName}_filter']`));
const processNameHighlighted: ElementFinder = element(by.css(`.adf-active [data-automation-id='${filterName}_filter']`));
try {
await BrowserVisibility.waitUntilElementIsVisible(processNameHighlighted);
return true;
@@ -44,7 +44,7 @@ export class FiltersPage {
}
async isFilterDisplayed(name): Promise<boolean> {
const filterName: ElementFinder = element(by.css(`button[data-automation-id='${name}_filter']`));
const filterName: ElementFinder = element(by.css(`[data-automation-id='${name}_filter']`));
try {
await BrowserVisibility.waitUntilElementIsVisible(filterName);
return true;
@@ -54,13 +54,13 @@ export class FiltersPage {
}
async checkFilterHasNoIcon(name): Promise<void> {
const filterName: ElementFinder = element(by.css(`button[data-automation-id='${name}_filter']`));
const filterName: ElementFinder = element(by.css(`[data-automation-id='${name}_filter']`));
await BrowserVisibility.waitUntilElementIsVisible(filterName);
await BrowserVisibility.waitUntilElementIsNotVisible(filterName.element(this.processIcon));
}
async getFilterIcon(name): Promise<string> {
const filterName: ElementFinder = element(by.css(`button[data-automation-id='${name}_filter']`));
const filterName: ElementFinder = element(by.css(`[data-automation-id='${name}_filter']`));
await BrowserVisibility.waitUntilElementIsVisible(filterName);
const icon = filterName.element(this.processIcon);
return BrowserActions.getText(icon);

View File

@@ -19,7 +19,7 @@ import { BrowserVisibility } from '../../core/utils/browser-visibility';
import { by, element, ElementFinder, Locator } from 'protractor';
import { BrowserActions } from '../../core/utils/browser-actions';
import { By } from 'selenium-webdriver';
import { DropdownPage } from '../../material/pages/dropdown.page';
import { DropdownPage } from '../../core/pages/material/dropdown.page';
export class FormFieldsPage {

View File

@@ -18,7 +18,7 @@
import { BrowserVisibility } from '../../core/utils/browser-visibility';
import { by, element, ElementFinder } from 'protractor';
import { BrowserActions } from '../../core/utils/browser-actions';
import { DropdownPage } from '../../material/pages/dropdown.page';
import { DropdownPage } from '../../core/pages/material/dropdown.page';
export class SelectAppsDialog {

View File

@@ -18,7 +18,7 @@
import { by, element, Key, protractor, browser, ElementFinder } from 'protractor';
import { BrowserVisibility } from '../../core/utils/browser-visibility';
import { BrowserActions } from '../../core/utils/browser-actions';
import { DropdownPage } from '../../material/pages/dropdown.page';
import { DropdownPage } from '../../core/pages/material/dropdown.page';
import { FormFields } from '../../core/pages/form/form-fields';
export class StartProcessPage {

View File

@@ -22,10 +22,10 @@ export class TaskFiltersPage {
filtersPage = new FiltersPage();
myTasks: ElementFinder = element(by.css('button[data-automation-id="My Tasks_filter"]'));
queuedTask: ElementFinder = element(by.css('button[data-automation-id="Queued Tasks_filter"]'));
completedTask: ElementFinder = element(by.css('button[data-automation-id="Completed Tasks_filter"]'));
involvedTask: ElementFinder = element(by.css('button[data-automation-id="Involved Tasks_filter"]'));
myTasks: ElementFinder = element(by.css('[data-automation-id="My Tasks_filter"]'));
queuedTask: ElementFinder = element(by.css('[data-automation-id="Queued Tasks_filter"]'));
completedTask: ElementFinder = element(by.css('[data-automation-id="Completed Tasks_filter"]'));
involvedTask: ElementFinder = element(by.css('[data-automation-id="Involved Tasks_filter"]'));
accordionMenu: ElementFinder = element(by.css('.app-processes-menu mat-accordion'));
async clickMyTasksFilterButton(): Promise<void> {

View File

@@ -15,4 +15,5 @@
* limitations under the License.
*/
export * from './actions/public-api';
export * from './pages/public-api';

View File

@@ -31,46 +31,21 @@ export interface TestConfiguration {
password: string
};
admin: {
email: string,
password: string
};
main: {
timeout: number;
rootPath: string;
};
adf: {
url: string;
port: string;
login: string;
adminUser: string;
adminEmail: string;
adminPassword: string;
hostBPM: string;
clientIdSso: string;
hostSso: () => string;
hostIdentity: () => string;
};
adf_acs: {
protocol: string;
host: string;
port: string;
apiContextRoot: string;
clientIdSso: string;
};
adf_external_acs: {
protocol: string;
host: string;
port: string;
apiContextRoot: string;
clientIdSso: string;
};
adf_aps: {
protocol: string;
host: string;
port: string;
apiContextRoot: string;
clientIdSso: string;
};
}

View File

@@ -16,10 +16,7 @@
*/
export * from './lib/core/public-api';
export * from './lib/form-cloud/public-api';
export * from './lib/material/public-api';
export * from './lib/content-services/public-api';
export * from './lib/material/public-api';
export * from './lib/process-services/public-api';
export * from './lib/process-services-cloud/public-api';
export * from './lib/testing.module';