From c22589100f4ee2b5461e7f9d63d85216fa15a672 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Fri, 1 Dec 2023 13:04:32 +0100 Subject: [PATCH 01/23] [ACS-6435] playwright e2e for list views personal files --- .github/workflows/pull-request.yml | 4 +- e2e/playwright/list-views/.eslintrc.json | 26 +++ e2e/playwright/list-views/exclude.tests.json | 1 + .../list-views/playwright.config.ts | 44 +++++ e2e/playwright/list-views/project.json | 22 +++ .../list-views/src/tests/favorites.spec.ts | 155 ++++++++++++++++++ .../src/tests/personal-files.spec.ts | 92 +++++++++++ .../list-views/tsconfig.e2e.adf.json | 15 ++ e2e/playwright/list-views/tsconfig.e2e.json | 15 ++ .../suites/list-views/favorites.test.ts | 145 ---------------- .../suites/list-views/personal-files.test.ts | 124 -------------- .../dataTable/data-table.component.ts | 34 +++- .../src/page-objects/pages/favorites.page.ts | 3 +- 13 files changed, 407 insertions(+), 273 deletions(-) create mode 100644 e2e/playwright/list-views/.eslintrc.json create mode 100644 e2e/playwright/list-views/exclude.tests.json create mode 100644 e2e/playwright/list-views/playwright.config.ts create mode 100644 e2e/playwright/list-views/project.json create mode 100644 e2e/playwright/list-views/src/tests/favorites.spec.ts create mode 100644 e2e/playwright/list-views/src/tests/personal-files.spec.ts create mode 100644 e2e/playwright/list-views/tsconfig.e2e.adf.json create mode 100755 e2e/playwright/list-views/tsconfig.e2e.json delete mode 100755 e2e/protractor/suites/list-views/favorites.test.ts delete mode 100755 e2e/protractor/suites/list-views/personal-files.test.ts diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index a61fcc6062..0549c56814 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -109,8 +109,6 @@ jobs: fail-fast: false matrix: e2e-suites: - - name: "listViews" - id: 1 - name: "search" id: 2 - name: "viewer,infoDrawer,extensions" @@ -178,6 +176,8 @@ jobs: id: 6 - name: "pagination" id: 7 + - name: "list-views" + id: 8 steps: - name: Checkout uses: actions/checkout@v3 diff --git a/e2e/playwright/list-views/.eslintrc.json b/e2e/playwright/list-views/.eslintrc.json new file mode 100644 index 0000000000..9e1357d874 --- /dev/null +++ b/e2e/playwright/list-views/.eslintrc.json @@ -0,0 +1,26 @@ +{ + "extends": "../../../.eslintrc.json", + "ignorePatterns": [ + "!**/*" + ], + "overrides": [ + { + "files": [ + "*.ts" + ], + "parserOptions": { + "project": [ + "e2e/playwright/list-views/tsconfig.e2e.json" + ], + "createDefaultProgram": true + }, + "plugins": [ + "rxjs", + "unicorn" + ], + "rules": { + "@typescript-eslint/no-floating-promises": "off" + } + } + ] +} diff --git a/e2e/playwright/list-views/exclude.tests.json b/e2e/playwright/list-views/exclude.tests.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/e2e/playwright/list-views/exclude.tests.json @@ -0,0 +1 @@ +{} diff --git a/e2e/playwright/list-views/playwright.config.ts b/e2e/playwright/list-views/playwright.config.ts new file mode 100644 index 0000000000..8b7f9faa6e --- /dev/null +++ b/e2e/playwright/list-views/playwright.config.ts @@ -0,0 +1,44 @@ +/*! + * Copyright © 2005-2023 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 { PlaywrightTestConfig } from '@playwright/test'; +import { CustomConfig, getGlobalConfig, getExcludedTestsRegExpArray } from '@alfresco/playwright-shared'; +import EXCLUDED_JSON from './exclude.tests.json'; + +const config: PlaywrightTestConfig = { + ...getGlobalConfig, + + grepInvert: getExcludedTestsRegExpArray(EXCLUDED_JSON, 'List Views'), + projects: [ + { + name: 'List Views', + testDir: './src/tests', + use: { + users: ['hruser', 'admin'] + } + } + ] +}; + +export default config; diff --git a/e2e/playwright/list-views/project.json b/e2e/playwright/list-views/project.json new file mode 100644 index 0000000000..a55e67f9fd --- /dev/null +++ b/e2e/playwright/list-views/project.json @@ -0,0 +1,22 @@ +{ + "name": "list-views-e2e", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "e2e/playwright/list-views", + "projectType": "application", + "targets": { + "e2e": { + "executor": "nx:run-commands", + "options": { + "commands": ["npx playwright test --config=e2e/playwright/list-views/playwright.config.ts"] + }, + "configurations": { + "production": { + "devServerTarget": "content-ce:serve:production" + } + } + }, + "lint": { + "executor": "@angular-eslint/builder:lint" + } + } +} diff --git a/e2e/playwright/list-views/src/tests/favorites.spec.ts b/e2e/playwright/list-views/src/tests/favorites.spec.ts new file mode 100644 index 0000000000..66615de4cd --- /dev/null +++ b/e2e/playwright/list-views/src/tests/favorites.spec.ts @@ -0,0 +1,155 @@ +/*! + * Copyright © 2005-2023 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 { expect } from '@playwright/test'; +import { ApiClientFactory, LoginPage, NodesApi, Utils, test, SitesApi, FavoritesPageApi, timeouts } from '@alfresco/playwright-shared'; +import { Site } from '@alfresco/js-api'; + +test.describe('Favorites Files', () => { + const apiClientFactory = new ApiClientFactory(); + let nodesApi: NodesApi; + let nodesApiAdmin: NodesApi; + let siteActionsAdmin: SitesApi; + let favoritesActions: FavoritesPageApi; + const username = `user-${Utils.random()}`; + const siteName = `site-${Utils.random()}`; + const favFolderName = `favFolder-${Utils.random()}`; + const parentFolder = `parent-${Utils.random()}`; + const fileName1 = `file1-${Utils.random()}.txt`; + const fileName2 = `file2-${Utils.random()}.txt`; + const fileName3 = `file3-${Utils.random()}.txt`; + const fileName4 = `file4-${Utils.random()}.txt`; + + test.beforeAll(async () => { + try { + test.setTimeout(timeouts.extendedTest); + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username }); + nodesApi = await NodesApi.initialize(username, username); + nodesApiAdmin = await NodesApi.initialize('admin'); + siteActionsAdmin = await SitesApi.initialize('admin'); + favoritesActions = await FavoritesPageApi.initialize(username, username); + const consumerFavoritesTotalItems = await favoritesActions.getFavoritesTotalItems(username); + const folderFavId = (await nodesApi.createFolder(favFolderName)).entry.id; + const parentId = (await nodesApi.createFolder(parentFolder)).entry.id; + await siteActionsAdmin.createSite(siteName, Site.VisibilityEnum.PUBLIC); + const docLibId = await siteActionsAdmin.getDocLibId(siteName); + await siteActionsAdmin.addSiteMember(siteName, username, Site.RoleEnum.SiteManager); + await favoritesActions.addFavoritesByIds('folder', [folderFavId]); + const file1Id = (await nodesApiAdmin.createFile(fileName1, docLibId)).entry.id; + const file2Id = (await nodesApi.createFile(fileName2, parentId)).entry.id; + const file3Id = (await nodesApi.createFile(fileName3, parentId)).entry.id; + const file4Id = (await nodesApi.createFile(fileName4, parentId)).entry.id; + + await favoritesActions.addFavoritesByIds('file', [file1Id]); + await favoritesActions.addFavoriteById('file', file2Id); + await favoritesActions.addFavoriteById('file', file3Id); + await favoritesActions.addFavoriteById('file', file4Id); + await nodesApi.deleteNodes([file3Id, file4Id], false); + await apiClientFactory.trashCan.restoreDeletedNode(file4Id); + await Promise.all([ + favoritesActions.isFavoriteWithRetry(username, folderFavId, { expect: true }), + favoritesActions.waitForApi(username, { expect: consumerFavoritesTotalItems + 4 }) + ]); + } catch (error) { + console.error(`beforeAll failed : ${error}`); + } + }); + + test.beforeEach(async ({ page }) => { + const loginPage = new LoginPage(page); + try { + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); + } catch (error) { + console.error(`beforeEach failed : ${error}`); + } + }); + + test.afterAll(async () => { + try { + await nodesApi.deleteCurrentUserNodes(); + } catch (error) { + console.error(`afterAll failed : ${error}`); + } + }); + + test.describe(`Regular user's Favorites files`, () => { + test.beforeEach(async ({ favoritePage }) => { + favoritePage.navigate(); + }); + + test('[C280482] has the correct columns', async ({ favoritePage }) => { + const expectedColumns = ['Name', 'Location', 'Size', 'Modified', 'Modified by', 'Tags']; + const actualColumns = await favoritePage.dataTable.getColumnHeaders(); + expect(actualColumns).toEqual(expectedColumns); + }); + + test(`[C213228] deleted favorite file does not appear`, async ({ favoritePage }) => { + expect(await favoritePage.dataTable.isItemPresent(fileName3), `${fileName3} is displayed`).not.toBe(true); + }); + + test(`[C213229] file is displayed after it is restored from Trashcan`, async ({ favoritePage }) => { + expect(await favoritePage.dataTable.isItemPresent(fileName4), `${fileName4} not displayed`).toBe(true); + }); + + test('[C213231] Location column displays the parent folder of the files', async ({ favoritePage }) => { + expect(await favoritePage.dataTable.getItemLocationText(fileName2)).toEqual(parentFolder); + expect(await favoritePage.dataTable.getItemLocationText(favFolderName)).toEqual('Personal Files'); + expect(await favoritePage.dataTable.getItemLocationTooltip(fileName2)).toEqual(`Personal Files/${parentFolder}`); + expect(await favoritePage.dataTable.getItemLocationTooltip(favFolderName)).toEqual('Personal Files'); + expect(await favoritePage.dataTable.getItemLocationText(fileName1)).toEqual(siteName); + expect(await favoritePage.dataTable.getItemLocationTooltip(fileName1)).toContain(`${siteName}`); + }); + + test('[C213650] Location column redirect - item in user Home', async ({ favoritePage }) => { + await favoritePage.dataTable.clickItemLocation(favFolderName); + await favoritePage.dataTable.spinnerWaitForReload(); + expect(await favoritePage.breadcrumb.getAllItems()).toEqual(['Personal Files']); + }); + + test('[C280484] Location column redirect - file in folder', async ({ favoritePage }) => { + await favoritePage.dataTable.clickItemLocation(fileName2); + await favoritePage.dataTable.spinnerWaitForReload(); + expect(await favoritePage.breadcrumb.getAllItems()).toEqual(['Personal Files', parentFolder]); + }); + + test('[C280485] Location column redirect - file in site', async ({ favoritePage }) => { + await favoritePage.dataTable.clickItemLocation(fileName1); + await favoritePage.dataTable.spinnerWaitForReload(); + expect(await favoritePage.breadcrumb.getAllItems()).toEqual(['My Libraries', siteName]); + }); + + test('[C213230] Navigate into folder from Favorites', async ({ favoritePage }) => { + await favoritePage.dataTable.performClickFolderOrFileToOpen(favFolderName); + await favoritePage.dataTable.spinnerWaitForReload(); + expect(await favoritePage.breadcrumb.currentItem.innerText()).toBe(favFolderName); + }); + }); +}); diff --git a/e2e/playwright/list-views/src/tests/personal-files.spec.ts b/e2e/playwright/list-views/src/tests/personal-files.spec.ts new file mode 100644 index 0000000000..a4ae055b2e --- /dev/null +++ b/e2e/playwright/list-views/src/tests/personal-files.spec.ts @@ -0,0 +1,92 @@ +/*! + * Copyright © 2005-2023 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 { expect } from '@playwright/test'; +import { APP_ROUTES, ApiClientFactory, LoginPage, NodesApi, SIDEBAR_LABELS, Utils, test } from '@alfresco/playwright-shared'; + +test.describe('Personal Files', () => { + const apiClientFactory = new ApiClientFactory(); + let nodesApi: NodesApi; + const username = `user-${Utils.random()}`; + const userFolder = `user-folder-${Utils.random()}`; + + test.beforeAll(async () => { + try { + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username }); + nodesApi = await NodesApi.initialize(username, username); + await nodesApi.createFolder(userFolder); + } catch (error) { + console.error(`beforeAll failed : ${error}`); + } + }); + + test.afterAll(async () => { + try { + await nodesApi.deleteCurrentUserNodes(); + } catch (error) { + console.error(`afterAll failed : ${error}`); + } + }); + + test.describe(`Regular user's personal files`, () => { + test.beforeEach(async ({ page }) => { + const loginPage = new LoginPage(page); + try { + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); + } catch (error) { + console.error(`beforeEach failed : ${error}`); + } + }); + + test('[C217142] has the correct columns', async ({ personalFiles }) => { + const expectedColumns = ['Name', 'Size', 'Modified', 'Modified by', 'Tags']; + const actualColumns = await personalFiles.dataTable.getColumnHeaders(); + expect(actualColumns).toEqual(expectedColumns); + }); + + test('[C217143] has default sorted column', async ({ personalFiles }) => { + expect(await personalFiles.dataTable.getSortedColumnHeaderText()).toBe('Name'); + }); + + test('[C213245] redirects to Personal Files on clicking the link from sidebar', async ({ personalFiles }) => { + await personalFiles.dataTable.performClickFolderOrFileToOpen(userFolder); + await personalFiles.sidenav.openPanel(SIDEBAR_LABELS.PERSONAL_FILES); + await personalFiles.dataTable.spinnerWaitForReload(); + expect(personalFiles.page.url()).toContain(APP_ROUTES.PERSONAL_FILES); + expect(await personalFiles.sidenav.isActive(SIDEBAR_LABELS.PERSONAL_FILES), 'My Libraries link not active').toBe(true); + }); + + test('[C213246] page loads correctly after browser refresh', async ({ personalFiles }) => { + await personalFiles.reload(); + expect(personalFiles.page.url()).toContain(APP_ROUTES.PERSONAL_FILES); + }); + }); +}); diff --git a/e2e/playwright/list-views/tsconfig.e2e.adf.json b/e2e/playwright/list-views/tsconfig.e2e.adf.json new file mode 100644 index 0000000000..87cbcf775a --- /dev/null +++ b/e2e/playwright/list-views/tsconfig.e2e.adf.json @@ -0,0 +1,15 @@ +{ + "extends": "../../../tsconfig.adf.json", + "compilerOptions": { + "outDir": "../../out-tsc/e2e", + "baseUrl": "./", + "module": "commonjs", + "target": "es2017", + "types": ["jasmine", "jasminewd2", "node"], + "skipLibCheck": true, + "paths": { + "@alfresco/playwright-shared": ["../../../projects/aca-playwright-shared/src/index.ts"] + } + }, + "exclude": ["node_modules"] +} diff --git a/e2e/playwright/list-views/tsconfig.e2e.json b/e2e/playwright/list-views/tsconfig.e2e.json new file mode 100755 index 0000000000..c317985239 --- /dev/null +++ b/e2e/playwright/list-views/tsconfig.e2e.json @@ -0,0 +1,15 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/e2e", + "baseUrl": "./", + "module": "commonjs", + "target": "es2017", + "types": ["jasmine", "jasminewd2", "node", "@playwright/test"], + "skipLibCheck": true, + "paths": { + "@alfresco/playwright-shared": ["../../../projects/aca-playwright-shared/src/index.ts"] + } + }, + "exclude": ["node_modules"] +} diff --git a/e2e/protractor/suites/list-views/favorites.test.ts b/e2e/protractor/suites/list-views/favorites.test.ts deleted file mode 100755 index 649dd7c703..0000000000 --- a/e2e/protractor/suites/list-views/favorites.test.ts +++ /dev/null @@ -1,145 +0,0 @@ -/*! - * Copyright © 2005-2023 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 { AdminActions, UserActions, SITE_VISIBILITY, SITE_ROLES, LoginPage, BrowsingPage, Utils, RepoClient } from '@alfresco/aca-testing-shared'; - -describe('Favorites', () => { - const username = `user-${Utils.random()}`; - - const siteName = `site-${Utils.random()}`; - const favFolderName = `favFolder-${Utils.random()}`; - const parentFolder = `parent-${Utils.random()}`; - const fileName1 = `file1-${Utils.random()}.txt`; - const fileName2 = `file2-${Utils.random()}.txt`; - const fileName3 = `file3-${Utils.random()}.txt`; - const fileName4 = `file4-${Utils.random()}.txt`; - - const apis = { - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable, breadcrumb } = page; - - const adminApiActions = new AdminActions(); - const userActions = new UserActions(); - - let parentId: string; - let folderId: string; - - beforeAll(async () => { - await adminApiActions.createUser({ username }); - - await adminApiActions.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC); - const docLibId = await adminApiActions.sites.getDocLibId(siteName); - await adminApiActions.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_MANAGER.ROLE); - - const file1Id = (await adminApiActions.nodes.createFile(fileName1, docLibId)).entry.id; - folderId = (await apis.user.nodes.createFolder(favFolderName)).entry.id; - parentId = (await apis.user.nodes.createFolder(parentFolder)).entry.id; - const file2Id = (await apis.user.nodes.createFile(fileName2, parentId)).entry.id; - const file3Id = (await apis.user.nodes.createFile(fileName3, parentId)).entry.id; - const file4Id = (await apis.user.nodes.createFile(fileName4, parentId)).entry.id; - - await apis.user.favorites.addFavoriteById('file', file1Id); - await apis.user.favorites.addFavoriteById('folder', folderId); - await apis.user.favorites.addFavoriteById('file', file2Id); - await apis.user.favorites.addFavoriteById('file', file3Id); - await apis.user.favorites.addFavoriteById('file', file4Id); - - await userActions.login(username, username); - await userActions.deleteNodes([file3Id, file4Id], false); - await userActions.trashcanApi.restoreDeletedNode(file4Id); - await loginPage.loginWith(username); - }); - - beforeEach(async () => { - await page.clickFavoritesAndWait(); - }); - - afterAll(async () => { - await userActions.login(username, username); - await userActions.deleteNodes([folderId, parentId]); - await userActions.emptyTrashcan(); - - await adminApiActions.login(); - await adminApiActions.deleteSites([siteName]); - }); - - it('[C280482] has the correct columns', async () => { - const expectedColumns = ['Name', 'Location', 'Size', 'Modified', 'Modified by', 'Tags']; - const actualColumns = await dataTable.getColumnHeadersText(); - - await expect(actualColumns).toEqual(expectedColumns); - }); - - it('[C213226] displays the favorite files and folders', async () => { - expect(await dataTable.getRowsCount()).toEqual(4, 'Incorrect number of items displayed'); - expect(await dataTable.isItemPresent(fileName1)).toBe(true, `${fileName1} not displayed`); - expect(await dataTable.isItemPresent(fileName2)).toBe(true, `${fileName2} not displayed`); - expect(await dataTable.isItemPresent(favFolderName)).toBe(true, `${favFolderName} not displayed`); - }); - - it(`[C213228] deleted favorite file does not appear`, async () => { - expect(await dataTable.isItemPresent(fileName3)).not.toBe(true, `${fileName3} is displayed`); - }); - - it(`[C213229] file is displayed after it is restored from Trashcan`, async () => { - expect(await dataTable.isItemPresent(fileName4)).toBe(true, `${fileName4} not displayed`); - }); - - it('[C213231] Location column displays the parent folder of the files', async () => { - expect(await dataTable.getItemLocation(fileName1)).toEqual(siteName); - expect(await dataTable.getItemLocation(fileName2)).toEqual(parentFolder); - expect(await dataTable.getItemLocation(favFolderName)).toEqual('Personal Files'); - }); - - it('[C213671] Location column displays a tooltip with the entire path of the file', async () => { - expect(await dataTable.getItemLocationTooltip(fileName1)).toEqual(`File Libraries/${siteName}`); - expect(await dataTable.getItemLocationTooltip(fileName2)).toEqual(`Personal Files/${parentFolder}`); - expect(await dataTable.getItemLocationTooltip(favFolderName)).toEqual('Personal Files'); - }); - - it('[C213650] Location column redirect - item in user Home', async () => { - await dataTable.clickItemLocation(favFolderName); - expect(await breadcrumb.getAllItems()).toEqual(['Personal Files']); - }); - - it('[C280484] Location column redirect - file in folder', async () => { - await dataTable.clickItemLocation(fileName2); - expect(await breadcrumb.getAllItems()).toEqual(['Personal Files', parentFolder]); - }); - - it('[C280485] Location column redirect - file in site', async () => { - await dataTable.clickItemLocation(fileName1); - expect(await breadcrumb.getAllItems()).toEqual(['My Libraries', siteName]); - }); - - it('[C213230] Navigate into folder from Favorites', async () => { - await dataTable.doubleClickOnRowByName(favFolderName); - await dataTable.waitForEmptyState(); - expect(await breadcrumb.currentItem.getText()).toBe(favFolderName); - }); -}); diff --git a/e2e/protractor/suites/list-views/personal-files.test.ts b/e2e/protractor/suites/list-views/personal-files.test.ts deleted file mode 100755 index 03d2e83852..0000000000 --- a/e2e/protractor/suites/list-views/personal-files.test.ts +++ /dev/null @@ -1,124 +0,0 @@ -/*! - * Copyright © 2005-2023 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 { browser } from 'protractor'; - -import { AdminActions, APP_ROUTES, LoginPage, BrowsingPage, Utils, RepoClient } from '@alfresco/aca-testing-shared'; - -describe('Personal Files', () => { - const username = `user-${Utils.random()}`; - - const apis = { - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable } = page; - - const adminFolder = `admin-folder-${Utils.random()}`; - - const userFolder = `user-folder-${Utils.random()}`; - const userFile = `file-${Utils.random()}.txt`; - const adminApiActions = new AdminActions(); - - beforeAll(async () => { - await Promise.all([adminApiActions.createUser({ username }), adminApiActions.nodes.createFolders([adminFolder])]); - await apis.user.nodes.createFolders([userFolder]); - await apis.user.nodes.createFiles([userFile], userFolder); - }); - - afterAll(async () => { - await Promise.all([adminApiActions.nodes.deleteNodes([adminFolder]), apis.user.nodes.deleteNodes([userFolder])]); - }); - - describe(`Admin user's personal files`, () => { - beforeAll(async () => { - await loginPage.loginWithAdmin(); - }); - - beforeEach(async () => { - await page.clickPersonalFilesAndWait(); - }); - - it('[C213241] has Data Dictionary and created content', async () => { - expect(await dataTable.isItemPresent('Data Dictionary')).toBe(true, 'Data Dictionary not displayed'); - expect(await dataTable.isItemPresent(adminFolder)).toBe(true, 'admin folder not displayed'); - }); - }); - - describe(`Regular user's personal files`, () => { - beforeAll(async () => { - await loginPage.loginWith(username); - }); - - beforeEach(async () => { - await page.clickPersonalFilesAndWait(); - }); - - it('[C217142] has the correct columns', async () => { - const expectedColumns = ['Name', 'Size', 'Modified', 'Modified by', 'Tags']; - const actualColumns = await dataTable.getColumnHeadersText(); - - await expect(actualColumns).toEqual(expectedColumns); - }); - - it('[C217143] has default sorted column', async () => { - expect(await dataTable.getSortedColumnHeaderText()).toBe('Name'); - }); - - it('[C213242] has user created content', async () => { - expect(await dataTable.isItemPresent(userFolder)).toBe(true, 'user folder not displayed'); - }); - - it('[C213244] navigates to folder', async () => { - const nodeId = (await apis.user.nodes.getNodeByPath(`/${userFolder}`)).entry.id; - - await dataTable.doubleClickOnRowByName(userFolder); - await dataTable.waitForHeader(); - - expect(await browser.getCurrentUrl()).toContain(nodeId, 'Node ID is not in the URL'); - expect(await dataTable.isItemPresent(userFile)).toBe(true, 'user file is missing'); - }); - - it('[C213245] redirects to Personal Files on clicking the link from sidebar', async () => { - await page.dataTable.doubleClickOnRowByName(userFolder); - await page.clickPersonalFiles(); - const url = await browser.getCurrentUrl(); - expect(url.endsWith(APP_ROUTES.PERSONAL_FILES)).toBe(true, 'incorrect url'); - }); - - it('[C213246] page loads correctly after browser refresh', async () => { - await page.refresh(); - expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); - }); - - it('[C213247] page load by URL', async () => { - const url = await browser.getCurrentUrl(); - await page.clickTrash(); - await browser.get(url); - expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); - }); - }); -}); diff --git a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts index 4e51de20ba..aa42857a2e 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts @@ -26,6 +26,7 @@ import { Locator, Page } from '@playwright/test'; import { BaseComponent } from '../base.component'; import { MatMenuComponent } from './mat-menu.component'; import { PaginationActionsType, PaginationComponent } from '../pagination.component'; +import { timeouts } from '../../../utils'; export class DataTableComponent extends BaseComponent { private static rootElement = 'adf-datatable'; @@ -40,6 +41,8 @@ export class DataTableComponent extends BaseComponent { getEmptyContentTitleLocator = this.getChild('adf-empty-content .adf-empty-content__title'); getEmptyContentSubTitleLocator = this.getChild('adf-empty-content .adf-empty-content__subtitle'); getSelectedRow = this.getChild('.adf-datatable-row.adf-is-selected'); + sortedAscColumnHeader = this.getChild('.adf-datatable__header--sorted-asc .adf-datatable-cell-header-content .adf-datatable-cell-value'); + columnHeaders = this.getChild('.adf-datatable-row .adf-datatable-cell-header .adf-datatable-cell-value'); /** Locator for row (or rows) */ getRowLocator = this.getChild(`adf-datatable-row`); @@ -188,7 +191,7 @@ export class DataTableComponent extends BaseComponent { async goThroughPagesLookingForRowWithName(name: string | number): Promise { await this.spinnerWaitForReload(); - if (await this.getRowByName(name).isVisible()) { + if ((await this.getRowByName(name).isVisible()) || (await this.pagination.totalPageLocator.textContent()) == ' of 1 ') { return null; } @@ -230,4 +233,33 @@ export class DataTableComponent extends BaseComponent { const row = this.getRowByName(itemName); return await row.locator('.adf-datatable-selected').isVisible(); } + + async getColumnHeaders(): Promise> { + const columnNameLocator = this.columnHeaders; + await this.columnHeaders.nth(0).waitFor({ state: 'attached' }); + return columnNameLocator.allTextContents(); + } + + async getSortedColumnHeaderText(): Promise { + return this.sortedAscColumnHeader.innerText(); + } + + private getItemLocationEl(name: string): Locator { + return this.getRowByName(name).locator('.aca-location-link'); + } + + async getItemLocationText(name: string): Promise { + await this.getItemLocationEl(name).locator('a').waitFor({ state: 'attached' }); + return this.getItemLocationEl(name).innerText(); + } + + async getItemLocationTooltip(name: string): Promise { + const location = this.getItemLocationEl(name); + await location.hover(); + return location.locator('a').getAttribute('title', { timeout: timeouts.normal }); + } + + async clickItemLocation(name: string): Promise { + await this.getItemLocationEl(name).click(); + } } diff --git a/projects/aca-playwright-shared/src/page-objects/pages/favorites.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/favorites.page.ts index 8574042dc1..6a7c47c07e 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/favorites.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/favorites.page.ts @@ -24,7 +24,7 @@ import { Page } from '@playwright/test'; import { BasePage } from './base.page'; -import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent, PaginationComponent } from '../components'; +import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent, PaginationComponent, Breadcrumb } from '../components'; import { AcaHeader } from '../components/aca-header.component'; import { AdfFolderDialogComponent, ViewerOverlayDialogComponent } from '../components/dialogs'; @@ -43,6 +43,7 @@ export class FavoritesPage extends BasePage { public viewerDialog = new ViewerOverlayDialogComponent(this.page); public sidenav = new SidenavComponent(this.page); public pagination = new PaginationComponent(this.page); + public breadcrumb = new Breadcrumb(this.page); async waitForPageLoad() { await this.page.waitForURL(`**/${FavoritesPage.pageUrl}`); From d15515795d628f4969e5e53d33ab785d51870d5a Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Tue, 5 Dec 2023 16:57:39 +0100 Subject: [PATCH 02/23] e2e test for trash page --- .../list-views/src/tests/trash.test.ts | 141 ++++++++++++++++++ .../suites/list-views/trash.test.ts | 72 +-------- .../dataTable/data-table.component.ts | 15 +- .../src/page-objects/pages/trash.page.ts | 3 +- 4 files changed, 157 insertions(+), 74 deletions(-) create mode 100755 e2e/playwright/list-views/src/tests/trash.test.ts diff --git a/e2e/playwright/list-views/src/tests/trash.test.ts b/e2e/playwright/list-views/src/tests/trash.test.ts new file mode 100755 index 0000000000..e3638885cb --- /dev/null +++ b/e2e/playwright/list-views/src/tests/trash.test.ts @@ -0,0 +1,141 @@ +/*! + * Copyright © 2005-2023 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 { expect } from '@playwright/test'; +import { ApiClientFactory, LoginPage, NodesApi, SitesApi, Utils, test } from '@alfresco/playwright-shared'; +import { Site } from '@alfresco/js-api'; + +test.describe('Trash', () => { + const apiClientFactory = new ApiClientFactory(); + let nodesApi: NodesApi; + let siteActionsAdmin: SitesApi; + let nodesApiAdmin: NodesApi; + const username = `user-${Utils.random()}`; + const siteName = `site-${Utils.random()}`; + const fileSite = `file1-${Utils.random()}.txt`; + + const folderUser = `folder-${Utils.random()}`; + let folderUserId: string; + const fileUser = `file-${Utils.random()}.txt`; + let fileUserId: string; + + const folderDeleted = `folder-${Utils.random()}`; + let folderDeletedId: string; + const fileDeleted = `file-${Utils.random()}.txt`; + let fileDeletedId: string; + + const folderNotDeleted = `folder-${Utils.random()}`; + let folderNotDeletedId: string; + const fileInFolder = `file-${Utils.random()}.txt`; + let fileInFolderId: string; + + test.beforeAll(async () => { + try { + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username }); + siteActionsAdmin = await SitesApi.initialize('admin'); + nodesApi = await NodesApi.initialize(username, username); + nodesApiAdmin = await NodesApi.initialize('admin'); + + await siteActionsAdmin.createSite(siteName, Site.VisibilityEnum.PUBLIC); + const docLibId = await siteActionsAdmin.getDocLibId(siteName); + await siteActionsAdmin.addSiteMember(siteName, username, Site.RoleEnum.SiteManager); + const fileSiteId = (await nodesApiAdmin.createFile(fileSite, docLibId)).entry.id; + + folderUserId = (await nodesApi.createFolder(folderUser)).entry.id; + folderDeletedId = (await nodesApi.createFolder(folderDeleted)).entry.id; + folderNotDeletedId = (await nodesApi.createFolder(folderNotDeleted)).entry.id; + fileUserId = (await nodesApi.createFile(fileUser)).entry.id; + fileDeletedId = (await nodesApi.createFile(fileDeleted, folderDeletedId)).entry.id; + fileInFolderId = (await nodesApi.createFile(fileInFolder, folderNotDeletedId)).entry.id; + + await nodesApi.deleteNodes([fileSiteId, fileUserId, folderUserId, fileInFolderId, fileDeletedId, folderDeletedId], false); + } catch (error) { + console.error(`----- beforeAll failed : ${error}`); + } + }); + + test.afterAll(async () => { + try { + await nodesApi.deleteCurrentUserNodes(); + } catch (error) { + console.error(`----- afterAll failed : ${error}`); + } + }); + + test.describe.only(`Regular user's personal files`, () => { + test.beforeEach(async ({ page }) => { + const loginPage = new LoginPage(page); + try { + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); + } catch (error) { + console.error(`beforeEach failed : ${error}`); + } + }); + + test.beforeEach(async ({ trashPage }) => { + await trashPage.navigate(); + }); + + test('[C280494] has the correct columns', async ({ trashPage }) => { + const expectedColumns = ['Name', 'Location', 'Size', 'Deleted']; + const actualColumns = await trashPage.dataTable.getColumnHeaders(); + + expect(actualColumns).toEqual(expectedColumns); + }); + + test('[C213219] default sorting column', async ({ trashPage }) => { + expect(await trashPage.dataTable.getSortedColumnHeaderText()).toBe('Deleted'); + expect(await trashPage.dataTable.getSortingOrder()).toBe('desc'); + }); + + test('[C280500] Location column is empty if parent folder no longer exists', async ({ trashPage }) => { + expect(await trashPage.dataTable.getItemLocationText(fileDeleted)).toEqual(''); + }); + + test('[C217144] Location column redirect - file in user Home', async ({ trashPage }) => { + await trashPage.dataTable.clickItemLocation(fileUser); + await trashPage.dataTable.spinnerWaitForReload(); + expect(await trashPage.breadcrumb.getAllItems()).toEqual(['Personal Files']); + }); + + test('[C280496] Location column redirect - file in folder', async ({ trashPage }) => { + await trashPage.dataTable.clickItemLocation(fileInFolder); + await trashPage.dataTable.spinnerWaitForReload(); + expect(await trashPage.breadcrumb.getAllItems()).toEqual(['Personal Files', folderNotDeleted]); + }); + + test('[C280497] Location column redirect - file in site', async ({ trashPage }) => { + await trashPage.dataTable.clickItemLocation(fileSite); + await trashPage.dataTable.spinnerWaitForReload(); + expect(await trashPage.breadcrumb.getAllItems()).toEqual(['My Libraries', siteName]); + }); + }); +}); diff --git a/e2e/protractor/suites/list-views/trash.test.ts b/e2e/protractor/suites/list-views/trash.test.ts index f6ca1aa37b..b6cae2a866 100755 --- a/e2e/protractor/suites/list-views/trash.test.ts +++ b/e2e/protractor/suites/list-views/trash.test.ts @@ -58,7 +58,7 @@ describe('Trash', () => { const loginPage = new LoginPage(); const page = new BrowsingPage(); - const { dataTable, breadcrumb } = page; + const { dataTable } = page; const adminApiActions = new AdminActions(); const userActions = new UserActions(); @@ -119,75 +119,5 @@ describe('Trash', () => { expect(actualColumns).toEqual(expectedColumns); }); - - it('[C280493] displays the files and folders deleted by everyone', async () => { - expect(await dataTable.isItemPresent(fileAdmin)).toBe(true, `${fileAdmin} not displayed`); - expect(await dataTable.isItemPresent(folderAdmin)).toBe(true, `${folderAdmin} not displayed`); - expect(await dataTable.isItemPresent(fileUser)).toBe(true, `${fileUser} not displayed`); - expect(await dataTable.isItemPresent(folderUser)).toBe(true, `${folderUser} not displayed`); - expect(await dataTable.isItemPresent(fileSite)).toBe(true, `${fileSite} not displayed`); - }); - }); - - describe('as user', () => { - beforeAll(async () => { - await loginPage.loginWith(username); - }); - - beforeEach(async () => { - await page.clickTrashAndWait(); - }); - - it('[C280494] has the correct columns', async () => { - const expectedColumns = ['Name', 'Location', 'Size', 'Deleted']; - const actualColumns = await dataTable.getColumnHeadersText(); - - expect(actualColumns).toEqual(expectedColumns); - }); - - it('[C213218] displays the files and folders deleted by the user', async () => { - expect(await dataTable.getRowsCount()).toEqual(6, 'Incorrect number of deleted items displayed'); - - expect(await dataTable.isItemPresent(fileSite)).toBe(true, `${fileSite} not displayed`); - expect(await dataTable.isItemPresent(fileUser)).toBe(true, `${fileUser} not displayed`); - expect(await dataTable.isItemPresent(folderUser)).toBe(true, `${folderUser} not displayed`); - expect(await dataTable.isItemPresent(fileAdmin)).toBe(false, `${fileAdmin} is displayed`); - }); - - it('[C213219] default sorting column', async () => { - expect(await dataTable.getSortedColumnHeaderText()).toBe('Deleted'); - expect(await dataTable.getSortingOrder()).toBe('desc'); - }); - - it('[C280498] Location column displays the parent folder of the file', async () => { - expect(await dataTable.getItemLocation(fileInFolder)).toEqual(folderNotDeleted); - expect(await dataTable.getItemLocation(fileUser)).toEqual('Personal Files'); - expect(await dataTable.getItemLocation(fileSite)).toEqual(siteName); - }); - - it('[C280499] Location column displays a tooltip with the entire path of the file', async () => { - expect(await dataTable.getItemLocationTooltip(fileInFolder)).toEqual(`Personal Files/${folderNotDeleted}`); - expect(await dataTable.getItemLocationTooltip(fileUser)).toEqual('Personal Files'); - expect(await dataTable.getItemLocationTooltip(fileSite)).toEqual(`File Libraries/${siteName}`); - }); - - it('[C280500] Location column is empty if parent folder no longer exists', async () => { - expect(await dataTable.getItemLocation(fileDeleted)).toEqual(''); - }); - - it('[C217144] Location column redirect - file in user Home', async () => { - await dataTable.clickItemLocation(fileUser); - expect(await breadcrumb.getAllItems()).toEqual(['Personal Files']); - }); - - it('[C280496] Location column redirect - file in folder', async () => { - await dataTable.clickItemLocation(fileInFolder); - expect(await breadcrumb.getAllItems()).toEqual(['Personal Files', folderNotDeleted]); - }); - - it('[C280497] Location column redirect - file in site', async () => { - await dataTable.clickItemLocation(fileSite); - expect(await breadcrumb.getAllItems()).toEqual(['My Libraries', siteName]); - }); }); }); diff --git a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts index aa42857a2e..e651bd52b4 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts @@ -41,7 +41,8 @@ export class DataTableComponent extends BaseComponent { getEmptyContentTitleLocator = this.getChild('adf-empty-content .adf-empty-content__title'); getEmptyContentSubTitleLocator = this.getChild('adf-empty-content .adf-empty-content__subtitle'); getSelectedRow = this.getChild('.adf-datatable-row.adf-is-selected'); - sortedAscColumnHeader = this.getChild('.adf-datatable__header--sorted-asc .adf-datatable-cell-header-content .adf-datatable-cell-value'); + sortedColumnHeader = this.getChild(`.adf-datatable__header--sorted-asc .adf-datatable-cell-header-content .adf-datatable-cell-value, + .adf-datatable__header--sorted-desc .adf-datatable-cell-header-content .adf-datatable-cell-value`); columnHeaders = this.getChild('.adf-datatable-row .adf-datatable-cell-header .adf-datatable-cell-value'); /** Locator for row (or rows) */ @@ -241,7 +242,7 @@ export class DataTableComponent extends BaseComponent { } async getSortedColumnHeaderText(): Promise { - return this.sortedAscColumnHeader.innerText(); + return this.sortedColumnHeader.innerText(); } private getItemLocationEl(name: string): Locator { @@ -262,4 +263,14 @@ export class DataTableComponent extends BaseComponent { async clickItemLocation(name: string): Promise { await this.getItemLocationEl(name).click(); } + + async getSortingOrder(): Promise { + const str = await this.sortedColumnHeader.locator('../..').getAttribute('class'); + if (str.includes('asc')) { + return 'asc'; + }else if (str.includes('desc')) { + return 'desc'; + } + return 'none'; + } } diff --git a/projects/aca-playwright-shared/src/page-objects/pages/trash.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/trash.page.ts index b6a512a8de..09a57e123e 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/trash.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/trash.page.ts @@ -24,7 +24,7 @@ import { Page } from '@playwright/test'; import { BasePage } from './base.page'; -import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent } from '../components'; +import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent, Breadcrumb } from '../components'; import { AcaHeader } from '../components/aca-header.component'; import { AdfFolderDialogComponent, ViewerOverlayDialogComponent } from '../components/dialogs'; @@ -42,4 +42,5 @@ export class TrashPage extends BasePage { public viewer = new ViewerComponent(this.page); public viewerDialog = new ViewerOverlayDialogComponent(this.page); public sidenav = new SidenavComponent(this.page); + public breadcrumb = new Breadcrumb(this.page); } From be2ef586309f47b311d5074694e757c06fcce5a3 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Tue, 5 Dec 2023 17:12:53 +0100 Subject: [PATCH 03/23] e2e test for trash page --- e2e/playwright/list-views/src/tests/trash.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/playwright/list-views/src/tests/trash.test.ts b/e2e/playwright/list-views/src/tests/trash.test.ts index e3638885cb..117c7392b2 100755 --- a/e2e/playwright/list-views/src/tests/trash.test.ts +++ b/e2e/playwright/list-views/src/tests/trash.test.ts @@ -84,7 +84,7 @@ test.describe('Trash', () => { } }); - test.describe.only(`Regular user's personal files`, () => { + test.describe(`Regular user's personal files`, () => { test.beforeEach(async ({ page }) => { const loginPage = new LoginPage(page); try { From bae18775256cb47ea1053e2fe5a6b78412a47f55 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Wed, 6 Dec 2023 12:48:22 +0100 Subject: [PATCH 04/23] e2e test for file-libraries page --- .../list-views/src/tests/favorites.spec.ts | 24 +- .../src/tests/file-libraries.spec.ts | 171 +++++++++++ .../src/tests/personal-files.spec.ts | 24 +- .../tests/{trash.test.ts => trash.spec.ts} | 24 +- .../suites/list-views/file-libraries.test.ts | 234 --------------- .../suites/list-views/tooltips.test.ts | 278 ------------------ .../src/fixtures/page-initialization.ts | 5 + .../dataTable/data-table.component.ts | 6 +- 8 files changed, 205 insertions(+), 561 deletions(-) create mode 100755 e2e/playwright/list-views/src/tests/file-libraries.spec.ts rename e2e/playwright/list-views/src/tests/{trash.test.ts => trash.spec.ts} (92%) delete mode 100755 e2e/protractor/suites/list-views/file-libraries.test.ts delete mode 100755 e2e/protractor/suites/list-views/tooltips.test.ts diff --git a/e2e/playwright/list-views/src/tests/favorites.spec.ts b/e2e/playwright/list-views/src/tests/favorites.spec.ts index 66615de4cd..4a55b761fd 100644 --- a/e2e/playwright/list-views/src/tests/favorites.spec.ts +++ b/e2e/playwright/list-views/src/tests/favorites.spec.ts @@ -79,25 +79,17 @@ test.describe('Favorites Files', () => { test.beforeEach(async ({ page }) => { const loginPage = new LoginPage(page); - try { - await loginPage.loginUser( - { username, password: username }, - { - withNavigation: true, - waitForLoading: true - } - ); - } catch (error) { - console.error(`beforeEach failed : ${error}`); - } + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); }); test.afterAll(async () => { - try { - await nodesApi.deleteCurrentUserNodes(); - } catch (error) { - console.error(`afterAll failed : ${error}`); - } + await nodesApi.deleteCurrentUserNodes(); }); test.describe(`Regular user's Favorites files`, () => { diff --git a/e2e/playwright/list-views/src/tests/file-libraries.spec.ts b/e2e/playwright/list-views/src/tests/file-libraries.spec.ts new file mode 100755 index 0000000000..ae0143445f --- /dev/null +++ b/e2e/playwright/list-views/src/tests/file-libraries.spec.ts @@ -0,0 +1,171 @@ +/*! + * Copyright © 2005-2023 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 { expect } from '@playwright/test'; +import { ApiClientFactory, FavoritesPageApi, LoginPage, SitesApi, Utils, test, timeouts } from '@alfresco/playwright-shared'; +import { Site } from '@alfresco/js-api'; + +test.describe.only('File Libraries', () => { + const apiClientFactory = new ApiClientFactory(); + let siteActionsAdmin: SitesApi; + let siteActionsUser: SitesApi; + let favoritesActions: FavoritesPageApi; + + const username = `user-${Utils.random()}`; + const userSitePrivate = `user-priv-${Utils.random()}`; + const userSiteModerated = `user-mode-${Utils.random()}`; + const userSitePublic = `user-pub-${Utils.random()}`; + const siteName = `siteName-${Utils.random()}`; + + const siteId1 = Utils.random(); + const siteId2 = Utils.random(); + + const adminSite1 = `admin1-${Utils.random()}`; + const adminSite2 = `admin2-${Utils.random()}`; + const adminSite3 = `admin3-${Utils.random()}`; + const adminSite4 = `admin4-${Utils.random()}`; + const adminSite5 = `admin5-${Utils.random()}`; + + const siteDescription = 'my site description'; + + test.beforeAll(async () => { + try { + test.setTimeout(timeouts.extendedTest); + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username }); + siteActionsAdmin = await SitesApi.initialize('admin'); + siteActionsUser = await SitesApi.initialize(username, username); + favoritesActions = await FavoritesPageApi.initialize(username, username); + + await siteActionsUser.createSite(userSitePublic, Site.VisibilityEnum.PUBLIC); + await siteActionsUser.createSite(userSiteModerated, Site.VisibilityEnum.MODERATED, siteDescription); + await siteActionsUser.createSite(userSitePrivate, Site.VisibilityEnum.PRIVATE, null); + + await siteActionsAdmin.createSite(adminSite1, Site.VisibilityEnum.PUBLIC); + await siteActionsAdmin.createSite(adminSite2, Site.VisibilityEnum.PUBLIC); + await siteActionsAdmin.createSite(adminSite3, Site.VisibilityEnum.PUBLIC); + await siteActionsAdmin.createSite(adminSite4, Site.VisibilityEnum.PUBLIC); + await siteActionsAdmin.createSite(adminSite5, Site.VisibilityEnum.PUBLIC); + await siteActionsAdmin.addSiteMember(adminSite1, username, Site.RoleEnum.SiteConsumer); + await siteActionsAdmin.addSiteMember(adminSite2, username, Site.RoleEnum.SiteContributor); + await siteActionsAdmin.addSiteMember(adminSite3, username, Site.RoleEnum.SiteCollaborator); + await siteActionsAdmin.addSiteMember(adminSite4, username, Site.RoleEnum.SiteManager); + await siteActionsAdmin.addSiteMember(adminSite5, username, Site.RoleEnum.SiteConsumer); + + await favoritesActions.addFavoriteById('site', adminSite1); + await favoritesActions.addFavoriteById('site', adminSite2); + await favoritesActions.addFavoriteById('site', adminSite3); + await favoritesActions.addFavoriteById('site', adminSite4); + + await siteActionsUser.createSite(siteName, Site.VisibilityEnum.PUBLIC, null, siteId1); + await siteActionsUser.createSite(siteName, Site.VisibilityEnum.PUBLIC, null, siteId2); + } catch (error) { + console.error(`----- beforeAll failed : ${error}`); + } + }); + + test.afterAll(async () => { + await siteActionsUser.deleteSites([userSitePublic, userSiteModerated, userSitePrivate, siteId1, siteId2]); + await siteActionsAdmin.deleteSites([adminSite1, adminSite2, adminSite3, adminSite4, adminSite5]); + }); + + test.describe('My Libraries', () => { + test.beforeEach(async ({ page, myLibrariesPage }) => { + const loginPage = new LoginPage(page); + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); + await myLibrariesPage.navigate(); + }); + + test('[C217095] has the correct columns', async ({ myLibrariesPage }) => { + const expectedColumns = ['Name', 'Description', 'My Role', 'Visibility']; + const actualColumns = await myLibrariesPage.dataTable.getColumnHeaders(); + expect(actualColumns).toEqual(expectedColumns); + }); + + test('[C289905] Library visibility is correctly displayed', async ({ myLibrariesPage }) => { + const expectedSitesVisibility = { + [userSitePrivate]: Site.VisibilityEnum.PRIVATE, + [userSiteModerated]: Site.VisibilityEnum.MODERATED, + [userSitePublic]: Site.VisibilityEnum.PUBLIC + }; + for (const site of Object.keys(expectedSitesVisibility)) { + const sitesVisibility = await myLibrariesPage.dataTable.getRowAllInnerTexts(site); + expect(sitesVisibility.toLowerCase()).toContain(expectedSitesVisibility[site].toLowerCase()); + } + }); + + test('[C289903] User role is correctly displayed', async ({ myLibrariesPage }) => { + const expectedSitesRoles = { + [adminSite1]: Site.RoleEnum.SiteConsumer, + [adminSite2]: Site.RoleEnum.SiteContributor, + [adminSite3]: Site.RoleEnum.SiteCollaborator, + [adminSite4]: Site.RoleEnum.SiteManager + }; + + for (const site of Object.keys(expectedSitesRoles)) { + const sitesRowNames = await myLibrariesPage.dataTable.getRowAllInnerTexts(site); + expect(sitesRowNames.toLowerCase()).toContain(expectedSitesRoles[site].split('Site')[1].toLowerCase()); + } + }); + + test('[C217098] Site ID is displayed when two sites have the same name', async ({ myLibrariesPage }) => { + const expectedSites = [`${siteName} (${siteId1})`, `${siteName} (${siteId2})`]; + const actualSite1 = await myLibrariesPage.dataTable.getRowAllInnerTexts(siteId1); + expect(actualSite1).toContain(expectedSites[0]); + const actualSite2 = await myLibrariesPage.dataTable.getRowAllInnerTexts(siteId2); + expect(actualSite2).toContain(expectedSites[1]); + }); + }); + + test.describe.only('Favorite Libraries', () => { + test.beforeEach(async ({ page, favoritesLibrariesPage }) => { + const loginPage = new LoginPage(page); + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); + await favoritesLibrariesPage.navigate(); + }); + + test('[C289893] has the correct columns', async ({ favoritesLibrariesPage }) => { + const expectedColumns = ['Name', 'Description', 'My Role', 'Visibility']; + const actualColumns = await favoritesLibrariesPage.dataTable.getColumnHeaders(); + + expect(actualColumns).toEqual(expectedColumns); + }); + + test('[C289897] User can see only his favorite sites', async ({ favoritesLibrariesPage }) => { + expect(await favoritesLibrariesPage.dataTable.isItemPresent(adminSite5), `${adminSite5} should not appear`).toBe(false); + }); + }); +}); diff --git a/e2e/playwright/list-views/src/tests/personal-files.spec.ts b/e2e/playwright/list-views/src/tests/personal-files.spec.ts index a4ae055b2e..85371fe5fb 100644 --- a/e2e/playwright/list-views/src/tests/personal-files.spec.ts +++ b/e2e/playwright/list-views/src/tests/personal-files.spec.ts @@ -43,27 +43,19 @@ test.describe('Personal Files', () => { }); test.afterAll(async () => { - try { - await nodesApi.deleteCurrentUserNodes(); - } catch (error) { - console.error(`afterAll failed : ${error}`); - } + await nodesApi.deleteCurrentUserNodes(); }); test.describe(`Regular user's personal files`, () => { test.beforeEach(async ({ page }) => { const loginPage = new LoginPage(page); - try { - await loginPage.loginUser( - { username, password: username }, - { - withNavigation: true, - waitForLoading: true - } - ); - } catch (error) { - console.error(`beforeEach failed : ${error}`); - } + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); }); test('[C217142] has the correct columns', async ({ personalFiles }) => { diff --git a/e2e/playwright/list-views/src/tests/trash.test.ts b/e2e/playwright/list-views/src/tests/trash.spec.ts similarity index 92% rename from e2e/playwright/list-views/src/tests/trash.test.ts rename to e2e/playwright/list-views/src/tests/trash.spec.ts index 117c7392b2..00cc0191bb 100755 --- a/e2e/playwright/list-views/src/tests/trash.test.ts +++ b/e2e/playwright/list-views/src/tests/trash.spec.ts @@ -77,27 +77,19 @@ test.describe('Trash', () => { }); test.afterAll(async () => { - try { - await nodesApi.deleteCurrentUserNodes(); - } catch (error) { - console.error(`----- afterAll failed : ${error}`); - } + await nodesApi.deleteCurrentUserNodes(); }); test.describe(`Regular user's personal files`, () => { test.beforeEach(async ({ page }) => { const loginPage = new LoginPage(page); - try { - await loginPage.loginUser( - { username, password: username }, - { - withNavigation: true, - waitForLoading: true - } - ); - } catch (error) { - console.error(`beforeEach failed : ${error}`); - } + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); }); test.beforeEach(async ({ trashPage }) => { diff --git a/e2e/protractor/suites/list-views/file-libraries.test.ts b/e2e/protractor/suites/list-views/file-libraries.test.ts deleted file mode 100755 index 7a9bc6dffb..0000000000 --- a/e2e/protractor/suites/list-views/file-libraries.test.ts +++ /dev/null @@ -1,234 +0,0 @@ -/*! - * Copyright © 2005-2023 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 { AdminActions, SITE_VISIBILITY, SITE_ROLES, LoginPage, BrowsingPage, Utils, RepoClient } from '@alfresco/aca-testing-shared'; -import { Logger } from '@alfresco/adf-testing'; - -describe('File Libraries', () => { - const username = `user-${Utils.random()}`; - const password = username; - - const userSitePrivate = `user-private-${Utils.random()}`; - const userSiteModerated = `user-moderated-${Utils.random()}`; - const userSitePublic = `user-public-${Utils.random()}`; - - const siteName = `siteName-${Utils.random()}`; - - const siteId1 = Utils.random(); - const siteId2 = Utils.random(); - - const adminSite1 = `admin1-${Utils.random()}`; - const adminSite2 = `admin2-${Utils.random()}`; - const adminSite3 = `admin3-${Utils.random()}`; - const adminSite4 = `admin4-${Utils.random()}`; - const adminSite5 = `admin5-${Utils.random()}`; - const adminSite6 = `admin6-${Utils.random()}`; - - const siteDescription = 'my site description'; - - const apis = { - user: new RepoClient(username, password) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable } = page; - const adminApiActions = new AdminActions(); - - const sortAlphabetically = (a: string, b: string) => a.localeCompare(b); - const sortAndCompare = (actual: string[], expected: string[]) => { - actual.sort(sortAlphabetically); - expected.sort(sortAlphabetically); - expect(actual).toEqual(expected); - }; - - beforeAll(async () => { - try { - await adminApiActions.createUser({ username }); - - await apis.user.sites.createSite(userSitePublic, SITE_VISIBILITY.PUBLIC); - await apis.user.sites.createSite(userSiteModerated, SITE_VISIBILITY.MODERATED, siteDescription); - await apis.user.sites.createSite(userSitePrivate, SITE_VISIBILITY.PRIVATE, null); - - await adminApiActions.sites.createSite(adminSite1, SITE_VISIBILITY.PUBLIC); - await adminApiActions.sites.createSite(adminSite2, SITE_VISIBILITY.PUBLIC); - await adminApiActions.sites.createSite(adminSite3, SITE_VISIBILITY.PUBLIC); - await adminApiActions.sites.createSite(adminSite4, SITE_VISIBILITY.PUBLIC); - await adminApiActions.sites.createSite(adminSite5, SITE_VISIBILITY.PUBLIC); - await adminApiActions.sites.createSite(adminSite6, SITE_VISIBILITY.PUBLIC); - await adminApiActions.sites.addSiteMember(adminSite1, username, SITE_ROLES.SITE_CONSUMER.ROLE); - await adminApiActions.sites.addSiteMember(adminSite2, username, SITE_ROLES.SITE_CONTRIBUTOR.ROLE); - await adminApiActions.sites.addSiteMember(adminSite3, username, SITE_ROLES.SITE_COLLABORATOR.ROLE); - await adminApiActions.sites.addSiteMember(adminSite4, username, SITE_ROLES.SITE_MANAGER.ROLE); - await adminApiActions.sites.addSiteMember(adminSite6, username, SITE_ROLES.SITE_CONSUMER.ROLE); - - await apis.user.favorites.addFavoriteById('site', adminSite1); - await apis.user.favorites.addFavoriteById('site', adminSite2); - await apis.user.favorites.addFavoriteById('site', adminSite3); - await apis.user.favorites.addFavoriteById('site', adminSite4); - - await apis.user.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC, null, siteId1); - await apis.user.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC, null, siteId2); - - await loginPage.loginWith(username); - } catch (error) { - Logger.error(`----- beforeAll failed : ${error}`); - } - }); - - afterAll(async () => { - await apis.user.sites.deleteSites([userSitePublic, userSiteModerated, userSitePrivate, siteId1, siteId2]); - await adminApiActions.sites.deleteSites([adminSite1, adminSite2, adminSite3, adminSite4, adminSite5, adminSite6]); - }); - - describe('My Libraries', () => { - beforeEach(async () => { - await page.goToMyLibrariesAndWait(); - }); - - it('[C217095] has the correct columns', async () => { - const expectedColumns = ['Name', 'Description', 'My Role', 'Visibility']; - const actualColumns = await dataTable.getColumnHeadersText(); - - await expect(actualColumns).toEqual(expectedColumns); - }); - - it('[C280501] User can see only the sites he is a member of', async () => { - const sitesCount = await dataTable.getRowsCount(); - - expect(sitesCount).toEqual(10, 'Incorrect number of sites displayed'); - expect(await dataTable.isItemPresent(adminSite5)).toBe(false, `${adminSite5} should not appear in the list`); - }); - - it('[C289905] Library visibility is correctly displayed', async () => { - const expectedSitesVisibility = { - [userSitePrivate]: SITE_VISIBILITY.PRIVATE, - [userSiteModerated]: SITE_VISIBILITY.MODERATED, - [userSitePublic]: SITE_VISIBILITY.PUBLIC - }; - - const sitesList = await dataTable.getSitesNameAndVisibility(); - - for (const site of Object.keys(expectedSitesVisibility)) { - expect(sitesList[site]).toEqual(expectedSitesVisibility[site]); - } - }); - - it('[C289903] User role is correctly displayed', async () => { - const expectedSitesRoles = { - [adminSite1]: SITE_ROLES.SITE_CONSUMER.LABEL, - [adminSite2]: SITE_ROLES.SITE_CONTRIBUTOR.LABEL, - [adminSite3]: SITE_ROLES.SITE_COLLABORATOR.LABEL, - [adminSite4]: SITE_ROLES.SITE_MANAGER.LABEL - }; - - const sitesList = await dataTable.getSitesNameAndRole(); - - for (const site of Object.keys(expectedSitesRoles)) { - expect(sitesList[site]).toEqual(expectedSitesRoles[site]); - } - }); - - it('[C217098] Site ID is displayed when two sites have the same name', async () => { - const expectedSites = [`${siteName} (${siteId1})`, `${siteName} (${siteId2})`]; - const actualSites = await dataTable.getCellsContainingName(siteName); - sortAndCompare(actualSites, expectedSites); - }); - - it('[C217096] Tooltip for sites without description', async () => { - const tooltip = await dataTable.getItemNameTooltip(userSitePrivate); - expect(tooltip).toBe(`${userSitePrivate}`); - }); - - it('[C217097] Tooltip for sites with description', async () => { - const tooltip = await dataTable.getItemNameTooltip(userSiteModerated); - expect(tooltip).toBe(`${siteDescription}`); - }); - }); - - describe('Favorite Libraries', () => { - beforeEach(async () => { - await page.goToFavoriteLibrariesAndWait(); - }); - - it('[C289893] has the correct columns', async () => { - const expectedColumns = ['Name', 'Description', 'My Role', 'Visibility']; - const actualColumns = await dataTable.getColumnHeadersText(); - - await expect(actualColumns).toEqual(expectedColumns); - }); - - it('[C289897] User can see only his favorite sites', async () => { - const sitesCount = await dataTable.getRowsCount(); - - expect(sitesCount).toEqual(9, 'Incorrect number of sites displayed'); - expect(await dataTable.isItemPresent(adminSite6)).toBe(false, `${adminSite6} should not appear`); - }); - - it('[C289906] Library visibility is correctly displayed', async () => { - const expectedSitesVisibility = { - [userSitePrivate]: SITE_VISIBILITY.PRIVATE, - [userSiteModerated]: SITE_VISIBILITY.MODERATED, - [userSitePublic]: SITE_VISIBILITY.PUBLIC - }; - - const sitesList = await dataTable.getSitesNameAndVisibility(); - - for (const site of Object.keys(expectedSitesVisibility)) { - expect(sitesList[site]).toEqual(expectedSitesVisibility[site]); - } - }); - - it('[C289904] User role is correctly displayed', async () => { - const expectedSitesRoles = { - [adminSite1]: SITE_ROLES.SITE_CONSUMER.LABEL, - [adminSite2]: SITE_ROLES.SITE_CONTRIBUTOR.LABEL, - [adminSite3]: SITE_ROLES.SITE_COLLABORATOR.LABEL, - [adminSite4]: SITE_ROLES.SITE_MANAGER.LABEL - }; - - const sitesList = await dataTable.getSitesNameAndRole(); - - for (const site of Object.keys(expectedSitesRoles)) { - expect(sitesList[site]).toEqual(expectedSitesRoles[site]); - } - }); - - it('[C289896] Site ID is displayed when two sites have the same name', async () => { - const expectedSites = [`${siteName} (${siteId1})`, `${siteName} (${siteId2})`]; - const actualSites = await dataTable.getCellsContainingName(siteName); - sortAndCompare(actualSites, expectedSites); - }); - - it('[C289894] Tooltip for sites without description', async () => { - const tooltip = await dataTable.getItemNameTooltip(userSitePrivate); - expect(tooltip).toBe(`${userSitePrivate}`); - }); - - it('[C289895] Tooltip for sites with description', async () => { - const tooltip = await dataTable.getItemNameTooltip(userSiteModerated); - expect(tooltip).toBe(`${siteDescription}`); - }); - }); -}); diff --git a/e2e/protractor/suites/list-views/tooltips.test.ts b/e2e/protractor/suites/list-views/tooltips.test.ts deleted file mode 100755 index 91702247bb..0000000000 --- a/e2e/protractor/suites/list-views/tooltips.test.ts +++ /dev/null @@ -1,278 +0,0 @@ -/*! - * Copyright © 2005-2023 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 { AdminActions, UserActions, LoginPage, BrowsingPage, Utils, RepoClient } from '@alfresco/aca-testing-shared'; - -describe('File / folder tooltips', () => { - const username = `user-${Utils.random()}`; - - const apis = { - user: new RepoClient(username, username) - }; - - const parent = `parent-${Utils.random()}`; - - const file = `file1-${Utils.random()}`; - const fileWithDesc = `file2-${Utils.random()}`; - const fileWithTitle = `file3-${Utils.random()}`; - const fileWithTitleAndDesc = `file4-${Utils.random()}`; - const fileNameEqTitleEqDesc = `file5-${Utils.random()}`; - const fileNameEqTitleDiffDesc = `file6-${Utils.random()}`; - const fileNameEqDescDiffTitle = `file7-${Utils.random()}`; - const fileTitleEqDesc = `file8-${Utils.random()}`; - let parentId: string; - let file1Id: string; - let file2Id: string; - let file3Id: string; - let file4Id: string; - let file5Id: string; - let file6Id: string; - let file7Id: string; - let file8Id: string; - - const fileTitle = 'file title'; - const fileDescription = 'file description'; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable } = page; - - const adminApiActions = new AdminActions(); - const userActions = new UserActions(); - - beforeAll(async () => { - await adminApiActions.createUser({ username }); - - parentId = (await apis.user.nodes.createFolder(parent)).entry.id; - - file1Id = (await apis.user.nodes.createFile(file, parentId)).entry.id; - file2Id = (await apis.user.nodes.createFile(fileWithDesc, parentId, '', fileDescription)).entry.id; - file3Id = (await apis.user.nodes.createFile(fileWithTitle, parentId, fileTitle)).entry.id; - file4Id = (await apis.user.nodes.createFile(fileWithTitleAndDesc, parentId, fileTitle, fileDescription)).entry.id; - file5Id = (await apis.user.nodes.createFile(fileNameEqTitleEqDesc, parentId, fileNameEqTitleEqDesc, fileNameEqTitleEqDesc)).entry.id; - file6Id = (await apis.user.nodes.createFile(fileNameEqTitleDiffDesc, parentId, fileNameEqTitleDiffDesc, fileDescription)).entry.id; - file7Id = (await apis.user.nodes.createFile(fileNameEqDescDiffTitle, parentId, fileTitle, fileNameEqDescDiffTitle)).entry.id; - file8Id = (await apis.user.nodes.createFile(fileTitleEqDesc, parentId, fileTitle, fileTitle)).entry.id; - - await apis.user.shared.shareFilesByIds([file1Id, file2Id, file3Id, file4Id, file5Id, file6Id, file7Id, file8Id]); - await apis.user.favorites.addFavoritesByIds('file', [file1Id, file2Id, file3Id, file4Id, file5Id, file6Id, file7Id, file8Id]); - - await apis.user.shared.waitForFilesToBeShared([file1Id, file2Id, file3Id, file4Id, file5Id, file6Id, file7Id, file8Id]); - - await loginPage.loginWith(username); - }); - - afterAll(async () => { - await userActions.login(username, username); - await userActions.deleteNodes([parentId]); - await userActions.emptyTrashcan(); - }); - - describe('on Personal Files', () => { - beforeAll(async () => { - await page.clickPersonalFilesAndWait(); - await dataTable.doubleClickOnRowByName(parent); - }); - - it('[C255871] File with name, no title, no description', async () => { - expect(await dataTable.getItemNameTooltip(file)).toEqual(`${file}`); - }); - - it('[C255872] File with name and description, no title', async () => { - expect(await dataTable.getItemNameTooltip(fileWithDesc)).toEqual(`${fileWithDesc}\n${fileDescription}`); - }); - - it('[C255873] File with name and title, no description', async () => { - expect(await dataTable.getItemNameTooltip(fileWithTitle)).toEqual(`${fileWithTitle}\n${fileTitle}`); - }); - - it('[C255874] File with name and title and description, all different', async () => { - expect(await dataTable.getItemNameTooltip(fileWithTitleAndDesc)).toEqual(`${fileTitle}\n${fileDescription}`); - }); - - it('[C255875] File with name and title and description, all equal', async () => { - expect(await dataTable.getItemNameTooltip(fileNameEqTitleEqDesc)).toEqual(`${fileNameEqTitleEqDesc}`); - }); - - it('[C255876] File with name = title, different description', async () => { - expect(await dataTable.getItemNameTooltip(fileNameEqTitleDiffDesc)).toEqual(`${fileNameEqTitleDiffDesc}\n${fileDescription}`); - }); - - it('[C255877] File with name = description, different title', async () => { - expect(await dataTable.getItemNameTooltip(fileNameEqDescDiffTitle)).toEqual(`${fileTitle}\n${fileNameEqDescDiffTitle}`); - }); - - it('[C255878] File with title = description, different name', async () => { - expect(await dataTable.getItemNameTooltip(fileTitleEqDesc)).toEqual(`${fileTitle}`); - }); - }); - - describe('on Recent Files', () => { - beforeAll(async () => { - await apis.user.search.waitForApi(username, { expect: 8 }); - await page.clickRecentFilesAndWait(); - }); - - it('[C280135] File with name, no title, no description', async () => { - expect(await dataTable.getItemNameTooltip(file)).toEqual(`${file}`); - }); - - it('[C280136] File with name and description, no title', async () => { - expect(await dataTable.getItemNameTooltip(fileWithDesc)).toEqual(`${fileWithDesc}\n${fileDescription}`); - }); - - it('[C280137] File with name and title, no description', async () => { - expect(await dataTable.getItemNameTooltip(fileWithTitle)).toEqual(`${fileWithTitle}\n${fileTitle}`); - }); - - it('[C280138] File with name and title and description, all different', async () => { - expect(await dataTable.getItemNameTooltip(fileWithTitleAndDesc)).toEqual(`${fileTitle}\n${fileDescription}`); - }); - - it('[C280139] File with name and title and description, all equal', async () => { - expect(await dataTable.getItemNameTooltip(fileNameEqTitleEqDesc)).toEqual(`${fileNameEqTitleEqDesc}`); - }); - - it('[C280140] File with name = title, different description', async () => { - expect(await dataTable.getItemNameTooltip(fileNameEqTitleDiffDesc)).toEqual(`${fileNameEqTitleDiffDesc}\n${fileDescription}`); - }); - - it('[C280141] File with name = description, different title', async () => { - expect(await dataTable.getItemNameTooltip(fileNameEqDescDiffTitle)).toEqual(`${fileTitle}\n${fileNameEqDescDiffTitle}`); - }); - - it('[C280142] File with title = description, different name', async () => { - expect(await dataTable.getItemNameTooltip(fileTitleEqDesc)).toEqual(`${fileTitle}`); - }); - }); - - describe('on Favorites', () => { - beforeAll(async () => { - await page.clickFavoritesAndWait(); - }); - - it('[C280151] File with name, no title, no description', async () => { - expect(await dataTable.getItemNameTooltip(file)).toEqual(`${file}`); - }); - - it('[C280152] File with name and description, no title', async () => { - expect(await dataTable.getItemNameTooltip(fileWithDesc)).toEqual(`${fileWithDesc}\n${fileDescription}`); - }); - - it('[C280153] File with name and title, no description', async () => { - expect(await dataTable.getItemNameTooltip(fileWithTitle)).toEqual(`${fileWithTitle}\n${fileTitle}`); - }); - - it('[C280154] File with name and title and description, all different', async () => { - expect(await dataTable.getItemNameTooltip(fileWithTitleAndDesc)).toEqual(`${fileTitle}\n${fileDescription}`); - }); - - it('[C280155] File with name and title and description, all equal', async () => { - expect(await dataTable.getItemNameTooltip(fileNameEqTitleEqDesc)).toEqual(`${fileNameEqTitleEqDesc}`); - }); - - it('[C280156] File with name = title, different description', async () => { - expect(await dataTable.getItemNameTooltip(fileNameEqTitleDiffDesc)).toEqual(`${fileNameEqTitleDiffDesc}\n${fileDescription}`); - }); - - it('[C280157] File with name = description, different title', async () => { - expect(await dataTable.getItemNameTooltip(fileNameEqDescDiffTitle)).toEqual(`${fileTitle}\n${fileNameEqDescDiffTitle}`); - }); - - it('[C280158] File with title = description, different name', async () => { - expect(await dataTable.getItemNameTooltip(fileTitleEqDesc)).toEqual(`${fileTitle}`); - }); - }); - - describe('on Trash', () => { - const parentForTrash = `parent-${Utils.random()}`; - let parentForTrashId: string; - let file1TrashId: string; - let file2TrashId: string; - let file3TrashId: string; - let file4TrashId: string; - let file5TrashId: string; - let file6TrashId: string; - let file7TrashId: string; - let file8TrashId: string; - - beforeAll(async () => { - parentForTrashId = (await apis.user.nodes.createFolder(parentForTrash)).entry.id; - file1TrashId = (await apis.user.nodes.createFile(file, parentForTrashId)).entry.id; - file2TrashId = (await apis.user.nodes.createFile(fileWithDesc, parentForTrashId, '', fileDescription)).entry.id; - file3TrashId = (await apis.user.nodes.createFile(fileWithTitle, parentForTrashId, fileTitle)).entry.id; - file4TrashId = (await apis.user.nodes.createFile(fileWithTitleAndDesc, parentForTrashId, fileTitle, fileDescription)).entry.id; - file5TrashId = (await apis.user.nodes.createFile(fileNameEqTitleEqDesc, parentForTrashId, fileNameEqTitleEqDesc, fileNameEqTitleEqDesc)).entry - .id; - file6TrashId = (await apis.user.nodes.createFile(fileNameEqTitleDiffDesc, parentForTrashId, fileNameEqTitleDiffDesc, fileDescription)).entry.id; - file7TrashId = (await apis.user.nodes.createFile(fileNameEqDescDiffTitle, parentForTrashId, fileTitle, fileNameEqDescDiffTitle)).entry.id; - file8TrashId = (await apis.user.nodes.createFile(fileTitleEqDesc, parentForTrashId, fileTitle, fileTitle)).entry.id; - - await apis.user.nodes.deleteNodesById( - [file1TrashId, file2TrashId, file3TrashId, file4TrashId, file5TrashId, file6TrashId, file7TrashId, file8TrashId], - false - ); - - await page.clickTrashAndWait(); - }); - - afterAll(async () => { - await userActions.login(username, username); - await userActions.deleteNodes([parentForTrashId]); - await userActions.emptyTrashcan(); - }); - - it('[C280159] File with name, no title, no description', async () => { - expect(await dataTable.getItemNameTooltip(file)).toEqual(`${file}`); - }); - - it('[C280160] File with name and description, no title', async () => { - expect(await dataTable.getItemNameTooltip(fileWithDesc)).toEqual(`${fileWithDesc}\n${fileDescription}`); - }); - - it('[C280161] File with name and title, no description', async () => { - expect(await dataTable.getItemNameTooltip(fileWithTitle)).toEqual(`${fileWithTitle}\n${fileTitle}`); - }); - - it('[C280162] File with name and title and description, all different', async () => { - expect(await dataTable.getItemNameTooltip(fileWithTitleAndDesc)).toEqual(`${fileTitle}\n${fileDescription}`); - }); - - it('[C280163] File with name and title and description, all equal', async () => { - expect(await dataTable.getItemNameTooltip(fileNameEqTitleEqDesc)).toEqual(`${fileNameEqTitleEqDesc}`); - }); - - it('[C280164] File with name = title, different description', async () => { - expect(await dataTable.getItemNameTooltip(fileNameEqTitleDiffDesc)).toEqual(`${fileNameEqTitleDiffDesc}\n${fileDescription}`); - }); - - it('[C280165] File with name = description, different title', async () => { - expect(await dataTable.getItemNameTooltip(fileNameEqDescDiffTitle)).toEqual(`${fileTitle}\n${fileNameEqDescDiffTitle}`); - }); - - it('[C280166] File with title = description, different name', async () => { - expect(await dataTable.getItemNameTooltip(fileTitleEqDesc)).toEqual(`${fileTitle}`); - }); - }); -}); diff --git a/projects/aca-playwright-shared/src/fixtures/page-initialization.ts b/projects/aca-playwright-shared/src/fixtures/page-initialization.ts index 39ba021cad..2e7fa81610 100644 --- a/projects/aca-playwright-shared/src/fixtures/page-initialization.ts +++ b/projects/aca-playwright-shared/src/fixtures/page-initialization.ts @@ -33,6 +33,7 @@ import { SharedPage, SearchPage, FavoritesPage, + FavoritesLibrariesPage, FavoritesPageApi, TrashPage, LoginPage, @@ -49,6 +50,7 @@ interface Pages { sharedPage: SharedPage; searchPage: SearchPage; favoritePage: FavoritesPage; + favoritesLibrariesPage: FavoritesLibrariesPage; trashPage: TrashPage; loginPage: LoginPage; } @@ -80,6 +82,9 @@ export const test = base.extend({ favoritePage: async ({ page }, use) => { await use(new FavoritesPage(page)); }, + favoritesLibrariesPage: async ({ page }, use) => { + await use(new FavoritesLibrariesPage(page)); + }, trashPage: async ({ page }, use) => { await use(new TrashPage(page)); }, diff --git a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts index e651bd52b4..9cce9b59e4 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts @@ -268,9 +268,13 @@ export class DataTableComponent extends BaseComponent { const str = await this.sortedColumnHeader.locator('../..').getAttribute('class'); if (str.includes('asc')) { return 'asc'; - }else if (str.includes('desc')) { + } else if (str.includes('desc')) { return 'desc'; } return 'none'; } + + async getRowAllInnerTexts(name: string): Promise { + return (await this.getRowByName(name).locator('span').allInnerTexts()).toString(); + } } From 13b54fee0653e3d0bf9f350e9ed51dc56c76a66f Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Wed, 6 Dec 2023 13:06:37 +0100 Subject: [PATCH 05/23] e2e test for file-libraries page fix --- .../aca-playwright-shared/src/fixtures/page-initialization.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/aca-playwright-shared/src/fixtures/page-initialization.ts b/projects/aca-playwright-shared/src/fixtures/page-initialization.ts index 2e7fa81610..f2bf490072 100644 --- a/projects/aca-playwright-shared/src/fixtures/page-initialization.ts +++ b/projects/aca-playwright-shared/src/fixtures/page-initialization.ts @@ -33,13 +33,13 @@ import { SharedPage, SearchPage, FavoritesPage, - FavoritesLibrariesPage, FavoritesPageApi, TrashPage, LoginPage, NodesApi, SitesApi, - users + users, + FavoritesLibrariesPage } from '../'; interface Pages { From 6ef8b9d66d7506f9854b0c6b178bd9e7381e132e Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Wed, 6 Dec 2023 16:27:07 +0100 Subject: [PATCH 06/23] e2e test for file-libraries page fix --- e2e/playwright/list-views/src/tests/file-libraries.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/playwright/list-views/src/tests/file-libraries.spec.ts b/e2e/playwright/list-views/src/tests/file-libraries.spec.ts index ae0143445f..d0b6eeefed 100755 --- a/e2e/playwright/list-views/src/tests/file-libraries.spec.ts +++ b/e2e/playwright/list-views/src/tests/file-libraries.spec.ts @@ -26,7 +26,7 @@ import { expect } from '@playwright/test'; import { ApiClientFactory, FavoritesPageApi, LoginPage, SitesApi, Utils, test, timeouts } from '@alfresco/playwright-shared'; import { Site } from '@alfresco/js-api'; -test.describe.only('File Libraries', () => { +test.describe('File Libraries', () => { const apiClientFactory = new ApiClientFactory(); let siteActionsAdmin: SitesApi; let siteActionsUser: SitesApi; @@ -144,7 +144,7 @@ test.describe.only('File Libraries', () => { }); }); - test.describe.only('Favorite Libraries', () => { + test.describe('Favorite Libraries', () => { test.beforeEach(async ({ page, favoritesLibrariesPage }) => { const loginPage = new LoginPage(page); await loginPage.loginUser( From 3f3d03de912df48b8546804cefddd2ad2d416298 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Thu, 7 Dec 2023 16:21:18 +0100 Subject: [PATCH 07/23] e2e test shared recent page --- .../list-views/src/tests/recent-files.spec.ts | 121 +++++++++++++++ .../list-views/src/tests/shared-files.spec.ts | 140 +++++++++++++++++ .../suites/list-views/recent-files.test.ts | 134 ----------------- .../suites/list-views/shared-files.test.ts | 141 ------------------ .../src/api/shared-links-api.ts | 45 +++++- .../page-objects/pages/recent-files.page.ts | 3 +- .../src/page-objects/pages/shared.page.ts | 3 +- 7 files changed, 309 insertions(+), 278 deletions(-) create mode 100755 e2e/playwright/list-views/src/tests/recent-files.spec.ts create mode 100644 e2e/playwright/list-views/src/tests/shared-files.spec.ts delete mode 100755 e2e/protractor/suites/list-views/recent-files.test.ts delete mode 100755 e2e/protractor/suites/list-views/shared-files.test.ts diff --git a/e2e/playwright/list-views/src/tests/recent-files.spec.ts b/e2e/playwright/list-views/src/tests/recent-files.spec.ts new file mode 100755 index 0000000000..f7ba925973 --- /dev/null +++ b/e2e/playwright/list-views/src/tests/recent-files.spec.ts @@ -0,0 +1,121 @@ +/*! + * Copyright © 2005-2023 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 { expect } from '@playwright/test'; +import { ApiClientFactory, LoginPage, NodesApi, SearchPageApi, SitesApi, TrashcanApi, Utils, test } from '@alfresco/playwright-shared'; +import { Site } from '@alfresco/js-api'; + +test.describe('Recent Files', () => { + const apiClientFactory = new ApiClientFactory(); + let nodeActionsUser: NodesApi; + let siteActionsUser: SitesApi; + const username = `user-${Utils.random()}`; + + const folderName = `folder-${Utils.random()}`; + let folderId: string; + const fileName1 = `file-${Utils.random()}.txt`; + const fileName2 = `file-${Utils.random()}.txt`; + let file2Id: string; + const fileName3 = `file-${Utils.random()}.txt`; + + const siteName = `site-${Utils.random()}`; + const folderSite = `folder2-${Utils.random()}`; + let folderSiteId: string; + const fileSite = `file-${Utils.random()}.txt`; + + test.beforeAll(async () => { + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username }); + nodeActionsUser = await NodesApi.initialize(username, username); + siteActionsUser = await SitesApi.initialize(username, username); + + folderId = (await nodeActionsUser.createFolder(folderName)).entry.id; + await nodeActionsUser.createFiles([fileName1], folderName); + file2Id = (await nodeActionsUser.createFile(fileName2)).entry.id; + const id = (await nodeActionsUser.createFile(fileName3)).entry.id; + + await nodeActionsUser.deleteNodes([id], false); + + await siteActionsUser.createSite(siteName, Site.VisibilityEnum.PUBLIC); + const docLibId = await siteActionsUser.getDocLibId(siteName); + folderSiteId = (await nodeActionsUser.createFolder(folderSite, docLibId)).entry.id; + await nodeActionsUser.createFile(fileSite, folderSiteId); + + const searchApi = await SearchPageApi.initialize(username, username); + await searchApi.waitForApi(username, { expect: 3 }); + }); + + test.beforeEach(async ({ page, recentFilesPage }) => { + const loginPage = new LoginPage(page); + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); + await recentFilesPage.navigate(); + }); + + test.afterAll(async () => { + await nodeActionsUser.deleteNodes([folderId, file2Id]); + await siteActionsUser.deleteSites([siteName]); + const trashcanApi = await TrashcanApi.initialize(username, username); + await trashcanApi.emptyTrashcan(); + }); + + test('[C213168] has the correct columns', async ({ recentFilesPage }) => { + const expectedColumns = ['Name', 'Location', 'Size', 'Modified', 'Tags']; + const actualColumns = await recentFilesPage.dataTable.getColumnHeaders(); + + await expect(actualColumns).toEqual(expectedColumns); + }); + + test('[C213171] default sorting column', async ({ recentFilesPage }) => { + expect(await recentFilesPage.dataTable.getSortedColumnHeaderText()).toBe('Modified'); + expect(await recentFilesPage.dataTable.getSortingOrder()).toBe('desc'); + }); + + test(`[C213174] file not displayed if it's been deleted`, async ({ recentFilesPage }) => { + expect(await recentFilesPage.dataTable.isItemPresent(fileName3), `${fileName3} is displayed`).not.toBe(true); + }); + + test('[C213176] Location column redirect - file in user Home', async ({ recentFilesPage }) => { + await recentFilesPage.dataTable.clickItemLocation(fileName2); + await recentFilesPage.dataTable.spinnerWaitForReload(); + expect(await recentFilesPage.breadcrumb.getAllItems()).toEqual(['Personal Files']); + }); + + test('[C280486] Location column redirect - file in folder', async ({ recentFilesPage }) => { + await recentFilesPage.dataTable.clickItemLocation(fileName1); + await recentFilesPage.dataTable.spinnerWaitForReload(); + expect(await recentFilesPage.breadcrumb.getAllItems()).toEqual(['Personal Files', folderName]); + }); + + test('[C280487] Location column redirect - file in site', async ({ recentFilesPage }) => { + await recentFilesPage.dataTable.clickItemLocation(fileSite); + await recentFilesPage.dataTable.spinnerWaitForReload(); + expect(await recentFilesPage.breadcrumb.getAllItems()).toEqual(['My Libraries', siteName, folderSite]); + }); +}); diff --git a/e2e/playwright/list-views/src/tests/shared-files.spec.ts b/e2e/playwright/list-views/src/tests/shared-files.spec.ts new file mode 100644 index 0000000000..d955098519 --- /dev/null +++ b/e2e/playwright/list-views/src/tests/shared-files.spec.ts @@ -0,0 +1,140 @@ +/*! + * Copyright © 2005-2023 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 { expect } from '@playwright/test'; +import { ApiClientFactory, LoginPage, NodesApi, Utils, test, SitesApi, timeouts, SharedLinksApi } from '@alfresco/playwright-shared'; +import { Site } from '@alfresco/js-api'; + +test.describe.only('Shared Files', () => { + const apiClientFactory = new ApiClientFactory(); + let nodesApi: NodesApi; + let nodesApiAdmin: NodesApi; + let siteActionsAdmin: SitesApi; + let shareActionsAdmin: SharedLinksApi; + let shareActions: SharedLinksApi; + const username = `user-${Utils.random()}`; + + const siteName = `site-${Utils.random()}`; + const fileAdmin = `fileSite-${Utils.random()}.txt`; + + const folderUser = `folder-${Utils.random()}`; + let folderId: string; + const file1User = `file1-${Utils.random()}.txt`; + let file1Id: string; + const file2User = `file2-${Utils.random()}.txt`; + let file2Id: string; + const file3User = `file3-${Utils.random()}.txt`; + let file3Id: string; + const file4User = `file4-${Utils.random()}.txt`; + let file4Id: string; + + test.beforeAll(async () => { + test.setTimeout(timeouts.extendedTest); + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username }); + siteActionsAdmin = await SitesApi.initialize('admin'); + nodesApiAdmin = await NodesApi.initialize('admin'); + shareActionsAdmin = await SharedLinksApi.initialize('admin'); + nodesApi = await NodesApi.initialize(username, username); + shareActions = await SharedLinksApi.initialize(username, username); + + await siteActionsAdmin.createSite(siteName, Site.VisibilityEnum.PUBLIC); + await siteActionsAdmin.addSiteMember(siteName, username, Site.RoleEnum.SiteConsumer); + const docLibId = await siteActionsAdmin.getDocLibId(siteName); + const nodeId = (await nodesApiAdmin.createFile(fileAdmin, docLibId)).entry.id; + + await shareActionsAdmin.shareFileById(nodeId); + await shareActionsAdmin.waitForFilesToBeShared([nodeId]); + + folderId = (await nodesApi.createFolder(folderUser)).entry.id; + file1Id = (await nodesApi.createFile(file1User, folderId)).entry.id; + file2Id = (await nodesApi.createFile(file2User)).entry.id; + file3Id = (await nodesApi.createFile(file3User)).entry.id; + file4Id = (await nodesApi.createFile(file4User)).entry.id; + + await shareActions.shareFilesByIds([file1Id, file2Id, file3Id, file4Id]); + await shareActions.waitForFilesToBeShared([file1Id, file2Id, file3Id, file4Id]); + + await nodesApi.deleteNodeById(file2Id); + await shareActions.unshareFileById(file3Id); + + await shareActions.waitForFilesToNotBeShared([file2Id, file3Id]); + }); + + test.beforeEach(async ({ page, sharedPage }) => { + const loginPage = new LoginPage(page); + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); + await sharedPage.navigate(); + }); + + test.afterAll(async () => { + await siteActionsAdmin.deleteSites([siteName]); + await nodesApi.deleteNodeById(folderId); + await nodesApi.deleteNodeById(file4Id); + }); + + test('[C213113] has the correct columns', async ({ sharedPage }) => { + const expectedColumns = ['Name', 'Location', 'Size', 'Modified', 'Modified by', 'Shared by', 'Tags']; + const actualColumns = await sharedPage.dataTable.getColumnHeaders(); + + await expect(actualColumns).toEqual(expectedColumns); + }); + + test('[C213115] default sorting column', async ({ sharedPage }) => { + expect(await sharedPage.dataTable.getSortedColumnHeaderText()).toBe('Modified'); + expect(await sharedPage.dataTable.getSortingOrder()).toBe('desc'); + }); + + test(`[C213117] file not displayed if it's been deleted`, async ({ sharedPage }) => { + expect(await sharedPage.dataTable.isItemPresent(file2User), `${file2User} is displayed`).toBe(false); + }); + + test('[C213118] unshared file is not displayed', async ({ sharedPage }) => { + expect(await sharedPage.dataTable.isItemPresent(file3User), `${file3User} is displayed`).toBe(false); + }); + + test('[C213666] Location column redirect - file in user Home', async ({ sharedPage }) => { + await sharedPage.dataTable.clickItemLocation(file4User); + await sharedPage.dataTable.spinnerWaitForReload(); + expect(await sharedPage.breadcrumb.getAllItems()).toEqual(['Personal Files']); + }); + + test('[C280490] Location column redirect - file in folder', async ({ sharedPage }) => { + await sharedPage.dataTable.clickItemLocation(file1User); + await sharedPage.dataTable.spinnerWaitForReload(); + expect(await sharedPage.breadcrumb.getAllItems()).toEqual(['Personal Files', folderUser]); + }); + + test('[C280491] Location column redirect - file in site', async ({ sharedPage }) => { + await sharedPage.dataTable.clickItemLocation(fileAdmin); + await sharedPage.dataTable.spinnerWaitForReload(); + expect(await sharedPage.breadcrumb.getAllItems()).toEqual(['My Libraries', siteName]); + }); +}); diff --git a/e2e/protractor/suites/list-views/recent-files.test.ts b/e2e/protractor/suites/list-views/recent-files.test.ts deleted file mode 100755 index 5a9231878f..0000000000 --- a/e2e/protractor/suites/list-views/recent-files.test.ts +++ /dev/null @@ -1,134 +0,0 @@ -/*! - * Copyright © 2005-2023 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 { AdminActions, UserActions, SITE_VISIBILITY, LoginPage, BrowsingPage, Utils, RepoClient } from '@alfresco/aca-testing-shared'; - -describe('Recent Files', () => { - const username = `user-${Utils.random()}`; - - const folderName = `folder-${Utils.random()}`; - let folderId: string; - const fileName1 = `file-${Utils.random()}.txt`; - const fileName2 = `file-${Utils.random()}.txt`; - let file2Id: string; - const fileName3 = `file-${Utils.random()}.txt`; - - const siteName = `site-${Utils.random()}`; - const folderSite = `folder2-${Utils.random()}`; - let folderSiteId: string; - const fileSite = `file-${Utils.random()}.txt`; - - const apis = { - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable, breadcrumb } = page; - - const adminApiActions = new AdminActions(); - const userActions = new UserActions(); - - beforeAll(async () => { - await adminApiActions.createUser({ username }); - - folderId = (await apis.user.nodes.createFolders([folderName])).entry.id; - await apis.user.nodes.createFiles([fileName1], folderName); - file2Id = (await apis.user.nodes.createFiles([fileName2])).entry.id; - const id = (await apis.user.nodes.createFiles([fileName3])).entry.id; - - await userActions.login(username, username); - await userActions.deleteNodes([id], false); - - await apis.user.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC); - const docLibId = await apis.user.sites.getDocLibId(siteName); - folderSiteId = (await apis.user.nodes.createFolder(folderSite, docLibId)).entry.id; - await apis.user.nodes.createFile(fileSite, folderSiteId); - - await apis.user.search.waitForApi(username, { expect: 3 }); - - await loginPage.loginWith(username); - }); - - beforeEach(async () => { - await page.clickRecentFilesAndWait(); - }); - - afterAll(async () => { - await userActions.login(username, username); - await userActions.deleteNodes([folderId, file2Id]); - await userActions.deleteSites([siteName]); - await userActions.emptyTrashcan(); - }); - - it('[C213168] has the correct columns', async () => { - const expectedColumns = ['Name', 'Location', 'Size', 'Modified', 'Tags']; - const actualColumns = await dataTable.getColumnHeadersText(); - - await expect(actualColumns).toEqual(expectedColumns); - }); - - it('[C213171] default sorting column', async () => { - expect(await dataTable.getSortedColumnHeaderText()).toBe('Modified'); - expect(await dataTable.getSortingOrder()).toBe('desc'); - }); - - it('[C213170] displays the files added by the current user in the last 30 days', async () => { - expect(await dataTable.getRowsCount()).toEqual(3, 'Incorrect number of files displayed'); - expect(await dataTable.isItemPresent(fileName1)).toBe(true, `${fileName1} not displayed`); - expect(await dataTable.isItemPresent(fileName2)).toBe(true, `${fileName2} not displayed`); - expect(await dataTable.isItemPresent(fileSite)).toBe(true, `${fileSite} not displayed`); - }); - - it(`[C213174] file not displayed if it's been deleted`, async () => { - expect(await dataTable.isItemPresent(fileName3)).not.toBe(true, `${fileName3} is displayed`); - }); - - it('[C213175] Location column displays the parent folder of the file', async () => { - expect(await dataTable.getItemLocation(fileName1)).toEqual(folderName); - expect(await dataTable.getItemLocation(fileName2)).toEqual('Personal Files'); - expect(await dataTable.getItemLocation(fileSite)).toEqual(folderSite); - }); - - it('[C213177] Location column displays a tooltip with the entire path of the file', async () => { - expect(await dataTable.getItemLocationTooltip(fileName1)).toEqual(`Personal Files/${folderName}`); - expect(await dataTable.getItemLocationTooltip(fileName2)).toEqual('Personal Files'); - expect(await dataTable.getItemLocationTooltip(fileSite)).toEqual(`File Libraries/${siteName}/${folderSite}`); - }); - - it('[C213176] Location column redirect - file in user Home', async () => { - await dataTable.clickItemLocation(fileName2); - expect(await breadcrumb.getAllItems()).toEqual(['Personal Files']); - }); - - it('[C280486] Location column redirect - file in folder', async () => { - await dataTable.clickItemLocation(fileName1); - expect(await breadcrumb.getAllItems()).toEqual(['Personal Files', folderName]); - }); - - it('[C280487] Location column redirect - file in site', async () => { - await dataTable.clickItemLocation(fileSite); - expect(await breadcrumb.getAllItems()).toEqual(['My Libraries', siteName, folderSite]); - }); -}); diff --git a/e2e/protractor/suites/list-views/shared-files.test.ts b/e2e/protractor/suites/list-views/shared-files.test.ts deleted file mode 100755 index 27b93a4aa7..0000000000 --- a/e2e/protractor/suites/list-views/shared-files.test.ts +++ /dev/null @@ -1,141 +0,0 @@ -/*! - * Copyright © 2005-2023 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 { AdminActions, SITE_VISIBILITY, SITE_ROLES, LoginPage, BrowsingPage, Utils, RepoClient } from '@alfresco/aca-testing-shared'; - -describe('Shared Files', () => { - const username = `user-${Utils.random()}`; - const password = username; - - const siteName = `site-${Utils.random()}`; - const fileAdmin = `fileSite-${Utils.random()}.txt`; - - const folderUser = `folder-${Utils.random()}`; - let folderId: string; - const file1User = `file1-${Utils.random()}.txt`; - let file1Id: string; - const file2User = `file2-${Utils.random()}.txt`; - let file2Id: string; - const file3User = `file3-${Utils.random()}.txt`; - let file3Id: string; - const file4User = `file4-${Utils.random()}.txt`; - let file4Id: string; - - const apis = { - user: new RepoClient(username, password) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable, breadcrumb } = page; - const adminApiActions = new AdminActions(); - - beforeAll(async () => { - await adminApiActions.createUser({ username }); - await adminApiActions.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC); - await adminApiActions.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_CONSUMER.ROLE); - const docLibId = await adminApiActions.sites.getDocLibId(siteName); - const nodeId = (await adminApiActions.nodes.createFile(fileAdmin, docLibId)).entry.id; - - await adminApiActions.shareNodes([nodeId]); - await adminApiActions.shared.waitForFilesToBeShared([nodeId]); - - folderId = (await apis.user.nodes.createFolder(folderUser)).entry.id; - file1Id = (await apis.user.nodes.createFile(file1User, folderId)).entry.id; - file2Id = (await apis.user.nodes.createFile(file2User)).entry.id; - file3Id = (await apis.user.nodes.createFile(file3User)).entry.id; - file4Id = (await apis.user.nodes.createFile(file4User)).entry.id; - - await apis.user.shared.shareFilesByIds([file1Id, file2Id, file3Id, file4Id]); - await apis.user.shared.waitForFilesToBeShared([file1Id, file2Id, file3Id, file4Id]); - - await apis.user.nodes.deleteNodeById(file2Id); - await apis.user.shared.unshareFileById(file3Id); - - await apis.user.shared.waitForFilesToNotBeShared([file2Id, file3Id]); - - await loginPage.loginWith(username); - }); - - beforeEach(async () => { - await page.clickSharedFilesAndWait(); - }); - - afterAll(async () => { - await adminApiActions.sites.deleteSite(siteName); - await apis.user.nodes.deleteNodeById(folderId); - await apis.user.nodes.deleteNodeById(file4Id); - }); - - it('[C213113] has the correct columns', async () => { - const expectedColumns = ['Name', 'Location', 'Size', 'Modified', 'Modified by', 'Shared by', 'Tags']; - const actualColumns = await dataTable.getColumnHeadersText(); - - await expect(actualColumns).toEqual(expectedColumns); - }); - - it('[C213115] default sorting column', async () => { - expect(await dataTable.getSortedColumnHeaderText()).toBe('Modified'); - expect(await dataTable.getSortingOrder()).toBe('desc'); - }); - - it('[C213114] displays the files shared by everyone', async () => { - expect(await dataTable.isItemPresent(fileAdmin)).toBe(true, `${fileAdmin} not displayed`); - expect(await dataTable.isItemPresent(file1User)).toBe(true, `${file1User} not displayed`); - }); - - it(`[C213117] file not displayed if it's been deleted`, async () => { - expect(await dataTable.isItemPresent(file2User)).toBe(false, `${file2User} is displayed`); - }); - - it('[C213118] unshared file is not displayed', async () => { - expect(await dataTable.isItemPresent(file3User)).toBe(false, `${file3User} is displayed`); - }); - - it('[C213665] Location column displays the parent folder of the file', async () => { - expect(await dataTable.getItemLocationTooltip(file4User)).toEqual('Personal Files'); - expect(await dataTable.getItemLocation(fileAdmin)).toEqual(siteName); - expect(await dataTable.getItemLocation(file1User)).toEqual(folderUser); - }); - - it('[C213666] Location column redirect - file in user Home', async () => { - await dataTable.clickItemLocation(file4User); - expect(await breadcrumb.getAllItems()).toEqual(['Personal Files']); - }); - - it('[C280490] Location column redirect - file in folder', async () => { - await dataTable.clickItemLocation(file1User); - expect(await breadcrumb.getAllItems()).toEqual(['Personal Files', folderUser]); - }); - - it('[C280491] Location column redirect - file in site', async () => { - await dataTable.clickItemLocation(fileAdmin); - expect(await breadcrumb.getAllItems()).toEqual(['My Libraries', siteName]); - }); - - it('[C213667] Location column displays a tooltip with the entire path of the file', async () => { - expect(await dataTable.getItemLocationTooltip(fileAdmin)).toEqual(`File Libraries/${siteName}`); - expect(await dataTable.getItemLocationTooltip(file1User)).toEqual(`Personal Files/${folderUser}`); - }); -}); 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 48800b8cc9..3fb228f958 100755 --- a/projects/aca-playwright-shared/src/api/shared-links-api.ts +++ b/projects/aca-playwright-shared/src/api/shared-links-api.ts @@ -73,7 +73,7 @@ export class SharedLinksApi { return await this.apiService.share.listSharedLinks(opts); } catch (error) { console.error(`SharedLinksApi getSharedLinks : catch : `, error); - return new SharedLinkPaging; + return new SharedLinkPaging(); } } @@ -95,4 +95,47 @@ export class SharedLinksApi { console.error(`\tWait 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: null } }).entry.id; + } catch (error) { + console.error(`SharedLinksApi getSharedIdOfNode : catch : `, error); + return null; + } + } + + async unshareFileById(fileId: string): Promise { + try { + const sharedId = await this.getSharedIdOfNode(fileId); + return await this.apiService.share.deleteSharedLink(sharedId); + } catch (error) { + console.error(`SharedLinksApi unshareFileById : catch : `, error); + } + } + + async waitForFilesToNotBeShared(filesIds: string[]): Promise { + try { + const sharedFile = async () => { + const sharedFiles = (await this.getSharedLinks()).list.entries.map((link) => link.entry.nodeId); + + const foundItems = filesIds.some((id) => { + return sharedFiles.includes(id); + }); + + if (foundItems) { + return Promise.reject(foundItems); + } else { + return Promise.resolve(foundItems); + } + }; + + return 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`); + } + } } diff --git a/projects/aca-playwright-shared/src/page-objects/pages/recent-files.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/recent-files.page.ts index 2fedf41f6d..98d0ddb3fc 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/recent-files.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/recent-files.page.ts @@ -24,7 +24,7 @@ import { Page } from '@playwright/test'; import { BasePage } from './base.page'; -import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent } from '../components'; +import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent, Breadcrumb } from '../components'; import { AcaHeader } from '../components/aca-header.component'; import { AdfFolderDialogComponent } from '../components/dialogs'; @@ -41,4 +41,5 @@ export class RecentFilesPage extends BasePage { public dataTable = new DataTableComponent(this.page); public viewer = new ViewerComponent(this.page); public sidenav = new SidenavComponent(this.page); + public breadcrumb = new Breadcrumb(this.page); } diff --git a/projects/aca-playwright-shared/src/page-objects/pages/shared.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/shared.page.ts index 88372b5e9b..84ecb34ee0 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/shared.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/shared.page.ts @@ -24,7 +24,7 @@ import { Page } from '@playwright/test'; import { BasePage } from './base.page'; -import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent } from '../components'; +import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent, Breadcrumb } from '../components'; import { AcaHeader } from '../components/aca-header.component'; import { AdfFolderDialogComponent, ViewerOverlayDialogComponent } from '../components/dialogs'; @@ -42,4 +42,5 @@ export class SharedPage extends BasePage { public viewer = new ViewerComponent(this.page); public viewerDialog = new ViewerOverlayDialogComponent(this.page); public sidenav = new SidenavComponent(this.page); + public breadcrumb = new Breadcrumb(this.page); } From 53cdf51d95883d9ab6d9051734d7a90bb15f2907 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Thu, 7 Dec 2023 16:22:11 +0100 Subject: [PATCH 08/23] e2e test shared recent page fix --- e2e/playwright/list-views/src/tests/shared-files.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/playwright/list-views/src/tests/shared-files.spec.ts b/e2e/playwright/list-views/src/tests/shared-files.spec.ts index d955098519..dc172ff565 100644 --- a/e2e/playwright/list-views/src/tests/shared-files.spec.ts +++ b/e2e/playwright/list-views/src/tests/shared-files.spec.ts @@ -26,7 +26,7 @@ import { expect } from '@playwright/test'; import { ApiClientFactory, LoginPage, NodesApi, Utils, test, SitesApi, timeouts, SharedLinksApi } from '@alfresco/playwright-shared'; import { Site } from '@alfresco/js-api'; -test.describe.only('Shared Files', () => { +test.describe('Shared Files', () => { const apiClientFactory = new ApiClientFactory(); let nodesApi: NodesApi; let nodesApiAdmin: NodesApi; From 0431ee435a0ee698cdada2f00988142517f49eb1 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Fri, 8 Dec 2023 11:20:20 +0100 Subject: [PATCH 09/23] e2e test review comment fix --- .../list-views/src/tests/favorites.spec.ts | 11 +++++------ .../list-views/src/tests/file-libraries.spec.ts | 9 +++------ .../list-views/src/tests/recent-files.spec.ts | 2 +- .../list-views/src/tests/shared-files.spec.ts | 15 +++++---------- e2e/playwright/list-views/src/tests/trash.spec.ts | 5 +++-- 5 files changed, 17 insertions(+), 25 deletions(-) diff --git a/e2e/playwright/list-views/src/tests/favorites.spec.ts b/e2e/playwright/list-views/src/tests/favorites.spec.ts index 4a55b761fd..3f4c8fe2c5 100644 --- a/e2e/playwright/list-views/src/tests/favorites.spec.ts +++ b/e2e/playwright/list-views/src/tests/favorites.spec.ts @@ -27,11 +27,8 @@ import { ApiClientFactory, LoginPage, NodesApi, Utils, test, SitesApi, Favorites import { Site } from '@alfresco/js-api'; test.describe('Favorites Files', () => { - const apiClientFactory = new ApiClientFactory(); let nodesApi: NodesApi; - let nodesApiAdmin: NodesApi; let siteActionsAdmin: SitesApi; - let favoritesActions: FavoritesPageApi; const username = `user-${Utils.random()}`; const siteName = `site-${Utils.random()}`; const favFolderName = `favFolder-${Utils.random()}`; @@ -44,12 +41,13 @@ test.describe('Favorites Files', () => { test.beforeAll(async () => { try { test.setTimeout(timeouts.extendedTest); + const apiClientFactory = new ApiClientFactory(); await apiClientFactory.setUpAcaBackend('admin'); await apiClientFactory.createUser({ username }); nodesApi = await NodesApi.initialize(username, username); - nodesApiAdmin = await NodesApi.initialize('admin'); + const nodesApiAdmin = await NodesApi.initialize('admin'); siteActionsAdmin = await SitesApi.initialize('admin'); - favoritesActions = await FavoritesPageApi.initialize(username, username); + const favoritesActions = await FavoritesPageApi.initialize(username, username); const consumerFavoritesTotalItems = await favoritesActions.getFavoritesTotalItems(username); const folderFavId = (await nodesApi.createFolder(favFolderName)).entry.id; const parentId = (await nodesApi.createFolder(parentFolder)).entry.id; @@ -90,11 +88,12 @@ test.describe('Favorites Files', () => { test.afterAll(async () => { await nodesApi.deleteCurrentUserNodes(); + await siteActionsAdmin.deleteSites([siteName]); }); test.describe(`Regular user's Favorites files`, () => { test.beforeEach(async ({ favoritePage }) => { - favoritePage.navigate(); + await favoritePage.navigate(); }); test('[C280482] has the correct columns', async ({ favoritePage }) => { diff --git a/e2e/playwright/list-views/src/tests/file-libraries.spec.ts b/e2e/playwright/list-views/src/tests/file-libraries.spec.ts index d0b6eeefed..79d41836fd 100755 --- a/e2e/playwright/list-views/src/tests/file-libraries.spec.ts +++ b/e2e/playwright/list-views/src/tests/file-libraries.spec.ts @@ -27,10 +27,8 @@ import { ApiClientFactory, FavoritesPageApi, LoginPage, SitesApi, Utils, test, t import { Site } from '@alfresco/js-api'; test.describe('File Libraries', () => { - const apiClientFactory = new ApiClientFactory(); let siteActionsAdmin: SitesApi; let siteActionsUser: SitesApi; - let favoritesActions: FavoritesPageApi; const username = `user-${Utils.random()}`; const userSitePrivate = `user-priv-${Utils.random()}`; @@ -47,17 +45,16 @@ test.describe('File Libraries', () => { const adminSite4 = `admin4-${Utils.random()}`; const adminSite5 = `admin5-${Utils.random()}`; - const siteDescription = 'my site description'; - test.beforeAll(async () => { try { test.setTimeout(timeouts.extendedTest); + const apiClientFactory = new ApiClientFactory(); await apiClientFactory.setUpAcaBackend('admin'); await apiClientFactory.createUser({ username }); siteActionsAdmin = await SitesApi.initialize('admin'); siteActionsUser = await SitesApi.initialize(username, username); - favoritesActions = await FavoritesPageApi.initialize(username, username); - + const favoritesActions = await FavoritesPageApi.initialize(username, username); + const siteDescription = 'my site description'; await siteActionsUser.createSite(userSitePublic, Site.VisibilityEnum.PUBLIC); await siteActionsUser.createSite(userSiteModerated, Site.VisibilityEnum.MODERATED, siteDescription); await siteActionsUser.createSite(userSitePrivate, Site.VisibilityEnum.PRIVATE, null); diff --git a/e2e/playwright/list-views/src/tests/recent-files.spec.ts b/e2e/playwright/list-views/src/tests/recent-files.spec.ts index f7ba925973..15fd13093c 100755 --- a/e2e/playwright/list-views/src/tests/recent-files.spec.ts +++ b/e2e/playwright/list-views/src/tests/recent-files.spec.ts @@ -89,7 +89,7 @@ test.describe('Recent Files', () => { const expectedColumns = ['Name', 'Location', 'Size', 'Modified', 'Tags']; const actualColumns = await recentFilesPage.dataTable.getColumnHeaders(); - await expect(actualColumns).toEqual(expectedColumns); + expect(actualColumns).toEqual(expectedColumns); }); test('[C213171] default sorting column', async ({ recentFilesPage }) => { diff --git a/e2e/playwright/list-views/src/tests/shared-files.spec.ts b/e2e/playwright/list-views/src/tests/shared-files.spec.ts index dc172ff565..c541a7ea52 100644 --- a/e2e/playwright/list-views/src/tests/shared-files.spec.ts +++ b/e2e/playwright/list-views/src/tests/shared-files.spec.ts @@ -29,15 +29,11 @@ import { Site } from '@alfresco/js-api'; test.describe('Shared Files', () => { const apiClientFactory = new ApiClientFactory(); let nodesApi: NodesApi; - let nodesApiAdmin: NodesApi; let siteActionsAdmin: SitesApi; - let shareActionsAdmin: SharedLinksApi; - let shareActions: SharedLinksApi; - const username = `user-${Utils.random()}`; + const username = `user-${Utils.random()}`; const siteName = `site-${Utils.random()}`; const fileAdmin = `fileSite-${Utils.random()}.txt`; - const folderUser = `folder-${Utils.random()}`; let folderId: string; const file1User = `file1-${Utils.random()}.txt`; @@ -54,10 +50,10 @@ test.describe('Shared Files', () => { await apiClientFactory.setUpAcaBackend('admin'); await apiClientFactory.createUser({ username }); siteActionsAdmin = await SitesApi.initialize('admin'); - nodesApiAdmin = await NodesApi.initialize('admin'); - shareActionsAdmin = await SharedLinksApi.initialize('admin'); + const nodesApiAdmin = await NodesApi.initialize('admin'); + const shareActionsAdmin = await SharedLinksApi.initialize('admin'); nodesApi = await NodesApi.initialize(username, username); - shareActions = await SharedLinksApi.initialize(username, username); + const shareActions = await SharedLinksApi.initialize(username, username); await siteActionsAdmin.createSite(siteName, Site.VisibilityEnum.PUBLIC); await siteActionsAdmin.addSiteMember(siteName, username, Site.RoleEnum.SiteConsumer); @@ -96,8 +92,7 @@ test.describe('Shared Files', () => { test.afterAll(async () => { await siteActionsAdmin.deleteSites([siteName]); - await nodesApi.deleteNodeById(folderId); - await nodesApi.deleteNodeById(file4Id); + await nodesApi.deleteNodes([folderId, file4Id]); }); test('[C213113] has the correct columns', async ({ sharedPage }) => { diff --git a/e2e/playwright/list-views/src/tests/trash.spec.ts b/e2e/playwright/list-views/src/tests/trash.spec.ts index 00cc0191bb..725ff5ae7b 100755 --- a/e2e/playwright/list-views/src/tests/trash.spec.ts +++ b/e2e/playwright/list-views/src/tests/trash.spec.ts @@ -30,7 +30,7 @@ test.describe('Trash', () => { const apiClientFactory = new ApiClientFactory(); let nodesApi: NodesApi; let siteActionsAdmin: SitesApi; - let nodesApiAdmin: NodesApi; + const username = `user-${Utils.random()}`; const siteName = `site-${Utils.random()}`; const fileSite = `file1-${Utils.random()}.txt`; @@ -56,7 +56,7 @@ test.describe('Trash', () => { await apiClientFactory.createUser({ username }); siteActionsAdmin = await SitesApi.initialize('admin'); nodesApi = await NodesApi.initialize(username, username); - nodesApiAdmin = await NodesApi.initialize('admin'); + const nodesApiAdmin = await NodesApi.initialize('admin'); await siteActionsAdmin.createSite(siteName, Site.VisibilityEnum.PUBLIC); const docLibId = await siteActionsAdmin.getDocLibId(siteName); @@ -78,6 +78,7 @@ test.describe('Trash', () => { test.afterAll(async () => { await nodesApi.deleteCurrentUserNodes(); + await siteActionsAdmin.deleteSites([siteName]); }); test.describe(`Regular user's personal files`, () => { From 7ecc25a02d5ae614298926a3351788ea77ed4059 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Fri, 8 Dec 2023 15:53:11 +0100 Subject: [PATCH 10/23] e2e test review fix flaky test fix --- .../src/tests/file-libraries.spec.ts | 8 +++--- .../src/tests/personal-files.spec.ts | 2 +- .../list-views/src/tests/recent-files.spec.ts | 5 ++-- .../list-views/src/tests/shared-files.spec.ts | 22 ++++++---------- .../list-views/src/tests/trash.spec.ts | 26 +++++-------------- .../pagination/src/tests/favorites.ts | 15 +++-------- .../pagination/src/tests/personal-files.ts | 14 +++------- 7 files changed, 30 insertions(+), 62 deletions(-) diff --git a/e2e/playwright/list-views/src/tests/file-libraries.spec.ts b/e2e/playwright/list-views/src/tests/file-libraries.spec.ts index 79d41836fd..43cf172f90 100755 --- a/e2e/playwright/list-views/src/tests/file-libraries.spec.ts +++ b/e2e/playwright/list-views/src/tests/file-libraries.spec.ts @@ -112,9 +112,9 @@ test.describe('File Libraries', () => { [userSiteModerated]: Site.VisibilityEnum.MODERATED, [userSitePublic]: Site.VisibilityEnum.PUBLIC }; - for (const site of Object.keys(expectedSitesVisibility)) { + for (const [site, visibility] of Object.keys(expectedSitesVisibility)) { const sitesVisibility = await myLibrariesPage.dataTable.getRowAllInnerTexts(site); - expect(sitesVisibility.toLowerCase()).toContain(expectedSitesVisibility[site].toLowerCase()); + expect(sitesVisibility.toLowerCase()).toContain(visibility.toLowerCase()); } }); @@ -126,9 +126,9 @@ test.describe('File Libraries', () => { [adminSite4]: Site.RoleEnum.SiteManager }; - for (const site of Object.keys(expectedSitesRoles)) { + for (const [site, role] of Object.keys(expectedSitesRoles)) { const sitesRowNames = await myLibrariesPage.dataTable.getRowAllInnerTexts(site); - expect(sitesRowNames.toLowerCase()).toContain(expectedSitesRoles[site].split('Site')[1].toLowerCase()); + expect(sitesRowNames.toLowerCase()).toContain(role.split('Site')[1].toLowerCase()); } }); diff --git a/e2e/playwright/list-views/src/tests/personal-files.spec.ts b/e2e/playwright/list-views/src/tests/personal-files.spec.ts index 85371fe5fb..35e4fad9d8 100644 --- a/e2e/playwright/list-views/src/tests/personal-files.spec.ts +++ b/e2e/playwright/list-views/src/tests/personal-files.spec.ts @@ -26,13 +26,13 @@ import { expect } from '@playwright/test'; import { APP_ROUTES, ApiClientFactory, LoginPage, NodesApi, SIDEBAR_LABELS, Utils, test } from '@alfresco/playwright-shared'; test.describe('Personal Files', () => { - const apiClientFactory = new ApiClientFactory(); let nodesApi: NodesApi; const username = `user-${Utils.random()}`; const userFolder = `user-folder-${Utils.random()}`; test.beforeAll(async () => { try { + const apiClientFactory = new ApiClientFactory(); await apiClientFactory.setUpAcaBackend('admin'); await apiClientFactory.createUser({ username }); nodesApi = await NodesApi.initialize(username, username); diff --git a/e2e/playwright/list-views/src/tests/recent-files.spec.ts b/e2e/playwright/list-views/src/tests/recent-files.spec.ts index 15fd13093c..27bb4282b1 100755 --- a/e2e/playwright/list-views/src/tests/recent-files.spec.ts +++ b/e2e/playwright/list-views/src/tests/recent-files.spec.ts @@ -27,7 +27,6 @@ import { ApiClientFactory, LoginPage, NodesApi, SearchPageApi, SitesApi, Trashca import { Site } from '@alfresco/js-api'; test.describe('Recent Files', () => { - const apiClientFactory = new ApiClientFactory(); let nodeActionsUser: NodesApi; let siteActionsUser: SitesApi; const username = `user-${Utils.random()}`; @@ -41,10 +40,10 @@ test.describe('Recent Files', () => { const siteName = `site-${Utils.random()}`; const folderSite = `folder2-${Utils.random()}`; - let folderSiteId: string; const fileSite = `file-${Utils.random()}.txt`; test.beforeAll(async () => { + const apiClientFactory = new ApiClientFactory(); await apiClientFactory.setUpAcaBackend('admin'); await apiClientFactory.createUser({ username }); nodeActionsUser = await NodesApi.initialize(username, username); @@ -59,7 +58,7 @@ test.describe('Recent Files', () => { await siteActionsUser.createSite(siteName, Site.VisibilityEnum.PUBLIC); const docLibId = await siteActionsUser.getDocLibId(siteName); - folderSiteId = (await nodeActionsUser.createFolder(folderSite, docLibId)).entry.id; + const folderSiteId = (await nodeActionsUser.createFolder(folderSite, docLibId)).entry.id; await nodeActionsUser.createFile(fileSite, folderSiteId); const searchApi = await SearchPageApi.initialize(username, username); diff --git a/e2e/playwright/list-views/src/tests/shared-files.spec.ts b/e2e/playwright/list-views/src/tests/shared-files.spec.ts index c541a7ea52..7b6c7b7d27 100644 --- a/e2e/playwright/list-views/src/tests/shared-files.spec.ts +++ b/e2e/playwright/list-views/src/tests/shared-files.spec.ts @@ -27,7 +27,6 @@ import { ApiClientFactory, LoginPage, NodesApi, Utils, test, SitesApi, timeouts, import { Site } from '@alfresco/js-api'; test.describe('Shared Files', () => { - const apiClientFactory = new ApiClientFactory(); let nodesApi: NodesApi; let siteActionsAdmin: SitesApi; @@ -35,18 +34,14 @@ test.describe('Shared Files', () => { const siteName = `site-${Utils.random()}`; const fileAdmin = `fileSite-${Utils.random()}.txt`; const folderUser = `folder-${Utils.random()}`; - let folderId: string; const file1User = `file1-${Utils.random()}.txt`; - let file1Id: string; const file2User = `file2-${Utils.random()}.txt`; - let file2Id: string; const file3User = `file3-${Utils.random()}.txt`; - let file3Id: string; const file4User = `file4-${Utils.random()}.txt`; - let file4Id: string; test.beforeAll(async () => { test.setTimeout(timeouts.extendedTest); + const apiClientFactory = new ApiClientFactory(); await apiClientFactory.setUpAcaBackend('admin'); await apiClientFactory.createUser({ username }); siteActionsAdmin = await SitesApi.initialize('admin'); @@ -63,11 +58,11 @@ test.describe('Shared Files', () => { await shareActionsAdmin.shareFileById(nodeId); await shareActionsAdmin.waitForFilesToBeShared([nodeId]); - folderId = (await nodesApi.createFolder(folderUser)).entry.id; - file1Id = (await nodesApi.createFile(file1User, folderId)).entry.id; - file2Id = (await nodesApi.createFile(file2User)).entry.id; - file3Id = (await nodesApi.createFile(file3User)).entry.id; - file4Id = (await nodesApi.createFile(file4User)).entry.id; + const folderId = (await nodesApi.createFolder(folderUser)).entry.id; + const file1Id = (await nodesApi.createFile(file1User, folderId)).entry.id; + const file2Id = (await nodesApi.createFile(file2User)).entry.id; + const file3Id = (await nodesApi.createFile(file3User)).entry.id; + const file4Id = (await nodesApi.createFile(file4User)).entry.id; await shareActions.shareFilesByIds([file1Id, file2Id, file3Id, file4Id]); await shareActions.waitForFilesToBeShared([file1Id, file2Id, file3Id, file4Id]); @@ -92,14 +87,13 @@ test.describe('Shared Files', () => { test.afterAll(async () => { await siteActionsAdmin.deleteSites([siteName]); - await nodesApi.deleteNodes([folderId, file4Id]); + await nodesApi.deleteCurrentUserNodes(); }); test('[C213113] has the correct columns', async ({ sharedPage }) => { const expectedColumns = ['Name', 'Location', 'Size', 'Modified', 'Modified by', 'Shared by', 'Tags']; const actualColumns = await sharedPage.dataTable.getColumnHeaders(); - - await expect(actualColumns).toEqual(expectedColumns); + expect(actualColumns).toEqual(expectedColumns); }); test('[C213115] default sorting column', async ({ sharedPage }) => { diff --git a/e2e/playwright/list-views/src/tests/trash.spec.ts b/e2e/playwright/list-views/src/tests/trash.spec.ts index 725ff5ae7b..b3a250ddce 100755 --- a/e2e/playwright/list-views/src/tests/trash.spec.ts +++ b/e2e/playwright/list-views/src/tests/trash.spec.ts @@ -27,50 +27,38 @@ import { ApiClientFactory, LoginPage, NodesApi, SitesApi, Utils, test } from '@a import { Site } from '@alfresco/js-api'; test.describe('Trash', () => { - const apiClientFactory = new ApiClientFactory(); let nodesApi: NodesApi; let siteActionsAdmin: SitesApi; const username = `user-${Utils.random()}`; const siteName = `site-${Utils.random()}`; const fileSite = `file1-${Utils.random()}.txt`; - - const folderUser = `folder-${Utils.random()}`; - let folderUserId: string; const fileUser = `file-${Utils.random()}.txt`; - let fileUserId: string; - - const folderDeleted = `folder-${Utils.random()}`; - let folderDeletedId: string; const fileDeleted = `file-${Utils.random()}.txt`; - let fileDeletedId: string; - const folderNotDeleted = `folder-${Utils.random()}`; - let folderNotDeletedId: string; const fileInFolder = `file-${Utils.random()}.txt`; - let fileInFolderId: string; test.beforeAll(async () => { try { + const apiClientFactory = new ApiClientFactory(); await apiClientFactory.setUpAcaBackend('admin'); await apiClientFactory.createUser({ username }); siteActionsAdmin = await SitesApi.initialize('admin'); nodesApi = await NodesApi.initialize(username, username); const nodesApiAdmin = await NodesApi.initialize('admin'); + const folderDeleted = `folder-${Utils.random()}`; await siteActionsAdmin.createSite(siteName, Site.VisibilityEnum.PUBLIC); const docLibId = await siteActionsAdmin.getDocLibId(siteName); await siteActionsAdmin.addSiteMember(siteName, username, Site.RoleEnum.SiteManager); const fileSiteId = (await nodesApiAdmin.createFile(fileSite, docLibId)).entry.id; - folderUserId = (await nodesApi.createFolder(folderUser)).entry.id; - folderDeletedId = (await nodesApi.createFolder(folderDeleted)).entry.id; - folderNotDeletedId = (await nodesApi.createFolder(folderNotDeleted)).entry.id; - fileUserId = (await nodesApi.createFile(fileUser)).entry.id; - fileDeletedId = (await nodesApi.createFile(fileDeleted, folderDeletedId)).entry.id; - fileInFolderId = (await nodesApi.createFile(fileInFolder, folderNotDeletedId)).entry.id; + const folderDeletedId = (await nodesApi.createFolder(folderDeleted)).entry.id; + const folderNotDeletedId = (await nodesApi.createFolder(folderNotDeleted)).entry.id; + const fileDeletedId = (await nodesApi.createFile(fileDeleted, folderDeletedId)).entry.id; + const fileInFolderId = (await nodesApi.createFile(fileInFolder, folderNotDeletedId)).entry.id; - await nodesApi.deleteNodes([fileSiteId, fileUserId, folderUserId, fileInFolderId, fileDeletedId, folderDeletedId], false); + await nodesApi.deleteNodes([fileSiteId, fileInFolderId, fileDeletedId, folderDeletedId], false); } catch (error) { console.error(`----- beforeAll failed : ${error}`); } diff --git a/e2e/playwright/pagination/src/tests/favorites.ts b/e2e/playwright/pagination/src/tests/favorites.ts index 5205165abc..f71491432e 100644 --- a/e2e/playwright/pagination/src/tests/favorites.ts +++ b/e2e/playwright/pagination/src/tests/favorites.ts @@ -44,21 +44,13 @@ export function favoritesTests(username: string) { expect(await favoritePage.pagination.isNextEnabled()).toBe(true); }); - test('[C280114] Items per page values', async ({ favoritePage }) => { - await favoritePage.pagination.openMaxItemsMenu(); - expect(await (await favoritePage.pagination.getNthItem(1)).innerText()).toBe('25'); - expect(await (await favoritePage.pagination.getNthItem(2)).innerText()).toBe('50'); - expect(await (await favoritePage.pagination.getNthItem(3)).innerText()).toBe('100'); - await favoritePage.pagination.closeMenu(); - }); - test('[C280115] current page menu items', 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'); - expect(await favoritePage.pagination.getItemsCount()).toBe(3); - await favoritePage.pagination.closeMenu(); await favoritePage.pagination.openMaxItemsMenu(); await favoritePage.pagination.clickMenuItem('50'); @@ -89,9 +81,10 @@ export function favoritesTests(username: string) { 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'); }); diff --git a/e2e/playwright/pagination/src/tests/personal-files.ts b/e2e/playwright/pagination/src/tests/personal-files.ts index c1b4d05c80..03f03b4ad4 100644 --- a/e2e/playwright/pagination/src/tests/personal-files.ts +++ b/e2e/playwright/pagination/src/tests/personal-files.ts @@ -44,20 +44,13 @@ export function personalFilesTests(userName: string, parentName: string) { expect(await personalFiles.pagination.isNextEnabled()).toBe(true); }); - test('[C280078] Items per page values', async ({ personalFiles }) => { - await personalFiles.pagination.openMaxItemsMenu(); - expect(await (await personalFiles.pagination.getNthItem(1)).innerText()).toBe('25'); - expect(await (await personalFiles.pagination.getNthItem(2)).innerText()).toBe('50'); - expect(await (await personalFiles.pagination.getNthItem(3)).innerText()).toBe('100'); - await personalFiles.closeMenu(); - }); - test('[C280079] current page menu items', 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'); - expect(await personalFiles.pagination.getItemsCount()).toBe(3); await personalFiles.pagination.openMaxItemsMenu(); await personalFiles.pagination.clickMenuItem('50'); @@ -86,9 +79,10 @@ export function personalFilesTests(userName: string, parentName: string) { 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'); }); From 709f996441181f2bf57c3df4cfa6fd192631b6e5 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Fri, 8 Dec 2023 17:50:22 +0100 Subject: [PATCH 11/23] e2e test fail test fix --- e2e/playwright/list-views/src/tests/file-libraries.spec.ts | 2 +- e2e/playwright/list-views/src/tests/recent-files.spec.ts | 3 ++- e2e/playwright/list-views/src/tests/trash.spec.ts | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/e2e/playwright/list-views/src/tests/file-libraries.spec.ts b/e2e/playwright/list-views/src/tests/file-libraries.spec.ts index 43cf172f90..0f869861f4 100755 --- a/e2e/playwright/list-views/src/tests/file-libraries.spec.ts +++ b/e2e/playwright/list-views/src/tests/file-libraries.spec.ts @@ -128,7 +128,7 @@ test.describe('File Libraries', () => { for (const [site, role] of Object.keys(expectedSitesRoles)) { const sitesRowNames = await myLibrariesPage.dataTable.getRowAllInnerTexts(site); - expect(sitesRowNames.toLowerCase()).toContain(role.split('Site')[1].toLowerCase()); + expect(sitesRowNames).toContain(role); } }); diff --git a/e2e/playwright/list-views/src/tests/recent-files.spec.ts b/e2e/playwright/list-views/src/tests/recent-files.spec.ts index 27bb4282b1..84efecf8fb 100755 --- a/e2e/playwright/list-views/src/tests/recent-files.spec.ts +++ b/e2e/playwright/list-views/src/tests/recent-files.spec.ts @@ -23,7 +23,7 @@ */ import { expect } from '@playwright/test'; -import { ApiClientFactory, LoginPage, NodesApi, SearchPageApi, SitesApi, TrashcanApi, Utils, test } from '@alfresco/playwright-shared'; +import { ApiClientFactory, LoginPage, NodesApi, SearchPageApi, SitesApi, TrashcanApi, Utils, test, timeouts } from '@alfresco/playwright-shared'; import { Site } from '@alfresco/js-api'; test.describe('Recent Files', () => { @@ -43,6 +43,7 @@ test.describe('Recent Files', () => { const fileSite = `file-${Utils.random()}.txt`; test.beforeAll(async () => { + test.setTimeout(timeouts.extendedTest); const apiClientFactory = new ApiClientFactory(); await apiClientFactory.setUpAcaBackend('admin'); await apiClientFactory.createUser({ username }); diff --git a/e2e/playwright/list-views/src/tests/trash.spec.ts b/e2e/playwright/list-views/src/tests/trash.spec.ts index b3a250ddce..6c47c8fb1f 100755 --- a/e2e/playwright/list-views/src/tests/trash.spec.ts +++ b/e2e/playwright/list-views/src/tests/trash.spec.ts @@ -52,13 +52,14 @@ test.describe('Trash', () => { const docLibId = await siteActionsAdmin.getDocLibId(siteName); await siteActionsAdmin.addSiteMember(siteName, username, Site.RoleEnum.SiteManager); const fileSiteId = (await nodesApiAdmin.createFile(fileSite, docLibId)).entry.id; + const fileUserId = (await nodesApi.createFile(fileUser)).entry.id; const folderDeletedId = (await nodesApi.createFolder(folderDeleted)).entry.id; const folderNotDeletedId = (await nodesApi.createFolder(folderNotDeleted)).entry.id; const fileDeletedId = (await nodesApi.createFile(fileDeleted, folderDeletedId)).entry.id; const fileInFolderId = (await nodesApi.createFile(fileInFolder, folderNotDeletedId)).entry.id; - await nodesApi.deleteNodes([fileSiteId, fileInFolderId, fileDeletedId, folderDeletedId], false); + await nodesApi.deleteNodes([fileSiteId, fileUserId, fileInFolderId, fileDeletedId, folderDeletedId], false); } catch (error) { console.error(`----- beforeAll failed : ${error}`); } From 8a3a9a1f6056b3bef69450dc7eba758000269433 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Sat, 9 Dec 2023 15:42:06 +0100 Subject: [PATCH 12/23] e2e test fail fix --- projects/aca-playwright-shared/src/api/shared-links-api.ts | 4 ++-- .../page-objects/components/dataTable/data-table.component.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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 3fb228f958..b7f995a32f 100755 --- a/projects/aca-playwright-shared/src/api/shared-links-api.ts +++ b/projects/aca-playwright-shared/src/api/shared-links-api.ts @@ -100,14 +100,14 @@ export class SharedLinksApi { try { const sharedLinksEntries = (await this.getSharedLinks())?.list.entries; const found = sharedLinksEntries.find((sharedLink) => sharedLink.entry.nodeId === fileId); - return (found || { entry: { id: null } }).entry.id; + return found?.entry.id; } catch (error) { console.error(`SharedLinksApi getSharedIdOfNode : catch : `, error); return null; } } - async unshareFileById(fileId: string): Promise { + async unshareFileById(fileId: string): Promise { try { const sharedId = await this.getSharedIdOfNode(fileId); return await this.apiService.share.deleteSharedLink(sharedId); diff --git a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts index 28681ae33c..430c3de7ae 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts @@ -192,7 +192,7 @@ export class DataTableComponent extends BaseComponent { async goThroughPagesLookingForRowWithName(name: string | number): Promise { await this.spinnerWaitForReload(); - if ((await this.getRowByName(name).isVisible()) || (await this.pagination.totalPageLocator.textContent()) == ' of 1 ') { + if ((await this.getRowByName(name).isVisible()) || (await this.pagination.totalPageLocator.textContent()) === ' of 1 ') { return null; } From aec61108f26d2020d6f994e25ee8c571f3b50b92 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Mon, 11 Dec 2023 09:49:29 +0100 Subject: [PATCH 13/23] test code fix --- e2e/playwright/list-views/src/tests/file-libraries.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/playwright/list-views/src/tests/file-libraries.spec.ts b/e2e/playwright/list-views/src/tests/file-libraries.spec.ts index 0f869861f4..f2774ce8f9 100755 --- a/e2e/playwright/list-views/src/tests/file-libraries.spec.ts +++ b/e2e/playwright/list-views/src/tests/file-libraries.spec.ts @@ -112,7 +112,7 @@ test.describe('File Libraries', () => { [userSiteModerated]: Site.VisibilityEnum.MODERATED, [userSitePublic]: Site.VisibilityEnum.PUBLIC }; - for (const [site, visibility] of Object.keys(expectedSitesVisibility)) { + for (const [site, visibility] of Object.entries(expectedSitesVisibility)) { const sitesVisibility = await myLibrariesPage.dataTable.getRowAllInnerTexts(site); expect(sitesVisibility.toLowerCase()).toContain(visibility.toLowerCase()); } @@ -126,9 +126,9 @@ test.describe('File Libraries', () => { [adminSite4]: Site.RoleEnum.SiteManager }; - for (const [site, role] of Object.keys(expectedSitesRoles)) { + for (const [site, role] of Object.entries(expectedSitesRoles)) { const sitesRowNames = await myLibrariesPage.dataTable.getRowAllInnerTexts(site); - expect(sitesRowNames).toContain(role); + expect(sitesRowNames).toContain(role.split('Site')[1]); } }); From 8a6498af9998e8760da75f320e948e9187959d88 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Mon, 11 Dec 2023 10:16:13 +0100 Subject: [PATCH 14/23] protractor list-view test enable --- .github/workflows/pull-request.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index dc150c1220..c19fad2a31 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -109,6 +109,8 @@ jobs: fail-fast: false matrix: e2e-suites: + - name: "listViews" + id: 1 - name: "search" id: 2 - name: "viewer,infoDrawer,extensions" From 89ac123f90bdeef848daf33bf588006bdd7cce5c Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Mon, 18 Dec 2023 18:14:36 +0100 Subject: [PATCH 15/23] [ACS-6510] listview playwright e2e test --- .../list-views/src/tests/empty-list.spec.ts | 78 ++++ .../src/tests/generic-errors.spec.ts | 99 +++++ .../list-views/src/tests/permissions.spec.ts | 207 +++++++++++ .../src/tests/sort-list-login.spec.ts | 164 +++++++++ .../list-views/src/tests/sort-list.spec.ts | 282 ++++++++++++++ .../list-views/src/tests/trash-admin.spec.ts | 63 ++++ e2e/protractor/protractor.excludes.json | 1 - .../suites/list-views/empty-list.test.ts | 43 --- .../suites/list-views/generic-errors.test.ts | 104 ------ .../suites/list-views/permissions.test.ts | 177 --------- .../suites/list-views/sort-list.test.ts | 348 ------------------ .../suites/list-views/trash.test.ts | 123 ------- .../src/api/file-actions.ts | 33 +- .../src/api/nodes-api.ts | 8 + .../src/api/sites-api.ts | 23 +- .../dataTable/data-table.component.ts | 63 +++- .../components/error.component.ts | 36 ++ .../src/page-objects/components/index.ts | 1 + .../components/pagination.component.ts | 12 +- .../page-objects/pages/personal-files.page.ts | 4 +- .../src/page-objects/pages/trash.page.ts | 3 +- 21 files changed, 1057 insertions(+), 815 deletions(-) create mode 100755 e2e/playwright/list-views/src/tests/empty-list.spec.ts create mode 100755 e2e/playwright/list-views/src/tests/generic-errors.spec.ts create mode 100755 e2e/playwright/list-views/src/tests/permissions.spec.ts create mode 100644 e2e/playwright/list-views/src/tests/sort-list-login.spec.ts create mode 100644 e2e/playwright/list-views/src/tests/sort-list.spec.ts create mode 100755 e2e/playwright/list-views/src/tests/trash-admin.spec.ts delete mode 100755 e2e/protractor/suites/list-views/generic-errors.test.ts delete mode 100755 e2e/protractor/suites/list-views/permissions.test.ts delete mode 100644 e2e/protractor/suites/list-views/sort-list.test.ts delete mode 100755 e2e/protractor/suites/list-views/trash.test.ts create mode 100644 projects/aca-playwright-shared/src/page-objects/components/error.component.ts diff --git a/e2e/playwright/list-views/src/tests/empty-list.spec.ts b/e2e/playwright/list-views/src/tests/empty-list.spec.ts new file mode 100755 index 0000000000..6a4236d0b4 --- /dev/null +++ b/e2e/playwright/list-views/src/tests/empty-list.spec.ts @@ -0,0 +1,78 @@ +/*! + * Copyright © 2005-2023 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 { expect } from '@playwright/test'; +import { ApiClientFactory, LoginPage, Utils, test } from '@alfresco/playwright-shared'; + +test.describe('Empty list views', () => { + const username = `user-${Utils.random()}`; + + test.beforeAll(async () => { + const apiClientFactory = new ApiClientFactory(); + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username }); + }); + + test.beforeEach(async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); + }); + + test('[C217099] empty My Libraries', async ({ myLibrariesPage }) => { + await myLibrariesPage.navigate(); + expect(await myLibrariesPage.dataTable.isEmpty(), 'list is not empty').toBe(true); + expect(await myLibrariesPage.dataTable.getEmptyStateTitle()).toContain(`You aren't a member of any File Libraries yet`); + expect(await myLibrariesPage.dataTable.getEmptyStateSubtitle()).toContain('Join libraries to upload, view, and share files.'); + }); + + test('[C280134] [C280120] Empty Trash - pagination controls not displayed', async ({ trashPage }) => { + await trashPage.navigate(); + expect(await trashPage.dataTable.isEmpty(), 'list is not empty').toBe(true); + expect(await trashPage.dataTable.getEmptyStateTitle()).toContain('Trash is empty'); + expect(await trashPage.dataTable.getEmptyListText()).toContain('Items you delete are moved to the Trash.'); + expect(await trashPage.dataTable.getEmptyListText()).toContain('Empty Trash to permanently delete items.'); + expect(await trashPage.pagination.isRangePresent(), 'Range is present').toBe(false); + expect(await trashPage.pagination.isMaxItemsPresent(), 'Max items is present').toBe(false); + }); + + test('[C290123] [C290031] Empty Search results - pagination controls not displayed', async ({ personalFiles, searchPage }) => { + await personalFiles.acaHeader.searchButton.click(); + await searchPage.searchInput.searchButton.click(); + await searchPage.searchOverlay.checkFilesAndFolders(); + await searchPage.searchOverlay.searchFor('InvalidText'); + await searchPage.reload({ waitUntil: 'domcontentloaded' }); + await searchPage.dataTable.spinnerWaitForReload(); + + expect(await personalFiles.pagination.isRangePresent(), 'Range is present').toBe(false); + expect(await personalFiles.pagination.isMaxItemsPresent(), 'Max items is present').toBe(false); + expect(await personalFiles.dataTable.isEmpty(), 'list is not empty').toBe(true); + expect(await personalFiles.dataTable.emptySearchText.innerText()).toContain('Your search returned 0 results'); + }); +}); diff --git a/e2e/playwright/list-views/src/tests/generic-errors.spec.ts b/e2e/playwright/list-views/src/tests/generic-errors.spec.ts new file mode 100755 index 0000000000..616726344b --- /dev/null +++ b/e2e/playwright/list-views/src/tests/generic-errors.spec.ts @@ -0,0 +1,99 @@ +/*! + * Copyright © 2005-2023 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 { expect } from '@playwright/test'; +import { ApiClientFactory, LoginPage, NodesApi, TrashcanApi, Utils, test } from '@alfresco/playwright-shared'; + +test.describe('Generic errors', () => { + const username = `user-${Utils.random()}`; + const username2 = `user2-${Utils.random()}`; + let parentId: string; + let file1Id: string; + let file2Id: string; + let actionUser: NodesApi; + + test.beforeAll(async () => { + try { + const parent = `folder-${Utils.random()}`; + const file1 = `file1-${Utils.random()}.txt`; + const file2 = `file2-${Utils.random()}.txt`; + const apiClientFactory = new ApiClientFactory(); + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username }); + await apiClientFactory.createUser({ username: username2 }); + + actionUser = await NodesApi.initialize(username, username); + parentId = (await actionUser.createFolder(parent)).entry.id; + file1Id = (await actionUser.createFile(file1, parentId)).entry.id; + file2Id = (await actionUser.createFile(file2, parentId)).entry.id; + } catch (error) { + console.error(`----- beforeAll failed : ${error}`); + } + }); + + test.beforeEach(async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); + }); + + test.afterAll(async () => { + actionUser = await NodesApi.initialize(username, username); + const trashcanApi = await TrashcanApi.initialize(username, username); + await actionUser.deleteNodeById(parentId); + await trashcanApi.emptyTrashcan(); + }); + + test('[C217313] File / folder not found', async ({ personalFiles }) => { + await actionUser.deleteNodeById(file1Id, false); + await personalFiles.navigate({ remoteUrl: `#/personal-files/${file1Id}` }); + + expect(await personalFiles.errorDialog.genericError.isVisible(), 'Generic error page not displayed').toBe(true); + expect(await personalFiles.errorDialog.genericErrorTitle.innerText()).toContain( + `This item no longer exists or you don't have permission to view it.` + ); + }); + + test('[C217314] Permission denied', async ({ personalFiles, loginPage }) => { + await loginPage.logoutUser(); + await loginPage.loginUser( + { username: username2, password: username2 }, + { + withNavigation: true, + waitForLoading: true + } + ); + await personalFiles.navigate({ remoteUrl: `#/personal-files/${file2Id}` }); + + expect(await personalFiles.errorDialog.genericError.isVisible(), 'Generic error page not displayed').toBe(true); + expect(await personalFiles.errorDialog.genericErrorTitle.innerText()).toContain( + `This item no longer exists or you don't have permission to view it.` + ); + }); +}); diff --git a/e2e/playwright/list-views/src/tests/permissions.spec.ts b/e2e/playwright/list-views/src/tests/permissions.spec.ts new file mode 100755 index 0000000000..b557433e63 --- /dev/null +++ b/e2e/playwright/list-views/src/tests/permissions.spec.ts @@ -0,0 +1,207 @@ +/*! + * Copyright © 2005-2023 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 { expect } from '@playwright/test'; +import { + ApiClientFactory, + FavoritesPageApi, + FileActionsApi, + LoginPage, + NodesApi, + SharedLinksApi, + SitesApi, + Utils, + test, + timeouts +} from '@alfresco/playwright-shared'; +import { Site } from '@alfresco/js-api'; + +test.describe('Special permissions', () => { + const username = `userPermissions-${Utils.random()}`; + let siteApiAdmin: SitesApi; + test.beforeAll(async () => { + const apiClientFactory = new ApiClientFactory(); + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username }); + }); + + test.describe('file not displayed if user no longer has permissions on it', () => { + const sitePrivate = `private-${Utils.random()}`; + const fileName = `file-${Utils.random()}.txt`; + + test.beforeAll(async () => { + test.setTimeout(timeouts.webServer); + const userFavoritesApi = await FavoritesPageApi.initialize(username, username); + const userFileActionApi = await FileActionsApi.initialize(username, username); + siteApiAdmin = await SitesApi.initialize('admin'); + const nodeApiAdmin = await NodesApi.initialize('admin'); + const shareApiAdmin = await SharedLinksApi.initialize('admin'); + const shareApiUser = await SharedLinksApi.initialize(username, username); + + await siteApiAdmin.createSite(sitePrivate, Site.VisibilityEnum.PRIVATE); + await siteApiAdmin.addSiteMember(sitePrivate, username, Site.RoleEnum.SiteCollaborator); + const docLibId = await siteApiAdmin.getDocLibId(sitePrivate); + const fileId = (await nodeApiAdmin.createFile(fileName, docLibId)).entry.id; + await shareApiAdmin.shareFileById(fileId); + await userFavoritesApi.addFavoriteById('file', fileId); + + await userFileActionApi.updateNodeContent(fileId, 'edited by user'); + + await userFileActionApi.waitForNodes(username, { expect: 1 }); + + await shareApiAdmin.waitForFilesToBeShared([fileId]); + await shareApiUser.waitForFilesToBeShared([fileId]); + }); + + test.beforeEach(async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); + }); + + test.afterEach(async () => { + await siteApiAdmin.addSiteMember(sitePrivate, username, Site.RoleEnum.SiteCollaborator); + }); + + test.afterAll(async () => { + await siteApiAdmin.deleteSites([sitePrivate]); + }); + + test('[C213173] on Recent Files', async ({ recentFilesPage }) => { + await recentFilesPage.navigate(); + expect(await recentFilesPage.dataTable.getRowsCount(), 'Incorrect number of items').toBe(2); + await siteApiAdmin.deleteSiteMember(sitePrivate, username); + await recentFilesPage.reload(); + expect(await recentFilesPage.dataTable.isEmpty(), 'Items are still displayed').toBe(true); + }); + + test('[C213227] on Favorites', async ({ favoritePage }) => { + await favoritePage.navigate(); + expect(await favoritePage.dataTable.getRowsCount(), 'Incorrect number of items').toBe(2); + await siteApiAdmin.deleteSiteMember(sitePrivate, username); + await favoritePage.reload(); + expect(await favoritePage.dataTable.isEmpty(), 'Items are still displayed').toBe(true); + }); + + test('[C213116] on Shared Files', async ({ sharedPage }) => { + await sharedPage.navigate(); + expect(await sharedPage.dataTable.getRowsCount(), 'Incorrect number of items').toBe(2); + await siteApiAdmin.deleteSiteMember(sitePrivate, username); + await sharedPage.reload(); + expect(await sharedPage.dataTable.getRowsCount(), 'Incorrect number of items').toBe(0); + }); + + test('[C290122] on Search Results', async ({ personalFiles, searchPage }) => { + await personalFiles.acaHeader.searchButton.click(); + await searchPage.searchInput.searchButton.click(); + await searchPage.searchOverlay.checkFilesAndFolders(); + await searchPage.searchOverlay.searchFor(fileName); + await searchPage.dataTable.spinnerWaitForReload(); + + expect(await searchPage.dataTable.getRowsCount(), 'Incorrect number of items').toBe(2); + + await siteApiAdmin.deleteSiteMember(sitePrivate, username); + + await searchPage.reload(); + await searchPage.dataTable.spinnerWaitForReload(); + + expect(await searchPage.dataTable.getRowsCount(), 'Incorrect number of items').toBe(0); + }); + }); + + test.describe(`Location column is empty if user doesn't have permissions on the file's parent folder`, () => { + const sitePrivate = `private-${Utils.random()}`; + const fileName = `file-${Utils.random()}.txt`; + let adminSiteApiActions: SitesApi; + + test.beforeAll(async () => { + test.setTimeout(timeouts.webServer); + const userFavoritesApi = await FavoritesPageApi.initialize(username, username); + const userShareActionApi = await SharedLinksApi.initialize(username, username); + const userNodeActionApi = await NodesApi.initialize(username, username); + adminSiteApiActions = await SitesApi.initialize('admin'); + + await adminSiteApiActions.createSite(sitePrivate, Site.VisibilityEnum.PRIVATE); + await adminSiteApiActions.addSiteMember(sitePrivate, username, Site.RoleEnum.SiteCollaborator); + const docLibId = await adminSiteApiActions.getDocLibId(sitePrivate); + const fileId = (await userNodeActionApi.createFile(fileName, docLibId)).entry.id; + await userFavoritesApi.addFavoriteById('file', fileId); + + await userShareActionApi.shareFileById(fileId); + await userShareActionApi.waitForFilesToBeShared([fileId]); + + // await apis.user.search.waitForApi(username, { expect: 1 }); + await adminSiteApiActions.deleteSiteMember(sitePrivate, username); + }); + + test.beforeEach(async ({ page }) => { + const loginPage = new LoginPage(page); + await loginPage.loginUser( + { username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); + }); + + test.afterAll(async () => { + await adminSiteApiActions.deleteSites([sitePrivate]); + }); + + test('[C213178] on Recent Files', async ({ recentFilesPage }) => { + await recentFilesPage.navigate(); + expect(await recentFilesPage.dataTable.getRowsCount(), 'Incorrect number of items').toBe(2); + expect(await recentFilesPage.dataTable.getItemLocationText(fileName)).toEqual('Unknown'); + }); + + test('[C213672] on Favorites', async ({ favoritePage }) => { + await favoritePage.navigate(); + expect(await favoritePage.dataTable.getRowsCount(), 'Incorrect number of items').toBe(2); + expect(await favoritePage.dataTable.getItemLocationText(fileName)).toEqual('Unknown'); + }); + + test(`[C213668] on Shared Files`, async ({ sharedPage }) => { + await sharedPage.navigate(); + expect(await sharedPage.dataTable.getRowsCount(), 'Incorrect number of items').toBe(2); + expect(await sharedPage.dataTable.getItemLocationText(fileName)).toEqual('Unknown'); + }); + + test('[C306868] on Search results', async ({ personalFiles, searchPage }) => { + await personalFiles.acaHeader.searchButton.click(); + await searchPage.searchInput.searchButton.click(); + await searchPage.searchOverlay.checkFilesAndFolders(); + await searchPage.searchOverlay.searchFor(fileName); + await searchPage.dataTable.spinnerWaitForReload(); + + expect(await searchPage.dataTable.getRowsCount(), 'Incorrect number of items').toBe(2); + expect(await searchPage.dataTable.getItemLocationText(fileName)).toEqual('Unknown'); + }); + }); +}); diff --git a/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts b/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts new file mode 100644 index 0000000000..ef43667102 --- /dev/null +++ b/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts @@ -0,0 +1,164 @@ +/*! + * Copyright © 2005-2023 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 { expect } from '@playwright/test'; +import { ApiClientFactory, FileActionsApi, LoginPage, NodesApi, TEST_FILES, test, timeouts } from '@alfresco/playwright-shared'; + +test.describe('Remember sorting', () => { + interface NodesIds { + [index: string]: string; + } + + const timestamp = new Date().getTime(); + const user1 = `userSortLogin1-${timestamp}`; + const user2 = `userSortLogin2-${timestamp}`; + const pdfFileNames = [...new Array(14).fill(100)].map((v, i) => `file-${v + i}.pdf`); + const jpgFileNames = [...new Array(12).fill(114)].map((v, i) => `file-${v + i}.jpg`); + + const testData = { + user1: { + files: { + jpg: jpgFileNames, + pdf: pdfFileNames + } + }, + user2: { + files: [pdfFileNames[0], jpgFileNames[0]] + } + }; + + let initialSortState: { + sortingColumn: string; + sortingOrder: string; + firstElement: string; + }; + + test.beforeAll(async () => { + test.setTimeout(timeouts.extendedTest); + const apiClientFactory = new ApiClientFactory(); + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username: user1 }); + await apiClientFactory.createUser({ username: user2 }); + const fileActionUser1 = await FileActionsApi.initialize(user1, user1); + const fileActionUser2 = await FileActionsApi.initialize(user2, user2); + const filesIdsUser1: NodesIds = {}; + const filesIdsUser2: NodesIds = {}; + await Promise.all( + testData.user1.files.pdf.map( + async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) + ) + ); + await Promise.all( + testData.user1.files.jpg.map( + async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.JPG_FILE.path, i, '-my-')).entry.id) + ) + ); + await Promise.all( + testData.user2.files.map( + async (i) => (filesIdsUser2[i] = (await fileActionUser2.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) + ) + ); + }); + + test.beforeEach(async ({ page, personalFiles }) => { + const loginPage = new LoginPage(page); + await loginPage.loginUser( + { username: user1, password: user1 }, + { + withNavigation: true, + waitForLoading: true + } + ); + await personalFiles.dataTable.sortBy('Name', 'asc'); + await personalFiles.dataTable.spinnerWaitForReload(); + initialSortState = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + }); + + test.afterAll(async () => { + const nodeActionUser1 = await NodesApi.initialize(user1, user1); + const nodeActionUser2 = await NodesApi.initialize(user2, user2); + await nodeActionUser1.deleteCurrentUserNodes(); + await nodeActionUser2.deleteCurrentUserNodes(); + }); + + test.describe('User Tests', () => { + test('[C261137] Size sort order is retained when user logs out and logs back in', async ({ personalFiles, loginPage }) => { + await personalFiles.dataTable.sortBy('Name', 'desc'); + await personalFiles.dataTable.spinnerWaitForReload(); + + const expectedSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + expect(expectedSortData).not.toEqual(initialSortState); + + await loginPage.logoutUser(); + await FileActionsApi.initialize(user1, user1); + await loginPage.loginUser({ username: user1, password: user1 }, { withNavigation: true, waitForLoading: true }); + + const actualSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + expect(actualSortData).toEqual(expectedSortData); + }); + + test('[C261150] Sort order is not retained between different users', async ({ personalFiles, loginPage }) => { + await personalFiles.dataTable.sortBy('Size', 'asc'); + await personalFiles.dataTable.spinnerWaitForReload(); + + const expectedSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + await loginPage.logoutUser(); + await FileActionsApi.initialize(user2, user2); + await loginPage.loginUser( + { username: user2, password: user2 }, + { + withNavigation: true, + waitForLoading: true + } + ); + + const actualSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + expect(actualSortData).not.toEqual(expectedSortData); + }); + }); +}); diff --git a/e2e/playwright/list-views/src/tests/sort-list.spec.ts b/e2e/playwright/list-views/src/tests/sort-list.spec.ts new file mode 100644 index 0000000000..3804ac7819 --- /dev/null +++ b/e2e/playwright/list-views/src/tests/sort-list.spec.ts @@ -0,0 +1,282 @@ +/*! + * Copyright © 2005-2023 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 { expect } from '@playwright/test'; +import { ApiClientFactory, FavoritesPageApi, FileActionsApi, LoginPage, NodesApi, TEST_FILES, test, timeouts } from '@alfresco/playwright-shared'; + +test.describe('Remember sorting', () => { + interface NodesIds { + [index: string]: string; + } + + const timestamp = new Date().getTime(); + const user1 = `userSort1-${timestamp}`; + const user2 = `userSort2-${timestamp}`; + const pdfFileNames = [...new Array(14).fill(100)].map((v, i) => `file-${v + i}.pdf`); + const jpgFileNames = [...new Array(12).fill(114)].map((v, i) => `file-${v + i}.jpg`); + const folderToMove = `folder1`; + const folderToContain = `folder2`; + const uiCreatedFolder = `folder3`; + + const testData = { + user1: { + files: { + jpg: jpgFileNames, + pdf: pdfFileNames + } + }, + user2: { + files: [pdfFileNames[0], jpgFileNames[0]] + } + }; + + let initialSortState: { + sortingColumn: string; + sortingOrder: string; + firstElement: string; + }; + let nodeActionUser1: NodesApi; + + test.beforeAll(async () => { + test.setTimeout(timeouts.extendedTest); + const apiClientFactory = new ApiClientFactory(); + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username: user1 }); + await apiClientFactory.createUser({ username: user2 }); + const fileActionUser1 = await FileActionsApi.initialize(user1, user1); + const fileActionUser2 = await FileActionsApi.initialize(user2, user2); + const favoritesActions = await FavoritesPageApi.initialize(user1, user1); + nodeActionUser1 = await NodesApi.initialize(user1, user1); + const filesIdsUser1: NodesIds = {}; + const filesIdsUser2: NodesIds = {}; + await Promise.all( + testData.user1.files.pdf.map( + async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) + ) + ); + await Promise.all( + testData.user1.files.jpg.map( + async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.JPG_FILE.path, i, '-my-')).entry.id) + ) + ); + await Promise.all( + testData.user2.files.map( + async (i) => (filesIdsUser2[i] = (await fileActionUser2.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) + ) + ); + await favoritesActions.addFavoritesByIds('file', [filesIdsUser1[pdfFileNames[0]], filesIdsUser1[pdfFileNames[1]]]); + }); + + test.beforeEach(async ({ page, personalFiles }) => { + const loginPage = new LoginPage(page); + await loginPage.loginUser( + { username: user1, password: user1 }, + { + withNavigation: true, + waitForLoading: true + } + ); + await personalFiles.dataTable.sortBy('Name', 'asc'); + await personalFiles.dataTable.spinnerWaitForReload(); + initialSortState = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + }); + + test.afterAll(async () => { + nodeActionUser1 = await NodesApi.initialize(user1, user1); + const nodeActionUser2 = await NodesApi.initialize(user2, user2); + await nodeActionUser1.deleteCurrentUserNodes(); + await nodeActionUser2.deleteCurrentUserNodes(); + }); + + test('[C261136] Sort order is retained when navigating to another part of the app', async ({ personalFiles, favoritePage }) => { + await personalFiles.dataTable.sortBy('Name', 'desc'); + await personalFiles.dataTable.spinnerWaitForReload(); + + const expectedSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + expect(expectedSortData).not.toEqual(initialSortState); + + await favoritePage.navigate(); + await personalFiles.navigate(); + + const actualSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + expect(actualSortData).toEqual(expectedSortData); + }); + + test('[C589205] Size sort order is retained after viewing a file and closing the viewer', async ({ personalFiles }) => { + await personalFiles.dataTable.sortBy('Size', 'desc'); + await personalFiles.dataTable.spinnerWaitForReload(); + + const expectedSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + await personalFiles.dataTable.performClickFolderOrFileToOpen(expectedSortData.firstElement); + await personalFiles.viewer.closeButtonLocator.click(); + await personalFiles.waitForPageLoad(); + + const actualSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + expect(actualSortData).toEqual(expectedSortData); + }); + + test('[C261153] Sort order should be remembered separately on each list view', async ({ personalFiles, favoritePage }) => { + await personalFiles.dataTable.sortBy('Size', 'desc'); + await personalFiles.dataTable.spinnerWaitForReload(); + + const personalFilesSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + await favoritePage.navigate(); + await favoritePage.dataTable.sortBy('Name', 'asc'); + await favoritePage.dataTable.spinnerWaitForReload(); + + const favouritesSortData = { + sortingColumn: await favoritePage.dataTable.getSortedColumnHeaderText(), + sortingOrder: await favoritePage.dataTable.getSortingOrder(), + firstElement: await favoritePage.dataTable.getFirstElementDetail('Name') + }; + + expect(favouritesSortData).not.toEqual(personalFilesSortData); + + await personalFiles.navigate(); + + const personalFilesSortDataAfterFavSort = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + expect(personalFilesSortDataAfterFavSort).toEqual(personalFilesSortData); + }); + + test('[C261147] Sort order is retained when user changes the page from pagination', async ({ personalFiles }) => { + const lastFileInArray = testData.user1.files.jpg.slice(-1).pop(); + const firstFileInArray = testData.user1.files.pdf[0]; + + await personalFiles.pagination.clickOnNextPage(); + await personalFiles.dataTable.spinnerWaitForReload(); + + let expectedPersonalFilesSortDataPage2 = { + sortingColumn: 'Name', + sortingOrder: 'asc', + firstElement: lastFileInArray + }; + + let currentPersonalFilesSortDataPage2 = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + expect(currentPersonalFilesSortDataPage2).toEqual(expectedPersonalFilesSortDataPage2); + + await personalFiles.dataTable.sortBy('Name', 'desc'); + await personalFiles.dataTable.spinnerWaitForReload(); + + expectedPersonalFilesSortDataPage2 = { + sortingColumn: 'Name', + sortingOrder: 'desc', + firstElement: firstFileInArray + }; + + currentPersonalFilesSortDataPage2 = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + expect(expectedPersonalFilesSortDataPage2).toEqual(currentPersonalFilesSortDataPage2); + }); + + test.describe('Folder actions', () => { + test.beforeAll(async () => { + const folderIds: NodesIds = {}; + folderIds[folderToContain] = (await nodeActionUser1.createFolder(folderToContain)).entry.id; + folderIds[folderToMove] = (await nodeActionUser1.createFolder(folderToMove)).entry.id; + }); + + test('[C261138] Sort order is retained when creating a new folder', async ({ personalFiles }) => { + await personalFiles.dataTable.sortBy('Name', 'desc'); + await personalFiles.dataTable.spinnerWaitForReload(); + + const expectedSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: uiCreatedFolder + }; + + await personalFiles.selectCreateFolder(); + await personalFiles.folderDialog.createNewFolderDialog(uiCreatedFolder); + await personalFiles.dataTable.isItemPresent(uiCreatedFolder); + + const actualSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + expect(actualSortData).toEqual(expectedSortData); + }); + + test('[C261139] Sort order is retained when moving a file', async ({ personalFiles }) => { + const expectedSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: folderToContain + }; + await personalFiles.copyOrMoveContentInDatatable([folderToMove], folderToContain, 'Move'); + await personalFiles.dataTable.spinnerWaitForReload(); + const actualSortData = { + sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await personalFiles.dataTable.getSortingOrder(), + firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') + }; + + expect(actualSortData).toEqual(expectedSortData); + }); + }); +}); diff --git a/e2e/playwright/list-views/src/tests/trash-admin.spec.ts b/e2e/playwright/list-views/src/tests/trash-admin.spec.ts new file mode 100755 index 0000000000..b84eda52e1 --- /dev/null +++ b/e2e/playwright/list-views/src/tests/trash-admin.spec.ts @@ -0,0 +1,63 @@ +/*! + * Copyright © 2005-2023 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 { expect } from '@playwright/test'; +import { ApiClientFactory, NodesApi, Utils, getUserState, test } from '@alfresco/playwright-shared'; + +test.use({ storageState: getUserState('admin') }); +test.describe('Trash admin', () => { + const folderAdmin = `deleteFolder-${Utils.random()}`; + let folderAdminId: string; + let adminApiActions: NodesApi; + + test.beforeAll(async () => { + try { + const apiClientFactory = new ApiClientFactory(); + await apiClientFactory.setUpAcaBackend('admin'); + adminApiActions = await NodesApi.initialize('admin'); + folderAdminId = (await adminApiActions.createFolder(folderAdmin)).entry.id; + await adminApiActions.deleteNodeById(folderAdminId, false); + } catch (error) { + console.error(`----- beforeAll failed : ${error}`); + } + }); + + test.afterAll(async () => { + try { + await adminApiActions.deleteDeletedNode(folderAdminId); + } catch (error) { + console.error(`----- afterAll failed : ${error}`); + } + }); + + test.describe('as admin', () => { + test('[C213217] has the correct columns', async ({ trashPage }) => { + await trashPage.navigate(); + const expectedColumns = ['Name', 'Location', 'Size', 'Deleted', 'Deleted by']; + const actualColumns = await trashPage.dataTable.getColumnHeaders(); + + expect(actualColumns).toEqual(expectedColumns); + }); + }); +}); diff --git a/e2e/protractor/protractor.excludes.json b/e2e/protractor/protractor.excludes.json index c96b1052fa..3e61b1fd1b 100644 --- a/e2e/protractor/protractor.excludes.json +++ b/e2e/protractor/protractor.excludes.json @@ -1,5 +1,4 @@ { - "C589205": "https://alfresco.atlassian.net/browse/ACA-4353", "C261153": "https://alfresco.atlassian.net/browse/AAE-7517", "C306959": "https://alfresco.atlassian.net/browse/ACA-4620", "C213134": "temp, see https://alfresco.atlassian.net/browse/ACS-5189", diff --git a/e2e/protractor/suites/list-views/empty-list.test.ts b/e2e/protractor/suites/list-views/empty-list.test.ts index cdcc0a09d2..e620c61cb4 100755 --- a/e2e/protractor/suites/list-views/empty-list.test.ts +++ b/e2e/protractor/suites/list-views/empty-list.test.ts @@ -37,13 +37,6 @@ describe('Empty list views', () => { await loginPage.loginWith(username); }); - it('[C217099] empty My Libraries', async () => { - await page.goToMyLibraries(); - expect(await dataTable.isEmpty()).toBe(true, 'list is not empty'); - expect(await dataTable.getEmptyStateTitle()).toContain(`You aren't a member of any File Libraries yet`); - expect(await dataTable.getEmptyStateSubtitle()).toContain('Join libraries to upload, view, and share files.'); - }); - it('[C289911] empty Favorite Libraries', async () => { await page.goToFavoriteLibraries(); expect(await dataTable.isEmpty()).toBe(true, 'list is not empty'); @@ -65,14 +58,6 @@ describe('Empty list views', () => { expect(await dataTable.getEmptyStateSubtitle()).toContain('Favorite items that you want to easily find later.'); }); - it('[C280134] empty Trash', async () => { - await page.clickTrash(); - expect(await dataTable.isEmpty()).toBe(true, 'list is not empty'); - expect(await dataTable.getEmptyStateTitle()).toContain('Trash is empty'); - expect(await dataTable.getEmptyListText()).toContain('Items you delete are moved to the Trash.'); - expect(await dataTable.getEmptyListText()).toContain('Empty Trash to permanently delete items.'); - }); - it('[C280111] Favorites - pagination controls not displayed', async () => { await page.clickFavorites(); expect(await pagination.isRangePresent()).toBe(false, 'Range is present'); @@ -133,21 +118,6 @@ describe('Empty list views', () => { expect(await pagination.isNextButtonPresent()).toBe(false, 'Next button is present'); }); - it('[C290123] Search results - pagination controls not displayed', async () => { - await toolbar.clickSearchIconButton(); - await searchInput.clickSearchButton(); - /* cspell:disable-next-line */ - await searchInput.searchFor('qwertyuiop'); - await dataTable.waitForBody(); - - expect(await pagination.isRangePresent()).toBe(false, 'Range is present'); - expect(await pagination.isMaxItemsPresent()).toBe(false, 'Max items is present'); - expect(await pagination.isCurrentPagePresent()).toBe(false, 'Current page is present'); - expect(await pagination.isTotalPagesPresent()).toBe(false, 'Total pages is present'); - expect(await pagination.isPreviousButtonPresent()).toBe(false, 'Previous button is present'); - expect(await pagination.isNextButtonPresent()).toBe(false, 'Next button is present'); - }); - it('[C290020] Empty Search results - Libraries', async () => { await page.goToMyLibraries(); await toolbar.clickSearchIconButton(); @@ -160,17 +130,4 @@ describe('Empty list views', () => { expect(await dataTable.isEmpty()).toBe(true, 'list is not empty'); expect(await dataTable.emptySearchText.getText()).toContain('Your search returned 0 results'); }); - - it('[C290031] Empty Search results - Files / Folders', async () => { - await page.clickPersonalFiles(); - await toolbar.clickSearchIconButton(); - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - /* cspell:disable-next-line */ - await searchInput.searchFor('qwertyuiop'); - await dataTable.waitForBody(); - - expect(await dataTable.isEmpty()).toBe(true, 'list is not empty'); - expect(await dataTable.emptySearchText.getText()).toContain('Your search returned 0 results'); - }); }); diff --git a/e2e/protractor/suites/list-views/generic-errors.test.ts b/e2e/protractor/suites/list-views/generic-errors.test.ts deleted file mode 100755 index 71b6eead7b..0000000000 --- a/e2e/protractor/suites/list-views/generic-errors.test.ts +++ /dev/null @@ -1,104 +0,0 @@ -/*! - * Copyright © 2005-2023 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 { browser } from 'protractor'; -import { AdminActions, UserActions, LoginPage, BrowsingPage, Utils, RepoClient } from '@alfresco/aca-testing-shared'; -import { Logger } from '@alfresco/adf-testing'; - -describe('Generic errors', () => { - const username = `user-${Utils.random()}`; - const username2 = `user2-${Utils.random()}`; - - const parent = `folder-${Utils.random()}`; - let parentId: string; - const file1 = `file1-${Utils.random()}.txt`; - let file1Id: string; - const file2 = `file2-${Utils.random()}.txt`; - - const apis = { - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable } = page; - - const adminApiActions = new AdminActions(); - const userActions = new UserActions(); - - beforeAll(async () => { - try { - await adminApiActions.createUser({ username }); - await adminApiActions.createUser({ username: username2 }); - await userActions.login(username, username); - - parentId = await apis.user.createFolder(parent); - file1Id = await apis.user.createFile(file1, parentId); - await apis.user.nodes.createFile(file2, parentId); - - await loginPage.loginWith(username); - } catch (error) { - Logger.error(`----- beforeAll failed : ${error}`); - } - }); - - afterAll(async () => { - await userActions.login(username, username); - await userActions.deleteNodes([parentId]); - await userActions.emptyTrashcan(); - }); - - it('[C217313] File / folder not found', async () => { - await page.clickPersonalFilesAndWait(); - await dataTable.doubleClickOnRowByName(parent); - await dataTable.doubleClickOnRowByName(file1); - const URL = await browser.getCurrentUrl(); - await userActions.deleteNodes([file1Id], false); - await browser.get(URL); - - expect(await page.genericError.isDisplayed()).toBe(true, 'Generic error page not displayed'); - expect(await page.genericErrorTitle.getText()).toContain(`This item no longer exists or you don't have permission to view it.`); - }); - - it('[C217315] Invalid URL', async () => { - await page.load('/invalid page'); - - expect(await page.genericError.isDisplayed()).toBe(true, 'Generic error page not displayed'); - expect(await page.genericErrorTitle.getText()).toContain(`This item no longer exists or you don't have permission to view it.`); - }); - - it('[C217314] Permission denied', async () => { - await page.clickPersonalFilesAndWait(); - await dataTable.doubleClickOnRowByName(parent); - await dataTable.doubleClickOnRowByName(file2); - const URL = await browser.getCurrentUrl(); - await loginPage.loginWith(username2); - await browser.get(URL); - - expect(await page.genericError.isDisplayed()).toBe(true, 'Generic error page not displayed'); - expect(await page.genericErrorTitle.getText()).toContain(`This item no longer exists or you don't have permission to view it.`); - - await loginPage.loginWith(username); - }); -}); diff --git a/e2e/protractor/suites/list-views/permissions.test.ts b/e2e/protractor/suites/list-views/permissions.test.ts deleted file mode 100755 index b79ed7001b..0000000000 --- a/e2e/protractor/suites/list-views/permissions.test.ts +++ /dev/null @@ -1,177 +0,0 @@ -/*! - * Copyright © 2005-2023 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 { AdminActions, UserActions, SITE_VISIBILITY, SITE_ROLES, LoginPage, BrowsingPage, Utils, RepoClient } from '@alfresco/aca-testing-shared'; - -describe('Special permissions', () => { - const username = `user-${Utils.random()}`; - - const apis = { - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable, toolbar } = page; - const { searchInput } = page.pageLayoutHeader; - - const adminApiActions = new AdminActions(); - const userActions = new UserActions(); - - beforeAll(async () => { - await adminApiActions.createUser({ username }); - }); - - describe('file not displayed if user no longer has permissions on it', () => { - const sitePrivate = `private-${Utils.random()}`; - const fileName = `file-${Utils.random()}.txt`; - let fileId: string; - - beforeAll(async () => { - await adminApiActions.login(); - await adminApiActions.sites.createSite(sitePrivate, SITE_VISIBILITY.PRIVATE); - await adminApiActions.sites.addSiteMember(sitePrivate, username, SITE_ROLES.SITE_COLLABORATOR.ROLE); - const docLibId = await adminApiActions.sites.getDocLibId(sitePrivate); - fileId = (await adminApiActions.nodes.createFile(fileName, docLibId)).entry.id; - await apis.user.favorites.addFavoriteById('file', fileId); - - await adminApiActions.login(); - await adminApiActions.shareNodes([fileId]); - await apis.user.nodes.updateNodeContent(fileId, 'edited by user'); - - await apis.user.search.waitForApi(username, { expect: 1 }); - - await adminApiActions.login(); - await adminApiActions.shared.waitForFilesToBeShared([fileId]); - - await loginPage.loginWith(username); - }); - - afterEach(async () => { - await adminApiActions.sites.addSiteMember(sitePrivate, username, SITE_ROLES.SITE_COLLABORATOR.ROLE); - }); - - afterAll(async () => { - await adminApiActions.sites.deleteSite(sitePrivate); - }); - - it('[C213173] on Recent Files', async () => { - await page.clickRecentFilesAndWait(); - expect(await dataTable.getRowsCount()).toBe(1, 'Incorrect number of items'); - await adminApiActions.sites.deleteSiteMember(sitePrivate, username); - await page.refresh(); - expect(await dataTable.isEmpty()).toBe(true, 'Items are still displayed'); - }); - - it('[C213227] on Favorites', async () => { - await page.clickFavoritesAndWait(); - expect(await dataTable.getRowsCount()).toBe(1, 'Incorrect number of items'); - await adminApiActions.sites.deleteSiteMember(sitePrivate, username); - await page.refresh(); - expect(await dataTable.isEmpty()).toBe(true, 'Items are still displayed'); - }); - - it('[C213116] on Shared Files', async () => { - await page.clickSharedFilesAndWait(); - expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not displayed`); - await adminApiActions.sites.deleteSiteMember(sitePrivate, username); - await page.refresh(); - expect(await dataTable.isItemPresent(fileName)).toBe(false, `${fileName} is displayed`); - }); - - it('[C290122] on Search Results', async () => { - await toolbar.clickSearchIconButton(); - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - await searchInput.searchFor(fileName); - await dataTable.waitForBody(); - - expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} is not displayed`); - - await adminApiActions.sites.deleteSiteMember(sitePrivate, username); - - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - await searchInput.searchFor(fileName); - await dataTable.waitForBody(); - - expect(await dataTable.isItemPresent(fileName)).toBe(false, `${fileName} is displayed`); - }); - }); - - describe(`Location column is empty if user doesn't have permissions on the file's parent folder`, () => { - const sitePrivate = `private-${Utils.random()}`; - const fileName = `file-${Utils.random()}.txt`; - let fileId; - - beforeAll(async () => { - await adminApiActions.sites.createSite(sitePrivate, SITE_VISIBILITY.PRIVATE); - await adminApiActions.sites.addSiteMember(sitePrivate, username, SITE_ROLES.SITE_COLLABORATOR.ROLE); - const docLibId = await adminApiActions.sites.getDocLibId(sitePrivate); - fileId = (await apis.user.nodes.createFile(fileName, docLibId)).entry.id; - await apis.user.favorites.addFavoriteById('file', fileId); - - await userActions.login(username, username); - await userActions.shareNodes([fileId]); - await apis.user.shared.waitForFilesToBeShared([fileId]); - - await apis.user.search.waitForApi(username, { expect: 1 }); - await adminApiActions.sites.deleteSiteMember(sitePrivate, username); - await loginPage.loginWith(username); - }); - - afterAll(async () => { - await adminApiActions.sites.deleteSite(sitePrivate); - }); - - it('[C213178] on Recent Files', async () => { - await page.clickRecentFilesAndWait(); - expect(await dataTable.getRowsCount()).toBe(1, 'Incorrect number of items'); - expect(await dataTable.getItemLocation(fileName)).toEqual('Unknown'); - }); - - it('[C213672] on Favorites', async () => { - await page.clickFavoritesAndWait(); - expect(await dataTable.getRowsCount()).toBe(1, 'Incorrect number of items'); - expect(await dataTable.getItemLocation(fileName)).toEqual('Unknown'); - }); - - it(`[C213668] on Shared Files`, async () => { - await page.clickSharedFilesAndWait(); - expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not displayed`); - expect(await dataTable.getItemLocation(fileName)).toEqual('Unknown'); - }); - - it('[C306868] on Search results', async () => { - await toolbar.clickSearchIconButton(); - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - await searchInput.searchFor(fileName); - await dataTable.waitForBody(); - - expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} is not displayed`); - expect(await dataTable.getItemLocation(fileName)).toEqual('Unknown'); - }); - }); -}); diff --git a/e2e/protractor/suites/list-views/sort-list.test.ts b/e2e/protractor/suites/list-views/sort-list.test.ts deleted file mode 100644 index d826938b17..0000000000 --- a/e2e/protractor/suites/list-views/sort-list.test.ts +++ /dev/null @@ -1,348 +0,0 @@ -/*! - * Copyright © 2005-2023 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 { AdminActions, LoginPage, RepoClient, FILES, BrowsingPage, DataTable, CreateOrEditFolderDialog } from '@alfresco/aca-testing-shared'; -import { BrowserActions, ContentNodeSelectorDialogPage, DocumentListPage, PaginationPage, ViewerPage } from '@alfresco/adf-testing'; - -describe('Remember sorting', () => { - interface NodesIds { - [index: string]: string; - } - - const timestamp = new Date().getTime(); - const user1 = `user1-${timestamp}`; - const user2 = `user2-${timestamp}`; - const pdfFileNames = [...new Array(14).fill(100)].map((v, i) => `file-${v + i}.pdf`); - const jpgFileNames = [...new Array(12).fill(114)].map((v, i) => `file-${v + i}.jpg`); - const folderToMove = `folder1`; - const folderToContain = `folder2`; - const uiCreatedFolder = `folder3`; - const filesIdsUser1: NodesIds = {}; - const filesIdsUser2: NodesIds = {}; - const folderIds: NodesIds = {}; - - const testData = { - user1: { - files: { - jpg: jpgFileNames, - pdf: pdfFileNames - } - }, - user2: { - files: [pdfFileNames[0], jpgFileNames[0]] - } - }; - - let initialSortState: { - sortingColumn: string; - sortingOrder: string; - firstElement: string; - }; - - const apis = { - user1: new RepoClient(user1, user1), - user2: new RepoClient(user2, user2) - }; - - const loginPage = new LoginPage(); - const browsingPage = new BrowsingPage(); - const dataTable = new DataTable(); - const documentListPage = new DocumentListPage(); - const viewerPage = new ViewerPage(); - const adminApiActions = new AdminActions(); - const createDialog = new CreateOrEditFolderDialog(); - const contentNodeSelectorDialogPage = new ContentNodeSelectorDialogPage(); - const paginationPage = new PaginationPage(); - - beforeAll(async () => { - await adminApiActions.createUser({ username: user1 }); - await adminApiActions.createUser({ username: user2 }); - await Promise.all( - testData.user1.files.pdf.map( - async (i) => (filesIdsUser1[i] = (await apis.user1.upload.uploadFileWithRename(FILES.pdfFile, '-my-', i)).entry.id) - ) - ); - await Promise.all( - testData.user1.files.jpg.map( - async (i) => (filesIdsUser1[i] = (await apis.user1.upload.uploadFileWithRename(FILES.jpgFile, '-my-', i)).entry.id) - ) - ); - await Promise.all( - testData.user2.files.map(async (i) => (filesIdsUser2[i] = (await apis.user2.upload.uploadFileWithRename(FILES.pdfFile, '-my-', i)).entry.id)) - ); - await apis.user1.favorites.addFavoritesByIds('file', [filesIdsUser1[pdfFileNames[0]], filesIdsUser1[pdfFileNames[1]]]); - await loginPage.loginWith(user1); - }); - - beforeEach(async () => { - await browsingPage.clickPersonalFilesAndWait(); - await dataTable.sortBy('Name', 'asc'); - await dataTable.waitForBody(); - initialSortState = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - }); - - afterAll(async () => { - await Promise.all(Object.keys(filesIdsUser1).map((i) => apis.user1.nodes.deleteNodeById(filesIdsUser1[i]))); - await Promise.all(Object.keys(filesIdsUser2).map((i) => apis.user2.nodes.deleteNodeById(filesIdsUser2[i]))); - }); - - it('[C261136] Sort order is retained when navigating to another part of the app', async () => { - await dataTable.sortBy('Name', 'desc'); - await dataTable.waitForFirstElementToChange(initialSortState.firstElement); - await dataTable.waitForBody(); - - const expectedSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - expect(expectedSortData).not.toEqual(initialSortState); - - await browsingPage.clickFavorites(); - await browsingPage.clickPersonalFilesAndWait(); - - const actualSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - expect(actualSortData).toEqual(expectedSortData); - }); - - it('[C261137] Size sort order is retained when user logs out and logs back in', async () => { - await dataTable.sortBy('Name', 'desc'); - await dataTable.waitForFirstElementToChange(initialSortState.firstElement); - await dataTable.waitForBody(); - - const expectedSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - expect(expectedSortData).not.toEqual(initialSortState); - - await browsingPage.signOut(); - await loginPage.loginWith(user1); - - const actualSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - expect(actualSortData).toEqual(expectedSortData); - }); - - describe('Folder actions', () => { - beforeAll(async () => { - folderIds[folderToContain] = (await apis.user1.nodes.createFolder(folderToContain)).entry.id; - folderIds[folderToMove] = (await apis.user1.nodes.createFolder(folderToMove)).entry.id; - }); - - afterAll(async () => { - folderIds[uiCreatedFolder] = await apis.user1.nodes.getNodeIdFromParent(uiCreatedFolder, '-my-'); - await Promise.all(Object.keys(folderIds).map((i) => apis.user1.nodes.deleteNodeById(folderIds[i]))); - }); - - it('[C261138] Sort order is retained when creating a new folder', async () => { - await dataTable.sortBy('Name', 'desc'); - await dataTable.waitForFirstElementToChange(initialSortState.firstElement); - await dataTable.waitForBody(); - - const expectedSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: uiCreatedFolder - }; - - await browsingPage.sidenav.openCreateFolderDialog(); - await createDialog.waitForDialogToOpen(); - await createDialog.enterName(uiCreatedFolder); - await BrowserActions.click(createDialog.createButton); - await createDialog.waitForDialogToClose(); - await documentListPage.dataTable.checkRowContentIsDisplayed(uiCreatedFolder); - - const actualSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - expect(actualSortData).toEqual(expectedSortData); - }); - - it('[C261139] Sort order is retained when moving a file', async () => { - const expectedSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: folderToContain - }; - - await browsingPage.dataTable.rightClickOnItem(folderToMove); - await dataTable.menu.clickMenuItem('Move'); - await contentNodeSelectorDialogPage.clickContentNodeSelectorResult(folderToContain); - await contentNodeSelectorDialogPage.clickMoveCopyButton(); - await documentListPage.dataTable.checkRowContentIsNotDisplayed(folderToMove); - - const actualSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - expect(actualSortData).toEqual(expectedSortData); - }); - }); - - it('[C589205] Size sort order is retained after viewing a file and closing the viewer', async () => { - await dataTable.sortBy('Size', 'desc'); - await dataTable.waitForFirstElementToChange(initialSortState.firstElement); - await dataTable.waitForBody(); - - const expectedSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - await dataTable.doubleClickOnRowByName(expectedSortData.firstElement); - await viewerPage.clickCloseButton(); - await browsingPage.clickPersonalFilesAndWait(); - - const actualSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - expect(actualSortData).toEqual(expectedSortData); - }); - - it('[C261153] Sort order should be remembered separately on each list view', async () => { - await dataTable.sortBy('Size', 'desc'); - await dataTable.waitForFirstElementToChange(initialSortState.firstElement); - await dataTable.waitForBody(); - - const personalFilesSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - await browsingPage.clickFavoritesAndWait(); - await dataTable.sortBy('Name', 'asc'); - await dataTable.waitForFirstElementToChange(personalFilesSortData.firstElement); - await dataTable.waitForBody(); - - const favouritesSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - expect(favouritesSortData).not.toEqual(personalFilesSortData); - - await browsingPage.clickPersonalFilesAndWait(); - - const personalFilesSortDataAfterFavSort = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - expect(personalFilesSortDataAfterFavSort).toEqual(personalFilesSortData); - }); - - it('[C261147] Sort order is retained when user changes the page from pagination', async () => { - const lastFileInArray = testData.user1.files.jpg.slice(-1).pop(); - const firstFileInArray = testData.user1.files.pdf[0]; - - await paginationPage.clickOnNextPage(); - await dataTable.waitForBody(); - - let expectedPersonalFilesSortDataPage2 = { - sortingColumn: 'Name', - sortingOrder: 'asc', - firstElement: lastFileInArray - }; - - let currentPersonalFilesSortDataPage2 = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - expect(currentPersonalFilesSortDataPage2).toEqual(expectedPersonalFilesSortDataPage2); - - await dataTable.sortBy('Name', 'desc'); - await dataTable.waitForFirstElementToChange(currentPersonalFilesSortDataPage2.firstElement); - await dataTable.waitForBody(); - - expectedPersonalFilesSortDataPage2 = { - sortingColumn: 'Name', - sortingOrder: 'desc', - firstElement: firstFileInArray - }; - - currentPersonalFilesSortDataPage2 = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - expect(expectedPersonalFilesSortDataPage2).toEqual(currentPersonalFilesSortDataPage2); - }); - - it('[C261150] Sort order is not retained between different users', async () => { - await dataTable.sortBy('Size', 'asc'); - await dataTable.waitForFirstElementToChange(initialSortState.firstElement); - await dataTable.waitForBody(); - - const expectedSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - await browsingPage.signOut(); - await loginPage.loginWith(user2); - - const actualSortData = { - sortingColumn: await dataTable.getSortedColumnHeaderText(), - sortingOrder: await dataTable.getSortingOrder(), - firstElement: await documentListPage.dataTable.getFirstElementDetail('Name') - }; - - expect(actualSortData).not.toEqual(expectedSortData); - - await browsingPage.signOut(); - }); -}); diff --git a/e2e/protractor/suites/list-views/trash.test.ts b/e2e/protractor/suites/list-views/trash.test.ts deleted file mode 100755 index b6cae2a866..0000000000 --- a/e2e/protractor/suites/list-views/trash.test.ts +++ /dev/null @@ -1,123 +0,0 @@ -/*! - * Copyright © 2005-2023 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 { AdminActions, UserActions, SITE_VISIBILITY, SITE_ROLES, LoginPage, BrowsingPage, Utils, RepoClient } from '@alfresco/aca-testing-shared'; -import { Logger } from '@alfresco/adf-testing'; - -describe('Trash', () => { - const username = `user-${Utils.random()}`; - - const siteName = `site-${Utils.random()}`; - const fileSite = `file-${Utils.random()}.txt`; - let fileSiteId: string; - - const folderAdmin = `folder-${Utils.random()}`; - let folderAdminId: string; - const fileAdmin = `file-${Utils.random()}.txt`; - let fileAdminId: string; - - const folderUser = `folder-${Utils.random()}`; - let folderUserId: string; - const fileUser = `file-${Utils.random()}.txt`; - let fileUserId: string; - - const folderDeleted = `folder-${Utils.random()}`; - let folderDeletedId: string; - const fileDeleted = `file-${Utils.random()}.txt`; - let fileDeletedId: string; - - const folderNotDeleted = `folder-${Utils.random()}`; - let folderNotDeletedId: string; - const fileInFolder = `file-${Utils.random()}.txt`; - let fileInFolderId: string; - - const apis = { - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable } = page; - - const adminApiActions = new AdminActions(); - const userActions = new UserActions(); - - beforeAll(async () => { - try { - await adminApiActions.createUser({ username }); - - fileAdminId = (await adminApiActions.nodes.createFiles([fileAdmin])).entry.id; - folderAdminId = (await adminApiActions.nodes.createFolders([folderAdmin])).entry.id; - await adminApiActions.sites.createSite(siteName, SITE_VISIBILITY.PUBLIC); - await adminApiActions.sites.addSiteMember(siteName, username, SITE_ROLES.SITE_MANAGER.ROLE); - const docLibId = await adminApiActions.sites.getDocLibId(siteName); - fileSiteId = (await adminApiActions.nodes.createFile(fileSite, docLibId)).entry.id; - - await adminApiActions.nodes.deleteNodesById([fileAdminId, folderAdminId], false); - - fileUserId = (await apis.user.nodes.createFiles([fileUser])).entry.id; - folderUserId = (await apis.user.nodes.createFolders([folderUser])).entry.id; - folderDeletedId = (await apis.user.nodes.createFolder(folderDeleted)).entry.id; - fileDeletedId = (await apis.user.nodes.createFiles([fileDeleted], folderDeleted)).entry.id; - folderNotDeletedId = (await apis.user.nodes.createFolder(folderNotDeleted)).entry.id; - fileInFolderId = (await apis.user.nodes.createFiles([fileInFolder], folderNotDeleted)).entry.id; - - await apis.user.nodes.deleteNodesById([fileSiteId, fileUserId, folderUserId, fileInFolderId, fileDeletedId, folderDeletedId], false); - } catch (error) { - Logger.error(`----- beforeAll failed : ${error}`); - } - }); - - afterAll(async () => { - try { - await adminApiActions.login(); - await adminApiActions.deleteSites([siteName]); - await adminApiActions.trashcanApi.deleteDeletedNode(fileAdminId); - await adminApiActions.trashcanApi.deleteDeletedNode(folderAdminId); - - await userActions.login(username, username); - await userActions.deleteNodes([folderNotDeletedId]); - await userActions.emptyTrashcan(); - } catch (error) { - Logger.error(`----- afterAll failed : ${error}`); - } - }); - - describe('as admin', () => { - beforeAll(async () => { - await loginPage.loginWithAdmin(); - }); - - beforeEach(async () => { - await page.clickTrashAndWait(); - }); - - it('[C213217] has the correct columns', async () => { - const expectedColumns = ['Name', 'Location', 'Size', 'Deleted', 'Deleted by']; - const actualColumns = await dataTable.getColumnHeadersText(); - - expect(actualColumns).toEqual(expectedColumns); - }); - }); -}); diff --git a/projects/aca-playwright-shared/src/api/file-actions.ts b/projects/aca-playwright-shared/src/api/file-actions.ts index f2883c5383..2b57cd6532 100644 --- a/projects/aca-playwright-shared/src/api/file-actions.ts +++ b/projects/aca-playwright-shared/src/api/file-actions.ts @@ -50,7 +50,13 @@ export class FileActionsApi { }); } - async uploadFileWithRename(fileLocation: string, newName: string, parentId: string = '-my-', title: string = '', description: string = '') { + async uploadFileWithRename( + fileLocation: string, + newName: string, + parentId: string = '-my-', + title: string = '', + description: string = '' + ): Promise { const file = fs.createReadStream(fileLocation); const nodeProps = { properties: { @@ -67,6 +73,7 @@ export class FileActionsApi { try { return await this.apiService.upload.uploadFile(file, '', parentId, nodeProps, opts); } catch (error) { + return null; Logger.error(`${this.constructor.name} ${this.uploadFileWithRename.name}`, error); } } @@ -93,7 +100,7 @@ export class FileActionsApi { async getNodeProperty(nodeId: string, property: string): Promise { try { const node = await this.getNodeById(nodeId); - return (node.entry.properties?.[property]) || ''; + return node.entry.properties?.[property] || ''; } catch (error) { Logger.error(`${this.constructor.name} ${this.getNodeProperty.name}`, error); return ''; @@ -145,7 +152,7 @@ export class FileActionsApi { return this.apiService.search.search(data); } catch (error) { Logger.error(`SearchApi queryNodesNames : catch : `, error); - return new ResultSetPaging; + return new ResultSetPaging(); } } @@ -167,4 +174,24 @@ export class FileActionsApi { Logger.error(`\tExpected: ${data.expect} items, but found ${error}`); } } + + async updateNodeContent( + nodeId: string, + content: string, + majorVersion: boolean = true, + comment?: string, + newName?: string + ): Promise { + try { + const opts = { + majorVersion, + comment, + name: newName + }; + return await this.apiService.nodes.updateNodeContent(nodeId, content, opts); + } catch (error) { + console.error(`${this.constructor.name} ${this.updateNodeContent.name}`, error); + return null; + } + } } diff --git a/projects/aca-playwright-shared/src/api/nodes-api.ts b/projects/aca-playwright-shared/src/api/nodes-api.ts index c83f563888..4037ffd87e 100755 --- a/projects/aca-playwright-shared/src/api/nodes-api.ts +++ b/projects/aca-playwright-shared/src/api/nodes-api.ts @@ -81,6 +81,14 @@ export class NodesApi { } } + async deleteDeletedNode(name: string): Promise { + try { + await this.apiService.trashCan.deleteDeletedNode(name); + } catch (error) { + console.error(`${this.constructor.name} ${this.deleteDeletedNode.name}: ${error}`); + } + } + private async createNode( nodeType: string, name: string, diff --git a/projects/aca-playwright-shared/src/api/sites-api.ts b/projects/aca-playwright-shared/src/api/sites-api.ts index 1b33218104..a2e27f2b3c 100755 --- a/projects/aca-playwright-shared/src/api/sites-api.ts +++ b/projects/aca-playwright-shared/src/api/sites-api.ts @@ -23,7 +23,16 @@ */ import { ApiClientFactory } from './api-client-factory'; -import { Site, SiteBodyCreate, SiteEntry, SiteMemberEntry, SiteMembershipBodyCreate, SiteMembershipBodyUpdate, SiteMembershipRequestBodyCreate, SiteMembershipRequestEntry } from '@alfresco/js-api'; +import { + Site, + SiteBodyCreate, + SiteEntry, + SiteMemberEntry, + SiteMembershipBodyCreate, + SiteMembershipBodyUpdate, + SiteMembershipRequestBodyCreate, + SiteMembershipRequestEntry +} from '@alfresco/js-api'; export class SitesApi { private apiService: ApiClientFactory; @@ -88,7 +97,7 @@ export class SitesApi { return await this.apiService.sites.updateSiteMembership(siteId, userId, siteRole); } catch (error) { console.error(`SitesApi updateSiteMember : catch : `, error); - return new SiteMemberEntry; + return new SiteMemberEntry(); } } @@ -105,7 +114,7 @@ export class SitesApi { return this.updateSiteMember(siteId, userId, role); } else { console.error(`SitesApi addSiteMember : catch : `, error); - return new SiteMemberEntry; + return new SiteMemberEntry(); } } } @@ -141,4 +150,12 @@ export class SitesApi { return null; } } + + async deleteSiteMember(siteId: string, userId: string) { + try { + return await this.apiService.sites.deleteSiteMembership(siteId, userId); + } catch (error) { + console.error(`SitesApi deleteSiteMember : catch : `, error); + } + } } diff --git a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts index 430c3de7ae..1a618fe2ac 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts @@ -44,6 +44,10 @@ export class DataTableComponent extends BaseComponent { sortedColumnHeader = this.getChild(`.adf-datatable__header--sorted-asc .adf-datatable-cell-header-content .adf-datatable-cell-value, .adf-datatable__header--sorted-desc .adf-datatable-cell-header-content .adf-datatable-cell-value`); columnHeaders = this.getChild('.adf-datatable-row .adf-datatable-cell-header .adf-datatable-cell-value'); + emptyList = this.getChild('div.adf-no-content-container'); + emptyListTitle = this.getChild('.adf-empty-content__title'); + emptyListSubtitle = this.getChild('.adf-empty-content__subtitle'); + emptySearchText = this.getChild('.empty-search__text'); /** Locator for row (or rows) */ getRowLocator = this.getChild(`adf-datatable-row`); @@ -123,17 +127,21 @@ export class DataTableComponent extends BaseComponent { getSearchResultLinkByName = (name: string): Locator => this.getChild('.aca-search-results-row span[role="link"]', { hasText: name }); - async sortBy(columnTitle: string, order: 'Ascending' | 'Descending'): Promise { - const columnHeaderLocator = this.getColumnHeaderByTitleLocator(columnTitle); - await this.spinnerWaitForReload(); - await columnHeaderLocator.click(); + getColumnValuesByName = (name: string): Locator => this.getChild(`div[title="${name}"] span`); - const sortAttribute = await columnHeaderLocator.getAttribute('aria-sort'); - if (sortAttribute !== order) { - await columnHeaderLocator.click(); - } + getColumnHeaderByName = (headerTitle: string): Locator => + this.getChild('.adf-datatable-row .adf-datatable-cell-header .adf-datatable-cell-value', { hasText: headerTitle }); - await this.spinnerWaitForReload(); + async sortBy(label: string, order: 'asc' | 'desc'): Promise { + const sortColumn = await this.getSortedColumnHeaderText(); + let sortOrder = await this.getSortingOrder(); + if (sortColumn !== label) { + await this.getColumnHeaderByName(label).click({ force: true }); + sortOrder = await this.getSortingOrder(); + } + if (sortOrder !== order) { + await this.getChild('span[class*="adf-datatable__header--sorted"]').click(); + } } /** @@ -281,4 +289,41 @@ export class DataTableComponent extends BaseComponent { async getRowAllInnerTexts(name: string): Promise { return (await this.getRowByName(name).locator('span').allInnerTexts()).toString(); } + + async getFirstElementDetail(name: string): Promise { + const firstNode = this.getColumnValuesByName(name).first(); + return firstNode.innerText(); + } + + async isEmpty(): Promise { + return this.emptyList.isVisible(); + } + + async getEmptyStateTitle(): Promise { + const isEmpty = await this.isEmpty(); + if (isEmpty) { + return this.emptyListTitle.innerText(); + } + return ''; + } + + async getEmptyStateSubtitle(): Promise { + const isEmpty = await this.isEmpty(); + if (isEmpty) { + return this.emptyListSubtitle.innerText(); + } + return ''; + } + + async getEmptyListText(): Promise { + const isEmpty = await this.isEmpty(); + if (isEmpty) { + return this.getChild('adf-custom-empty-content-template').innerText(); + } + return ''; + } + + async getRowsCount(): Promise { + return this.getRowLocator.count(); + } } diff --git a/projects/aca-playwright-shared/src/page-objects/components/error.component.ts b/projects/aca-playwright-shared/src/page-objects/components/error.component.ts new file mode 100644 index 0000000000..cbdcd16656 --- /dev/null +++ b/projects/aca-playwright-shared/src/page-objects/components/error.component.ts @@ -0,0 +1,36 @@ +/*! + * Copyright © 2005-2023 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 { Page } from '@playwright/test'; +import { BaseComponent } from './base.component'; + +export class ErrorComponent extends BaseComponent { + private static rootElement = 'aca-page-layout'; + genericError = this.getChild('aca-generic-error'); + genericErrorTitle = this.getChild('.generic-error__title'); + + constructor(page: Page) { + super(page, ErrorComponent.rootElement); + } +} diff --git a/projects/aca-playwright-shared/src/page-objects/components/index.ts b/projects/aca-playwright-shared/src/page-objects/components/index.ts index 3083c6a25c..ec64165a7d 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/index.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/index.ts @@ -38,3 +38,4 @@ export * from './search/search-overlay.components'; export * from './breadcrumb/breadcrumb.component'; export * from './sidenav.component'; export * from './aca-header.component'; +export * from './error.component'; diff --git a/projects/aca-playwright-shared/src/page-objects/components/pagination.component.ts b/projects/aca-playwright-shared/src/page-objects/components/pagination.component.ts index cafbcb512c..dd73f11e64 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/pagination.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/pagination.component.ts @@ -105,7 +105,7 @@ export class PaginationComponent extends BaseComponent { if (await this.isNextEnabled()) { await this.nextButton.click(); } - } catch(error) { + } catch (error) { throw new Error(`Failed on previous click: ${error}`); } } @@ -115,7 +115,7 @@ export class PaginationComponent extends BaseComponent { if (await this.isPreviousEnabled()) { await this.previousButton.click(); } - } catch(error) { + } catch (error) { throw new Error(`Failed on previous click: ${error}`); } } @@ -166,4 +166,12 @@ export class PaginationComponent extends BaseComponent { async closeMenu(): Promise { await this.page.keyboard.press('Escape'); } + + async isRangePresent() { + return this.range.isVisible(); + } + + async isMaxItemsPresent() { + return this.maxItems.isVisible(); + } } diff --git a/projects/aca-playwright-shared/src/page-objects/pages/personal-files.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/personal-files.page.ts index af46e02ef8..9d014df8ea 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/personal-files.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/personal-files.page.ts @@ -36,7 +36,8 @@ import { MatMenuComponent, ViewerComponent, SidenavComponent, - PaginationComponent + PaginationComponent, + ErrorComponent } from '../components'; export class PersonalFilesPage extends BasePage { @@ -58,6 +59,7 @@ export class PersonalFilesPage extends BasePage { public sidenav = new SidenavComponent(this.page); public createFromTemplateDialogComponent = new CreateFromTemplateDialogComponent(this.page); public pagination = new PaginationComponent(this.page); + public errorDialog = new ErrorComponent(this.page); async selectCreateFolder(): Promise { await this.acaHeader.createButton.click(); diff --git a/projects/aca-playwright-shared/src/page-objects/pages/trash.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/trash.page.ts index 09a57e123e..848f5367c3 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/trash.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/trash.page.ts @@ -24,7 +24,7 @@ import { Page } from '@playwright/test'; import { BasePage } from './base.page'; -import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent, Breadcrumb } from '../components'; +import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent, Breadcrumb, PaginationComponent } from '../components'; import { AcaHeader } from '../components/aca-header.component'; import { AdfFolderDialogComponent, ViewerOverlayDialogComponent } from '../components/dialogs'; @@ -43,4 +43,5 @@ export class TrashPage extends BasePage { public viewerDialog = new ViewerOverlayDialogComponent(this.page); public sidenav = new SidenavComponent(this.page); public breadcrumb = new Breadcrumb(this.page); + public pagination = new PaginationComponent(this.page); } From 54689aa79f597c953332f4754bab4899dc9a66b9 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Mon, 18 Dec 2023 20:07:55 +0100 Subject: [PATCH 16/23] code fix --- .../src/tests/sort-list-login.spec.ts | 74 +++++++++---------- .../src/api/file-actions.ts | 2 +- 2 files changed, 34 insertions(+), 42 deletions(-) diff --git a/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts b/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts index ef43667102..1ae1e48753 100644 --- a/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts +++ b/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts @@ -23,16 +23,39 @@ */ import { expect } from '@playwright/test'; -import { ApiClientFactory, FileActionsApi, LoginPage, NodesApi, TEST_FILES, test, timeouts } from '@alfresco/playwright-shared'; +import { + ApiClientFactory, + FileActionsApi, + LoginPage, + NodesApi, + PersonalFilesPage, + TEST_FILES, + Utils, + test, + timeouts +} from '@alfresco/playwright-shared'; + +let initialSortState: { + sortingColumn: string; + sortingOrder: string; + firstElement: string; +}; + +async function getSortState(myPersonalFiles: PersonalFilesPage): Promise { + return { + sortingColumn: await myPersonalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await myPersonalFiles.dataTable.getSortingOrder(), + firstElement: await myPersonalFiles.dataTable.getFirstElementDetail('Name') + }; +} -test.describe('Remember sorting', () => { +test.describe.only('Remember sorting', () => { interface NodesIds { [index: string]: string; } - const timestamp = new Date().getTime(); - const user1 = `userSortLogin1-${timestamp}`; - const user2 = `userSortLogin2-${timestamp}`; + const user1 = `userSortLogin1-${Utils.random()}`; + const user2 = `userSortLogin2-${Utils.random()}`; const pdfFileNames = [...new Array(14).fill(100)].map((v, i) => `file-${v + i}.pdf`); const jpgFileNames = [...new Array(12).fill(114)].map((v, i) => `file-${v + i}.jpg`); @@ -48,12 +71,6 @@ test.describe('Remember sorting', () => { } }; - let initialSortState: { - sortingColumn: string; - sortingOrder: string; - firstElement: string; - }; - test.beforeAll(async () => { test.setTimeout(timeouts.extendedTest); const apiClientFactory = new ApiClientFactory(); @@ -92,11 +109,7 @@ test.describe('Remember sorting', () => { ); await personalFiles.dataTable.sortBy('Name', 'asc'); await personalFiles.dataTable.spinnerWaitForReload(); - initialSortState = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; + initialSortState = await getSortState(personalFiles); }); test.afterAll(async () => { @@ -110,37 +123,21 @@ test.describe('Remember sorting', () => { test('[C261137] Size sort order is retained when user logs out and logs back in', async ({ personalFiles, loginPage }) => { await personalFiles.dataTable.sortBy('Name', 'desc'); await personalFiles.dataTable.spinnerWaitForReload(); - - const expectedSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; - + const expectedSortData = await getSortState(personalFiles); expect(expectedSortData).not.toEqual(initialSortState); await loginPage.logoutUser(); await FileActionsApi.initialize(user1, user1); await loginPage.loginUser({ username: user1, password: user1 }, { withNavigation: true, waitForLoading: true }); - const actualSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; - + const actualSortData = await getSortState(personalFiles); expect(actualSortData).toEqual(expectedSortData); }); test('[C261150] Sort order is not retained between different users', async ({ personalFiles, loginPage }) => { await personalFiles.dataTable.sortBy('Size', 'asc'); await personalFiles.dataTable.spinnerWaitForReload(); - - const expectedSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; + const expectedSortData = await getSortState(personalFiles); await loginPage.logoutUser(); await FileActionsApi.initialize(user2, user2); @@ -152,12 +149,7 @@ test.describe('Remember sorting', () => { } ); - const actualSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; - + const actualSortData = await getSortState(personalFiles); expect(actualSortData).not.toEqual(expectedSortData); }); }); diff --git a/projects/aca-playwright-shared/src/api/file-actions.ts b/projects/aca-playwright-shared/src/api/file-actions.ts index 2b57cd6532..4285d1a82c 100644 --- a/projects/aca-playwright-shared/src/api/file-actions.ts +++ b/projects/aca-playwright-shared/src/api/file-actions.ts @@ -73,8 +73,8 @@ export class FileActionsApi { try { return await this.apiService.upload.uploadFile(file, '', parentId, nodeProps, opts); } catch (error) { - return null; Logger.error(`${this.constructor.name} ${this.uploadFileWithRename.name}`, error); + return null; } } From f7409c767a637a4c3f5a59d239b637c76be2bd7d Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Tue, 19 Dec 2023 08:22:46 +0100 Subject: [PATCH 17/23] code fix --- e2e/playwright/list-views/src/tests/sort-list-login.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts b/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts index 1ae1e48753..5ecb414c58 100644 --- a/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts +++ b/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts @@ -49,7 +49,7 @@ async function getSortState(myPersonalFiles: PersonalFilesPage): Promise { +test.describe('Remember sorting', () => { interface NodesIds { [index: string]: string; } From bf9a75935e7d629277e25f9810506cd7627de009 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Tue, 19 Dec 2023 10:56:45 +0100 Subject: [PATCH 18/23] code fix --- e2e/playwright/list-views/src/tests/permissions.spec.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/e2e/playwright/list-views/src/tests/permissions.spec.ts b/e2e/playwright/list-views/src/tests/permissions.spec.ts index b557433e63..5f610bb889 100755 --- a/e2e/playwright/list-views/src/tests/permissions.spec.ts +++ b/e2e/playwright/list-views/src/tests/permissions.spec.ts @@ -155,8 +155,6 @@ test.describe('Special permissions', () => { await userShareActionApi.shareFileById(fileId); await userShareActionApi.waitForFilesToBeShared([fileId]); - - // await apis.user.search.waitForApi(username, { expect: 1 }); await adminSiteApiActions.deleteSiteMember(sitePrivate, username); }); From 6e03faf37bf7ba5aca8d37a371ab8d5936ba9c89 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Tue, 19 Dec 2023 14:21:01 +0100 Subject: [PATCH 19/23] code fix --- package-lock.json | 761 +++++++++++++++++++++++++--------------------- package.json | 3 +- 2 files changed, 422 insertions(+), 342 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2262dd14f3..edee6e14fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -69,7 +69,6 @@ "@types/superagent": "^4.1.10", "@typescript-eslint/eslint-plugin": "^5.59.0", "@typescript-eslint/parser": "^5.48.2", - "ajv-cli": "^4.2.0", "dotenv": "16.3.1", "dotenv-expand": "^5.1.0", "eslint": "^8.42.0", @@ -91,7 +90,7 @@ "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "^2.0.0", "karma-mocha-reporter": "^2.2.5", - "lint-staged": "^14.0.1", + "lint-staged": "^15.2.0", "ng-packagr": "^14.2.2", "node-stream-zip": "^1.14.0", "nx": "17.0.2", @@ -10537,54 +10536,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-cli": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/ajv-cli/-/ajv-cli-4.2.0.tgz", - "integrity": "sha512-3Ab8Kuh7QnyXxg+v4NFzah1LLBHgYBUVtJZC8bOaDAdl766kT6Usw5f+g8UcFN+24lYIbchaQBQ+uUntYpBEyQ==", - "dev": true, - "dependencies": { - "ajv": "^7.2.1", - "fast-json-patch": "^2.0.0", - "glob": "^7.1.0", - "js-yaml": "^3.14.0", - "json-schema-migrate": "^1.1.0", - "json5": "^2.1.3", - "minimist": "^1.2.0" - }, - "bin": { - "ajv": "dist/index.js" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/ajv-cli/node_modules/ajv": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.2.4.tgz", - "integrity": "sha512-nBeQgg/ZZA3u3SYxyaDvpvDtgZ/EZPF547ARgZBrG9Bhu1vKDwAIjtIf+sDtJUKa2zOcEbmRLBRSyMraS/Oy1A==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-cli/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/ajv-formats": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", @@ -12124,6 +12075,72 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", + "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/cli-width": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", @@ -14052,12 +14069,6 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -15826,24 +15837,6 @@ "node": ">= 6" } }, - "node_modules/fast-json-patch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-2.2.1.tgz", - "integrity": "sha512-4j5uBaTnsYAV5ebkidvxiLUYOwjQ+JSFljeqfTxCrH9bDmlCQaOJFS84oDJ2rAXZq2yskmk3ORfoP9DCwqFNig==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^2.0.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/fast-json-patch/node_modules/fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -16469,6 +16462,18 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", @@ -20049,37 +20054,6 @@ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "dev": true }, - "node_modules/json-schema-migrate": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/json-schema-migrate/-/json-schema-migrate-1.1.0.tgz", - "integrity": "sha512-PggRuqHB+k1OMz0N1vXCMmwwr8cAsKWVOG5jZh1I2xSyePpRoBG6xOlWG50qe2Ca3hxfWWqZHLEYqJw2/4765g==", - "dev": true, - "dependencies": { - "ajv": "^7.0.0-beta.9" - } - }, - "node_modules/json-schema-migrate/node_modules/ajv": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.2.4.tgz", - "integrity": "sha512-nBeQgg/ZZA3u3SYxyaDvpvDtgZ/EZPF547ARgZBrG9Bhu1vKDwAIjtIf+sDtJUKa2zOcEbmRLBRSyMraS/Oy1A==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/json-schema-migrate/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -20794,71 +20768,32 @@ "dev": true }, "node_modules/lint-staged": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-14.0.1.tgz", - "integrity": "sha512-Mw0cL6HXnHN1ag0mN/Dg4g6sr8uf8sn98w2Oc1ECtFto9tvRF7nkXGJRbx8gPlHyoR0pLyBr2lQHbWwmUHe1Sw==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.0.tgz", + "integrity": "sha512-TFZzUEV00f+2YLaVPWBWGAMq7So6yQx+GG8YRMDeOEIf95Zn5RyiLMsEiX4KTNl9vq/w+NqRJkLA1kPIo15ufQ==", "dev": true, "dependencies": { "chalk": "5.3.0", - "commander": "11.0.0", + "commander": "11.1.0", "debug": "4.3.4", - "execa": "7.2.0", - "lilconfig": "2.1.0", - "listr2": "6.6.1", + "execa": "8.0.1", + "lilconfig": "3.0.0", + "listr2": "8.0.0", "micromatch": "4.0.5", "pidtree": "0.6.0", "string-argv": "0.3.2", - "yaml": "2.3.1" + "yaml": "2.3.4" }, "bin": { "lint-staged": "bin/lint-staged.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=18.12.0" }, "funding": { "url": "https://opencollective.com/lint-staged" } }, - "node_modules/lint-staged/node_modules/ansi-escapes": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", - "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", - "dev": true, - "dependencies": { - "type-fest": "^1.0.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/lint-staged/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/lint-staged/node_modules/chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", @@ -20871,100 +20806,57 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/lint-staged/node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", - "dev": true, - "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/node_modules/cli-truncate": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", - "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", - "dev": true, - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/lint-staged/node_modules/commander": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", - "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "dev": true, "engines": { "node": ">=16" } }, - "node_modules/lint-staged/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/lint-staged/node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true - }, "node_modules/lint-staged/node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", - "signal-exit": "^3.0.7", + "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" }, "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + "node": ">=16.17" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/lint-staged/node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "node_modules/lint-staged/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, "engines": { - "node": ">=14.18.0" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "node_modules/lint-staged/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=16.17.0" } }, "node_modules/lint-staged/node_modules/is-stream": { @@ -20979,48 +20871,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/listr2": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-6.6.1.tgz", - "integrity": "sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==", - "dev": true, - "dependencies": { - "cli-truncate": "^3.1.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^5.0.1", - "rfdc": "^1.3.0", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "node_modules/lint-staged/node_modules/log-update": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", - "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", + "node_modules/lint-staged/node_modules/lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", "dev": true, - "dependencies": { - "ansi-escapes": "^5.0.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^5.0.0", - "strip-ansi": "^7.0.1", - "wrap-ansi": "^8.0.1" - }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=14" } }, "node_modules/lint-staged/node_modules/mimic-fn": { @@ -21077,142 +20934,139 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "node_modules/lint-staged/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/lint-staged/node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/lint-staged/node_modules/restore-cursor/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, "engines": { - "node": ">=6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "node_modules/lint-staged/node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", "dev": true, - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "node": ">= 14" } }, - "node_modules/lint-staged/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "node_modules/listr2": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.0.tgz", + "integrity": "sha512-u8cusxAcyqAiQ2RhYvV7kRKNLgUvtObIbhOX2NCXqvp1UU32xIg5CT22ykS2TPKJXZWJwtK3IKLiqAGlGNE+Zg==", "dev": true, "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.3.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18.0.0" } }, - "node_modules/lint-staged/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/lint-staged/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/lint-staged/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", + "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lint-staged/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" + "ansi-regex": "^6.0.1" }, "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/lint-staged/node_modules/yaml": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", - "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, "engines": { - "node": ">= 14" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/loader-runner": { @@ -21367,6 +21221,193 @@ "node": ">=8" } }, + "node_modules/log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", + "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", + "dev": true, + "dependencies": { + "type-fest": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", + "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/log4js": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", @@ -28180,6 +28221,46 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/slide": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", diff --git a/package.json b/package.json index 8804fd6441..33f0917eac 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,6 @@ "@types/superagent": "^4.1.10", "@typescript-eslint/eslint-plugin": "^5.59.0", "@typescript-eslint/parser": "^5.48.2", - "ajv-cli": "^4.2.0", "dotenv": "16.3.1", "dotenv-expand": "^5.1.0", "eslint": "^8.42.0", @@ -114,7 +113,7 @@ "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "^2.0.0", "karma-mocha-reporter": "^2.2.5", - "lint-staged": "^14.0.1", + "lint-staged": "^15.2.0", "ng-packagr": "^14.2.2", "node-stream-zip": "^1.14.0", "nx": "17.0.2", From e25e96b667e39de2c0cd303afc50909869e94aff Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Wed, 20 Dec 2023 07:20:29 +0100 Subject: [PATCH 20/23] code fix --- .../list-views/src/tests/sort-list-login.spec.ts | 12 ++++-------- .../list-views/src/tests/sort-list.spec.ts | 12 ++++-------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts b/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts index 5ecb414c58..c026e7221e 100644 --- a/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts +++ b/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts @@ -81,21 +81,17 @@ test.describe('Remember sorting', () => { const fileActionUser2 = await FileActionsApi.initialize(user2, user2); const filesIdsUser1: NodesIds = {}; const filesIdsUser2: NodesIds = {}; - await Promise.all( + await Promise.all([ testData.user1.files.pdf.map( async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) - ) - ); - await Promise.all( + ), testData.user1.files.jpg.map( async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.JPG_FILE.path, i, '-my-')).entry.id) - ) - ); - await Promise.all( + ), testData.user2.files.map( async (i) => (filesIdsUser2[i] = (await fileActionUser2.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) ) - ); + ]); }); test.beforeEach(async ({ page, personalFiles }) => { diff --git a/e2e/playwright/list-views/src/tests/sort-list.spec.ts b/e2e/playwright/list-views/src/tests/sort-list.spec.ts index 3804ac7819..16d6e4ba33 100644 --- a/e2e/playwright/list-views/src/tests/sort-list.spec.ts +++ b/e2e/playwright/list-views/src/tests/sort-list.spec.ts @@ -70,21 +70,17 @@ test.describe('Remember sorting', () => { nodeActionUser1 = await NodesApi.initialize(user1, user1); const filesIdsUser1: NodesIds = {}; const filesIdsUser2: NodesIds = {}; - await Promise.all( + await Promise.all([ testData.user1.files.pdf.map( async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) - ) - ); - await Promise.all( + ), testData.user1.files.jpg.map( async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.JPG_FILE.path, i, '-my-')).entry.id) - ) - ); - await Promise.all( + ), testData.user2.files.map( async (i) => (filesIdsUser2[i] = (await fileActionUser2.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) ) - ); + ]); await favoritesActions.addFavoritesByIds('file', [filesIdsUser1[pdfFileNames[0]], filesIdsUser1[pdfFileNames[1]]]); }); From 3d607a86aba77c2beac92f7a69e3ae3ed5c9f542 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Wed, 20 Dec 2023 10:10:38 +0100 Subject: [PATCH 21/23] code fix --- .../list-views/src/tests/sort-list.spec.ts | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/e2e/playwright/list-views/src/tests/sort-list.spec.ts b/e2e/playwright/list-views/src/tests/sort-list.spec.ts index 16d6e4ba33..0de0f0fca0 100644 --- a/e2e/playwright/list-views/src/tests/sort-list.spec.ts +++ b/e2e/playwright/list-views/src/tests/sort-list.spec.ts @@ -23,16 +23,25 @@ */ import { expect } from '@playwright/test'; -import { ApiClientFactory, FavoritesPageApi, FileActionsApi, LoginPage, NodesApi, TEST_FILES, test, timeouts } from '@alfresco/playwright-shared'; +import { + ApiClientFactory, + FavoritesPageApi, + FileActionsApi, + LoginPage, + NodesApi, + TEST_FILES, + Utils, + test, + timeouts +} from '@alfresco/playwright-shared'; test.describe('Remember sorting', () => { interface NodesIds { [index: string]: string; } - const timestamp = new Date().getTime(); - const user1 = `userSort1-${timestamp}`; - const user2 = `userSort2-${timestamp}`; + const user1 = `userSort1-${Utils.random()}`; + const user2 = `userSort2-${Utils.random()}`; const pdfFileNames = [...new Array(14).fill(100)].map((v, i) => `file-${v + i}.pdf`); const jpgFileNames = [...new Array(12).fill(114)].map((v, i) => `file-${v + i}.jpg`); const folderToMove = `folder1`; @@ -70,17 +79,21 @@ test.describe('Remember sorting', () => { nodeActionUser1 = await NodesApi.initialize(user1, user1); const filesIdsUser1: NodesIds = {}; const filesIdsUser2: NodesIds = {}; - await Promise.all([ + await Promise.all( testData.user1.files.pdf.map( async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) - ), + ) + ); + await Promise.all( testData.user1.files.jpg.map( async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.JPG_FILE.path, i, '-my-')).entry.id) - ), + ) + ); + await Promise.all( testData.user2.files.map( async (i) => (filesIdsUser2[i] = (await fileActionUser2.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) ) - ]); + ); await favoritesActions.addFavoritesByIds('file', [filesIdsUser1[pdfFileNames[0]], filesIdsUser1[pdfFileNames[1]]]); }); From f523d03015acbbf7318121246b21b9f4ab1418d7 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Wed, 20 Dec 2023 13:53:40 +0100 Subject: [PATCH 22/23] code fix for review --- .../src/tests/sort-list-login.spec.ts | 152 ------------------ .../list-views/src/tests/sort-list.spec.ts | 148 +++++++---------- .../src/api/file-actions.ts | 22 +-- .../dataTable/data-table.component.ts | 19 +-- .../components/pagination.component.ts | 4 +- 5 files changed, 75 insertions(+), 270 deletions(-) delete mode 100644 e2e/playwright/list-views/src/tests/sort-list-login.spec.ts diff --git a/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts b/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts deleted file mode 100644 index c026e7221e..0000000000 --- a/e2e/playwright/list-views/src/tests/sort-list-login.spec.ts +++ /dev/null @@ -1,152 +0,0 @@ -/*! - * Copyright © 2005-2023 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 { expect } from '@playwright/test'; -import { - ApiClientFactory, - FileActionsApi, - LoginPage, - NodesApi, - PersonalFilesPage, - TEST_FILES, - Utils, - test, - timeouts -} from '@alfresco/playwright-shared'; - -let initialSortState: { - sortingColumn: string; - sortingOrder: string; - firstElement: string; -}; - -async function getSortState(myPersonalFiles: PersonalFilesPage): Promise { - return { - sortingColumn: await myPersonalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await myPersonalFiles.dataTable.getSortingOrder(), - firstElement: await myPersonalFiles.dataTable.getFirstElementDetail('Name') - }; -} - -test.describe('Remember sorting', () => { - interface NodesIds { - [index: string]: string; - } - - const user1 = `userSortLogin1-${Utils.random()}`; - const user2 = `userSortLogin2-${Utils.random()}`; - const pdfFileNames = [...new Array(14).fill(100)].map((v, i) => `file-${v + i}.pdf`); - const jpgFileNames = [...new Array(12).fill(114)].map((v, i) => `file-${v + i}.jpg`); - - const testData = { - user1: { - files: { - jpg: jpgFileNames, - pdf: pdfFileNames - } - }, - user2: { - files: [pdfFileNames[0], jpgFileNames[0]] - } - }; - - test.beforeAll(async () => { - test.setTimeout(timeouts.extendedTest); - const apiClientFactory = new ApiClientFactory(); - await apiClientFactory.setUpAcaBackend('admin'); - await apiClientFactory.createUser({ username: user1 }); - await apiClientFactory.createUser({ username: user2 }); - const fileActionUser1 = await FileActionsApi.initialize(user1, user1); - const fileActionUser2 = await FileActionsApi.initialize(user2, user2); - const filesIdsUser1: NodesIds = {}; - const filesIdsUser2: NodesIds = {}; - await Promise.all([ - testData.user1.files.pdf.map( - async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) - ), - testData.user1.files.jpg.map( - async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.JPG_FILE.path, i, '-my-')).entry.id) - ), - testData.user2.files.map( - async (i) => (filesIdsUser2[i] = (await fileActionUser2.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) - ) - ]); - }); - - test.beforeEach(async ({ page, personalFiles }) => { - const loginPage = new LoginPage(page); - await loginPage.loginUser( - { username: user1, password: user1 }, - { - withNavigation: true, - waitForLoading: true - } - ); - await personalFiles.dataTable.sortBy('Name', 'asc'); - await personalFiles.dataTable.spinnerWaitForReload(); - initialSortState = await getSortState(personalFiles); - }); - - test.afterAll(async () => { - const nodeActionUser1 = await NodesApi.initialize(user1, user1); - const nodeActionUser2 = await NodesApi.initialize(user2, user2); - await nodeActionUser1.deleteCurrentUserNodes(); - await nodeActionUser2.deleteCurrentUserNodes(); - }); - - test.describe('User Tests', () => { - test('[C261137] Size sort order is retained when user logs out and logs back in', async ({ personalFiles, loginPage }) => { - await personalFiles.dataTable.sortBy('Name', 'desc'); - await personalFiles.dataTable.spinnerWaitForReload(); - const expectedSortData = await getSortState(personalFiles); - expect(expectedSortData).not.toEqual(initialSortState); - - await loginPage.logoutUser(); - await FileActionsApi.initialize(user1, user1); - await loginPage.loginUser({ username: user1, password: user1 }, { withNavigation: true, waitForLoading: true }); - - const actualSortData = await getSortState(personalFiles); - expect(actualSortData).toEqual(expectedSortData); - }); - - test('[C261150] Sort order is not retained between different users', async ({ personalFiles, loginPage }) => { - await personalFiles.dataTable.sortBy('Size', 'asc'); - await personalFiles.dataTable.spinnerWaitForReload(); - const expectedSortData = await getSortState(personalFiles); - - await loginPage.logoutUser(); - await FileActionsApi.initialize(user2, user2); - await loginPage.loginUser( - { username: user2, password: user2 }, - { - withNavigation: true, - waitForLoading: true - } - ); - - const actualSortData = await getSortState(personalFiles); - expect(actualSortData).not.toEqual(expectedSortData); - }); - }); -}); diff --git a/e2e/playwright/list-views/src/tests/sort-list.spec.ts b/e2e/playwright/list-views/src/tests/sort-list.spec.ts index 0de0f0fca0..ac61d43280 100644 --- a/e2e/playwright/list-views/src/tests/sort-list.spec.ts +++ b/e2e/playwright/list-views/src/tests/sort-list.spec.ts @@ -27,19 +27,23 @@ import { ApiClientFactory, FavoritesPageApi, FileActionsApi, - LoginPage, NodesApi, + PersonalFilesPage, TEST_FILES, Utils, test, timeouts } from '@alfresco/playwright-shared'; -test.describe('Remember sorting', () => { - interface NodesIds { - [index: string]: string; - } +async function getSortState(myPersonalFiles: PersonalFilesPage): Promise<{ [key: string]: string }> { + return { + sortingColumn: await myPersonalFiles.dataTable.getSortedColumnHeaderText(), + sortingOrder: await myPersonalFiles.dataTable.getSortingOrder(), + firstElement: await myPersonalFiles.dataTable.getFirstElementDetail('Name') + }; +} +test.describe('Remember sorting', () => { const user1 = `userSort1-${Utils.random()}`; const user2 = `userSort2-${Utils.random()}`; const pdfFileNames = [...new Array(14).fill(100)].map((v, i) => `file-${v + i}.pdf`); @@ -60,11 +64,7 @@ test.describe('Remember sorting', () => { } }; - let initialSortState: { - sortingColumn: string; - sortingOrder: string; - firstElement: string; - }; + let initialSortState: { [key: string]: string }; let nodeActionUser1: NodesApi; test.beforeAll(async () => { @@ -77,8 +77,8 @@ test.describe('Remember sorting', () => { const fileActionUser2 = await FileActionsApi.initialize(user2, user2); const favoritesActions = await FavoritesPageApi.initialize(user1, user1); nodeActionUser1 = await NodesApi.initialize(user1, user1); - const filesIdsUser1: NodesIds = {}; - const filesIdsUser2: NodesIds = {}; + const filesIdsUser1: { [key: string]: string } = {}; + const filesIdsUser2: { [key: string]: string } = {}; await Promise.all( testData.user1.files.pdf.map( async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) @@ -97,8 +97,8 @@ test.describe('Remember sorting', () => { await favoritesActions.addFavoritesByIds('file', [filesIdsUser1[pdfFileNames[0]], filesIdsUser1[pdfFileNames[1]]]); }); - test.beforeEach(async ({ page, personalFiles }) => { - const loginPage = new LoginPage(page); + test.beforeEach(async ({ loginPage, personalFiles }) => { + await NodesApi.initialize(user1, user1); await loginPage.loginUser( { username: user1, password: user1 }, { @@ -108,11 +108,7 @@ test.describe('Remember sorting', () => { ); await personalFiles.dataTable.sortBy('Name', 'asc'); await personalFiles.dataTable.spinnerWaitForReload(); - initialSortState = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; + initialSortState = await getSortState(personalFiles); }); test.afterAll(async () => { @@ -126,79 +122,43 @@ test.describe('Remember sorting', () => { await personalFiles.dataTable.sortBy('Name', 'desc'); await personalFiles.dataTable.spinnerWaitForReload(); - const expectedSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; - + const expectedSortData = await getSortState(personalFiles); expect(expectedSortData).not.toEqual(initialSortState); await favoritePage.navigate(); await personalFiles.navigate(); - const actualSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; - + const actualSortData = await getSortState(personalFiles); expect(actualSortData).toEqual(expectedSortData); }); test('[C589205] Size sort order is retained after viewing a file and closing the viewer', async ({ personalFiles }) => { await personalFiles.dataTable.sortBy('Size', 'desc'); await personalFiles.dataTable.spinnerWaitForReload(); - - const expectedSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; + const expectedSortData = await getSortState(personalFiles); await personalFiles.dataTable.performClickFolderOrFileToOpen(expectedSortData.firstElement); await personalFiles.viewer.closeButtonLocator.click(); await personalFiles.waitForPageLoad(); - const actualSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; - + const actualSortData = await getSortState(personalFiles); expect(actualSortData).toEqual(expectedSortData); }); test('[C261153] Sort order should be remembered separately on each list view', async ({ personalFiles, favoritePage }) => { await personalFiles.dataTable.sortBy('Size', 'desc'); await personalFiles.dataTable.spinnerWaitForReload(); - - const personalFilesSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; + const personalFilesSortData = await getSortState(personalFiles); await favoritePage.navigate(); await favoritePage.dataTable.sortBy('Name', 'asc'); await favoritePage.dataTable.spinnerWaitForReload(); - const favouritesSortData = { - sortingColumn: await favoritePage.dataTable.getSortedColumnHeaderText(), - sortingOrder: await favoritePage.dataTable.getSortingOrder(), - firstElement: await favoritePage.dataTable.getFirstElementDetail('Name') - }; - + const favouritesSortData = await getSortState(personalFiles); expect(favouritesSortData).not.toEqual(personalFilesSortData); await personalFiles.navigate(); - - const personalFilesSortDataAfterFavSort = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; - + const personalFilesSortDataAfterFavSort = await getSortState(personalFiles); expect(personalFilesSortDataAfterFavSort).toEqual(personalFilesSortData); }); @@ -215,35 +175,24 @@ test.describe('Remember sorting', () => { firstElement: lastFileInArray }; - let currentPersonalFilesSortDataPage2 = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; - + let currentPersonalFilesSortDataPage2 = await getSortState(personalFiles); expect(currentPersonalFilesSortDataPage2).toEqual(expectedPersonalFilesSortDataPage2); await personalFiles.dataTable.sortBy('Name', 'desc'); await personalFiles.dataTable.spinnerWaitForReload(); - expectedPersonalFilesSortDataPage2 = { sortingColumn: 'Name', sortingOrder: 'desc', firstElement: firstFileInArray }; - currentPersonalFilesSortDataPage2 = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; - + currentPersonalFilesSortDataPage2 = await getSortState(personalFiles); expect(expectedPersonalFilesSortDataPage2).toEqual(currentPersonalFilesSortDataPage2); }); test.describe('Folder actions', () => { test.beforeAll(async () => { - const folderIds: NodesIds = {}; + const folderIds: { [key: string]: string } = {}; folderIds[folderToContain] = (await nodeActionUser1.createFolder(folderToContain)).entry.id; folderIds[folderToMove] = (await nodeActionUser1.createFolder(folderToMove)).entry.id; }); @@ -262,12 +211,7 @@ test.describe('Remember sorting', () => { await personalFiles.folderDialog.createNewFolderDialog(uiCreatedFolder); await personalFiles.dataTable.isItemPresent(uiCreatedFolder); - const actualSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; - + const actualSortData = await getSortState(personalFiles); expect(actualSortData).toEqual(expectedSortData); }); @@ -279,13 +223,43 @@ test.describe('Remember sorting', () => { }; await personalFiles.copyOrMoveContentInDatatable([folderToMove], folderToContain, 'Move'); await personalFiles.dataTable.spinnerWaitForReload(); - const actualSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: await personalFiles.dataTable.getFirstElementDetail('Name') - }; + const actualSortData = await getSortState(personalFiles); + expect(actualSortData).toEqual(expectedSortData); + }); + }); + + test.describe('User Tests', () => { + test('[C261137] Size sort order is retained when user logs out and logs back in', async ({ personalFiles, loginPage }) => { + await personalFiles.dataTable.sortBy('Name', 'desc'); + await personalFiles.dataTable.spinnerWaitForReload(); + const expectedSortData = await getSortState(personalFiles); + expect(expectedSortData).not.toEqual(initialSortState); + + await loginPage.logoutUser(); + await FileActionsApi.initialize(user1, user1); + await loginPage.loginUser({ username: user1, password: user1 }, { withNavigation: true, waitForLoading: true }); + const actualSortData = await getSortState(personalFiles); expect(actualSortData).toEqual(expectedSortData); }); + + test('[C261150] Sort order is not retained between different users', async ({ personalFiles, loginPage }) => { + await personalFiles.dataTable.sortBy('Size', 'asc'); + await personalFiles.dataTable.spinnerWaitForReload(); + const expectedSortData = await getSortState(personalFiles); + + await loginPage.logoutUser(); + await FileActionsApi.initialize(user2, user2); + await loginPage.loginUser( + { username: user2, password: user2 }, + { + withNavigation: true, + waitForLoading: true + } + ); + + const actualSortData = await getSortState(personalFiles); + expect(actualSortData).not.toEqual(expectedSortData); + }); }); }); diff --git a/projects/aca-playwright-shared/src/api/file-actions.ts b/projects/aca-playwright-shared/src/api/file-actions.ts index 4285d1a82c..6b41de50e4 100644 --- a/projects/aca-playwright-shared/src/api/file-actions.ts +++ b/projects/aca-playwright-shared/src/api/file-actions.ts @@ -41,7 +41,7 @@ export class FileActionsApi { return classObj; } - async uploadFile(fileLocation: string, fileName: string, parentFolderId: string): Promise { + async uploadFile(fileLocation: string, fileName: string, parentFolderId: string): Promise { const file = fs.createReadStream(fileLocation); return this.apiService.upload.uploadFile(file, '', parentFolderId, null, { name: fileName, @@ -56,7 +56,7 @@ export class FileActionsApi { parentId: string = '-my-', title: string = '', description: string = '' - ): Promise { + ): Promise { const file = fs.createReadStream(fileLocation); const nodeProps = { properties: { @@ -74,11 +74,11 @@ export class FileActionsApi { return await this.apiService.upload.uploadFile(file, '', parentId, nodeProps, opts); } catch (error) { Logger.error(`${this.constructor.name} ${this.uploadFileWithRename.name}`, error); - return null; + return Promise.reject(error); } } - async lockNodes(nodeIds: string[], lockType: string = 'ALLOW_OWNER_CHANGES') { + async lockNodes(nodeIds: string[], lockType: string = 'ALLOW_OWNER_CHANGES'): Promise { try { for (const nodeId of nodeIds) { await this.apiService.nodes.lockNode(nodeId, { type: lockType }); @@ -175,23 +175,17 @@ export class FileActionsApi { } } - async updateNodeContent( - nodeId: string, - content: string, - majorVersion: boolean = true, - comment?: string, - newName?: string - ): Promise { + async updateNodeContent(nodeId: string, content: string, majorVersion: boolean = true, comment?: string, newName?: string): Promise { try { const opts = { - majorVersion, - comment, + majorVersion: majorVersion, + comment: comment, name: newName }; return await this.apiService.nodes.updateNodeContent(nodeId, content, opts); } catch (error) { console.error(`${this.constructor.name} ${this.updateNodeContent.name}`, error); - return null; + return Promise.reject(error); } } } diff --git a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts index 1a618fe2ac..95df52d4be 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts @@ -48,6 +48,7 @@ export class DataTableComponent extends BaseComponent { emptyListTitle = this.getChild('.adf-empty-content__title'); emptyListSubtitle = this.getChild('.adf-empty-content__subtitle'); emptySearchText = this.getChild('.empty-search__text'); + emptyListTest = this.getChild('adf-custom-empty-content-template'); /** Locator for row (or rows) */ getRowLocator = this.getChild(`adf-datatable-row`); @@ -300,27 +301,15 @@ export class DataTableComponent extends BaseComponent { } async getEmptyStateTitle(): Promise { - const isEmpty = await this.isEmpty(); - if (isEmpty) { - return this.emptyListTitle.innerText(); - } - return ''; + return (await this.isEmpty()) ? this.emptyListTitle.innerText() : ''; } async getEmptyStateSubtitle(): Promise { - const isEmpty = await this.isEmpty(); - if (isEmpty) { - return this.emptyListSubtitle.innerText(); - } - return ''; + return (await this.isEmpty()) ? this.emptyListSubtitle.innerText() : ''; } async getEmptyListText(): Promise { - const isEmpty = await this.isEmpty(); - if (isEmpty) { - return this.getChild('adf-custom-empty-content-template').innerText(); - } - return ''; + return (await this.isEmpty()) ? this.emptyListTest.innerText() : ''; } async getRowsCount(): Promise { diff --git a/projects/aca-playwright-shared/src/page-objects/components/pagination.component.ts b/projects/aca-playwright-shared/src/page-objects/components/pagination.component.ts index dd73f11e64..ff58672902 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/pagination.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/pagination.component.ts @@ -167,11 +167,11 @@ export class PaginationComponent extends BaseComponent { await this.page.keyboard.press('Escape'); } - async isRangePresent() { + async isRangePresent(): Promise { return this.range.isVisible(); } - async isMaxItemsPresent() { + async isMaxItemsPresent(): Promise { return this.maxItems.isVisible(); } } From ca9258f40c640f91a70c4dd77a1d0650bff4822e Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Thu, 21 Dec 2023 16:52:51 +0100 Subject: [PATCH 23/23] code fix for review --- projects/aca-playwright-shared/src/api/file-actions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/aca-playwright-shared/src/api/file-actions.ts b/projects/aca-playwright-shared/src/api/file-actions.ts index 6b41de50e4..1e67b1957c 100644 --- a/projects/aca-playwright-shared/src/api/file-actions.ts +++ b/projects/aca-playwright-shared/src/api/file-actions.ts @@ -177,7 +177,7 @@ export class FileActionsApi { async updateNodeContent(nodeId: string, content: string, majorVersion: boolean = true, comment?: string, newName?: string): Promise { try { - const opts = { + const opts: { [key: string]: string | boolean } = { majorVersion: majorVersion, comment: comment, name: newName