From a2631db0e25c3828e0edf569e8c57ae296e4541d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=9Awiderski?= Date: Wed, 22 Apr 2026 11:26:39 +0200 Subject: [PATCH] [ACS-11612] helium ACA e2es updates (#5159) * [ACS-11612] helium ACA e2es updates * [ACS-11612] helium testing week small tests fixes * [ACS-11612] copilot review 1 * [ACS-11612] sonar fix 2 * [ACS-11612] copilot review fix 2 * [ACS-11612] shared links api small fixes * [ACS-11612] sonar cloud fix 3 * [ACS-11612] fixed returns for promise methods * [ACS-11612] eslint fix and added override-ci skip in yml --- .github/workflows/pull-request.yml | 5 + .../pagination/src/tests/favorites.ts | 100 ----------- .../src/tests/multiple-pages-files.e2e.ts | 159 ++++++++++++++++-- .../pagination/src/tests/personal-files.ts | 101 ----------- .../src/api/api-client-factory.ts | 43 +++-- .../src/api/categories-api.ts | 13 +- .../src/api/favorites-api.ts | 4 +- .../src/api/file-actions.ts | 16 +- .../src/api/nodes-api.ts | 103 ++++++++---- .../src/api/queries-api.ts | 7 +- .../src/api/search-api.ts | 20 ++- .../src/api/shared-links-api.ts | 70 ++++---- .../src/api/sites-api.ts | 39 +++-- .../aca-playwright-shared/src/api/tags-api.ts | 34 +++- .../src/api/trashcan-api.ts | 3 +- 15 files changed, 365 insertions(+), 352 deletions(-) delete mode 100644 e2e/playwright/pagination/src/tests/favorites.ts delete mode 100644 e2e/playwright/pagination/src/tests/personal-files.ts diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index a054402fe..3c3c99312 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -109,6 +109,7 @@ jobs: run: npm run ci:test -- $TEST_OPTS e2es-playwright: + if: ${{ !contains(github.event.pull_request.labels.*.name, 'override-ci') }} needs: [lint, build, unit-tests] name: E2E | ${{ matrix.browser || 'chromium' }} | ${{ matrix.e2e-suites.name }} | Playwright runs-on: ubuntu-24.04 @@ -256,6 +257,10 @@ jobs: }} run: exit 1 + - name: Check e2e skipped + if: ${{ contains(github.event.pull_request.labels.*.name, 'override-ci') }} + run: echo "E2E tests were skipped due to override-ci label" + - name: Checkout uses: actions/checkout@v6 with: diff --git a/e2e/playwright/pagination/src/tests/favorites.ts b/e2e/playwright/pagination/src/tests/favorites.ts deleted file mode 100644 index d4da84813..000000000 --- a/e2e/playwright/pagination/src/tests/favorites.ts +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * Alfresco Example Content Application - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * from Hyland Software. If not, see . - */ - -import { test } from '@alfresco/aca-playwright-shared'; -import { expect } from '@playwright/test'; - -export function favoritesTests(username: string) { - test.describe('Pagination controls : ', () => { - test.beforeEach(async ({ loginPage, favoritePage }) => { - await loginPage.navigate(); - await loginPage.loginUser({ username: username, password: username }); - - await favoritePage.navigate(); - await favoritePage.waitForPageLoad(); - }); - - test('[XAT-4575] Pagination control default items', async ({ favoritePage }) => { - expect(await favoritePage.pagination.getRange()).toContain('1-25 of 51'); - expect(await favoritePage.pagination.getMaxItems()).toContain('25'); - expect(await favoritePage.pagination.getCurrentPage()).toContain('Page 1'); - expect(await favoritePage.pagination.getTotalPages()).toContain('of 3'); - expect(await favoritePage.pagination.isPreviousEnabled()).toBe(false); - expect(await favoritePage.pagination.isNextEnabled()).toBe(true); - }); - - test('[XAT-4576] Items per page values', async ({ favoritePage }) => { - await favoritePage.pagination.openMaxItemsMenu(); - expect(await favoritePage.pagination.getItemsCount()).toBe(3); - await favoritePage.pagination.clickMenuItem('25'); - await favoritePage.dataTable.spinnerWaitForReload(); - expect(await favoritePage.pagination.getMaxItems()).toContain('25'); - expect(await favoritePage.pagination.getTotalPages()).toContain('of 3'); - - await favoritePage.pagination.openMaxItemsMenu(); - await favoritePage.pagination.clickMenuItem('50'); - await favoritePage.dataTable.spinnerWaitForReload(); - expect(await favoritePage.pagination.getMaxItems()).toContain('50'); - expect(await favoritePage.pagination.getTotalPages()).toContain('of 2'); - - await favoritePage.pagination.closeMenu(); - - await favoritePage.pagination.openMaxItemsMenu(); - await favoritePage.pagination.clickMenuItem('100'); - await favoritePage.dataTable.spinnerWaitForReload(); - expect(await favoritePage.pagination.getMaxItems()).toContain('100'); - expect(await favoritePage.pagination.getTotalPages()).toContain('of 1'); - - await favoritePage.pagination.resetToDefaultPageSize(); - }); - - test('[XAT-4578] Change the current page from the page selector', async ({ favoritePage }) => { - await favoritePage.pagination.clickOnNextPage(); - expect(await favoritePage.pagination.getRange()).toContain('Showing 26-50 of 51'); - expect(await favoritePage.pagination.getCurrentPage()).toContain('Page 2'); - expect(await favoritePage.pagination.isPreviousEnabled()).toBe(true); - expect(await favoritePage.pagination.isNextEnabled()).toBe(true); - await favoritePage.pagination.resetToDefaultPageSize(); - }); - - test('[XAT-4580] Next and Previous buttons navigation', async ({ favoritePage }) => { - await favoritePage.pagination.openMaxItemsMenu(); - await favoritePage.pagination.clickMenuItem('25'); - expect(await favoritePage.pagination.getMaxItems()).toContain('25'); - await favoritePage.pagination.clickOnNextPage(); - await favoritePage.dataTable.spinnerWaitForReload(); - expect(await favoritePage.pagination.getRange()).toContain('Showing 26-50 of 51'); - await favoritePage.pagination.clickOnPreviousPage(); - await favoritePage.dataTable.spinnerWaitForReload(); - expect(await favoritePage.pagination.getRange()).toContain('Showing 1-25 of 51'); - }); - - test('[XAT-4579] Next button is disabled on last page', async ({ favoritePage }) => { - await favoritePage.pagination.openMaxItemsMenu(); - await favoritePage.pagination.clickNthItem(3); - expect(await favoritePage.pagination.getCurrentPage()).toContain('Page 1'); - expect(await favoritePage.pagination.isNextEnabled()).toBe(false); - }); - }); -} diff --git a/e2e/playwright/pagination/src/tests/multiple-pages-files.e2e.ts b/e2e/playwright/pagination/src/tests/multiple-pages-files.e2e.ts index 35f9da4f2..21cc8a0bb 100755 --- a/e2e/playwright/pagination/src/tests/multiple-pages-files.e2e.ts +++ b/e2e/playwright/pagination/src/tests/multiple-pages-files.e2e.ts @@ -22,9 +22,79 @@ * from Hyland Software. If not, see . */ -import { ApiClientFactory, FavoritesPageApi, NodesApi, test, timeouts, Utils, TrashcanApi } from '@alfresco/aca-playwright-shared'; -import { personalFilesTests } from './personal-files'; -import { favoritesTests } from './favorites'; +import { + ApiClientFactory, + DataTableComponent, + FavoritesPageApi, + NodesApi, + PaginationComponent, + SearchApi, + test, + timeouts, + Utils, + TrashcanApi +} from '@alfresco/aca-playwright-shared'; +import { expect } from '@playwright/test'; + +async function assertDefaultPaginationState(pagination: PaginationComponent, range: string): Promise { + expect(await pagination.getRange()).toContain(range); + expect(await pagination.getMaxItems()).toContain('25'); + expect(await pagination.getCurrentPage()).toContain('Page 1'); + expect(await pagination.getTotalPages()).toContain('of 3'); + expect(await pagination.isPreviousEnabled()).toBe(false); + expect(await pagination.isNextEnabled()).toBe(true); +} + +async function assertItemsPerPage(pagination: PaginationComponent, dataTable: DataTableComponent): Promise { + await pagination.openMaxItemsMenu(); + expect(await pagination.getItemsCount()).toBe(3); + await pagination.clickMenuItem('25'); + await dataTable.spinnerWaitForReload(); + expect(await pagination.getMaxItems()).toContain('25'); + expect(await pagination.getTotalPages()).toContain('of 3'); + + await pagination.openMaxItemsMenu(); + await pagination.clickMenuItem('50'); + await dataTable.spinnerWaitForReload(); + expect(await pagination.getMaxItems()).toContain('50'); + expect(await pagination.getTotalPages()).toContain('of 2'); + + await pagination.openMaxItemsMenu(); + await pagination.clickMenuItem('100'); + await dataTable.spinnerWaitForReload(); + expect(await pagination.getMaxItems()).toContain('100'); + expect(await pagination.getTotalPages()).toContain('of 1'); + + await pagination.resetToDefaultPageSize(); +} + +async function assertNextPageNavigation(pagination: PaginationComponent): Promise { + await pagination.clickOnNextPage(); + expect(await pagination.getRange()).toContain('Showing 26-50 of 51'); + expect(await pagination.getCurrentPage()).toContain('Page 2'); + expect(await pagination.isPreviousEnabled()).toBe(true); + expect(await pagination.isNextEnabled()).toBe(true); + await pagination.resetToDefaultPageSize(); +} + +async function assertNextPreviousNavigation(pagination: PaginationComponent, dataTable: DataTableComponent): Promise { + await pagination.openMaxItemsMenu(); + await pagination.clickMenuItem('25'); + expect(await pagination.getMaxItems()).toContain('25'); + await pagination.clickOnNextPage(); + await dataTable.spinnerWaitForReload(); + expect(await pagination.getRange()).toContain('Showing 26-50 of 51'); + await pagination.clickOnPreviousPage(); + await dataTable.spinnerWaitForReload(); + expect(await pagination.getRange()).toContain('Showing 1-25 of 51'); +} + +async function assertNextButtonDisabledOnLastPage(pagination: PaginationComponent): Promise { + await pagination.openMaxItemsMenu(); + await pagination.clickNthItem(3); + expect(await pagination.getCurrentPage()).toContain('Page 1'); + expect(await pagination.isNextEnabled()).toBe(false); +} test.describe('Pagination on multiple pages : ', () => { const random = Utils.random(); @@ -32,9 +102,11 @@ test.describe('Pagination on multiple pages : ', () => { let nodesApi: NodesApi; let trashcanApi: TrashcanApi; let favoritesApi: FavoritesPageApi; + let searchApi: SearchApi; const parent = `parent-multi-${random}`; - let initialFavoritesTotalItems: number; + let parentId: string; + let fileIds: string[]; const apiClientFactory = new ApiClientFactory(); @@ -43,17 +115,18 @@ test.describe('Pagination on multiple pages : ', () => { await apiClientFactory.setUpAcaBackend('admin'); await apiClientFactory.createUser({ username }); nodesApi = await NodesApi.initialize(username, username); + trashcanApi = await TrashcanApi.initialize(username, username); favoritesApi = await FavoritesPageApi.initialize(username, username); + searchApi = await SearchApi.initialize(username, username); const files = Array(51) .fill('my-file') .map((name, index): string => `${name}-${index + 1}-${random}.txt`); - await nodesApi.createFolder(parent); - const filesIds = (await nodesApi.createFiles(files, parent)).list.entries.map((entries) => entries.entry.id); - initialFavoritesTotalItems = await favoritesApi.getFavoritesTotalItems(username); + parentId = (await nodesApi.createFolder(parent)).entry.id; + fileIds = (await nodesApi.createFiles(files, parent)).list?.entries?.map((entries) => entries.entry.id) ?? []; - await favoritesApi.addFavoritesByIds('file', filesIds); + expect(fileIds).toHaveLength(51); }); test.afterAll(async () => { @@ -61,14 +134,80 @@ test.describe('Pagination on multiple pages : ', () => { }); test.describe('on Personal Files', () => { - personalFilesTests(username, parent); + test.beforeAll(async () => { + await searchApi.waitForFolderPathIndexing(parentId, { nodesExpected: 51 }); + }); + + test.describe('Pagination controls : ', () => { + test.beforeEach(async ({ loginPage, personalFiles, page }) => { + await loginPage.navigate(); + await loginPage.loginUser({ username: username, password: username }); + await personalFiles.waitForPageLoad(); + await personalFiles.dataTable.getRowByName(parent).dblclick(); + await page.waitForTimeout(timeouts.tiny); + }); + + test('[XAT-4530] Pagination control default items', async ({ personalFiles }) => { + await assertDefaultPaginationState(personalFiles.pagination, 'Showing 1-25 of 51'); + }); + + test('[XAT-4531] Items per page values', async ({ personalFiles }) => { + await assertItemsPerPage(personalFiles.pagination, personalFiles.dataTable); + }); + + test('[XAT-4533] Change the current page from the page selector', async ({ personalFiles }) => { + await assertNextPageNavigation(personalFiles.pagination); + }); + + test('[XAT-4536] Next and Previous buttons navigation', async ({ personalFiles }) => { + await assertNextPreviousNavigation(personalFiles.pagination, personalFiles.dataTable); + }); + + test('[XAT-4534] Previous button is disabled on first page', async ({ personalFiles }) => { + expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 1'); + expect(await personalFiles.pagination.isPreviousEnabled()).toBe(false); + }); + + test('[XAT-4535] Next button is disabled on last page', async ({ personalFiles }) => { + await assertNextButtonDisabledOnLastPage(personalFiles.pagination); + }); + }); }); test.describe('on Favorites', () => { test.beforeAll(async () => { + const initialFavoritesTotalItems = await favoritesApi.getFavoritesTotalItems(username); + await favoritesApi.addFavoritesByIds('file', fileIds); await favoritesApi.waitForApi(username, { expect: initialFavoritesTotalItems + 51 }); }); - favoritesTests(username); + test.describe('Pagination controls : ', () => { + test.beforeEach(async ({ loginPage, favoritePage }) => { + await loginPage.navigate(); + await loginPage.loginUser({ username: username, password: username }); + await favoritePage.navigate(); + await favoritePage.waitForPageLoad(); + }); + + test('[XAT-4575] Pagination control default items', async ({ favoritePage }) => { + await assertDefaultPaginationState(favoritePage.pagination, '1-25 of 51'); + }); + + test('[XAT-4576] Items per page values', async ({ favoritePage }) => { + await assertItemsPerPage(favoritePage.pagination, favoritePage.dataTable); + }); + + test('[XAT-4578] Change the current page from the page selector', async ({ favoritePage }) => { + await assertNextPageNavigation(favoritePage.pagination); + }); + + test('[XAT-4580] Next and Previous buttons navigation', async ({ favoritePage }) => { + await assertNextPreviousNavigation(favoritePage.pagination, favoritePage.dataTable); + }); + + test('[XAT-4579] Next button is disabled on last page', async ({ favoritePage }) => { + await assertNextButtonDisabledOnLastPage(favoritePage.pagination); + }); + }); }); }); diff --git a/e2e/playwright/pagination/src/tests/personal-files.ts b/e2e/playwright/pagination/src/tests/personal-files.ts deleted file mode 100644 index e572b3c57..000000000 --- a/e2e/playwright/pagination/src/tests/personal-files.ts +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * Alfresco Example Content Application - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * from Hyland Software. If not, see . - */ - -import { test, timeouts } from '@alfresco/aca-playwright-shared'; -import { expect } from '@playwright/test'; - -export function personalFilesTests(userName: string, parentName: string) { - test.describe('Pagination controls : ', () => { - test.beforeEach(async ({ loginPage, personalFiles, page }) => { - await loginPage.navigate(); - await loginPage.loginUser({ username: userName, password: userName }); - await personalFiles.waitForPageLoad(); - await personalFiles.dataTable.getRowByName(parentName).dblclick(); - await page.waitForTimeout(timeouts.tiny); - }); - - test('[XAT-4530] Pagination control default items', async ({ personalFiles }) => { - expect(await personalFiles.pagination.getRange()).toContain('Showing 1-25 of 51'); - expect(await personalFiles.pagination.getMaxItems()).toContain('25'); - expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 1'); - expect(await personalFiles.pagination.getTotalPages()).toContain('of 3'); - expect(await personalFiles.pagination.isPreviousEnabled()).toBe(false); - expect(await personalFiles.pagination.isNextEnabled()).toBe(true); - }); - - test('[XAT-4531] Items per page values', async ({ personalFiles }) => { - await personalFiles.pagination.openMaxItemsMenu(); - expect(await personalFiles.pagination.getItemsCount()).toBe(3); - await personalFiles.pagination.clickMenuItem('25'); - await personalFiles.dataTable.spinnerWaitForReload(); - expect(await personalFiles.pagination.getMaxItems()).toContain('25'); - expect(await personalFiles.pagination.getTotalPages()).toContain('of 3'); - - await personalFiles.pagination.openMaxItemsMenu(); - await personalFiles.pagination.clickMenuItem('50'); - expect(await personalFiles.pagination.getMaxItems()).toContain('50'); - expect(await personalFiles.pagination.getTotalPages()).toContain('of 2'); - - await personalFiles.pagination.openMaxItemsMenu(); - await personalFiles.pagination.clickMenuItem('100'); - expect(await personalFiles.pagination.getMaxItems()).toContain('100'); - expect(await personalFiles.pagination.getTotalPages()).toContain('of 1'); - - await personalFiles.pagination.resetToDefaultPageSize(); - }); - - test('[XAT-4533] Change the current page from the page selector', async ({ personalFiles }) => { - await personalFiles.pagination.clickOnNextPage(); - expect(await personalFiles.pagination.getRange()).toContain('Showing 26-50 of 51'); - expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 2'); - expect(await personalFiles.pagination.isPreviousEnabled()).toBe(true); - expect(await personalFiles.pagination.isNextEnabled()).toBe(true); - await personalFiles.pagination.resetToDefaultPageSize(); - }); - - test('[XAT-4536] Next and Previous buttons navigation', async ({ personalFiles }) => { - await personalFiles.pagination.openMaxItemsMenu(); - await personalFiles.pagination.clickMenuItem('25'); - expect(await personalFiles.pagination.getMaxItems()).toContain('25'); - await personalFiles.pagination.clickOnNextPage(); - await personalFiles.dataTable.spinnerWaitForReload(); - expect(await personalFiles.pagination.getRange()).toContain('Showing 26-50 of 51'); - await personalFiles.pagination.clickOnPreviousPage(); - await personalFiles.dataTable.spinnerWaitForReload(); - expect(await personalFiles.pagination.getRange()).toContain('Showing 1-25 of 51'); - }); - - test('[XAT-4534] Previous button is disabled on first page', async ({ personalFiles }) => { - expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 1'); - expect(await personalFiles.pagination.isPreviousEnabled()).toBe(false); - }); - - test('[XAT-4535] Next button is disabled on last page', async ({ personalFiles }) => { - await personalFiles.pagination.openMaxItemsMenu(); - await personalFiles.pagination.clickNthItem(3); - expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 1'); - expect(await personalFiles.pagination.isNextEnabled()).toBe(false); - }); - }); -} diff --git a/projects/aca-playwright-shared/src/api/api-client-factory.ts b/projects/aca-playwright-shared/src/api/api-client-factory.ts index e5bb1d8a7..19a0c7db4 100644 --- a/projects/aca-playwright-shared/src/api/api-client-factory.ts +++ b/projects/aca-playwright-shared/src/api/api-client-factory.ts @@ -45,6 +45,7 @@ import { TagsApi } from '@alfresco/js-api'; import { users } from '../base-config'; +import { logger } from '../utils'; import { Person, PersonModel } from './people-api-models'; export interface AcaBackend { @@ -89,13 +90,9 @@ export class ApiClientFactory { public queriesApi: QueriesApi; public categoriesApi: CategoriesApi; public tagsApi: TagsApi; + constructor() { this.alfrescoApi = new AlfrescoApi(config); - } - - public async setUpAcaBackend(userName: string, password?: string): Promise { - await this.login(userName, password); - this.sites = new SitesApi(this.alfrescoApi); this.upload = new UploadApi(this.alfrescoApi); this.nodes = new NodesApi(this.alfrescoApi); @@ -107,6 +104,7 @@ export class ApiClientFactory { this.search = new SearchApi(this.alfrescoApi); this.securityGroupsApi = new SecurityGroupsApi(this.alfrescoApi); this.securityMarksApi = new SecurityMarksApi(this.alfrescoApi); + this.contentClient = new ContentClient(config, '/alfresco'); this.share = new SharedlinksApi(this.alfrescoApi); this.favorites = new FavoritesApi(this.alfrescoApi); this.trashCan = new TrashcanApi(this.alfrescoApi); @@ -114,7 +112,10 @@ export class ApiClientFactory { this.queriesApi = new QueriesApi(this.alfrescoApi); this.categoriesApi = new CategoriesApi(this.alfrescoApi); this.tagsApi = new TagsApi(this.alfrescoApi); + } + public async setUpAcaBackend(userName: string, password?: string): Promise { + await this.login(userName, password); return this; } @@ -124,49 +125,55 @@ export class ApiClientFactory { } async login(userName: string, password?: string) { - const predefinedUserKey = Object.keys(users).find((user) => user === userName || users[user].username === userName); + const predefinedUserKey = Object.keys(users).find( + (userAlias) => userAlias === userName || users[userAlias as keyof typeof users].username === userName + ) as keyof typeof users | undefined; const userToLog = predefinedUserKey ? users[predefinedUserKey] : undefined; - let e: any; const user = userToLog?.username ?? userName; const userPassword = userToLog?.password ?? password; + if (!userPassword) { + throw new Error(`[API Client Factory] No password provided for user ${user}`); + } try { - e = await this.alfrescoApi.login(user, userPassword); + await this.alfrescoApi.login(user, userPassword); } catch (error) { - console.error(`[API Client Factory] Log in user ${user} failed ${e}`); + logger.error(`[API Client Factory] Log in user ${user} failed ${error}`); throw error; } } async loginUser(user: PersonModel) { - let e: any; + if (!user.username || !user.password) { + throw new Error(`[API Client Factory] No username or password provided`); + } try { - e = await this.alfrescoApi.login(user.username, user.password); + await this.alfrescoApi.login(user.username, user.password); } catch (error) { - console.error(`[API Client Factory] Log in user ${user.username} failed ${e}`); + logger.error(`[API Client Factory] Log in user ${user.username} failed ${error}`); throw error; } } - async createUser(user: PersonModel): Promise { + async createUser(user: PersonModel): Promise { const person = new Person(user); const peopleApi = new PeopleApi(this.alfrescoApi); try { - return peopleApi.createPerson(person); + return await peopleApi.createPerson(person); } catch (error) { - console.error('[API Client Factory] createUser failed : ', error); + logger.error(`[API Client Factory] createUser failed: ${error}`); return null; } } - async changePassword(username: string, newPassword: string): Promise { + async changePassword(username: string, newPassword: string): Promise { const peopleApi = new PeopleApi(this.alfrescoApi); try { - return peopleApi.updatePerson(username, { password: newPassword }); + return await peopleApi.updatePerson(username, { password: newPassword }); } catch (error) { - console.error('[API Client Factory] changePassword failed : ', error); + logger.error(`[API Client Factory] changePassword failed: ${error}`); return null; } } diff --git a/projects/aca-playwright-shared/src/api/categories-api.ts b/projects/aca-playwright-shared/src/api/categories-api.ts index 12a72996f..c96ed53cb 100644 --- a/projects/aca-playwright-shared/src/api/categories-api.ts +++ b/projects/aca-playwright-shared/src/api/categories-api.ts @@ -23,6 +23,7 @@ */ import { ApiClientFactory } from './api-client-factory'; +import { logger } from '../utils'; import { CategoryEntry, CategoryBody, CategoryQuery, CategoryPaging, CategoryLinkBody } from '@alfresco/js-api'; export class CategoriesApi { @@ -42,21 +43,21 @@ export class CategoriesApi { try { return this.apiService.categoriesApi.createSubcategories(categoryId, categoryBodyCreate, opts); } catch (error) { - console.error(error); + logger.error(`${error}`); return null; } } - async deleteCategory(categoryId: string): Promise { - if (categoryId === null) { - console.error('categoryId is null, skipping deletion'); + async deleteCategory(categoryId?: string): Promise { + if (!categoryId) { + logger.error('categoryId is null, skipping deletion'); return; } try { await this.apiService.categoriesApi.deleteCategory(categoryId); } catch (error) { - console.error(`${this.constructor.name} ${this.deleteCategory.name}: ${error}`); + logger.error(`${this.constructor.name} ${this.deleteCategory.name}: ${error}`); } } @@ -68,7 +69,7 @@ export class CategoriesApi { try { return this.apiService.categoriesApi.linkNodeToCategory(nodeId, categoryLinkBodyCreate, opts); } catch (error) { - console.error(`${this.constructor.name} ${this.linkNodeToCategory.name}: ${error}`); + logger.error(`${this.constructor.name} ${this.linkNodeToCategory.name}: ${error}`); return null; } } diff --git a/projects/aca-playwright-shared/src/api/favorites-api.ts b/projects/aca-playwright-shared/src/api/favorites-api.ts index c15f8fea3..4753405f6 100755 --- a/projects/aca-playwright-shared/src/api/favorites-api.ts +++ b/projects/aca-playwright-shared/src/api/favorites-api.ts @@ -24,7 +24,7 @@ import { ApiClientFactory } from './api-client-factory'; import { FavoriteEntry, FavoritePaging } from '@alfresco/js-api'; -import { Utils } from '../utils'; +import { logger, Utils } from '../utils'; export class FavoritesPageApi { private readonly apiService: ApiClientFactory; @@ -124,7 +124,7 @@ export class FavoritesPageApi { } } } catch (error) { - console.error('FavoritesApi: removeFavoritesByIds failed ', error); + logger.error(`FavoritesApi: removeFavoritesByIds failed: ${error}`); } } } diff --git a/projects/aca-playwright-shared/src/api/file-actions.ts b/projects/aca-playwright-shared/src/api/file-actions.ts index 9c44a9a54..4bc8f6ed8 100644 --- a/projects/aca-playwright-shared/src/api/file-actions.ts +++ b/projects/aca-playwright-shared/src/api/file-actions.ts @@ -24,7 +24,7 @@ import * as fs from 'fs'; import { ApiClientFactory } from './api-client-factory'; -import { Utils, waitForApi } from '../utils'; +import { logger, Utils, waitForApi } from '../utils'; import { NodeBodyCreate, NodeEntry, ResultSetPaging, SearchRequest } from '@alfresco/js-api'; export class FileActionsApi { @@ -161,7 +161,9 @@ export class FileActionsApi { await waitForApi(apiCall, predicate, 30, 2500); } catch { const actual = await apiCall(); - throw new Error(`waitForNodes: Timed out waiting for "${searchTerm}" — expected ${data.expect} nodes, found ${actual}`); + const message = `waitForNodes: Timed out waiting for "${searchTerm}" — expected ${data.expect} nodes, found ${actual}`; + logger.error(message); + throw new Error(message); } } @@ -208,16 +210,16 @@ export class FileActionsApi { try { return (await this.queryNodesSearchHighlight(searchTerm)).list.pagination.totalItems; } catch (error) { - console.warn(`queryNodesSearchHighlight failed for "${searchTerm}":`, error); + logger.warn(`queryNodesSearchHighlight failed for "${searchTerm}": ${error}`); return 0; } }; try { await waitForApi(apiCall, predicate, 30, 2500); - console.log(`waitForNodesSearchHighlight: Found ${data.expect} nodes with search term "${searchTerm}"`); + logger.log(`waitForNodesSearchHighlight: Found ${data.expect} nodes with search term "${searchTerm}"`); } catch (error) { - console.error(`Error: ${error}`); + logger.error(`Error: ${error}`); } } @@ -228,9 +230,9 @@ export class FileActionsApi { comment: comment, name: newName }; - return this.apiService.nodes.updateNodeContent(nodeId, content, opts); + return await this.apiService.nodes.updateNodeContent(nodeId, content, opts); } catch (error) { - console.error(`${this.constructor.name} ${this.updateNodeContent.name}`, error); + logger.error(`${this.constructor.name} ${this.updateNodeContent.name}: ${error}`); return Promise.reject(error); } } diff --git a/projects/aca-playwright-shared/src/api/nodes-api.ts b/projects/aca-playwright-shared/src/api/nodes-api.ts index 7fd806535..6cb9e63e9 100755 --- a/projects/aca-playwright-shared/src/api/nodes-api.ts +++ b/projects/aca-playwright-shared/src/api/nodes-api.ts @@ -25,7 +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'; +import { logger, Utils } from '../utils'; export class NodesApi { private readonly apiService: ApiClientFactory; @@ -51,7 +51,9 @@ export class NodesApi { try { return await this.createNode('cm:folder', name, parentId, title, description, null, author, true, aspectNames); } catch (error) { - throw new Error(`${this.constructor.name} ${this.createFolder.name}: ${error}`); + const message = `${this.constructor.name} ${this.createFolder.name}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -67,7 +69,9 @@ export class NodesApi { try { return await this.createNode('cm:content', name, parentId, title, description, null, author, majorVersion, aspectNames); } catch (error) { - throw new Error(`${this.constructor.name} ${this.createFile.name}: ${error}`); + const message = `${this.constructor.name} ${this.createFile.name}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -75,7 +79,9 @@ export class NodesApi { try { return await this.createContent({ files: names }, relativePath); } catch (error) { - throw new Error(`${this.constructor.name} ${this.createFiles.name}: ${error}`); + const message = `${this.constructor.name} ${this.createFiles.name}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -87,6 +93,9 @@ export class NodesApi { createdFiles.push(file); } } + logger.info( + `${this.constructor.name} ${this.createMultipleFiles.name}: created ${createdFiles.length} of ${count} files in parent "${parentId}"` + ); return createdFiles; } @@ -94,7 +103,9 @@ export class NodesApi { try { return await this.createContent({ folders: names }, relativePath); } catch (error) { - throw new Error(`${this.constructor.name} ${this.createFolders.name}: ${error}`); + const message = `${this.constructor.name} ${this.createFolders.name}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -102,7 +113,7 @@ export class NodesApi { try { await this.apiService.trashCan.deleteDeletedNode(name); } catch (error) { - console.error(`${this.constructor.name} ${this.deleteDeletedNode.name}: ${error}`); + logger.error(`${this.constructor.name} ${this.deleteDeletedNode.name}: ${error}`); } } @@ -133,11 +144,13 @@ export class NodesApi { } try { - return this.apiService.nodes.createNode(parentId, nodeBody, { + return await this.apiService.nodes.createNode(parentId, nodeBody, { majorVersion }); } catch (error) { - throw new Error(`${this.constructor.name} ${this.createNode.name}: ${error}`); + const message = `${this.constructor.name} ${this.createNode.name}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -145,7 +158,7 @@ export class NodesApi { try { return this.apiService.nodes.updateNode(nodeId, { name: newName }); } catch (error) { - console.error(`${this.constructor.name} ${this.renameNode.name}`, error); + logger.error(`${this.constructor.name} ${this.renameNode.name}: ${error}`); return null; } } @@ -159,7 +172,7 @@ export class NodesApi { try { await this.apiService.nodes.deleteNodes(nodeIds, { permanent }); } catch (error) { - console.error(`${this.constructor.name} ${this.deleteNodes.name}`, error); + logger.error(`${this.constructor.name} ${this.deleteNodes.name}: ${error}`); } } @@ -167,7 +180,7 @@ export class NodesApi { try { return await this.apiService.nodes.updateNode(nodeId, nodeBodyUpdate, opts); } catch (error) { - console.error(`${this.constructor.name} ${this.updateNode.name}`, error); + logger.error(`${this.constructor.name} ${this.updateNode.name}: ${error}`); return null; } } @@ -182,7 +195,7 @@ export class NodesApi { const userNodesIds = userNodes.map((nodeChild) => nodeChild.entry.id); await this.deleteNodes(userNodesIds); } catch (error) { - console.error(`${this.constructor.name} ${this.deleteCurrentUserNodes.name}`, error); + logger.error(`${this.constructor.name} ${this.deleteCurrentUserNodes.name}: ${error}`); } } @@ -192,7 +205,7 @@ export class NodesApi { await this.apiService.nodes.lockNode(nodeId, { type: lockType }); } } catch (error) { - console.error(`${this.constructor.name} ${this.lockNodes.name}`, error); + logger.error(`${this.constructor.name} ${this.lockNodes.name}: ${error}`); } } @@ -202,7 +215,7 @@ export class NodesApi { await this.apiService.nodes.unlockNode(nodeId); } } catch (error) { - console.error(`${this.constructor.name} ${this.unlockNodes.name}`, error); + logger.error(`${this.constructor.name} ${this.unlockNodes.name}: ${error}`); } } @@ -210,7 +223,9 @@ export class NodesApi { try { return this.apiService.nodes.createNode('-my-', flattenNodeContentTree(content, relativePath) as any); } catch (error) { - throw new Error(`${this.constructor.name} ${this.createContent.name}: ${error}`); + const message = `${this.constructor.name} ${this.createContent.name}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -218,7 +233,9 @@ export class NodesApi { try { return this.apiService.nodes.getNode(id); } catch (error) { - throw new Error(`${this.constructor.name} ${this.getNodeById.name}: ${error}`); + const message = `${this.constructor.name} ${this.getNodeById.name}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -227,7 +244,7 @@ export class NodesApi { const children = (await this.getNodeChildren(parentId))?.list?.entries ?? []; return children.find((elem) => elem.entry.name === name)?.entry.id ?? ''; } catch (error) { - console.error(`${this.constructor.name} ${this.getNodeIdFromParent.name}`, error); + logger.error(`${this.constructor.name} ${this.getNodeIdFromParent.name}: ${error}`); return ''; } } @@ -239,7 +256,7 @@ export class NodesApi { }; return this.apiService.nodes.listNodeChildren(nodeId, opts); } catch (error) { - console.error(`${this.constructor.name} ${this.getNodeChildren.name}`, error); + logger.error(`${this.constructor.name} ${this.getNodeChildren.name}: ${error}`); return null; } } @@ -248,7 +265,7 @@ export class NodesApi { try { await this.apiService.nodes.deleteNode(id, { permanent }); } catch (error) { - console.error(`${this.constructor.name} ${this.deleteNodeById.name}`, error); + logger.error(`${this.constructor.name} ${this.deleteNodeById.name}: ${error}`); } } @@ -260,7 +277,7 @@ export class NodesApi { await this.deleteNodeById(nodeId); } } catch (error) { - console.error('Admin Actions - cleanupNodeTemplatesItems failed : ', error); + logger.error(`Admin Actions - cleanupNodeTemplatesItems failed: ${error}`); } } @@ -272,7 +289,7 @@ export class NodesApi { await this.deleteNodeById(nodeId); } } catch (error) { - console.error('Admin Actions - cleanupSpaceTemplatesFolder failed : ', error); + logger.error(`Admin Actions - cleanupSpaceTemplatesFolder failed: ${error}`); } } @@ -280,7 +297,7 @@ export class NodesApi { try { return this.getNodeIdFromParent('Node Templates', await this.getDataDictionaryId()); } catch (error) { - console.error('Admin Actions - getNodeTemplatesFolderId failed : ', error); + logger.error(`Admin Actions - getNodeTemplatesFolderId failed: ${error}`); return ''; } } @@ -289,14 +306,14 @@ export class NodesApi { try { return this.getNodeIdFromParent('Space Templates', await this.getDataDictionaryId()); } catch (error) { - console.error('Admin Actions - getSpaceTemplatesFolderId failed : ', error); + logger.error(`Admin Actions - getSpaceTemplatesFolderId failed: ${error}`); return ''; } } private async getDataDictionaryId(): Promise { return this.getNodeIdFromParent('Data Dictionary', '-root-').catch((error) => { - console.error('Admin Actions - getDataDictionaryId failed : ', error); + logger.error(`Admin Actions - getDataDictionaryId failed: ${error}`); return ''; }); } @@ -317,7 +334,7 @@ export class NodesApi { try { return this.apiService.nodes.updateNode(nodeId, data); } catch (error) { - console.error(`${this.constructor.name} ${this.setGranularPermission.name}`, error); + logger.error(`${this.constructor.name} ${this.setGranularPermission.name}: ${error}`); return null; } } @@ -329,7 +346,7 @@ export class NodesApi { return this.setInheritPermissions(nodeId, false); } catch (error) { - console.error('Admin Actions - removeUserAccessOnNodeTemplate failed : ', error); + logger.error(`Admin Actions - removeUserAccessOnNodeTemplate failed: ${error}`); return null; } } @@ -341,7 +358,7 @@ export class NodesApi { return this.setInheritPermissions(nodeId, false); } catch (error) { - console.error('Admin Actions - removeUserAccessOnSpaceTemplate failed : ', error); + logger.error(`Admin Actions - removeUserAccessOnSpaceTemplate failed: ${error}`); return null; } } @@ -356,7 +373,7 @@ export class NodesApi { try { return this.apiService.nodes.updateNode(nodeId, data); } catch (error) { - console.error(`${this.constructor.name} ${this.setInheritPermissions.name}`, error); + logger.error(`${this.constructor.name} ${this.setInheritPermissions.name}: ${error}`); return null; } } @@ -365,7 +382,7 @@ export class NodesApi { try { return this.apiService.nodes.updateNode(nodeId, { aspectNames }); } catch (error) { - console.error(`${this.constructor.name} ${this.addAspects.name}`, error); + logger.error(`${this.constructor.name} ${this.addAspects.name}: ${error}`); return null; } } @@ -385,7 +402,7 @@ export class NodesApi { await this.addAspects(originalNodeId, ['app:linked']); return link; } catch (error) { - console.error(`${this.constructor.name} ${this.createFileLink.name}`, error); + logger.error(`${this.constructor.name} ${this.createFileLink.name}: ${error}`); return null; } } @@ -408,7 +425,7 @@ export class NodesApi { await this.addAspects(originalNodeId, ['app:linked']); return link; } catch (error) { - console.error(`${this.constructor.name} ${this.createFolderLink.name}`, error); + logger.error(`${this.constructor.name} ${this.createFolderLink.name}: ${error}`); return null; } } @@ -421,7 +438,9 @@ export class NodesApi { return this.createFileLink(nodeId, destinationParentId); } catch (error) { - throw new Error(`Admin Actions - createLinkToFileName failed : ${error}`); + const message = `Admin Actions - createLinkToFileName failed : ${error}`; + logger.error(message); + throw new Error(message); } } @@ -432,7 +451,9 @@ export class NodesApi { const nodeId = await this.getNodeIdFromParent(originalFolderName, originalFolderParentId); return this.createFolderLink(nodeId, destinationParentId); } catch (error) { - throw new Error(`Admin Actions - createLinkToFolderName failed : ${error}`); + const message = `Admin Actions - createLinkToFolderName failed : ${error}`; + logger.error(message); + throw new Error(message); } } @@ -441,7 +462,9 @@ export class NodesApi { const node = await this.getNodeById(nodeId); return node.entry.properties?.[property] ?? ''; } catch (error) { - throw new Error(`${this.constructor.name} ${this.getNodeProperty.name}: ${error}`); + const message = `${this.constructor.name} ${this.getNodeProperty.name}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -450,7 +473,9 @@ export class NodesApi { const sharedId = await this.getNodeProperty(nodeId, 'qshare:sharedId'); return sharedId !== ''; } catch (error) { - throw new Error(`${this.constructor.name} ${this.isFileShared.name}: ${error}`); + const message = `${this.constructor.name} ${this.isFileShared.name}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -459,7 +484,9 @@ export class NodesApi { const lockType = await this.getNodeProperty(nodeId, 'cm:lockType'); return lockType || ''; } catch (error) { - throw new Error(`${this.constructor.name} ${this.getLockType.name}: ${error}`); + const message = `${this.constructor.name} ${this.getLockType.name}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -467,7 +494,9 @@ export class NodesApi { try { return (await this.getLockType(nodeId)) === 'WRITE_LOCK'; } catch (error) { - throw new Error(`${this.constructor.name} ${this.isFileLockedWrite.name}: ${error}`); + const message = `${this.constructor.name} ${this.isFileLockedWrite.name}: ${error}`; + logger.error(message); + throw new Error(message); } } } diff --git a/projects/aca-playwright-shared/src/api/queries-api.ts b/projects/aca-playwright-shared/src/api/queries-api.ts index b61f1c4e9..2f54778ae 100755 --- a/projects/aca-playwright-shared/src/api/queries-api.ts +++ b/projects/aca-playwright-shared/src/api/queries-api.ts @@ -23,7 +23,7 @@ */ import { FindQuery } from '@alfresco/js-api'; -import { Utils } from '../utils'; +import { logger, Utils } from '../utils'; import { ApiClientFactory } from './api-client-factory'; export class QueriesApi { @@ -52,8 +52,7 @@ export class QueriesApi { return await Utils.retryCall(sites); } catch (error) { - console.error(`QueriesApi waitForSites : catch : `); - console.error(`\tExpected: ${data.expect} items, but found ${error}`); + logger.error(`QueriesApi waitForSites : catch : Expected: ${data.expect} items, but found ${error}`); return null; } } @@ -68,7 +67,7 @@ export class QueriesApi { const sites = await this.apiService.queries.findSites(searchTerm, opts); return sites.list.pagination.totalItems; } catch (error) { - console.error(`QueriesApi findSitesTotalItems : catch :`, error); + logger.error(`QueriesApi findSitesTotalItems : catch : ${error}`); return null; } } diff --git a/projects/aca-playwright-shared/src/api/search-api.ts b/projects/aca-playwright-shared/src/api/search-api.ts index a80243183..662519d5f 100755 --- a/projects/aca-playwright-shared/src/api/search-api.ts +++ b/projects/aca-playwright-shared/src/api/search-api.ts @@ -23,7 +23,7 @@ */ import { ApiClientFactory } from './api-client-factory'; -import { Utils } from '../utils'; +import { logger, Utils } from '../utils'; import { ResultSetPaging, SearchRequest } from '@alfresco/js-api'; export class SearchApi { @@ -59,7 +59,7 @@ export class SearchApi { } async getTotalItems(username: string): Promise { - return (await this.querySearchFiles(username)).list.pagination.totalItems; + return (await this.querySearchFiles(username)).list?.pagination?.totalItems ?? 0; } async waitForApi(username: string, data: { expect: number }) { @@ -92,29 +92,31 @@ export class SearchApi { do { result = await this.apiService.search.search(query); - const currentCount = result.list.pagination.count; + const currentCount = result.list?.pagination?.count ?? 0; if (currentCount !== options.nodesExpected) { retryCount++; if (retryCount % 30 === 0) { - console.info( + logger.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`); + const message = `Expected ${options.nodesExpected} nodes but found ${currentCount} after ${retryLimit} retries`; + logger.error(message); + throw new Error(message); } await Utils.delayInSeconds(1); } - } while (result.list.pagination.count !== options.nodesExpected); + } while (result.list?.pagination?.count !== options.nodesExpected); - console.info(`waitForFolderPathIndexing: Found expected ${options.nodesExpected} nodes in folder ${folderId}`); - return result.list.pagination.count; + logger.info(`waitForFolderPathIndexing: Found expected ${options.nodesExpected} nodes in folder ${folderId}`); + return result.list?.pagination?.count ?? 0; } catch (error) { - console.error(`waitForFolderPathIndexing failed for folderId "${folderId}": ${error}`); + logger.error(`waitForFolderPathIndexing failed for folderId "${folderId}": ${error}`); throw error; } } diff --git a/projects/aca-playwright-shared/src/api/shared-links-api.ts b/projects/aca-playwright-shared/src/api/shared-links-api.ts index 8cea2ee22..e1641dde1 100755 --- a/projects/aca-playwright-shared/src/api/shared-links-api.ts +++ b/projects/aca-playwright-shared/src/api/shared-links-api.ts @@ -24,7 +24,7 @@ import { ApiClientFactory } from './api-client-factory'; import { SharedLinkEntry, SharedLinkPaging } from '@alfresco/js-api'; -import { Utils } from '../utils'; +import { logger, Utils } from '../utils'; export class SharedLinksApi { private readonly apiService: ApiClientFactory; @@ -44,7 +44,7 @@ export class SharedLinksApi { nodeId: id, expiresAt: expireDate }; - return this.apiService.share.createSharedLink(data); + return await this.apiService.share.createSharedLink(data); } catch (error) { return null; } @@ -56,11 +56,13 @@ export class SharedLinksApi { if (ids && ids.length > 0) { for (const id of ids) { const sharedLink = await this.shareFileById(id, expireDate); - sharedLinks.push(sharedLink); + if (sharedLink) { + sharedLinks.push(sharedLink); + } } } } catch (error) { - console.error(`SharedLinksApi shareFilesByIds : catch : `, error); + logger.error(`SharedLinksApi shareFilesByIds : catch : ${error}`); } return sharedLinks; } @@ -70,72 +72,68 @@ export class SharedLinksApi { const opts = { maxItems }; - return this.apiService.share.listSharedLinks(opts); + return await this.apiService.share.listSharedLinks(opts); } catch (error) { - console.error(`SharedLinksApi getSharedLinks : catch : `, error); + logger.error(`SharedLinksApi getSharedLinks : catch : ${error}`); return new SharedLinkPaging(); } } - async waitForFilesToBeShared(filesIds: string[]): Promise { + async waitForFilesToBeShared(fileIds: string[]): Promise { try { const sharedFile = async () => { - const sharedFiles = (await this.getSharedLinks()).list.entries.map((link) => link.entry.nodeId); - const foundItems = filesIds.every((id) => sharedFiles.includes(id)); - if (foundItems) { - return Promise.resolve(foundItems); - } else { - return Promise.reject(foundItems); + const sharedFiles = (await this.getSharedLinks()).list?.entries?.map((link) => link.entry.nodeId) ?? []; + const foundItems = fileIds.every((id) => sharedFiles.includes(id)); + if (!foundItems) { + const message = 'Not all files are shared yet'; + logger.error(message); + throw new Error(message); } }; - return await Utils.retryCall(sharedFile); + await Utils.retryCall(sharedFile); } catch (error) { - console.error(`SharedLinksApi waitForFilesToBeShared : catch : ${error}`); - console.error(`\tWait timeout reached waiting for files to be shared`); + logger.error(`SharedLinksApi waitForFilesToBeShared : catch : ${error} - Wait timeout reached waiting for files to be shared`); } } private async getSharedIdOfNode(fileId: string): Promise { - try { - const sharedLinksEntries = (await this.getSharedLinks())?.list.entries; - const found = sharedLinksEntries.find((sharedLink) => sharedLink.entry.nodeId === fileId); - return found?.entry.id; - } catch (error) { - console.error(`SharedLinksApi getSharedIdOfNode : catch : `, error); - return null; + const sharedLinksEntries = (await this.getSharedLinks())?.list?.entries ?? []; + const found = sharedLinksEntries.find((sharedLink) => sharedLink.entry.nodeId === fileId); + if (!found?.entry.id) { + const message = `SharedLinksApi getSharedIdOfNode: no shared link found for node ${fileId}`; + logger.error(message); + throw new Error(message); } + return found.entry.id; } async unshareFileById(fileId: string): Promise { try { const sharedId = await this.getSharedIdOfNode(fileId); - return this.apiService.share.deleteSharedLink(sharedId); + await this.apiService.share.deleteSharedLink(sharedId); } catch (error) { - console.error(`SharedLinksApi unshareFileById : catch : `, error); + logger.error(`SharedLinksApi unshareFileById : catch : ${error}`); } } - async waitForFilesToNotBeShared(filesIds: string[]): Promise { + async waitForFilesToNotBeShared(fileIds: string[]): Promise { try { const sharedFile = async () => { - const sharedFiles = (await this.getSharedLinks()).list.entries.map((link) => link.entry.nodeId); + const sharedFiles = (await this.getSharedLinks()).list?.entries?.map((link) => link.entry.nodeId) ?? []; - const foundItems = filesIds.some((id) => { - return sharedFiles.includes(id); - }); + const foundItems = fileIds.some((id) => sharedFiles.includes(id)); if (foundItems) { - return Promise.reject(foundItems); - } else { - return Promise.resolve(foundItems); + const message = 'Some files are still shared'; + logger.error(message); + throw new Error(message); } }; - return await Utils.retryCall(sharedFile); + await Utils.retryCall(sharedFile); } catch (error) { - console.error(`SharedLinksApi waitForFilesToNotBeShared : catch : ${error}`); - console.error(`\tWait timeout reached waiting for files to no longer be shared`); + logger.error(`SharedLinksApi waitForFilesToNotBeShared : catch : ${error} - Wait timeout reached waiting for files to no longer be shared`); } } } diff --git a/projects/aca-playwright-shared/src/api/sites-api.ts b/projects/aca-playwright-shared/src/api/sites-api.ts index b1946331d..269eaffc9 100755 --- a/projects/aca-playwright-shared/src/api/sites-api.ts +++ b/projects/aca-playwright-shared/src/api/sites-api.ts @@ -23,6 +23,7 @@ */ import { ApiClientFactory } from './api-client-factory'; +import { logger } from '../utils'; import { Site, SiteBodyCreate, @@ -55,9 +56,11 @@ export class SitesApi { } as SiteBodyCreate; try { - return this.apiService.sites.createSite(site); + return await this.apiService.sites.createSite(site); } catch (error) { - throw new Error(`SitesApi ${this.createSite.name}: ${error}`); + const message = `SitesApi ${this.createSite.name}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -65,11 +68,15 @@ export class SitesApi { try { const id = (await this.apiService.sites.listSiteContainers(siteId)).list?.entries?.[0]?.entry?.id; if (!id) { - throw new Error(`Document library not found for site ${siteId}`); + const message = `Document library not found for site ${siteId}`; + logger.error(message); + throw new Error(message); } return id; } catch (error) { - throw new Error(`Failed to get document library ID for site ${siteId}: ${error}`); + const message = `Failed to get document library ID for site ${siteId}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -86,7 +93,7 @@ export class SitesApi { } } } catch (error) { - console.error(`${this.constructor.name} ${this.deleteSites.name}`, error); + logger.error(`${this.constructor.name} ${this.deleteSites.name}: ${error}`); } } @@ -96,9 +103,9 @@ export class SitesApi { } as SiteMembershipBodyUpdate; try { - return this.apiService.sites.updateSiteMembership(siteId, userId, siteRole); + return await this.apiService.sites.updateSiteMembership(siteId, userId, siteRole); } catch (error) { - console.error(`SitesApi updateSiteMember : catch : `, error); + logger.error(`SitesApi updateSiteMember : catch : ${error}`); return new SiteMemberEntry(); } } @@ -127,7 +134,9 @@ export class SitesApi { try { return this.apiService.sites.createSiteMembershipRequestForPerson(personId, body); } catch (error) { - throw new Error(`Failed to create site membership request for person ${personId} and site ${siteId}: ${error}`); + const message = `Failed to create site membership request for person ${personId} and site ${siteId}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -135,7 +144,9 @@ export class SitesApi { try { return this.apiService.sites.approveSiteMembershipRequest(siteId, inviteeId); } catch (error) { - throw new Error(`Failed to approve site membership request for invitee ${inviteeId} and site ${siteId}: ${error}`); + const message = `Failed to approve site membership request for invitee ${inviteeId} and site ${siteId}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -145,7 +156,9 @@ export class SitesApi { const requests = entries.map((e) => e.entry?.id).filter((id): id is string => !!id); return requests.includes(siteId); } catch (error) { - throw new Error(`Failed to check site membership request for person ${personId} and site ${siteId}: ${error}`); + const message = `Failed to check site membership request for person ${personId} and site ${siteId}: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -153,7 +166,7 @@ export class SitesApi { try { return this.apiService.sites.deleteSiteMembership(siteId, userId); } catch (error) { - console.error(`SitesApi deleteSiteMember : catch : `, error); + logger.error(`SitesApi deleteSiteMember : catch : ${error}`); } } @@ -161,7 +174,9 @@ export class SitesApi { try { return this.apiService.sites.getSite(siteId); } catch (error) { - throw new Error(`Failed to get site ${siteId}: ${error}`); + const message = `Failed to get site ${siteId}: ${error}`; + logger.error(message); + throw new Error(message); } } } diff --git a/projects/aca-playwright-shared/src/api/tags-api.ts b/projects/aca-playwright-shared/src/api/tags-api.ts index c212a104f..cf206c368 100644 --- a/projects/aca-playwright-shared/src/api/tags-api.ts +++ b/projects/aca-playwright-shared/src/api/tags-api.ts @@ -50,26 +50,34 @@ export class TagsApi { } else if ('list' in result) { const firstEntry = result.list?.entries?.[0]; if (!firstEntry) { - throw new Error(`createTags returned a paging result with no entries for tag "${tag}"`); + const message = `createTags returned a paging result with no entries for tag "${tag}"`; + logger.error(message); + throw new Error(message); } created = firstEntry; } else { - throw new Error(`createTags returned an unexpected response format for tag "${tag}"`); + const message = `createTags returned an unexpected response format for tag "${tag}"`; + logger.error(message); + throw new Error(message); } logger.info(`Tag created: "${created.entry.tag}" (id: ${created.entry.id})`); results.push(created); } return results; } catch (error) { - throw new Error(`Failed to create tags: ${error}`); + const message = `Failed to create tags: ${error}`; + logger.error(message); + throw new Error(message); } } async assignTagToNode(nodeId: string, tag: TagBody): Promise { try { - return this.apiService.tagsApi.assignTagToNode(nodeId, tag); + return await this.apiService.tagsApi.assignTagToNode(nodeId, tag); } catch (error) { - throw new Error(`Failed to assign tag to node: ${error}`); + const message = `Failed to assign tag to node: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -81,7 +89,9 @@ export class TagsApi { logger.info(`Tag deleted: ${tagLabel}(id: ${id})`); } } catch (error) { - throw new Error(`Failed to delete tags: ${error}`); + const message = `Failed to delete tags: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -89,7 +99,9 @@ export class TagsApi { try { return this.apiService.tagsApi.listTagsForNode(nodeId); } catch (error) { - throw new Error(`Failed to list tags for node: ${error}`); + const message = `Failed to list tags for node: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -97,7 +109,9 @@ export class TagsApi { try { return this.apiService.tagsApi.listTags(params); } catch (error) { - throw new Error(`Failed to list tags: ${error}`); + const message = `Failed to list tags: ${error}`; + logger.error(message); + throw new Error(message); } } @@ -107,7 +121,9 @@ export class TagsApi { const tags = response.list?.entries.map((entry) => entry.entry) || []; await this.deleteTags(...tags); } catch (error) { - throw new Error(`Failed to delete tags by tag name: ${error}`); + const message = `Failed to delete tags by tag name: ${error}`; + logger.error(message); + throw new Error(message); } } } diff --git a/projects/aca-playwright-shared/src/api/trashcan-api.ts b/projects/aca-playwright-shared/src/api/trashcan-api.ts index 1bcd591c9..b5fe74909 100644 --- a/projects/aca-playwright-shared/src/api/trashcan-api.ts +++ b/projects/aca-playwright-shared/src/api/trashcan-api.ts @@ -23,6 +23,7 @@ */ import { ApiClientFactory } from './api-client-factory'; +import { logger } from '../utils'; export class TrashcanApi { private readonly apiService = new ApiClientFactory(); @@ -50,7 +51,7 @@ export class TrashcanApi { } } } catch (error) { - console.error('User Actions - emptyTrashcan failed : ', error); + logger.error(`User Actions - emptyTrashcan failed: ${error}`); } } }