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] [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}`);