[ACS-11233] Testing week test cases automated in ACA (#5113)

* [ACS-11233] Testing week test cases automated in ACA

* [ACS-11233] last test additions from testing week

* [ACS-11233] sonar fix 1

* eslint configuration for e2e tests

* [ACS-11233] sonar fix 2

* [ACS-11233] sonar fix 3

* [ACS-11233] added viewer actions as a seperate test suite

* [ACS-11233] added viewer actions to pr yml

* [ACS-11233] deleted autocorrection

* [ACS-11233] review fix 1

* [ACS-11233] review fix 2

* [ACS-11233] small test fixes and report portal upload timeout change

* [ACS-11233] reportportal fix 2

* [ACS-11233] viewer tests fixes

* [ACS-11233] review fix 3

* [ACS-11233] review fix 4

* [ACS-11233] deleted angular inject test 1

* [ACS-11233] viewer tests fix 3
This commit is contained in:
Adam Świderski
2026-03-30 09:40:54 +02:00
committed by GitHub
parent 6fb8af3a20
commit ff38c7d19c
27 changed files with 1401 additions and 477 deletions
@@ -159,9 +159,9 @@ export class FileActionsApi {
try {
await waitForApi(apiCall, predicate, 30, 2500);
console.log(`waitForNodes: Found ${data.expect} nodes with search term "${searchTerm}"`);
} catch (error) {
console.error(`Error: ${error}`);
} catch {
const actual = await apiCall();
throw new Error(`waitForNodes: Timed out waiting for "${searchTerm}" — expected ${data.expect} nodes, found ${actual}`);
}
}
@@ -25,6 +25,7 @@
import { ApiClientFactory } from './api-client-factory';
import { NodeChildAssociationPaging, NodeEntry, NodePaging, NodesIncludeQuery, NodeBodyUpdate } from '@alfresco/js-api';
import { NodeContentTree, flattenNodeContentTree } from './node-content-tree';
import { Utils } from '../utils';
export class NodesApi {
private readonly apiService: ApiClientFactory;
@@ -81,6 +82,17 @@ export class NodesApi {
}
}
async createMultipleFiles(count: number, parentId = '-my-'): Promise<NodeEntry[]> {
const createdFiles: NodeEntry[] = [];
for (let i = 0; i < count; i++) {
const file = await this.createFile(`file-${Utils.random()}-${i}`, parentId);
if (file) {
createdFiles.push(file);
}
}
return createdFiles;
}
async createFolders(names: string[], relativePath = '/'): Promise<NodePaging> {
try {
return await this.createContent({ folders: names }, relativePath);
@@ -24,16 +24,16 @@
import { ApiClientFactory } from './api-client-factory';
import { Utils } from '../utils';
import { ResultSetPaging } from '@alfresco/js-api';
import { ResultSetPaging, SearchRequest } from '@alfresco/js-api';
export class SearchPageApi {
export class SearchApi {
private readonly apiService: ApiClientFactory;
constructor() {
this.apiService = new ApiClientFactory();
}
static async initialize(userName: string, password?: string): Promise<SearchPageApi> {
const classObj = new SearchPageApi();
static async initialize(userName: string, password?: string): Promise<SearchApi> {
const classObj = new SearchApi();
await classObj.apiService.setUpAcaBackend(userName, password);
return classObj;
}
@@ -76,4 +76,46 @@ export class SearchPageApi {
return await Utils.retryCall(searchFiles);
} catch {}
}
async waitForFolderPathIndexing(folderId: string, options: { nodesExpected: number }, maxRetries?: number): Promise<number> {
try {
const query: SearchRequest = {
query: {
query: `ANCESTOR:'workspace://SpacesStore/${folderId}' and TYPE:content`,
language: 'afts'
}
};
const retryLimit = maxRetries ?? 100;
let retryCount = 0;
let result: ResultSetPaging;
do {
result = await this.apiService.search.search(query);
const currentCount = result.list.pagination.count;
if (currentCount !== options.nodesExpected) {
retryCount++;
if (retryCount % 30 === 0) {
console.info(
`waitForFolderPathIndexing: After ${retryCount} seconds, expected ${options.nodesExpected} nodes but found ${currentCount} in folder ${folderId}`
);
}
if (retryCount >= retryLimit) {
throw new Error(`Expected ${options.nodesExpected} nodes but found ${currentCount} after ${retryLimit} retries`);
}
await Utils.delayInSeconds(1);
}
} while (result.list.pagination.count !== options.nodesExpected);
console.info(`waitForFolderPathIndexing: Found expected ${options.nodesExpected} nodes in folder ${folderId}`);
return result.list.pagination.count;
} catch (error) {
console.error(`waitForFolderPathIndexing failed for folderId "${folderId}": ${error}`);
throw error;
}
}
}
@@ -47,7 +47,8 @@ export const getReportPortalConfig = () => {
includeTestSteps: true,
skipPassed: true,
restClientConfig: {
timeout: timeouts.extendedTest
timeout: timeouts.sixtySeconds,
retry: 0
},
attributes,
description: `[Run ${env.GITHUB_RUN_ID}](${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}) - ${browser} - Failures only`
@@ -55,6 +55,7 @@ export class DataTableComponent extends BaseComponent {
searchFileName = '.search-file-name';
searchFileDescription = '[data-automation-id="search-results-entry-description"]';
searchFileContent = '.aca-result-content';
noPermissionsView = this.page.locator('aca-generic-error');
/** Locator for row (or rows) */
getRowLocator = this.page.getByRole('rowgroup').nth(1).locator('adf-datatable-row');
@@ -28,9 +28,30 @@ import { BaseComponent } from '../base.component';
export class ManageVersionsDialog extends BaseComponent {
private static readonly rootElement = '.adf-new-version-uploader-dialog';
async viewFileVersion(version: string): Promise<void> {
const versionActionsButton = this.getChild(`[id="adf-version-list-action-menu-button-${version}"]`);
await versionActionsButton.click();
async clickListActionButtonForVersion(version: string): Promise<void> {
await this.getChild(`[id="adf-version-list-action-menu-button-${version}"]`).click();
}
async isVersionPresent(version: string): Promise<boolean> {
return this.getChild(`[id="adf-version-list-item-version-${version}"]`).isVisible();
}
async isDescriptionPresent(version: string): Promise<boolean> {
return this.getChild(`[id="adf-version-list-item-comment-${version}"]`).isVisible();
}
async waitForProgressBarToDisappear(attachedTimeout = 5000): Promise<void> {
const loadingBar = this.getChild('[data-automation-id="version-history-loading-bar"]');
try {
await loadingBar.waitFor({ state: 'attached', timeout: attachedTimeout });
} catch {
return;
}
await loadingBar.waitFor({ state: 'detached' });
}
async waitForDialog(): Promise<void> {
await this.page.locator('[data-automation-id="new-version-uploader-dialog-title"]').waitFor();
}
constructor(page: Page) {
@@ -32,7 +32,7 @@ export class ViewerComponent extends BaseComponent {
public viewerLocator = this.getChild('adf-viewer-render');
public closeButtonLocator = this.getChild('.adf-viewer-close-button');
public fileTitleButtonLocator = this.getChild('.adf-viewer__file-title');
public fileTitleButtonLocator = this.getChild('#adf-viewer-display-name');
public pdfViewerContentPages = this.getChild('.adf-pdf-viewer__content .page');
public shareButton = this.getChild('button[id="share-action-button"]');
public downloadButton = this.getChild('button[id="app.viewer.download"]');
@@ -50,6 +50,9 @@ export class ViewerComponent extends BaseComponent {
public zoomScale = this.getChild('[data-automation-id="adf-page-scale"]');
public zoomResetButton = this.getChild('#viewer-reset-button');
public fitToPageButton = this.getChild('#viewer-scale-page-button');
public nextFileButton = this.getChild('[data-automation-id="adf-toolbar-next-file"]');
public previousFileButton = this.getChild('[data-automation-id="adf-toolbar-pref-file"]');
public noPermissionsView = this.getChild('aca-generic-error');
toolbar = new AcaHeader(this.page);
@@ -67,10 +70,8 @@ export class ViewerComponent extends BaseComponent {
return this.viewerLocator.isVisible();
}
async waitForViewerToOpen(waitForViewerContent?: 'wait for viewer content'): Promise<void> {
if (waitForViewerContent) {
await this.waitForViewerLoaderToFinish();
}
async waitForViewerToOpen(): Promise<void> {
await this.waitForViewerLoaderToFinish();
await this.viewerLocator.waitFor({ state: 'visible', timeout: timeouts.large });
}
@@ -194,4 +194,8 @@ export class Utils {
) {
await contentPage.page.waitForResponse((response) => response.url().includes(urlSubstring) && response.status() === statusCode);
}
static async delayInSeconds(seconds: number): Promise<void> {
await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}
}