[ci:force] - fixing lint

This commit is contained in:
VitoAlbano
2024-10-12 23:20:30 +01:00
committed by Vito Albano
parent 62baa655ed
commit c1a42596dd
16 changed files with 1474 additions and 5 deletions

View File

@@ -8,5 +8,6 @@
"@alfresco/js-api": ["../../../dist/libs/js-api"], "@alfresco/js-api": ["../../../dist/libs/js-api"],
"@alfresco/js-api/*": ["../../../dist/libs/js-api/*"] "@alfresco/js-api/*": ["../../../dist/libs/js-api/*"]
} }
} },
"include": ["src/**/*.ts", "index.ts"]
} }

View File

@@ -6,5 +6,5 @@
"useDefineForClassFields": false "useDefineForClassFields": false
}, },
"files": ["src/test.ts"], "files": ["src/test.ts"],
"include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"] "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "index.ts"]
} }

View File

@@ -15,5 +15,6 @@
}, },
"target": "ES2022", "target": "ES2022",
"useDefineForClassFields": false "useDefineForClassFields": false
} },
"include": ["src/**/*.ts", "index.ts"]
} }

View File

@@ -6,5 +6,5 @@
"useDefineForClassFields": false "useDefineForClassFields": false
}, },
"files": ["src/test.ts"], "files": ["src/test.ts"],
"include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts"] "include": ["**/*.spec.ts", "**/*.test.ts", "**/*.d.ts", "index.ts"]
} }

View File

@@ -15,4 +15,4 @@
* limitations under the License. * limitations under the License.
*/ */
export const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.document !== 'undefined'; export const isBrowser = (): boolean => typeof window?.document !== 'undefined';

View File

@@ -0,0 +1,138 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 '../../../../shared/api/api.service';
import { StringUtil } from '../../../../shared/utils/string.util';
import { ApiUtil } from '../../../../shared/api/api.util';
import { Logger } from '../../utils/logger';
import { browser } from 'protractor';
export class GroupIdentityService {
api: ApiService;
constructor(api: ApiService) {
this.api = api;
}
async createIdentityGroup(groupName = StringUtil.generateRandomString(5)): Promise<any> {
await this.createGroup(groupName);
const group = await this.getGroupInfoByGroupName(groupName);
return group;
}
async deleteIdentityGroup(groupId): Promise<void> {
await this.deleteGroup(groupId);
}
async createGroup(groupName: string): Promise<any> {
const path = '/groups';
const method = 'POST';
const queryParams = {};
const postBody = {
name: `${groupName}-${browser.params.groupSuffix}`
};
const data = await this.api.performIdentityOperation(path, method, queryParams, postBody);
return data;
}
async deleteGroup(groupId: string): Promise<any> {
const path = `/groups/${groupId}`;
const method = 'DELETE';
const queryParams = {};
const postBody = {};
const data = await this.api.performIdentityOperation(path, method, queryParams, postBody);
return data;
}
async getGroupInfoByGroupName(groupName: string): Promise<any> {
Logger.log(`Get GroupInfoByGroupName ${groupName}`);
const predicate = (result: any) => !!result;
const apiCall = async () => {
try {
const path = `/groups`;
const method = 'GET';
const queryParams = { search: groupName };
const postBody = {};
const data = await this.api.performIdentityOperation(path, method, queryParams, postBody);
Logger.log(`Data ${JSON.stringify(data)}`);
return data[0];
Logger.error('Group not found');
} catch (error) {
Logger.error('Group not found');
return null;
}
};
return ApiUtil.waitForApi(apiCall, predicate);
}
async assignRole(groupId: string, roleId: string, roleName: string): Promise<any> {
Logger.log(`Assign to group ${groupId} Role ${roleName}`);
const path = `/groups/${groupId}/role-mappings/realm`;
const method = 'POST';
const queryParams = {};
const postBody = [{ id: roleId, name: roleName }];
const data = await this.api.performIdentityOperation(path, method, queryParams, postBody);
return data;
}
/**
* Add client roles.
* @param groupId ID of the target group
* @param clientId ID of the client
* @param roleId ID of the clientRole
* @param roleName of the clientRole
* @returns Promise
*/
async addClientRole(groupId: string, clientId: string, roleId: string, roleName: string): Promise<any> {
const path = `/groups/${groupId}/role-mappings/clients/${clientId}`;
const method = 'POST';
const queryParams = {};
const postBody = [
{
id: roleId,
name: roleName,
composite: false,
clientRole: true,
containerId: clientId
}
];
return this.api.performIdentityOperation(path, method, queryParams, postBody);
}
/**
* Gets the client ID using the app name.
* @param applicationName Name of the app
* @returns client ID string
*/
async getClientIdByApplicationName(applicationName: string): Promise<any> {
const path = `/clients`;
const method = 'GET';
const queryParams = { clientId: applicationName };
const postBody = {};
const data = await this.api.performIdentityOperation(path, method, queryParams, postBody);
return data[0].id;
}
}

View File

@@ -0,0 +1,34 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 '../../../shared/utils/string.util';
/**
* Create tenant JSON Object
* @param details - JSON object used to overwrite the default values
*/
export class Tenant {
active = true;
configuration = 'DefaultConfig';
domain = 'DefaultDomain';
maxUsers = 10;
name = StringUtil.generateRandomString();
constructor(details?: any) {
Object.assign(this, details);
}
}

View File

@@ -0,0 +1,569 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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, protractor, ElementFinder, ElementArrayFinder, $, $$ } from 'protractor';
import { BrowserVisibility } from '../utils/browser-visibility';
import { BrowserActions } from '../utils/browser-actions';
import { Logger } from '../utils/logger';
import { materialLocators } from './public-api';
const MAX_LOADING_TIME = 120000;
export class DataTableComponentPage {
rootElement: ElementFinder;
list: ElementArrayFinder;
contents: ElementArrayFinder;
tableBody: ElementFinder;
allColumns: ElementArrayFinder;
selectedRowNumber: ElementFinder;
allSelectedRows: ElementArrayFinder;
selectAll: ElementFinder;
selectAllChecked: ElementFinder;
emptyList: ElementFinder;
emptyListTitle: ElementFinder;
emptyListSubtitle: ElementFinder;
noContentContainer: ElementFinder;
mainMenuButton: ElementFinder;
rows = `adf-datatable div[class*='adf-datatable-body'] adf-datatable-row[class*='adf-datatable-row']`;
constructor(rootElement = $$('adf-datatable').first()) {
this.rootElement = rootElement;
this.list = this.rootElement.$$(`div[class*='adf-datatable-body'] adf-datatable-row[class*='adf-datatable-row']`);
this.contents = this.rootElement.$$('.adf-datatable-body span');
this.tableBody = this.rootElement.$$(`.adf-datatable-body`).first();
this.allColumns = this.rootElement.$$('div[data-automation-id*="auto_header_content_id"]');
this.mainMenuButton = this.rootElement.$('[data-automation-id="adf-datatable-main-menu-button"]');
this.selectedRowNumber = this.rootElement.$(`adf-datatable-row[class*='is-selected'] div[data-automation-id*='text_']`);
this.allSelectedRows = this.rootElement.$$(`adf-datatable-row[class*='is-selected']`);
this.selectAllChecked = this.rootElement.$(`div[class*='adf-datatable-header'] ${materialLocators.Checkbox.root}.mat-mdc-checkbox-checked`);
this.selectAll = this.rootElement.$(`div[class*='adf-datatable-header'] ${materialLocators.Checkbox.root}`);
this.emptyList = this.rootElement.$(`adf-empty-content`);
this.emptyListTitle = this.rootElement.$(`.adf-empty-content__title`);
this.emptyListSubtitle = this.rootElement.$(`.adf-empty-content__subtitle`);
this.noContentContainer = $(`div[class*='adf-no-content-container']`);
}
geCellElementDetail(detail: string): ElementArrayFinder {
return $$(`adf-datatable div[title="${detail}"] span`);
}
async checkAllRowsButtonIsDisplayed(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.selectAll);
}
async checkAllRows(): Promise<void> {
await BrowserActions.click(this.selectAll);
await BrowserVisibility.waitUntilElementIsVisible(this.selectAllChecked);
}
async uncheckAllRows(): Promise<void> {
await BrowserActions.click(this.selectAll);
await BrowserVisibility.waitUntilElementIsNotVisible(this.selectAllChecked);
}
async clickCheckbox(columnName: string, columnValue: string): Promise<void> {
const checkbox = this.getRowCheckbox(columnName, columnValue);
await BrowserActions.click(checkbox);
}
async checkRowIsNotChecked(columnName: string, columnValue: string): Promise<void> {
const rowSelector = this.getRowCheckboxChecked(columnName, columnValue);
await BrowserVisibility.waitUntilElementIsNotVisible(rowSelector);
}
async checkRowIsChecked(columnName: string, columnValue: string): Promise<void> {
const rowCheckbox = this.getRowCheckboxChecked(columnName, columnValue);
await BrowserVisibility.waitUntilElementIsVisible(rowCheckbox);
}
getRowCheckbox(columnName: string, columnValue: string): ElementFinder {
return this.getRow(columnName, columnValue).$(materialLocators.Checkbox.root);
}
getRowCheckboxChecked(columnName: string, columnValue: string): ElementFinder {
return this.getRow(columnName, columnValue).$('mat-checkbox.mat-mdc-checkbox-checked');
}
async checkNoRowIsSelected(): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(this.selectedRowNumber);
}
async getNumberOfSelectedRows(): Promise<number> {
return this.allSelectedRows.count();
}
async selectRow(columnName: string, columnValue: string): Promise<void> {
await BrowserActions.closeMenuAndDialogs();
const row = this.getRow(columnName, columnValue);
await BrowserActions.click(row);
}
async selectRowWithKeyboard(columnName: string, columnValue: string): Promise<void> {
await browser.actions().sendKeys(protractor.Key.COMMAND).perform();
await this.selectRow(columnName, columnValue);
await browser.actions().sendKeys(protractor.Key.NULL).perform();
}
async checkRowIsSelected(columnName: string, columnValue: string): Promise<void> {
const selectedRow = this.getCellElementByValue(columnName, columnValue).element(
by.xpath(`ancestor::adf-datatable-row[contains(@class, 'is-selected')]`)
);
await BrowserVisibility.waitUntilElementIsVisible(selectedRow);
}
async checkRowIsNotSelected(columnName: string, columnValue: string): Promise<void> {
const selectedRow = this.getCellElementByValue(columnName, columnValue).element(
by.xpath(`ancestor::adf-datatable-row[contains(@class, 'is-selected')]`)
);
await BrowserVisibility.waitUntilElementIsNotVisible(selectedRow);
}
async getColumnValueForRow(identifyingColumn: string, identifyingValue: string, columnName: string): Promise<string> {
const row = this.getRow(identifyingColumn, identifyingValue);
await BrowserVisibility.waitUntilElementIsVisible(row);
const rowColumn = row.$(`div[title="${columnName}"] span`);
return BrowserActions.getText(rowColumn);
}
/**
* Check the list is sorted.
* @param sortOrder 'ASC' if the list is await expected to be sorted ascending and 'DESC' for descending
* @param columnTitle titleColumn column
* @param listType 'string' for string typed lists and 'number' for number typed (int, float) lists
* @returns 'true' if the list is sorted as await expected and 'false' if it isn't
*/
async checkListIsSorted(sortOrder: string, columnTitle: string, listType: string = 'STRING'): Promise<any> {
const column = $$(`div.adf-datatable-cell[title='${columnTitle}'] span`);
await BrowserVisibility.waitUntilElementIsVisible(column.first());
const initialList: string[] = [];
const length = await column.count();
for (let i = 0; i < length; i++) {
const text: string = await BrowserActions.getText(column.get(i));
if (text.length !== 0) {
initialList.push(text.toLowerCase());
}
}
let sortedList = [...initialList];
if (listType.toLocaleLowerCase() === 'string') {
sortedList = sortedList.sort();
} else if (listType.toLocaleLowerCase() === 'number') {
sortedList = sortedList.sort((a, b) => parseInt(a, 10) - parseInt(b, 10));
} else if (listType.toLocaleLowerCase() === 'priority') {
sortedList = sortedList.sort(this.sortPriority);
}
if (['desc', 'descending'].includes(sortOrder.toLocaleLowerCase())) {
sortedList = sortedList.reverse();
}
return initialList.toString() === sortedList.toString();
}
sortPriority(a: string, b: string) {
if (a === b) {
return 0;
}
if (a.toLocaleLowerCase() === 'none') {
return -1;
}
if (a.toLocaleLowerCase() === 'low') {
if (b === 'none') {
return 1;
} else {
return -1;
}
}
if (a.toLocaleLowerCase() === 'normal') {
if (b.toLocaleLowerCase() === 'high') {
return -1;
} else {
return 1;
}
}
return 1;
}
async rightClickOnRow(columnName: string, columnValue: string): Promise<void> {
await this.rightClickOnItem(columnName, columnValue);
await BrowserVisibility.waitUntilElementIsVisible($('#adf-context-menu-content'));
}
async getTooltip(columnName: string, columnValue: string): Promise<string> {
return BrowserActions.getAttribute(this.getCellElementByValue(columnName, columnValue), 'title');
}
async rightClickOnItem(columnName: string, columnValue: string): Promise<void> {
const row = this.getRow(columnName, columnValue);
await BrowserActions.rightClick(row);
}
getFileHyperlink(filename: string): ElementFinder {
return element(by.cssContainingText('adf-name-column[class*="adf-datatable-link"] span', filename));
}
async numberOfRows(): Promise<number> {
try {
await this.waitForFirstRow();
return this.rootElement.$$(this.rows).count();
} catch (e) {
return 0;
}
}
async waitForFirstRow(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.rootElement.$$(this.rows).first());
}
async getAllRowsColumnValues(column: string): Promise<string[]> {
let columnValues: string[] = [];
const columnLocator = $$(
`adf-datatable div[class*='adf-datatable-body'] adf-datatable-row[class*='adf-datatable-row'] div[title="${column}"] span`
);
await BrowserVisibility.waitUntilElementIsPresent(columnLocator.first(), 1000);
try {
await BrowserVisibility.waitUntilElementIsPresent(columnLocator.first(), 1000);
columnValues = await columnLocator.filter(async (el) => el.isPresent()).map(async (el) => el.getText());
} catch (error) {
Logger.log(error);
}
return columnValues;
}
async getRowsWithSameColumnValues(columnName: string, columnValue: string) {
const columnLocator = `div[title='${columnName}'] div[data-automation-id="text_${columnValue}"] span`;
await BrowserVisibility.waitUntilElementIsVisible(this.rootElement.$$(columnLocator).first());
return this.rootElement.$$(columnLocator).getText();
}
async doubleClickRow(columnName: string, columnValue: string): Promise<void> {
const row = this.getRow(columnName, columnValue);
await BrowserActions.click(row);
await browser.actions().sendKeys(protractor.Key.ENTER).perform();
}
async waitForTableBody(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.tableBody);
}
// @deprecated Use Playwright API instead
async getFirstElementDetail(detail: string): Promise<string> {
const firstNode = $$(`adf-datatable div[title="${detail}"] span`).first();
return BrowserActions.getText(firstNode);
}
/**
* Sort the list by name column.
* @param sortOrder 'ASC' to sort the list ascendant and 'DESC' for descendant
* @param titleColumn column title
*/
async sortByColumn(sortOrder: string, titleColumn: string): Promise<void> {
const locator = $(`div[data-automation-id="auto_id_${titleColumn}"]`);
await BrowserVisibility.waitUntilElementIsVisible(locator);
const result = await BrowserActions.getAttribute(locator, 'class');
if (sortOrder.toLocaleLowerCase() === 'asc') {
if (!result.includes('sorted-asc')) {
if (result.includes('sorted-desc') || result.includes('sortable')) {
await BrowserActions.click(locator);
}
}
} else {
if (result.includes('sorted-asc')) {
await BrowserActions.click(locator);
} else if (result.includes('sortable')) {
await BrowserActions.click(locator);
await BrowserActions.click(locator);
}
}
}
async checkContentIsDisplayed(columnName: string, columnValue: string, retry = 0): Promise<void> {
Logger.log(`Wait content is displayed ${columnName} ${columnValue} retry: ${retry}`);
const row = this.getCellElementByValue(columnName, columnValue);
try {
await BrowserVisibility.waitUntilElementIsVisible(row);
} catch (error) {
if (retry < 3) {
retry++;
await this.checkContentIsDisplayed(columnName, columnValue, retry);
} else {
throw error;
}
}
}
async checkContentIsNotDisplayed(columnName: string, columnValue: string, retry = 0): Promise<void> {
Logger.log(`Wait content is displayed ${columnName} ${columnValue} retry: ${retry}`);
const row = this.getCellElementByValue(columnName, columnValue);
try {
await BrowserVisibility.waitUntilElementIsNotVisible(row);
} catch (error) {
if (retry < 3) {
retry++;
await this.checkContentIsNotDisplayed(columnName, columnValue, retry);
} else {
throw error;
}
}
}
getRow(columnName: string, columnValue: string): ElementFinder {
return this.rootElement
.all(
by.xpath(
`//div[starts-with(@title, '${columnName}')]//div[contains(@data-automation-id, '${columnValue}')]//ancestor::adf-datatable-row[contains(@class, 'adf-datatable-row')]`
)
)
.first();
}
// @deprecated use Playwright instead
getRowByIndex(index: number): ElementFinder {
return this.rootElement.element(
by.xpath(`//div[contains(@class,'adf-datatable-body')]//adf-datatable-row[contains(@class,'adf-datatable-row')][${index}]`)
);
}
async contentInPosition(position: number): Promise<string> {
await BrowserVisibility.waitUntilElementIsVisible(this.contents.first());
return BrowserActions.getText(this.contents.get(position - 1));
}
getCellElementByValue(columnName: string, columnValue: string, columnPrefix = 'text_'): ElementFinder {
return this.rootElement.$$(`div[title="${columnName}"] div[data-automation-id="${columnPrefix}${columnValue}"] span`).first();
}
async tableIsLoaded(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.rootElement);
}
async waitTillContentLoaded(): Promise<void> {
if (await this.isSpinnerPresent()) {
Logger.log('wait datatable loading spinner disappear');
await BrowserVisibility.waitUntilElementIsNotVisible(
this.rootElement.element(by.tagName(materialLocators.Progress.spinner.root)),
MAX_LOADING_TIME
);
if (await this.isEmpty()) {
Logger.log('empty page');
} else {
await this.waitFirstElementPresent();
}
} else if (await this.isEmpty()) {
Logger.log('empty page');
} else {
try {
Logger.log('wait datatable loading spinner is present');
await BrowserVisibility.waitUntilElementIsVisible(this.rootElement.element(by.tagName(materialLocators.Progress.spinner.root)), 2000);
await BrowserVisibility.waitUntilElementIsNotVisible(
this.rootElement.element(by.tagName(materialLocators.Progress.spinner.root)),
MAX_LOADING_TIME
);
} catch (error) {
Logger.error('Loading spinner is not present');
}
if (await this.isEmpty()) {
Logger.log('empty page');
} else {
await this.waitFirstElementPresent();
}
}
}
async waitTillContentLoadedInfinitePagination(): Promise<void> {
await browser.sleep(500);
if (await this.isInfiniteSpinnerPresent()) {
Logger.log('wait datatable loading spinner disappear');
await BrowserVisibility.waitUntilElementIsNotVisible(element(by.tagName(materialLocators.Progress.bar.root)));
if (await this.isEmpty()) {
Logger.log('empty page');
} else {
await this.waitFirstElementPresent();
}
} else {
try {
Logger.log('wait datatable loading spinner is present');
await BrowserVisibility.waitUntilElementIsVisible(element(by.tagName(materialLocators.Progress.bar.root)));
} catch (error) {
Logger.error('Infinite pagination spinner is not present');
}
if (await this.isEmpty()) {
Logger.log('empty page');
} else {
await this.waitFirstElementPresent();
}
}
}
// @deprecated use Playwright instead
async isColumnDisplayed(columnTitle: string): Promise<boolean> {
const isColumnDisplayed = (await this.allColumns).some(async (column) => {
const columnText = await column.getText();
return columnText === columnTitle;
});
return isColumnDisplayed;
}
// @deprecated use Playwright instead
async getNumberOfColumns(): Promise<number> {
return this.allColumns.count();
}
async getNumberOfRows(): Promise<number> {
return this.list.count();
}
getCellByRowNumberAndColumnName(rowNumber: number, columnName: string): ElementFinder {
return this.list.get(rowNumber).$$(`div[title="${columnName}"] span`).first();
}
getCellByRowContentAndColumn(rowColumn: string, rowContent: string, columnName: string): ElementFinder {
return this.getRow(rowColumn, rowContent).$(`div[title='${columnName}']`);
}
async selectRowByContent(content: string): Promise<void> {
const row = this.getCellByContent(content);
await BrowserActions.click(row);
}
async checkRowByContentIsSelected(folderName: string): Promise<void> {
const selectedRow = this.getCellByContent(folderName).element(by.xpath(`ancestor::adf-datatable-row[contains(@class, 'is-selected')]`));
await BrowserVisibility.waitUntilElementIsVisible(selectedRow);
}
async checkRowByContentIsNotSelected(folderName: string): Promise<void> {
const selectedRow = this.getCellByContent(folderName).element(by.xpath(`ancestor::adf-datatable-row[contains(@class, 'is-selected')]`));
await BrowserVisibility.waitUntilElementIsNotVisible(selectedRow);
}
getCellByContent(content: string): ElementFinder {
return this.rootElement
.all(by.cssContainingText(`adf-datatable-row[class*='adf-datatable-row'] div[class*='adf-datatable-cell']`, content))
.first();
}
async checkCellByHighlightContent(content: string): Promise<void> {
const cell = this.rootElement.element(
by.cssContainingText(
`adf-datatable-row[class*='adf-datatable-row'] div[class*='adf-name-location-cell-name'] span.adf-highlight`,
content
)
);
await BrowserVisibility.waitUntilElementIsVisible(cell);
}
async clickRowByContent(name: string): Promise<void> {
const resultElement = this.rootElement.$$(`div[data-automation-id='${name}']`).first();
await BrowserActions.click(resultElement);
}
async clickRowByContentCheckbox(name: string): Promise<void> {
const resultElement = this.rootElement
.$$(`div[data-automation-id='${name}']`)
.first()
.element(by.xpath(`ancestor::adf-datatable-row/label/${materialLocators.Checkbox.root}`));
browser.actions().mouseMove(resultElement);
await BrowserActions.click(resultElement);
}
async checkRowContentIsDisplayed(content: string): Promise<void> {
const resultElement = this.rootElement.$$(`div[data-automation-id='${content}']`).first();
await BrowserVisibility.waitUntilElementIsVisible(resultElement);
}
async checkRowContentIsNotDisplayed(content: string): Promise<void> {
const resultElement = this.rootElement.$$(`div[data-automation-id='${content}']`).first();
await BrowserVisibility.waitUntilElementIsNotVisible(resultElement);
}
async checkRowContentIsDisabled(content: string): Promise<void> {
const resultElement = this.rootElement.$$(`div[data-automation-id='${content}'] div.adf-cell-value img[aria-label='Disabled']`).first();
await BrowserVisibility.waitUntilElementIsVisible(resultElement);
}
async doubleClickRowByContent(name: string): Promise<void> {
const resultElement = this.rootElement.$$(`div[data-automation-id='${name}']`).first();
await BrowserActions.click(resultElement);
await browser.actions().sendKeys(protractor.Key.ENTER).perform();
}
async isEmpty(): Promise<boolean> {
await browser.sleep(500);
let isDisplayed;
try {
isDisplayed = await this.emptyList.isDisplayed();
} catch (error) {
isDisplayed = false;
}
Logger.log(`empty page isDisplayed ${isDisplayed}`);
return isDisplayed;
}
private async isSpinnerPresent(): Promise<boolean> {
let isSpinnerPresent;
try {
isSpinnerPresent = await this.rootElement.element(by.tagName(materialLocators.Progress.spinner.root)).isDisplayed();
} catch (error) {
isSpinnerPresent = false;
}
return isSpinnerPresent;
}
private async isInfiniteSpinnerPresent(): Promise<boolean> {
let isSpinnerPresent;
try {
isSpinnerPresent = await this.rootElement.element(by.tagName(materialLocators.Progress.bar.root)).isDisplayed();
} catch (error) {
isSpinnerPresent = false;
}
return isSpinnerPresent;
}
private async waitFirstElementPresent(): Promise<void> {
try {
Logger.log('wait first element is present');
await BrowserVisibility.waitUntilElementIsVisible(this.contents.first());
} catch (error) {
Logger.log('Possible empty page');
}
}
}

View File

@@ -0,0 +1,65 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 '../utils/browser-visibility';
import { BrowserActions } from '../utils/browser-actions';
/** @deprecated Use Playwright API instead */
export class SnackbarPage {
notificationSnackBar = $$(`[data-automation-id='adf-snackbar-message-content']`).first();
snackBarAction = $(`[data-automation-id='adf-snackbar-message-content-action-button']`);
snackBarContainerCss = $$('adf-snackbar-content');
decorativeIconSnackBar = $(`[data-automation-id='adf-snackbar-decorative-icon']`);
async waitForSnackBarToAppear(timeout = 5000) {
return BrowserVisibility.waitUntilElementIsVisible(this.snackBarContainerCss.first(), timeout, 'snackbar did not appear');
}
async waitForSnackBarToClose(timeout = 15000) {
return BrowserVisibility.waitUntilElementIsNotVisible(this.snackBarContainerCss.first(), timeout);
}
async getSnackBarMessage(): Promise<string> {
await this.waitForSnackBarToAppear();
return this.notificationSnackBar.getText();
}
async getSnackBarActionMessage(): Promise<string> {
await this.waitForSnackBarToAppear();
return this.snackBarAction.getText();
}
async getSnackBarDecorativeIcon(): Promise<string> {
await this.waitForSnackBarToAppear();
return this.decorativeIconSnackBar.getText();
}
async clickSnackBarAction(): Promise<void> {
await this.waitForSnackBarToAppear();
await BrowserActions.click(this.snackBarAction);
}
async isNotificationSnackBarDisplayed(): Promise<boolean> {
try {
await BrowserVisibility.waitUntilElementIsVisible(this.notificationSnackBar, 2000);
return true;
} catch {
return false;
}
}
}

View File

@@ -0,0 +1,214 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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, ElementFinder, protractor, $ } from 'protractor';
import { BrowserActions } from './utils/browser-actions';
import { BrowserVisibility } from './utils/browser-visibility';
/**
* Provides a wrapper for the most common operations with the page elements.
*/
export class TestElement {
constructor(public elementFinder: ElementFinder) {}
/**
* Create a new instance with the element located by the id
* @param id The id of the element
* @returns test element wrapper
*/
static byId(id: string): TestElement {
return new TestElement(element(by.id(id)));
}
/**
* Create a new instance with the element located by the CSS class name
* @param selector The CSS class name to lookup
* @returns test element wrapper
*/
static byCss(selector: string): TestElement {
return new TestElement($(selector));
}
/**
* Create a new instance with the element that contains specific text
* @param selector the CSS selector
* @param text the text within the target element
* @returns test element wrapper
*/
static byText(selector: string, text: string): TestElement {
return new TestElement(element(by.cssContainingText(selector, text)));
}
/**
* Create a new instance with the element with specific HTML tag name
* @param selector the HTML tag name
* @returns test element wrapper
*/
static byTag(selector: string): TestElement {
return new TestElement(element(by.tagName(selector)));
}
/**
* Performs a click on this element
* @returns a promise that will be resolved when the click command has completed
*/
async click() {
return BrowserActions.click(this.elementFinder);
}
/**
* Checks that an element is present on the DOM of a page and visible
* @param waitTimeout How long to wait for the condition to be true
* @returns a promise that will be resolved when the element is present on the DOM of a page and visible
*/
async isVisible(waitTimeout?: number): Promise<boolean> {
try {
await BrowserVisibility.waitUntilElementIsVisible(this.elementFinder, waitTimeout);
return true;
} catch {
return false;
}
}
/**
* Waits until the element is present on the DOM of a page and visible
* @param waitTimeout How long to wait for the condition to be true
* @returns a promise that will be resolved when the element is present on the DOM of a page and visible
*/
async waitVisible(waitTimeout?: number): Promise<any> {
return BrowserVisibility.waitUntilElementIsVisible(this.elementFinder, waitTimeout);
}
/**
* Waits until the element is either invisible or not present on the DOM
* @param waitTimeout How long to wait for the condition to be true
* @returns a promise that will be resolved when the element is either invisible or not present on the DOM
*/
async waitNotVisible(waitTimeout?: number): Promise<any> {
return BrowserVisibility.waitUntilElementIsNotVisible(this.elementFinder, waitTimeout);
}
/**
* Checks that an element is present on the DOM of a page
* @param waitTimeout How long to wait for the condition to be true
* @returns a promise that will be resolved when the element is present on the DOM of a page
*/
async isPresent(waitTimeout?: number): Promise<boolean> {
try {
await BrowserVisibility.waitUntilElementIsPresent(this.elementFinder, waitTimeout);
return true;
} catch {
return false;
}
}
/**
* Waits until the element is present on the DOM of a page
* @param waitTimeout How long to wait for the condition to be true
* @returns a promise that will be resolved when the element is present on the DOM of a page
*/
async waitPresent(waitTimeout?: number): Promise<any> {
return BrowserVisibility.waitUntilElementIsPresent(this.elementFinder, waitTimeout);
}
/**
* Waits until the element is not attached to the DOM of a page
* @param waitTimeout How long to wait for the condition to be true
* @returns a promise that will be resolved when the element is not attached to the DOM of a page
*/
async waitNotPresent(waitTimeout?: number): Promise<any> {
return BrowserVisibility.waitUntilElementIsNotPresent(this.elementFinder, waitTimeout);
}
/**
* Waits until the given text is present in the elements value
* @param value the text to check
* @returns a promise that will be resolved when the element has the given value
*/
async waitHasValue(value: string): Promise<any> {
return BrowserVisibility.waitUntilElementHasValue(this.elementFinder, value);
}
/**
* Query whether the DOM element represented by this instance is enabled.
* @returns a promise that will be resolved with the enabled state of the element
*/
async isEnabled(): Promise<boolean> {
return this.elementFinder.isEnabled();
}
/**
* Query whether the DOM element represented by this instance is disabled.
* @returns a promise that will be resolved with the disabled state of the element
*/
async isDisabled(): Promise<boolean> {
return !(await this.elementFinder.isEnabled());
}
/**
* Test whether this element is currently displayed.
* @returns a promise that will be resolved with the displayed state of the element
*/
async isDisplayed(): Promise<boolean> {
try {
await this.elementFinder.isDisplayed();
return true;
} catch {
return false;
}
}
/**
* Query for the value of the given attribute of the element.
* @param attributeName The name of the attribute to query.
* @returns a promise that will be resolved with the value of the attribute
*/
async getAttribute(attributeName: string): Promise<string> {
return BrowserActions.getAttribute(this.elementFinder, attributeName);
}
/**
* Get the visible (i.e. not hidden by CSS) innerText of this element, including sub-elements, without any leading or trailing whitespace.
* @returns a promise that will be resolved with the visible innerText of the element
*/
async getText(): Promise<string> {
return BrowserActions.getText(this.elementFinder);
}
/**
* Gets the `value` attribute for the given input element
* @returns input value
*/
getInputValue(): Promise<string> {
return BrowserActions.getInputValue(this.elementFinder);
}
/**
* Enter the text
* @param text the text to enter
*/
async typeText(text: string): Promise<void> {
await BrowserActions.clearSendKeys(this.elementFinder, text);
}
/**
* Clears the input using Ctrl+A and Backspace combination
*/
async clearInput() {
await this.elementFinder.clear();
await this.elementFinder.sendKeys(' ', protractor.Key.CONTROL, 'a', protractor.Key.NULL, protractor.Key.BACK_SPACE);
}
}

View File

@@ -0,0 +1,31 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 class ArrayUtil {
/**
* Returns TRUE if the first array contains all elements from the second one.
* @param superset source array
* @param subset target array
* @returns `true` if array is included, otherwise `false`
*/
static arrayContainsArray(superset: any[], subset: any[]): boolean {
if (0 === subset.length) {
return false;
}
return subset.every((value) => superset.indexOf(value) >= 0);
}
}

View File

@@ -0,0 +1,31 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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, browser } from 'protractor';
/**
* Tagged template to convert a sting to an `ElementFinder`.
* @example ```const item = byCss`.adf-breadcrumb-item-current`;```
* @example ```const item = byCss`${variable}`;```
* @param literals literals
* @param placeholders placeholders
* @returns Instance of `ElementFinder` type.
*/
export const byCss = (literals: TemplateStringsArray, ...placeholders: string[]): ElementFinder => {
const selector = literals[0] || placeholders[0];
return browser.$(selector);
};

View File

@@ -0,0 +1,115 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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, $, ElementFinder, $$ } from 'protractor';
import { BrowserVisibility } from '../../core/utils/browser-visibility';
import { BrowserActions } from '../../core/utils/browser-actions';
import { FormFields } from '../../core/pages/form/form-fields';
import { TestElement } from '../../core/test-element';
import { materialLocators } from '../../public-api';
export class GroupCloudComponentPage {
groupCloudSearch = $('input[data-automation-id="adf-cloud-group-search-input"]');
groupField = $('group-cloud-widget .adf-readonly');
formFields = new FormFields();
getGroupRowLocatorByName = async (name: string): Promise<ElementFinder> =>
$$(`${materialLocators.Option.root}[data-automation-id="adf-cloud-group-chip-${name}"]`).first();
async searchGroups(name: string): Promise<void> {
await BrowserActions.clearSendKeys(this.groupCloudSearch, name, 100);
}
async searchGroupsToExisting(name: string) {
await BrowserActions.clearSendKeys(this.groupCloudSearch, name, 100);
}
async getGroupsFieldContent(): Promise<string> {
return BrowserActions.getInputValue(this.groupCloudSearch);
}
async selectGroupFromList(name: string): Promise<void> {
const groupRow = await this.getGroupRowLocatorByName(name);
await BrowserActions.click(groupRow);
await BrowserVisibility.waitUntilElementIsNotVisible(groupRow);
}
async checkGroupIsDisplayed(name: string): Promise<void> {
const groupRow = await this.getGroupRowLocatorByName(name);
await BrowserVisibility.waitUntilElementIsVisible(groupRow);
}
async checkGroupIsNotDisplayed(name: string): Promise<void> {
const groupRow = await this.getGroupRowLocatorByName(name);
await BrowserVisibility.waitUntilElementIsNotVisible(groupRow);
}
async checkSelectedGroup(group: string): Promise<boolean> {
try {
await TestElement.byText(`${materialLocators.Chip.grid.row.root}[data-automation-id*="adf-cloud-group-chip-"]`, group).waitVisible();
return true;
} catch (e) {
return false;
}
}
async checkGroupNotSelected(group: string): Promise<void> {
await BrowserVisibility.waitUntilElementIsNotVisible(
element(by.cssContainingText(`${materialLocators.Chip.grid.row.root}[data-automation-id*="adf-cloud-group-chip-"]`, group))
);
}
async removeSelectedGroup(group: string): Promise<void> {
const locator = $(
`${materialLocators.Chip.grid.row.root}[data-automation-id*="adf-cloud-group-chip-${group}"] ${materialLocators.Icon.root}`
);
await BrowserActions.click(locator);
}
async isGroupWidgetVisible(fieldId: string): Promise<boolean> {
try {
await this.formFields.checkWidgetIsVisible(fieldId);
return true;
} catch {
return false;
}
}
async checkGroupWidgetIsReadOnly(): Promise<boolean> {
try {
await BrowserVisibility.waitUntilElementIsVisible(this.groupField);
return true;
} catch {
return false;
}
}
async checkGroupActiveField(name: string): Promise<boolean> {
try {
await BrowserActions.clearSendKeys(this.groupField, name);
return true;
} catch {
return false;
}
}
async checkNoResultsFoundError(): Promise<void> {
const errorLocator = $('[data-automation-id="adf-cloud-group-no-results"]');
await BrowserVisibility.waitUntilElementIsVisible(errorLocator);
}
}

View File

@@ -0,0 +1,131 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { AlfrescoApi, AlfrescoApiConfig } from '@alfresco/js-api';
import { LoggerLike } from '../utils/logger';
export interface ApiServiceConfig {
appConfig: AlfrescoApiConfig;
users: {
[key: string]: {
username: string;
password: string;
};
};
}
export class ApiService {
apiService: AlfrescoApi;
constructor(private config: ApiServiceConfig, private logger: LoggerLike) {
this.logger.log('Api Service configuration' + JSON.stringify(this.config));
this.apiService = new AlfrescoApi(this.config.appConfig);
}
getInstance(): AlfrescoApi {
return this.apiService;
}
async login(username: string, password: string): Promise<void> {
await this.apiService.login(username, password);
}
/**
* Login using one of the account profiles from the `browser.params.testConfig`.
* Example: loginWithProfile('admin')
* @param profileName profile name
*/
async loginWithProfile(profileName: string): Promise<void> {
const profile = this.config.users[profileName];
if (profile) {
this.logger.log(
`try to login with ${profile.username} on HOST: ${this.apiService.config.hostEcm} AUTHTYPE: ${this.apiService.config.authType} PROVIDER: ${this.apiService.config.provider}`
);
try {
await this.apiService.login(profile.username, profile.password);
this.logger.log(`Successfuly logged in as ${profile.username}`);
} catch (error) {
this.logger.error(`Failed to login with ${profile.username}`, error?.message);
throw new Error(`Login failed with ${profile.username}`);
}
} else {
throw new Error(`Login profile "${profileName}" not found on "browser.params.testConfig".`);
}
}
// @deprecated
async performBpmOperation(path: string, method: string, queryParams: any, postBody: any): Promise<any> {
return new Promise((resolve, reject) => {
const uri = this.config.appConfig.hostBpm + path;
const pathParams = {};
const formParams = {};
const contentTypes = ['application/json'];
const accepts = ['application/json'];
const headerParams = {
// eslint-disable-next-line @typescript-eslint/naming-convention
Authorization: 'bearer ' + this.apiService.oauth2Auth.token
};
this.apiService.processClient
.callCustomApi(uri, method, pathParams, queryParams, headerParams, formParams, postBody, contentTypes, accepts, Object)
.then((data) => resolve(data))
.catch((err) => reject(err));
});
}
// @deprecated
async performIdentityOperation(path: string, method: string, queryParams: any, postBody: any): Promise<any> {
return new Promise((resolve, reject) => {
const uri = this.config.appConfig.oauth2.host.replace('/realms', '/admin/realms') + path;
const pathParams = {};
const formParams = {};
const contentTypes = ['application/json'];
const accepts = ['application/json'];
const headerParams = {
// eslint-disable-next-line @typescript-eslint/naming-convention
Authorization: 'bearer ' + this.apiService.oauth2Auth.token
};
return this.apiService.processClient
.callCustomApi(uri, method, pathParams, queryParams, headerParams, formParams, postBody, contentTypes, accepts, Object)
.then((data) => resolve(data))
.catch((err) => reject(err));
});
}
// @deprecated
async performECMOperation(path: string, method: string, queryParams: any, postBody: any): Promise<any> {
return new Promise((resolve, reject) => {
const uri = this.config.appConfig.hostEcm + path;
const pathParams = {};
const formParams = {};
const contentTypes = ['application/json'];
const accepts = ['application/json'];
const headerParams = {
// eslint-disable-next-line @typescript-eslint/naming-convention
Authorization: 'bearer ' + this.apiService.oauth2Auth.token
};
this.apiService.contentClient
.callCustomApi(uri, method, pathParams, queryParams, headerParams, formParams, postBody, contentTypes, accepts, Object)
.then((data) => resolve(data))
.catch((err) => reject(err));
});
}
}

View File

@@ -0,0 +1,125 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 class StringUtil {
static generatePasswordString(length: number = 8): string {
let text = '';
const lowerCaseLimit = Math.floor(length / 2);
text += StringUtil.generateRandomCharset(lowerCaseLimit, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
text += StringUtil.generateRandomCharset(length - lowerCaseLimit, 'abcdefghijklmnopqrstuvwxyz');
return text;
}
/**
* Generates a random string.
* @param length If this parameter is not provided the length is set to 8 by default.
* @returns random string
*/
static generateRandomString(length: number = 8): string {
return StringUtil.generateRandomCharset(length, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
}
/**
* Generates a random lowercase string.
* @param length If this parameter is not provided the length is set to 8 by default.
* @returns random string
*/
static generateRandomLowercaseString(length: number = 8): string {
return StringUtil.generateRandomCharset(length, 'abcdefghijklmnopqrstuvwxyz0123456789');
}
/**
* Generates a random email address following the format: abcdef@activiti.test.com
* @param domain email domain
* @param length email length
* @returns email address
*/
static generateRandomEmail(domain: string, length: number = 5): string {
let email = StringUtil.generateRandomCharset(length, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
email += domain;
return email.toLowerCase();
}
/**
* Generates a random string - digits only.
* @param length If this parameter is not provided the length is set to 8 by default.
* @returns random string
*/
static generateRandomStringDigits(length: number = 8): string {
return StringUtil.generateRandomCharset(length, '0123456789');
}
/**
* Generates a random string - non-latin characters only.
* @param length If this parameter is not provided the length is set to 3 by default.
* @returns random string
*/
static generateRandomStringNonLatin(length: number = 3): string {
return StringUtil.generateRandomCharset(length, '密码你好𠮷');
}
/**
* Generates a random string.
* @param length If this parameter is not provided the length is set to 8 by default.
* @param charSet to use
* @returns random string
*/
static generateRandomCharset(length: number = 8, charSet: string): string {
let text = '';
for (let i = 0; i < length; i++) {
text += charSet.charAt(Math.floor(Math.random() * charSet.length));
}
return text;
}
/**
* Generates a sequence of files with name: baseName + index + extension (e.g.) baseName1.txt, baseName2.txt, ...
* @param startIndex start index
* @param endIndex end index
* @param baseName the base name of all files
* @param extension the extension of the file
* @returns list of file names
*/
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;
}
/**
* Generates a random name for a process
* @param length {int} If this parameter is not provided the length is set to 5 by default.
* @returns process name
*/
static generateProcessName(length: number = 5): string {
return 'process_' + StringUtil.generateRandomString(length);
}
/**
* Generates a random name for a user task
* @param length If this parameter is not provided the length is set to 5 by default.
* @returns task name
*/
static generateUserTaskName(length: number = 5): string {
return 'userTask_' + StringUtil.generateRandomString(length);
}
}

View File

@@ -0,0 +1,14 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"declaration": true,
"declarationMap": true,
"resolveJsonModule": true,
"paths": {
"@alfresco/js-api": ["../../../dist/libs/js-api"],
"@alfresco/js-api/*": ["../../../dist/libs/js-api/*"]
}
},
"include": ["src/**/*.ts", "index.ts"]
}