diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index c0f6a5fc9b..9b3dc87f3d 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -127,16 +127,14 @@ jobs: id: 8 - name: "copyMoveActions" id: 9 - - name: "createActions" - id: 10 - name: "deleteActions" - id: 11 + id: 10 - name: "editActions,favoriteActions" - id: 12 + id: 11 - name: "libraryActions" - id: 13 + id: 12 - name: "uploadDownloadActions" - id: 14 + id: 13 steps: - name: Checkout uses: actions/checkout@v3 diff --git a/e2e/playwright/actions/src/tests/create-library.spec.ts b/e2e/playwright/actions/src/tests/create-library.spec.ts index 25f7021351..bde61ce502 100644 --- a/e2e/playwright/actions/src/tests/create-library.spec.ts +++ b/e2e/playwright/actions/src/tests/create-library.spec.ts @@ -23,12 +23,26 @@ */ import { expect } from '@playwright/test'; -import { Utils, ApiClientFactory, getUserState, test, libraryErrors } from '@alfresco/playwright-shared'; -import { SiteBodyCreate } from '@alfresco/js-api'; +import { + Utils, + ApiClientFactory, + test, + libraryErrors, + LoginPage, + SitesApi, + AdfLibraryDialogComponent, + DataTableComponent, + Breadcrumb, + TrashcanApi +} from '@alfresco/playwright-shared'; +import { logger } from '@alfresco/adf-cli/scripts/logger'; -test.use({ storageState: getUserState('hruser') }); test.describe('Create Libraries ', () => { const apiClientFactory = new ApiClientFactory(); + let sitesApi: SitesApi; + let libraryDialog: AdfLibraryDialogComponent; + let libraryTable: DataTableComponent; + let libraryBreadcrumb: Breadcrumb; let randomLibraryName: string; let randomLibraryId: string; let randomLibraryDescription: string; @@ -39,41 +53,59 @@ test.describe('Create Libraries ', () => { const publicVisibility = 'Public'; const moderatedVisibility = 'Moderated'; const privateVisibility = 'Private'; - const deleteAction = 'Delete'; const errorMessageNotPresent = 'Error message is not displayed'; - + const tabKeyString = 'Tab'; + const username = `user-${Utils.random()}`; const commonLibraryName = `playwright-library-${Utils.random()}`; - const commonLibraryId = `libraryId-${Utils.random()}`; const commonTrashLibraryName = `playwright-library-${Utils.random()}`; - const commonTrashLibraryId = `libraryId-${Utils.random()}`; + const createdLibrariesIds: string[] = []; test.beforeAll(async () => { - await apiClientFactory.setUpAcaBackend('hruser'); - await apiClientFactory.sites.createSite({ id: commonLibraryId, title: commonLibraryName, visibility: SiteBodyCreate.VisibilityEnum.PUBLIC }); - await apiClientFactory.sites.createSite({ - id: commonTrashLibraryId, - title: commonTrashLibraryName, - visibility: SiteBodyCreate.VisibilityEnum.PUBLIC - }); - await apiClientFactory.sites.deleteSite(commonTrashLibraryId); + try { + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username }); + sitesApi = await SitesApi.initialize(username, username); + await sitesApi.createSite(commonLibraryName); + createdLibrariesIds.push(commonLibraryName); + await sitesApi.createSite(commonTrashLibraryName); + await sitesApi.deleteSites([commonTrashLibraryName], false); + } catch (error) { + logger.error(`beforeAll failed : ${error}`); + } }); - test.beforeEach(async ({ myLibrariesPage }) => { + test.beforeEach(async ({ myLibrariesPage, page }) => { randomLibraryName = `playwright-library-${Utils.random()}`; randomLibraryId = `libraryId-${Utils.random()}`; randomLibraryDescription = `libraryDescription-${Utils.random()}`; - await myLibrariesPage.navigate(); + libraryDialog = myLibrariesPage.libraryDialog; + const loginPage = new LoginPage(page); + try { + await loginPage.loginUser( + { username: username, password: username }, + { + withNavigation: true, + waitForLoading: true + } + ); + await myLibrariesPage.navigate(); + await myLibrariesPage.selectCreateLibrary(); + } catch (error) { + logger.error(`beforeEach failed : ${error}`); + } }); test.afterAll(async () => { - await apiClientFactory.sites.deleteSite(commonLibraryId, { permanent: true }); + try { + await sitesApi.deleteSites(createdLibrariesIds); + const trashcanApi = await TrashcanApi.initialize(username, username); + await trashcanApi.emptyTrashcan(); + } catch (error) { + logger.error(`afterAll failed : ${error}`); + } }); - test('[C280024] Create Library dialog UI', async ({ myLibrariesPage }) => { - const libraryDialog = myLibrariesPage.libraryDialog; - - await myLibrariesPage.selectCreateLibrary(); - + test('[C280024] Create Library dialog UI', async () => { await expect(libraryDialog.getDialogTitle(libraryDialogTitle)).toBeVisible(); await expect(libraryDialog.getLabelText(libraryNameLabel)).toBeVisible(); await expect(libraryDialog.getLabelText(libraryIdLabel)).toBeVisible(); @@ -86,117 +118,90 @@ test.describe('Create Libraries ', () => { await expect(libraryDialog.createButton).toBeDisabled(); }); - test('[C280025] Create a public library', async ({ myLibrariesPage }) => { - const libraryDialog = myLibrariesPage.libraryDialog; - const libraryTable = myLibrariesPage.dataTable; - - await myLibrariesPage.selectCreateLibrary(); - await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName); - await expect(libraryDialog.getLabelText(libraryNameLabel)).toHaveValue(randomLibraryName); - await expect(libraryDialog.getLabelText(libraryIdLabel)).toHaveValue(randomLibraryName); - await libraryDialog.createButton.click(); - - await myLibrariesPage.navigate(); - await libraryTable.goThroughPagesLookingForRowWithName(randomLibraryName); - await expect(libraryTable.getCellByColumnNameAndRowItem(randomLibraryName, publicVisibility)).toBeVisible(); + test.describe('On My Libraries dataTable', () => { + test.beforeEach(async ({ myLibrariesPage }) => { + libraryTable = myLibrariesPage.dataTable; + libraryBreadcrumb = myLibrariesPage.breadcrumb; + }); - await libraryTable.performActionInExpandableMenu(randomLibraryName, deleteAction); - }); + test('[C280025] Create a public library', async ({ myLibrariesPage }) => { + await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName); + await expect(libraryDialog.getLabelText(libraryNameLabel)).toHaveValue(randomLibraryName); + await expect(libraryDialog.getLabelText(libraryIdLabel)).toHaveValue(randomLibraryName); + await libraryDialog.createButton.click(); + await expect(libraryBreadcrumb.getItemByTitle(randomLibraryName)).toBeVisible(); - test('[C289880] Create a moderated library', async ({ myLibrariesPage }) => { - const libraryDialog = myLibrariesPage.libraryDialog; - const libraryTable = myLibrariesPage.dataTable; + await myLibrariesPage.navigate(); + await expect(libraryTable.getCellByColumnNameAndRowItem(randomLibraryName, publicVisibility)).toBeVisible(); - await myLibrariesPage.selectCreateLibrary(); - await libraryDialog.createLibraryWithNameAndId(randomLibraryName, randomLibraryId, null, moderatedVisibility); + createdLibrariesIds.push(randomLibraryName); + }); - await myLibrariesPage.navigate(); - await libraryTable.goThroughPagesLookingForRowWithName(randomLibraryName); - await expect(libraryTable.getCellByColumnNameAndRowItem(randomLibraryName, moderatedVisibility)).toBeVisible(); + test('[C289880] Create a moderated library', async ({ myLibrariesPage }) => { + await libraryDialog.createLibraryWithNameAndId(randomLibraryName, randomLibraryId, null, moderatedVisibility); + await expect(libraryBreadcrumb.getItemByTitle(randomLibraryName)).toBeVisible(); - await libraryTable.performActionInExpandableMenu(randomLibraryName, deleteAction); - }); + await myLibrariesPage.navigate(); + await libraryTable.spinnerWaitForReload(); + await expect(libraryTable.getCellByColumnNameAndRowItem(randomLibraryName, moderatedVisibility)).toBeVisible(); - test('[C289881] Create a private library', async ({ myLibrariesPage }) => { - const libraryDialog = myLibrariesPage.libraryDialog; - const libraryTable = myLibrariesPage.dataTable; + createdLibrariesIds.push(randomLibraryId); + }); - await myLibrariesPage.selectCreateLibrary(); - await libraryDialog.createLibraryWithNameAndId(randomLibraryName, randomLibraryId, null, privateVisibility); + test('[C289881] Create a private library', async ({ myLibrariesPage }) => { + await libraryDialog.createLibraryWithNameAndId(randomLibraryName, randomLibraryId, null, privateVisibility); + await expect(libraryBreadcrumb.getItemByTitle(randomLibraryName)).toBeVisible(); - await myLibrariesPage.navigate(); - await libraryTable.goThroughPagesLookingForRowWithName(randomLibraryName); - await expect(libraryTable.getCellByColumnNameAndRowItem(randomLibraryName, privateVisibility)).toBeVisible(); + await myLibrariesPage.navigate(); + await expect(libraryTable.getCellByColumnNameAndRowItem(randomLibraryName, privateVisibility)).toBeVisible(); - await libraryTable.performActionInExpandableMenu(randomLibraryName, deleteAction); - }); + createdLibrariesIds.push(randomLibraryId); + }); - test('[C289882] Create a library with a given ID and description', async ({ myLibrariesPage }) => { - const libraryDialog = myLibrariesPage.libraryDialog; - const libraryTable = myLibrariesPage.dataTable; - const libraryViewDetails = myLibrariesPage.acaHeader.viewDetails; - const libraryDetails = myLibrariesPage.libraryDetails; - - await myLibrariesPage.selectCreateLibrary(); - await libraryDialog.createLibraryWithNameAndId(randomLibraryName, randomLibraryId, randomLibraryDescription); - - await myLibrariesPage.navigate(); - await libraryTable.goThroughPagesLookingForRowWithName(randomLibraryName); - await expect(libraryTable.getCellLinkByName(randomLibraryName).and(myLibrariesPage.page.getByTitle(randomLibraryDescription))).toBeVisible(); - await libraryTable.getRowByName(randomLibraryName).click(); - await libraryViewDetails.click(); - expect(await libraryDetails.getNameField('Name').locator('input').inputValue()).toBe(randomLibraryName); - expect(await libraryDetails.getIdField('Library ID').locator('input').inputValue()).toBe(randomLibraryId); - await expect(libraryDetails.getVisibilityField('Visibility').locator('.mat-select-value').getByText(publicVisibility)).toBeVisible(); - expect(await libraryDetails.getDescriptionField.inputValue()).toBe(randomLibraryDescription); - - await apiClientFactory.sites.deleteSite(randomLibraryId, { permanent: true }); - }); + test('[C289882] Create a library with a given ID and description', async ({ myLibrariesPage }) => { + const libraryViewDetails = myLibrariesPage.acaHeader.viewDetails; + const libraryDetails = myLibrariesPage.libraryDetails; - test('[C280027] Duplicate library ID', async ({ myLibrariesPage }) => { - const libraryDialog = myLibrariesPage.libraryDialog; + await libraryDialog.createLibraryWithNameAndId(randomLibraryName, randomLibraryId, randomLibraryDescription); + await expect(libraryBreadcrumb.getItemByTitle(randomLibraryName)).toBeVisible(); - await myLibrariesPage.selectCreateLibrary(); - await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName); - await libraryDialog.getLabelText(libraryIdLabel).clear(); - await libraryDialog.getLabelText(libraryIdLabel).fill(commonLibraryId); - await libraryDialog.page.keyboard.press('Tab'); - await expect(libraryDialog.getLabelText(libraryIdLabel)).toHaveValue(commonLibraryId); + await myLibrariesPage.navigate(); + await expect(libraryTable.getCellLinkByName(randomLibraryName).and(myLibrariesPage.page.getByTitle(randomLibraryDescription))).toBeVisible(); + await libraryTable.getRowByName(randomLibraryName).click(); + await libraryViewDetails.click(); + expect(await libraryDetails.getNameField('Name').locator('input').inputValue()).toBe(randomLibraryName); + expect(await libraryDetails.getIdField('Library ID').locator('input').inputValue()).toBe(randomLibraryId); + await expect(libraryDetails.getVisibilityField('Visibility').locator('.mat-select-value').getByText(publicVisibility)).toBeVisible(); + expect(await libraryDetails.getDescriptionField.inputValue()).toBe(randomLibraryDescription); - await expect(libraryDialog.createButton).toBeDisabled(); - expect(await libraryDialog.isErrorMessageDisplayed(libraryErrors.libraryIdIsNotAvailable), errorMessageNotPresent).toBe(true); - }); + createdLibrariesIds.push(randomLibraryId); + }); - test('[C280028] Create library using the ID of a library from the Trashcan', async ({ myLibrariesPage }) => { - const libraryDialog = myLibrariesPage.libraryDialog; + test('[C280029] Cancel button', async () => { + await expect(libraryDialog.getDialogTitle(libraryDialogTitle)).toBeVisible(); + await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName); + await libraryDialog.cancelButton.click(); - await myLibrariesPage.selectCreateLibrary(); - await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName); - await libraryDialog.getLabelText(libraryIdLabel).clear(); - await libraryDialog.getLabelText(libraryIdLabel).fill(commonTrashLibraryId); - await libraryDialog.page.keyboard.press('Tab'); + await expect(libraryDialog.getDialogTitle(libraryDialogTitle)).toBeHidden(); + await expect(libraryTable.getRowByName(randomLibraryName)).toHaveCount(0); + }); - await expect(libraryDialog.createButton).toBeEnabled(); - await libraryDialog.createButton.click(); - await expect(libraryDialog.createButton).toBeDisabled(); - expect(await libraryDialog.isErrorMessageDisplayed(libraryErrors.libraryIdIsAlreadyUsed), errorMessageNotPresent).toBe(true); - }); + test('[C280030] Create 2 libraries with same name but different IDs', async ({ myLibrariesPage }) => { + const libraryName = commonLibraryName + ' (' + commonLibraryName + ')'; + const libraryName2 = commonLibraryName + ' (' + randomLibraryId + ')'; - test('[C280029] Cancel button', async ({ myLibrariesPage }) => { - const libraryDialog = myLibrariesPage.libraryDialog; - const libraryTable = myLibrariesPage.dataTable; + await libraryDialog.createLibraryWithNameAndId(commonLibraryName, randomLibraryId); + await expect(libraryBreadcrumb.getItemByTitle(commonLibraryName)).toBeVisible(); - await myLibrariesPage.selectCreateLibrary(); - await expect(libraryDialog.getDialogTitle(libraryDialogTitle)).toBeVisible(); - await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName); - await libraryDialog.cancelButton.click(); + await myLibrariesPage.navigate(); + await expect(libraryTable.getRowByName(libraryName)).toBeVisible(); + await expect(libraryTable.getRowByName(libraryName2)).toBeVisible(); - await expect(libraryDialog.getDialogTitle(libraryDialogTitle)).toBeHidden(); - await expect(libraryTable.getRowByName(randomLibraryName)).toHaveCount(0); + createdLibrariesIds.push(randomLibraryId); + }); }); - test('[C280026] Library ID cannot contain special characters', async ({ myLibrariesPage }) => { - const libraryDialog = myLibrariesPage.libraryDialog; + test('[C280026] Library ID cannot contain special characters', async () => { const idsWithSpecialChars = [ 'a!a', 'a@a', @@ -217,34 +222,38 @@ test.describe('Create Libraries ', () => { 'a|a' ]; - await myLibrariesPage.selectCreateLibrary(); await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName); for (const specialLibraryId of idsWithSpecialChars) { await libraryDialog.getLabelText(libraryIdLabel).clear(); await libraryDialog.getLabelText(libraryIdLabel).fill(specialLibraryId); - await libraryDialog.page.keyboard.press('Tab'); + await libraryDialog.page.keyboard.press(tabKeyString); await expect(libraryDialog.getLabelText(libraryIdLabel)).toHaveValue(specialLibraryId); expect(await libraryDialog.isErrorMessageDisplayed(libraryErrors.useNumbersAndLettersOnly), errorMessageNotPresent).toBe(true); await expect(libraryDialog.createButton).toBeDisabled(); } }); - test('[C280030] Create 2 libraries with same name but different IDs', async ({ myLibrariesPage }) => { - const libraryDialog = myLibrariesPage.libraryDialog; - const libraryTable = myLibrariesPage.dataTable; - const libraryName = commonLibraryName + ' (' + commonLibraryId + ')'; - const libraryName2 = commonLibraryName + ' (' + randomLibraryId + ')'; + test('[C280027] Duplicate library ID', async () => { + await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName); + await libraryDialog.getLabelText(libraryIdLabel).clear(); + await libraryDialog.getLabelText(libraryIdLabel).fill(commonLibraryName); + await libraryDialog.page.keyboard.press(tabKeyString); + await expect(libraryDialog.getLabelText(libraryIdLabel)).toHaveValue(commonLibraryName); - await myLibrariesPage.selectCreateLibrary(); - await libraryDialog.createLibraryWithNameAndId(commonLibraryName, randomLibraryId); + await expect(libraryDialog.createButton).toBeDisabled(); + expect(await libraryDialog.isErrorMessageDisplayed(libraryErrors.libraryIdIsNotAvailable), errorMessageNotPresent).toBe(true); + }); - await myLibrariesPage.navigate(); - await libraryTable.goThroughPagesLookingForRowWithName(libraryName); - await expect(libraryTable.getRowByName(libraryName)).toBeVisible(); - await libraryTable.goThroughPagesLookingForRowWithName(libraryName2); - await expect(libraryTable.getRowByName(libraryName2)).toBeVisible(); + test('[C280028] Create library using the ID of a library from the Trashcan', async () => { + await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName); + await libraryDialog.getLabelText(libraryIdLabel).clear(); + await libraryDialog.getLabelText(libraryIdLabel).fill(commonTrashLibraryName); + await libraryDialog.page.keyboard.press(tabKeyString); - await apiClientFactory.sites.deleteSite(randomLibraryId, { permanent: true }); + await expect(libraryDialog.createButton).toBeEnabled(); + await libraryDialog.createButton.click(); + await expect(libraryDialog.createButton).toBeDisabled(); + expect(await libraryDialog.isErrorMessageDisplayed(libraryErrors.libraryIdIsAlreadyUsed), errorMessageNotPresent).toBe(true); }); }); diff --git a/projects/aca-playwright-shared/src/api/index.ts b/projects/aca-playwright-shared/src/api/index.ts index 0d7a98d447..a855779580 100644 --- a/projects/aca-playwright-shared/src/api/index.ts +++ b/projects/aca-playwright-shared/src/api/index.ts @@ -32,3 +32,4 @@ export * from './nodes-api'; export * from './sites-api'; export * from './node-content-tree'; export * from './search-api'; +export * from './trashcan-api'; diff --git a/projects/aca-playwright-shared/src/api/trashcan-api.ts b/projects/aca-playwright-shared/src/api/trashcan-api.ts new file mode 100644 index 0000000000..b5a4be5949 --- /dev/null +++ b/projects/aca-playwright-shared/src/api/trashcan-api.ts @@ -0,0 +1,58 @@ +/*! + * 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 + * along with Alfresco. If not, see . + */ + +import { ApiClientFactory } from './api-client-factory'; +import { logger } from '@alfresco/adf-cli/scripts/logger'; + +export class TrashcanApi { + private apiService = new ApiClientFactory(); + + static async initialize(userName: string, password?: string): Promise { + const classObj = new TrashcanApi(); + await classObj.apiService.setUpAcaBackend(userName, password); + return classObj; + } + + /** + * Empties the trashcan. Uses multiple batches 1000 nodes each. + */ + async emptyTrashcan(): Promise { + try { + const nodes = await this.apiService.trashCan.listDeletedNodes({ + maxItems: 1000 + }); + + if (nodes?.list?.entries?.length > 0) { + const ids = nodes.list.entries.map((entries) => entries.entry.id); + + for (const nodeId of ids) { + await this.apiService.trashCan.deleteDeletedNode(nodeId); + } + } + } catch (error) { + logger.error('User Actions - emptyTrashcan failed : ', error); + } + } + +}