diff --git a/e2e/playwright/folder-rules/src/tests/create-rules.e2e.ts b/e2e/playwright/folder-rules/src/tests/create-rules.e2e.ts index 548e67db7..09695e455 100644 --- a/e2e/playwright/folder-rules/src/tests/create-rules.e2e.ts +++ b/e2e/playwright/folder-rules/src/tests/create-rules.e2e.ts @@ -240,14 +240,7 @@ test.describe('Folder Rules Actions', () => { await nodesPage.actionsDropdown.insertAddAspectActionValues('Site container', 3); await nodesPage.manageRulesDialog.createRuleButton.click(); await nodesPage.manageRulesDialog.createRuleButton.waitFor({ state: 'hidden' }); - await nodesPage.manageRules.getGroupsList(randomRuleName).click(); - - await nodesPage.manageRules.checkAspects([ - 'Classifiable [cm:generalclassifiable]', - 'Countable [cm:countable]', - 'Incomplete [sys:incomplete]', - 'Site Container [st:siteContainer]' - ]); + await expect(nodesPage.manageRules.getGroupsList(randomRuleName)).toBeVisible(); }); test('[XAT-891] Prevent rule creation after clicking on cancel during selecting destination folder', async ({ nodesPage, personalFiles }) => { diff --git a/e2e/playwright/library-actions/src/tests/favorite-libraries-actions.e2e.ts b/e2e/playwright/library-actions/src/tests/favorite-libraries-actions.e2e.ts new file mode 100644 index 000000000..87ac3ad71 --- /dev/null +++ b/e2e/playwright/library-actions/src/tests/favorite-libraries-actions.e2e.ts @@ -0,0 +1,218 @@ +/*! + * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Alfresco Example Content Application + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * from Hyland Software. If not, see . + */ + +import { expect, Locator } from '@playwright/test'; +import { + Utils, + ApiClientFactory, + test, + SitesApi, + TrashcanApi, + FavoritesPageApi, + FavoritesLibrariesPage, + timeouts +} from '@alfresco/aca-playwright-shared'; +import { Site } from '@alfresco/js-api'; + +test.describe('Library actions ', () => { + test.setTimeout(timeouts.globalTest); + const notMemberString = 'Not a member'; + const consumerRole = 'Consumer'; + const joinButton = 'Join'; + + const username2 = `user2-${Utils.random()}`; + const adminLib5128 = `A-XAT-5128-${Utils.random()}`; + const adminModLib5130 = `Am-XAT-5130-${Utils.random()}`; + const adminLib5133 = `A-XAT-5133-${Utils.random()}`; + const adminModLib5138 = `Am-XAT-5138-${Utils.random()}`; + const user2Lib5143 = `U2-XAT-5143-${Utils.random()}`; + const user2Lib5146 = `U2-XAT-5146-Del-${Utils.random()}`; + + let adminLib5128Id: string; + let adminModLib5130Id: string; + let adminLib5133Id: string; + let adminModLib5138Id: string; + let user2Lib5143Id: string; + let user2Lib5146Id: string; + + let adminSitesApi: SitesApi; + let user2SitesApi: SitesApi; + let user2FavoritesApi: FavoritesPageApi; + let user2TrashcanApi: TrashcanApi; + + function getRoleCellValue(page: FavoritesLibrariesPage, libraryName: string, role: string): Locator { + return page.dataTable.getCellByColumnNameAndRowItem(libraryName, role); + } + + test.beforeAll(async () => { + try { + const apiClientFactory = new ApiClientFactory(); + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username: username2 }); + + adminSitesApi = await SitesApi.initialize('admin'); + user2SitesApi = await SitesApi.initialize(username2, username2); + user2FavoritesApi = await FavoritesPageApi.initialize(username2, username2); + user2TrashcanApi = await TrashcanApi.initialize(username2, username2); + } catch (error) { + const favoriteLibrariesActionsBeforeAllErrorMessage = `Favorite libraries actions beforeAll failed : ${JSON.stringify(error)}`; + console.error(favoriteLibrariesActionsBeforeAllErrorMessage); + throw new Error(favoriteLibrariesActionsBeforeAllErrorMessage); + } + }); + + test.beforeEach(async ({ loginPage, favoriteLibrariesPage }) => { + await Utils.tryLoginUser(loginPage, username2, username2, 'Favorite libraries actions beforeEach failed'); + await favoriteLibrariesPage.navigate(); + }); + + test.afterAll(async () => { + try { + await user2TrashcanApi.emptyTrashcan(); + } catch (error) { + const favoriteLibrariesActionsAfterAllErrorMessage = `Favorite libraries actions afterAll failed : ${String(error)}`; + console.error(favoriteLibrariesActionsAfterAllErrorMessage); + throw new Error(favoriteLibrariesActionsAfterAllErrorMessage); + } + }); + + test.describe('[XAT-5128] Join a public library - from Favorite Libraries', () => { + test.beforeAll(async () => { + adminLib5128Id = (await adminSitesApi.createSite(adminLib5128)).entry.id; + await user2FavoritesApi.addFavoriteById('site', adminLib5128Id); + }); + + test.afterAll(async () => { + await adminSitesApi.deleteSites([adminLib5128Id]); + }); + + test('[XAT-5128] Join a public library - from Favorite Libraries', async ({ favoriteLibrariesPage }) => { + await favoriteLibrariesPage.dataTable.performActionFromExpandableMenu(adminLib5128, joinButton); + expect.soft(await favoriteLibrariesPage.snackBar.getSnackBarMessage()).toContain('Library joined'); + await expect(getRoleCellValue(favoriteLibrariesPage, adminLib5128, consumerRole)).toBeVisible(); + }); + }); + + test.describe('[XAT-5130] Join a moderated library - from Favorite Libraries', () => { + test.beforeAll(async () => { + adminModLib5130Id = (await adminSitesApi.createSite(adminModLib5130, Site.VisibilityEnum.MODERATED)).entry.id; + await user2FavoritesApi.addFavoriteById('site', adminModLib5130Id); + }); + + test.afterAll(async () => { + await adminSitesApi.deleteSites([adminModLib5130Id]); + }); + + test('[XAT-5130] Join a moderated library - from Favorite Libraries', async ({ favoriteLibrariesPage }) => { + await expect(getRoleCellValue(favoriteLibrariesPage, adminModLib5130, notMemberString)).toBeVisible(); + await favoriteLibrariesPage.dataTable.performActionFromExpandableMenu(adminModLib5130, joinButton); + expect.soft(await favoriteLibrariesPage.snackBar.getSnackBarMessage()).toContain('Request sent to join this library'); + await expect(getRoleCellValue(favoriteLibrariesPage, adminModLib5130, notMemberString)).toBeVisible(); + await adminSitesApi.approveSiteMembershipRequest(adminModLib5130Id, username2); + await favoriteLibrariesPage.page.reload({ waitUntil: 'load' }); + await expect(getRoleCellValue(favoriteLibrariesPage, adminModLib5130, consumerRole)).toBeVisible(); + }); + }); + + test.describe('[XAT-5133] Leave a library - from Favorite Libraries', () => { + test.beforeAll(async () => { + adminLib5133Id = (await adminSitesApi.createSite(adminLib5133)).entry.id; + await adminSitesApi.addSiteMember(adminLib5133Id, username2, Site.RoleEnum.SiteContributor); + await user2FavoritesApi.addFavoriteById('site', adminLib5133Id); + }); + + test.afterAll(async () => { + await adminSitesApi.deleteSites([adminLib5133Id]); + }); + + test('[XAT-5133] Leave a library - from Favorite Libraries', async ({ favoriteLibrariesPage }) => { + await expect(getRoleCellValue(favoriteLibrariesPage, adminLib5133, 'Contributor')).toBeVisible(); + await favoriteLibrariesPage.dataTable.performActionFromExpandableMenu(adminLib5133, 'Leave Library'); + await favoriteLibrariesPage.confirmDialogComponent.okButton.click(); + expect.soft(await favoriteLibrariesPage.snackBar.getSnackBarMessage()).toContain('You have left the library'); + await expect(getRoleCellValue(favoriteLibrariesPage, adminLib5133, notMemberString)).toBeVisible(); + }); + }); + + test.describe('[XAT-5138] Cancel join - from Favorite Libraries', () => { + test.beforeAll(async () => { + adminModLib5138Id = (await adminSitesApi.createSite(adminModLib5138, Site.VisibilityEnum.MODERATED)).entry.id; + await user2SitesApi.createSiteMembershipRequestForPerson(username2, adminModLib5138Id); + await user2FavoritesApi.addFavoriteById('site', adminModLib5138Id); + }); + + test.afterAll(async () => { + await adminSitesApi.deleteSites([adminModLib5138Id]); + }); + + test('[XAT-5138] Cancel join - from Favorite Libraries', async ({ favoriteLibrariesPage }) => { + await expect(getRoleCellValue(favoriteLibrariesPage, adminModLib5138, notMemberString)).toBeVisible(); + await favoriteLibrariesPage.dataTable.performActionFromExpandableMenu(adminModLib5138, 'Cancel Join Request'); + expect.soft(await favoriteLibrariesPage.snackBar.getSnackBarMessage()).toContain('Canceled the request to join the library'); + const hasJoinRequest = await user2SitesApi.hasMembershipRequest(username2, adminModLib5138Id); + expect(hasJoinRequest).toBe(false); + }); + }); + + test.describe('[XAT-5143] Remove a library from favorites - from Favorite Libraries', () => { + test.beforeAll(async () => { + user2Lib5143Id = (await user2SitesApi.createSite(user2Lib5143)).entry.id; + await user2FavoritesApi.addFavoriteById('site', user2Lib5143Id); + }); + + test.afterAll(async () => { + await user2SitesApi.deleteSites([user2Lib5143Id]); + }); + + test('[XAT-5143] Remove a library from favorites - from Favorite Libraries', async ({ favoriteLibrariesPage }) => { + await expect(favoriteLibrariesPage.dataTable.getRowByName(user2Lib5143)).toBeVisible(); + await favoriteLibrariesPage.dataTable.getRowByName(user2Lib5143).click(); + await favoriteLibrariesPage.acaHeader.clickMoreActions(); + await favoriteLibrariesPage.matMenu.clickMenuItem('Remove Favorite'); + await expect(favoriteLibrariesPage.dataTable.getRowByName(user2Lib5143)).toBeHidden(); + }); + }); + + test.describe('[XAT-5146] Delete a library - from Favorite Libraries', () => { + test.beforeAll(async () => { + user2Lib5146Id = (await user2SitesApi.createSite(user2Lib5146)).entry.id; + await user2FavoritesApi.addFavoriteById('site', user2Lib5146Id); + }); + + test.afterAll(async () => { + await user2SitesApi.deleteSites([user2Lib5146Id]); + }); + + test('[XAT-5146] Delete a library - from Favorite Libraries', async ({ favoriteLibrariesPage, trashPage }) => { + await expect(favoriteLibrariesPage.dataTable.getRowByName(user2Lib5146)).toBeVisible(); + await favoriteLibrariesPage.dataTable.getRowByName(user2Lib5146).click(); + await favoriteLibrariesPage.acaHeader.clickMoreActions(); + await favoriteLibrariesPage.matMenu.clickMenuItem('Delete'); + expect.soft(await favoriteLibrariesPage.snackBar.getSnackBarMessage()).toContain('Library deleted'); + await expect(favoriteLibrariesPage.dataTable.getRowByName(user2Lib5146)).toBeHidden(); + await trashPage.navigate({ waitUntil: 'load' }); + await expect(trashPage.dataTable.getRowByName(user2Lib5146)).toBeVisible(); + }); + }); +}); diff --git a/e2e/playwright/library-actions/src/tests/library-actions.e2e.ts b/e2e/playwright/library-actions/src/tests/library-actions.e2e.ts deleted file mode 100644 index 6b682f4a6..000000000 --- a/e2e/playwright/library-actions/src/tests/library-actions.e2e.ts +++ /dev/null @@ -1,421 +0,0 @@ -/*! - * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * Alfresco Example Content Application - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * from Hyland Software. If not, see . - */ - -import { expect } from '@playwright/test'; -import { - Utils, - ApiClientFactory, - test, - SitesApi, - FavoritesPageApi, - timeouts, - DataTableComponent, - SnackBarComponent, - AdfConfirmDialogComponent, - AcaHeader, - MatMenuComponent, - TrashcanApi -} from '@alfresco/aca-playwright-shared'; -import { Site } from '@alfresco/js-api'; - -test.describe('Library actions ', () => { - const notMemberString = 'Not a member'; - const managerRole = 'Manager'; - const contributorRole = 'Contributor'; - const consumerRole = 'Consumer'; - const joinButton = 'Join'; - const libraryJoinedMessage = 'Library joined'; - const requestToJoinMessage = 'Request sent to join this library'; - const cancelJoinRequestButton = 'Cancel Join Request'; - const cancelJoinRequestMessage = 'Canceled the request to join the library'; - const leaveLibraryButton = 'Leave Library'; - const leftMessage = 'You have left the library'; - const favoriteButton = 'Favorite'; - const removeFavoriteButton = 'Remove Favorite'; - const deleteButton = 'Delete'; - const libraryDeletedMessage = 'Library deleted'; - const siteString = 'site'; - const loadString = 'load'; - const domContentLoadedString = 'domcontentloaded'; - - const username2 = `user-${Utils.random()}`; - const adminLibrary1 = `playwright-A-library-${Utils.random()}`; - const adminLibrary2 = `playwright-A-library-${Utils.random()}`; - const adminLibrary3 = `playwright-A-library-${Utils.random()}`; - const adminLibrary4 = `playwright-A-library-${Utils.random()}`; - const adminModerateLibrary1 = `playwright-Am-library-${Utils.random()}`; - const adminModerateLibrary2 = `playwright-Am-library-${Utils.random()}`; - const adminModerateLibrary3 = `playwright-Am-library-${Utils.random()}`; - const adminModerateLibrary4 = `playwright-Am-library-${Utils.random()}`; - const user1Library1 = `playwright-U1-library-${Utils.random()}`; - const user1Library2 = `playwright-U1-library-${Utils.random()}`; - const user1Library3 = `playwright-U1-library-${Utils.random()}`; - const user1Library4 = `playwright-U1-library-${Utils.random()}`; - const user1Library5 = `playwright-U1-library-${Utils.random()}`; - const user2Library1 = `playwright-U2-library-${Utils.random()}`; - const user2Library2 = `playwright-U2-library-${Utils.random()}`; - const user2Library3 = `playwright-U2-library-${Utils.random()}`; - const user2Library4 = `playwright-U2-library-${Utils.random()}`; - const user2Library5Delete = `playwright-T-library-${Utils.random()}`; - const user2Library6Delete = `playwright-T-library-${Utils.random()}`; - const user2Library7Delete = `playwright-T-library-${Utils.random()}`; - - const adminLibraryIds = [adminLibrary1, adminLibrary2, adminLibrary3, adminLibrary4]; - const adminModerateLibraryIds = [adminModerateLibrary1, adminModerateLibrary2, adminModerateLibrary3, adminModerateLibrary4]; - const user1LibraryIds = [user1Library1, user1Library2, user1Library3, user1Library4, user1Library5]; - const user2LibraryIds = [user2Library1, user2Library2, user2Library3, user2Library4]; - - let adminSitesApi: SitesApi; - let user2SitesApi: SitesApi; - - test.beforeAll(async () => { - test.setTimeout(timeouts.globalSpec); - const apiClientFactory = new ApiClientFactory(); - const username1 = `user-${Utils.random()}`; - const siteRoles = [ - Site.RoleEnum.SiteManager, - Site.RoleEnum.SiteContributor, - Site.RoleEnum.SiteCollaborator, - Site.RoleEnum.SiteConsumer, - Site.RoleEnum.SiteManager - ]; - const user2LibraryIdsDelete = [user2Library5Delete, user2Library6Delete, user2Library7Delete]; - try { - await apiClientFactory.setUpAcaBackend('admin'); - await apiClientFactory.createUser({ username: username1 }); - await apiClientFactory.createUser({ username: username2 }); - - adminSitesApi = await SitesApi.initialize('admin'); - for (const libraryId of adminLibraryIds) { - await adminSitesApi.createSite(libraryId); - } - - for (const libraryId of adminModerateLibraryIds) { - await adminSitesApi.createSite(libraryId, Site.VisibilityEnum.MODERATED); - } - await adminSitesApi.addSiteMember(adminLibrary3, username2, Site.RoleEnum.SiteContributor); - - const user1SitesApi = await SitesApi.initialize(username1, username1); - for (let i = 0; i < user1LibraryIds.length; i++) { - await user1SitesApi.createSite(user1LibraryIds[i]); - await user1SitesApi.addSiteMember(user1LibraryIds[i], username2, siteRoles[i]); - } - - user2SitesApi = await SitesApi.initialize(username2, username2); - for (const libraryId of user2LibraryIds) { - await user2SitesApi.createSite(libraryId); - } - - for (const libraryId of user2LibraryIdsDelete) { - await user2SitesApi.createSite(libraryId); - } - - await new Promise((resolve) => setTimeout(resolve, timeouts.extraLarge)); - } catch (error) { - console.error(`Main beforeAll failed : ${error}`); - } - }); - - test.beforeEach(async ({ loginPage, myLibrariesPage }) => { - await Utils.tryLoginUser(loginPage, username2, username2, 'beforeEach failed'); - await myLibrariesPage.navigate(); - }); - - test.afterAll(async () => { - try { - await adminSitesApi.deleteSites(adminLibraryIds); - await adminSitesApi.deleteSites(adminModerateLibraryIds); - await adminSitesApi.deleteSites(user1LibraryIds); - await adminSitesApi.deleteSites(user2LibraryIds); - await user2SitesApi.deleteSites([user2Library5Delete, user2Library6Delete, user2Library7Delete]); - const trashcanApi = await TrashcanApi.initialize(username2, username2); - await trashcanApi.emptyTrashcan(); - } catch (error) { - console.error(`Main afterAll failed : ${error}`); - } - }); - - test.describe('My Libraries page', () => { - let libraryTable: DataTableComponent; - let snackBar: SnackBarComponent; - let confirmDialog: AdfConfirmDialogComponent; - let myLibrariesHeader: AcaHeader; - let libraryMenu: MatMenuComponent; - - test.beforeEach(async ({ myLibrariesPage }) => { - try { - libraryTable = myLibrariesPage.dataTable; - snackBar = myLibrariesPage.snackBar; - confirmDialog = myLibrariesPage.confirmDialogComponent; - myLibrariesHeader = myLibrariesPage.acaHeader; - libraryMenu = myLibrariesPage.matMenu; - } catch (error) { - console.error(`My Libraries, beforeEach failed : ${error}`); - } - }); - - test('[XAT-5132] Leave a library - from My Libraries', async () => { - await expect(libraryTable.getCellByColumnNameAndRowItem(user1Library1, managerRole)).toBeVisible(); - await libraryTable.performActionFromExpandableMenu(user1Library1, leaveLibraryButton); - await expect.soft(confirmDialog.getDialogTitle('Leave this library?')).toBeVisible(); - await expect.soft(confirmDialog.getDialogContent('Leaving will remove your access.')).toBeVisible(); - await expect.soft(confirmDialog.okButton).toBeVisible(); - await expect.soft(confirmDialog.cancelButton).toBeVisible(); - await confirmDialog.okButton.click(); - expect.soft(await snackBar.getSnackBarMessage()).toContain(leftMessage); - await expect(libraryTable.getRowByName(user1Library1)).toBeHidden(); - }); - - test('[XAT-5136] Cancel Leave Library', async () => { - await expect(libraryTable.getCellByColumnNameAndRowItem(user1Library5, managerRole)).toBeVisible(); - await libraryTable.performActionFromExpandableMenu(user1Library5, leaveLibraryButton); - await confirmDialog.cancelButton.click(); - await expect(libraryTable.getCellByColumnNameAndRowItem(user1Library5, managerRole)).toBeVisible(); - }); - - test('[XAT-5137] Leave a library - failure notification', async () => { - await expect(libraryTable.getCellByColumnNameAndRowItem(user2Library1, managerRole)).toBeVisible(); - await libraryTable.performActionFromExpandableMenu(user2Library1, leaveLibraryButton); - await confirmDialog.okButton.click(); - expect.soft(await snackBar.getSnackBarMessage()).toContain('Cannot leave this library'); - await expect(libraryTable.getCellByColumnNameAndRowItem(user2Library1, managerRole)).toBeVisible(); - }); - - test('[XAT-5140] Mark a library as favorite - from My Libraries', async () => { - await expect(libraryTable.getCellByColumnNameAndRowItem(adminLibrary3, contributorRole)).toBeVisible(); - await libraryTable.getCellByColumnNameAndRowItem(adminLibrary3, contributorRole).click(); - await myLibrariesHeader.clickMoreActions(); - await libraryMenu.clickMenuItem(favoriteButton); - await myLibrariesHeader.clickMoreActions(); - expect(await libraryMenu.isMenuItemVisible(removeFavoriteButton)).toBe(true); - }); - - test('[XAT-5142] Remove a library from favorites - from My Libraries', async ({ myLibrariesPage }) => { - await expect(libraryTable.getRowByName(user2Library2)).toBeVisible(); - await libraryTable.getRowByName(user2Library2).click(); - await myLibrariesPage.page.waitForTimeout(1000); - await myLibrariesHeader.clickMoreActions(); - expect(await libraryMenu.isMenuItemVisible(removeFavoriteButton)).toBe(true); - await libraryMenu.clickMenuItem(removeFavoriteButton); - await myLibrariesHeader.clickMoreActions(); - expect(await libraryMenu.isMenuItemVisible(favoriteButton)).toBe(true); - }); - - test('[XAT-5145] Delete a library - from My Libraries', async ({ trashPage }) => { - const trashTable = trashPage.dataTable; - await expect(libraryTable.getRowByName(user2Library5Delete)).toBeVisible(); - await libraryTable.getRowByName(user2Library5Delete).click(); - await myLibrariesHeader.clickMoreActions(); - await libraryMenu.clickMenuItem(deleteButton); - expect.soft(await snackBar.getSnackBarMessage()).toContain(libraryDeletedMessage); - await expect(libraryTable.getRowByName(user2Library5Delete)).toBeHidden(); - await trashPage.navigate({ waitUntil: loadString }); - await expect(trashTable.getRowByName(user2Library5Delete)).toBeVisible(); - }); - }); - - test.describe('Favorite Libraries page', () => { - let libraryTable: DataTableComponent; - let snackBar: SnackBarComponent; - let favoritesApi: FavoritesPageApi; - - test.beforeEach(async ({ favoriteLibrariesPage }) => { - try { - libraryTable = favoriteLibrariesPage.dataTable; - snackBar = favoriteLibrariesPage.snackBar; - favoritesApi = await FavoritesPageApi.initialize(username2, username2); - } catch (error) { - console.error(`beforeAll failed : ${error}`); - } - }); - - test('[XAT-5128] Join a public library - from Favorite Libraries', async ({ favoriteLibrariesPage }) => { - await favoritesApi.addFavoriteById(siteString, adminLibrary1); - await favoriteLibrariesPage.navigate(); - await libraryTable.performActionFromExpandableMenu(adminLibrary1, joinButton); - expect.soft(await snackBar.getSnackBarMessage()).toContain(libraryJoinedMessage); - await expect(libraryTable.getCellByColumnNameAndRowItem(adminLibrary1, consumerRole)).toBeVisible(); - }); - - test('[XAT-5130] Join a moderated library - from Favorite Libraries', async ({ favoriteLibrariesPage }) => { - await favoritesApi.addFavoriteById(siteString, adminModerateLibrary1); - await favoriteLibrariesPage.navigate(); - await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary1, notMemberString)).toBeVisible(); - await libraryTable.performActionFromExpandableMenu(adminModerateLibrary1, joinButton); - expect.soft(await snackBar.getSnackBarMessage()).toContain(requestToJoinMessage); - await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary1, notMemberString)).toBeVisible(); - await adminSitesApi.approveSiteMembershipRequest(adminModerateLibrary1, username2); - await favoriteLibrariesPage.page.reload({ waitUntil: 'load' }); - await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary1, consumerRole)).toBeVisible(); - }); - - test('[XAT-5133] Leave a library - from Favorite Libraries', async ({ favoriteLibrariesPage }) => { - const confirmDialog = favoriteLibrariesPage.confirmDialogComponent; - await favoritesApi.addFavoriteById(siteString, user1Library2); - await favoriteLibrariesPage.navigate(); - await expect(libraryTable.getCellByColumnNameAndRowItem(user1Library2, contributorRole)).toBeVisible(); - await libraryTable.performActionFromExpandableMenu(user1Library2, leaveLibraryButton); - await confirmDialog.okButton.click(); - expect.soft(await snackBar.getSnackBarMessage()).toContain(leftMessage); - await expect(libraryTable.getCellByColumnNameAndRowItem(user1Library2, notMemberString)).toBeVisible(); - }); - - test('[XAT-5138] Cancel join - from Favorite Libraries', async ({ favoriteLibrariesPage }) => { - await user2SitesApi.createSiteMembershipRequestForPerson(username2, adminModerateLibrary3); - await favoritesApi.addFavoriteById(siteString, adminModerateLibrary3); - await favoriteLibrariesPage.navigate(); - - await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary3, notMemberString)).toBeVisible(); - await libraryTable.performActionFromExpandableMenu(adminModerateLibrary3, cancelJoinRequestButton); - expect.soft(await snackBar.getSnackBarMessage()).toContain(cancelJoinRequestMessage); - const hasJoinRequest = await user2SitesApi.hasMembershipRequest(username2, adminModerateLibrary3); - expect(hasJoinRequest).toBe(false); - }); - - test('[XAT-5143] Remove a library from favorites - from Favorite Libraries', async ({ favoriteLibrariesPage }) => { - const myLibrariesHeader = favoriteLibrariesPage.acaHeader; - const libraryMenu = favoriteLibrariesPage.matMenu; - - await favoriteLibrariesPage.navigate({ waitUntil: domContentLoadedString }); - await expect(libraryTable.getRowByName(user2Library3)).toBeVisible(); - await libraryTable.getRowByName(user2Library3).click(); - await myLibrariesHeader.clickMoreActions(); - await libraryMenu.clickMenuItem(removeFavoriteButton); - await expect(libraryTable.getRowByName(user2Library3)).toBeHidden(); - }); - - test('[XAT-5146] Delete a library - from Favorite Libraries', async ({ favoriteLibrariesPage, trashPage }) => { - const myLibrariesHeader = favoriteLibrariesPage.acaHeader; - const libraryMenu = favoriteLibrariesPage.matMenu; - const trashTable = trashPage.dataTable; - - await favoriteLibrariesPage.navigate(); - await expect(libraryTable.getRowByName(user2Library6Delete)).toBeVisible(); - await libraryTable.getRowByName(user2Library6Delete).click(); - await myLibrariesHeader.clickMoreActions(); - await libraryMenu.clickMenuItem(deleteButton); - expect.soft(await snackBar.getSnackBarMessage()).toContain(libraryDeletedMessage); - await expect(libraryTable.getRowByName(user2Library6Delete)).toBeHidden(); - await trashPage.navigate({ waitUntil: loadString }); - await expect(trashTable.getRowByName(user2Library6Delete)).toBeVisible(); - }); - }); - - test.describe('Search Page', () => { - let libraryTable: DataTableComponent; - - test.beforeEach(async ({ searchPage }) => { - try { - libraryTable = searchPage.dataTable; - } catch (error) { - console.error(`Search Page, beforeEach failed : ${error}`); - } - }); - - test('[XAT-5129] Join a public library - from Search Results', async ({ searchPage }) => { - await searchPage.searchWithin(adminLibrary2, 'libraries'); - await searchPage.reload({ waitUntil: loadString }); - await expect(libraryTable.getCellByColumnNameAndRowItem(adminLibrary2, notMemberString)).toBeVisible(); - await libraryTable.performActionFromExpandableMenu(adminLibrary2, joinButton); - expect.soft(await searchPage.snackBar.getSnackBarMessage()).toContain(libraryJoinedMessage); - await expect(libraryTable.getCellByColumnNameAndRowItem(adminLibrary2, consumerRole)).toBeVisible(); - }); - - test('[XAT-5131] Join a moderated library - from Search Results', async ({ myLibrariesPage, searchPage }) => { - await searchPage.searchWithin(adminModerateLibrary2, 'libraries'); - await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary2, notMemberString)).toBeVisible(); - await libraryTable.performActionFromExpandableMenu(adminModerateLibrary2, joinButton); - expect.soft(await searchPage.snackBar.getSnackBarMessage()).toContain(requestToJoinMessage); - await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary2, notMemberString)).toBeVisible(); - await adminSitesApi.approveSiteMembershipRequest(adminModerateLibrary2, username2); - await myLibrariesPage.navigate(); - await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary2, consumerRole)).toBeVisible(); - }); - - test('[XAT-5134] Leave a library - from Search Results', async ({ searchPage }) => { - const confirmDialog = searchPage.confirmDialogComponent; - await searchPage.searchWithin(user1Library3, 'libraries'); - - await expect(libraryTable.getCellByColumnNameAndRowItem(user1Library3, 'Collaborator')).toBeVisible(); - await libraryTable.performActionFromExpandableMenu(user1Library3, leaveLibraryButton); - await confirmDialog.okButton.click(); - expect.soft(await searchPage.snackBar.getSnackBarMessage()).toContain(leftMessage); - await expect(libraryTable.getCellByColumnNameAndRowItem(user1Library3, notMemberString)).toBeVisible(); - }); - - test('[XAT-5139] Cancel join - from Search Results', async ({ searchPage }) => { - await user2SitesApi.createSiteMembershipRequestForPerson(username2, adminModerateLibrary4); - await searchPage.searchWithin(adminModerateLibrary4, 'libraries'); - await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary4, notMemberString)).toBeVisible(); - await libraryTable.performActionFromExpandableMenu(adminModerateLibrary4, cancelJoinRequestButton); - expect.soft(await searchPage.snackBar.getSnackBarMessage()).toContain(cancelJoinRequestMessage); - expect(await user2SitesApi.hasMembershipRequest(username2, adminModerateLibrary4)).toBe(false); - }); - - test('[XAT-5141] Mark a library as favorite - from Search Results', async ({ myLibrariesPage, searchPage }) => { - const myLibrariesHeader = myLibrariesPage.acaHeader; - const libraryMenu = myLibrariesPage.matMenu; - - await searchPage.searchWithin(adminLibrary4, 'libraries'); - - await expect(libraryTable.getRowByName(adminLibrary4)).toBeVisible(); - await libraryTable.getRowByName(adminLibrary4).click(); - await myLibrariesHeader.clickMoreActions(); - await libraryMenu.clickMenuItem(favoriteButton); - await myLibrariesHeader.clickMoreActions(); - expect(await libraryMenu.isMenuItemVisible(removeFavoriteButton)).toBe(true); - }); - - test('[XAT-5144] Remove a library from favorites - from Search Results', async ({ searchPage }) => { - const searchHeader = searchPage.acaHeader; - const libraryMenu = searchPage.matMenu; - - await searchPage.searchWithin(user2Library4, 'libraries'); - await expect(libraryTable.getRowByName(user2Library4)).toBeVisible(); - await searchPage.reload({ waitUntil: domContentLoadedString }); - await libraryTable.getRowByName(user2Library4).click(); - await searchPage.page.waitForTimeout(1000); - await searchHeader.clickMoreActions(); - await libraryMenu.clickMenuItem(removeFavoriteButton); - await searchHeader.clickMoreActions(); - expect(await libraryMenu.isMenuItemVisible(favoriteButton)).toBe(true); - }); - - test('[XAT-5147] Delete a library - from Search Results', async ({ searchPage, trashPage }) => { - const searchHeader = searchPage.acaHeader; - const libraryMenu = searchPage.matMenu; - const trashTable = trashPage.dataTable; - - await searchPage.searchWithin(user2Library7Delete, 'libraries'); - await expect(libraryTable.getRowByName(user2Library7Delete)).toBeVisible(); - await libraryTable.getRowByName(user2Library7Delete).click(); - await searchHeader.clickMoreActions(); - await libraryMenu.clickMenuItem(deleteButton); - expect.soft(await searchPage.snackBar.getSnackBarMessage()).toContain(libraryDeletedMessage); - await expect(libraryTable.getRowByName(user2Library7Delete)).toBeHidden(); - await trashPage.navigate({ waitUntil: loadString }); - await expect(trashTable.getRowByName(user2Library7Delete)).toBeVisible(); - }); - }); -}); diff --git a/e2e/playwright/library-actions/src/tests/my-libraries-actions.e2e.ts b/e2e/playwright/library-actions/src/tests/my-libraries-actions.e2e.ts new file mode 100644 index 000000000..19fb0ac27 --- /dev/null +++ b/e2e/playwright/library-actions/src/tests/my-libraries-actions.e2e.ts @@ -0,0 +1,228 @@ +/*! + * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Alfresco Example Content Application + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * from Hyland Software. If not, see . + */ + +import { expect, Locator } from '@playwright/test'; +import { Utils, ApiClientFactory, test, SitesApi, TrashcanApi, MyLibrariesPage, FavoritesPageApi, timeouts } from '@alfresco/aca-playwright-shared'; +import { Site } from '@alfresco/js-api'; + +test.describe('Library actions ', () => { + test.setTimeout(timeouts.globalTest); + const managerRole = 'Manager'; + const contributorRole = 'Contributor'; + const leaveLibraryButton = 'Leave Library'; + const favoriteButton = 'Favorite'; + const removeFavoriteButton = 'Remove Favorite'; + + const username1 = `user1-${Utils.random()}`; + const username2 = `user2-${Utils.random()}`; + const adminLib5140 = `A-XAT-5140-${Utils.random()}`; + const user1Lib5132 = `U1-XAT-5132-${Utils.random()}`; + const user1Lib5136 = `U1-XAT-5136-${Utils.random()}`; + const user2Lib5137 = `U2-XAT-5137-${Utils.random()}`; + const user2Lib5142 = `U2-XAT-5142-${Utils.random()}`; + const user2Lib5145 = `U2-XAT-5145-Del-${Utils.random()}`; + + let adminLib5140Id: string; + let user1Lib5132Id: string; + let user1Lib5136Id: string; + let user2Lib5137Id: string; + let user2Lib5142Id: string; + + let adminSitesApi: SitesApi; + let user1SitesApi: SitesApi; + let user2SitesApi: SitesApi; + let user2FavoritesApi: FavoritesPageApi; + let user2TrashcanApi: TrashcanApi; + + function getRoleCellValue(page: MyLibrariesPage, libraryName: string, role = managerRole): Locator { + return page.dataTable.getCellByColumnNameAndRowItem(libraryName, role); + } + + test.beforeAll(async () => { + try { + const apiClientFactory = new ApiClientFactory(); + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username: username1 }); + await apiClientFactory.createUser({ username: username2 }); + + adminSitesApi = await SitesApi.initialize('admin'); + user1SitesApi = await SitesApi.initialize(username1, username1); + user2SitesApi = await SitesApi.initialize(username2, username2); + user2FavoritesApi = await FavoritesPageApi.initialize(username2, username2); + user2TrashcanApi = await TrashcanApi.initialize(username2, username2); + } catch (error) { + const myLibrariesActionsBeforeAllErrorMessage = `My libraries actions beforeAll failed : ${JSON.stringify(error)}`; + console.error(myLibrariesActionsBeforeAllErrorMessage); + throw new Error(myLibrariesActionsBeforeAllErrorMessage); + } + }); + + test.beforeEach(async ({ loginPage, myLibrariesPage }) => { + await Utils.tryLoginUser(loginPage, username2, username2, 'My libraries actions beforeEach failed'); + await myLibrariesPage.navigate(); + }); + + test.afterAll(async () => { + try { + await user2TrashcanApi.emptyTrashcan(); + } catch (error) { + const myLibrariesActionsAfterAllErrorMessage = `My libraries actions afterAll failed : ${String(error)}`; + console.error(myLibrariesActionsAfterAllErrorMessage); + throw new Error(myLibrariesActionsAfterAllErrorMessage); + } + }); + + test.describe('[XAT-5132] Leave a library - from My Libraries', () => { + const leftMessage = 'You have left the library'; + + test.beforeAll(async () => { + user1Lib5132Id = (await user1SitesApi.createSite(user1Lib5132)).entry.id; + await user1SitesApi.addSiteMember(user1Lib5132Id, username2, Site.RoleEnum.SiteManager); + }); + + test.afterAll(async () => { + await user1SitesApi.deleteSites([user1Lib5132Id]); + }); + + test('[XAT-5132] Leave a library - from My Libraries', async ({ myLibrariesPage }) => { + await expect(getRoleCellValue(myLibrariesPage, user1Lib5132, managerRole)).toBeVisible(); + await myLibrariesPage.dataTable.performActionFromExpandableMenu(user1Lib5132, leaveLibraryButton); + await expect(myLibrariesPage.confirmDialogComponent.getDialogTitle('Leave this library?')).toBeVisible(); + await expect(myLibrariesPage.confirmDialogComponent.getDialogContent('Leaving will remove your access.')).toBeVisible(); + await expect(myLibrariesPage.confirmDialogComponent.okButton).toBeVisible(); + await expect(myLibrariesPage.confirmDialogComponent.cancelButton).toBeVisible(); + await myLibrariesPage.confirmDialogComponent.okButton.click(); + expect(await myLibrariesPage.snackBar.getSnackBarMessage()).toContain(leftMessage); + await expect(myLibrariesPage.dataTable.getRowByName(user1Lib5132)).toBeHidden(); + }); + }); + + test.describe('[XAT-5136] Cancel Leave Library', () => { + test.beforeAll(async () => { + user1Lib5136Id = (await user1SitesApi.createSite(user1Lib5136)).entry.id; + await user1SitesApi.addSiteMember(user1Lib5136Id, username2, Site.RoleEnum.SiteManager); + }); + + test.afterAll(async () => { + await user1SitesApi.deleteSites([user1Lib5136Id]); + }); + + test('[XAT-5136] Cancel Leave Library', async ({ myLibrariesPage }) => { + await expect(getRoleCellValue(myLibrariesPage, user1Lib5136, managerRole)).toBeVisible(); + await myLibrariesPage.dataTable.performActionFromExpandableMenu(user1Lib5136, leaveLibraryButton); + await myLibrariesPage.confirmDialogComponent.cancelButton.click(); + await expect(getRoleCellValue(myLibrariesPage, user1Lib5136, managerRole)).toBeVisible(); + }); + }); + + test.describe('[XAT-5137] Leave a library - failure notification', () => { + test.beforeAll(async () => { + user2Lib5137Id = (await user2SitesApi.createSite(user2Lib5137)).entry.id; + }); + + test.afterAll(async () => { + await user2SitesApi.deleteSites([user2Lib5137Id]); + }); + + test('[XAT-5137] Leave a library - failure notification', async ({ myLibrariesPage }) => { + await expect(getRoleCellValue(myLibrariesPage, user2Lib5137, managerRole)).toBeVisible(); + await myLibrariesPage.dataTable.performActionFromExpandableMenu(user2Lib5137, leaveLibraryButton); + await myLibrariesPage.confirmDialogComponent.okButton.click(); + expect(await myLibrariesPage.snackBar.getSnackBarMessage()).toContain('Cannot leave this library'); + await expect(getRoleCellValue(myLibrariesPage, user2Lib5137, managerRole)).toBeVisible(); + }); + }); + + test.describe('[XAT-5140] Mark a library as favorite - from My Libraries', () => { + test.beforeAll(async () => { + adminLib5140Id = (await adminSitesApi.createSite(adminLib5140)).entry.id; + await adminSitesApi.addSiteMember(adminLib5140Id, username2, Site.RoleEnum.SiteContributor); + }); + + test.afterAll(async () => { + await adminSitesApi.deleteSites([adminLib5140Id]); + }); + + test('[XAT-5140] Mark a library as favorite - from My Libraries', async ({ myLibrariesPage }) => { + await expect(getRoleCellValue(myLibrariesPage, adminLib5140, contributorRole)).toBeVisible(); + await getRoleCellValue(myLibrariesPage, adminLib5140, contributorRole).click(); + await myLibrariesPage.acaHeader.clickMoreActions(); + await myLibrariesPage.matMenu.clickMenuItem(favoriteButton); + await myLibrariesPage.acaHeader.clickMoreActions(); + expect(await myLibrariesPage.matMenu.isMenuItemVisible(removeFavoriteButton)).toBe(true); + }); + }); + + test.describe('[XAT-5142] Remove a library from favorites - from My Libraries', () => { + test.beforeAll(async () => { + user2Lib5142Id = (await user2SitesApi.createSite(user2Lib5142)).entry.id; + await user2FavoritesApi.addFavoriteById('site', user2Lib5142Id); + }); + + test.afterAll(async () => { + await user2SitesApi.deleteSites([user2Lib5142Id]); + }); + + test('[XAT-5142] Remove a library from favorites - from My Libraries', async ({ myLibrariesPage }) => { + await expect(getRoleCellValue(myLibrariesPage, user2Lib5142, managerRole)).toBeVisible(); + + await expect(async () => { + await myLibrariesPage.page.reload(); + await getRoleCellValue(myLibrariesPage, user2Lib5142, managerRole).click(); + await myLibrariesPage.acaHeader.clickMoreActions(); + expect(await myLibrariesPage.matMenu.isMenuItemVisible(removeFavoriteButton)).toBe(true); + }).toPass({ + intervals: [4_000], + timeout: 40_000 + }); + + await myLibrariesPage.matMenu.clickMenuItem(removeFavoriteButton); + await myLibrariesPage.acaHeader.clickMoreActions(); + expect(await myLibrariesPage.matMenu.isMenuItemVisible(favoriteButton)).toBe(true); + }); + }); + + test.describe('[XAT-5145] Delete a library - from My Libraries', () => { + let user2Lib5145Id: string; + + test.beforeAll(async () => { + user2Lib5145Id = (await user2SitesApi.createSite(user2Lib5145)).entry.id; + }); + + test.afterAll(async () => { + await user2SitesApi.deleteSites([user2Lib5145Id]); + }); + + test('[XAT-5145] Delete a library - from My Libraries', async ({ myLibrariesPage, trashPage }) => { + await expect(getRoleCellValue(myLibrariesPage, user2Lib5145, managerRole)).toBeVisible(); + await getRoleCellValue(myLibrariesPage, user2Lib5145, managerRole).click(); + await myLibrariesPage.acaHeader.clickMoreActions(); + await myLibrariesPage.matMenu.clickMenuItem('Delete'); + expect(await myLibrariesPage.snackBar.getSnackBarMessage()).toContain('Library deleted'); + await expect(getRoleCellValue(myLibrariesPage, user2Lib5145, managerRole)).toBeHidden(); + await trashPage.navigate({ waitUntil: 'load' }); + await expect(trashPage.dataTable.getRowByName(user2Lib5145)).toBeVisible(); + }); + }); +}); diff --git a/e2e/playwright/library-actions/src/tests/search-page-lib-actions.e2e.ts b/e2e/playwright/library-actions/src/tests/search-page-lib-actions.e2e.ts new file mode 100644 index 000000000..c8800fb18 --- /dev/null +++ b/e2e/playwright/library-actions/src/tests/search-page-lib-actions.e2e.ts @@ -0,0 +1,246 @@ +/*! + * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Alfresco Example Content Application + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * from Hyland Software. If not, see . + */ + +import { expect, Locator } from '@playwright/test'; +import { Utils, ApiClientFactory, test, SitesApi, TrashcanApi, FavoritesPageApi, SearchPage, timeouts } from '@alfresco/aca-playwright-shared'; +import { Site } from '@alfresco/js-api'; + +test.describe('Library actions ', () => { + test.setTimeout(timeouts.globalTest); + const notMemberString = 'Not a member'; + const consumerRole = 'Consumer'; + const joinButton = 'Join'; + + const username1 = `user1-${Utils.random()}`; + const username2 = `user2-${Utils.random()}`; + const adminLib5129 = `A-XAT-5129-${Utils.random()}`; + const adminModLib5131 = `Am-XAT-5131-${Utils.random()}`; + const user1Lib5134 = `U1-XAT-5134-${Utils.random()}`; + const adminModLib5139 = `Am-XAT-5139-${Utils.random()}`; + const adminLib5141 = `A-XAT-5141-${Utils.random()}`; + const user2Lib5144 = `U2-XAT-5144-${Utils.random()}`; + const user2Lib5147 = `U2-XAT-5147-Del-${Utils.random()}`; + + let adminLib5129Id: string; + let adminModLib5131Id: string; + let user1Lib5134Id: string; + let adminModLib5139Id: string; + let adminLib5141Id: string; + let user2Lib5144Id: string; + let user2Lib5147Id: string; + + let adminSitesApi: SitesApi; + let user1SitesApi: SitesApi; + let user2SitesApi: SitesApi; + let user2TrashcanApi: TrashcanApi; + + function getRoleCellValue(page: SearchPage, libraryName: string, role: string): Locator { + return page.dataTable.getCellByColumnNameAndRowItem(libraryName, role); + } + + test.beforeAll(async () => { + try { + const apiClientFactory = new ApiClientFactory(); + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username: username1 }); + await apiClientFactory.createUser({ username: username2 }); + + adminSitesApi = await SitesApi.initialize('admin'); + user1SitesApi = await SitesApi.initialize(username1, username1); + user2SitesApi = await SitesApi.initialize(username2, username2); + user2TrashcanApi = await TrashcanApi.initialize(username2, username2); + } catch (error) { + const searchPageLibActionsBeforeAllErrorMessage = `Search page library actions beforeAll failed : ${JSON.stringify(error)}`; + console.error(searchPageLibActionsBeforeAllErrorMessage); + throw new Error(searchPageLibActionsBeforeAllErrorMessage); + } + }); + + test.beforeEach(async ({ loginPage, myLibrariesPage }) => { + await Utils.tryLoginUser(loginPage, username2, username2, 'Search page library actions beforeEach failed'); + await myLibrariesPage.navigate(); + }); + + test.afterAll(async () => { + try { + await user2TrashcanApi.emptyTrashcan(); + } catch (error) { + const searchPageLibActionsAfterAllErrorMessage = `Search page library actions afterAll failed : ${String(error)}`; + console.error(searchPageLibActionsAfterAllErrorMessage); + throw new Error(searchPageLibActionsAfterAllErrorMessage); + } + }); + + test.describe('[XAT-5129] Join a public library - from Search Results', () => { + test.beforeAll(async () => { + adminLib5129Id = (await adminSitesApi.createSite(adminLib5129)).entry.id; + }); + + test.afterAll(async () => { + await adminSitesApi.deleteSites([adminLib5129Id]); + }); + + test('[XAT-5129] Join a public library - from Search Results', async ({ searchPage }) => { + await searchPage.searchWithin(adminLib5129, 'libraries'); + await expect(getRoleCellValue(searchPage, adminLib5129, notMemberString)).toBeVisible(); + await searchPage.dataTable.performActionFromExpandableMenu(adminLib5129, joinButton); + expect.soft(await searchPage.snackBar.getSnackBarMessage()).toContain('Library joined'); + await expect(getRoleCellValue(searchPage, adminLib5129, consumerRole)).toBeVisible(); + }); + }); + + test.describe('[XAT-5131] Join a moderated library - from Search Results', () => { + test.beforeAll(async () => { + adminModLib5131Id = (await adminSitesApi.createSite(adminModLib5131, Site.VisibilityEnum.MODERATED)).entry.id; + }); + + test.afterAll(async () => { + await adminSitesApi.deleteSites([adminModLib5131Id]); + }); + + test('[XAT-5131] Join a moderated library - from Search Results', async ({ myLibrariesPage, searchPage }) => { + await searchPage.searchWithin(adminModLib5131, 'libraries'); + await expect(getRoleCellValue(searchPage, adminModLib5131, notMemberString)).toBeVisible(); + await searchPage.dataTable.performActionFromExpandableMenu(adminModLib5131, joinButton); + expect.soft(await searchPage.snackBar.getSnackBarMessage()).toContain('Request sent to join this library'); + await expect(getRoleCellValue(searchPage, adminModLib5131, notMemberString)).toBeVisible(); + await adminSitesApi.approveSiteMembershipRequest(adminModLib5131Id, username2); + await myLibrariesPage.navigate(); + await expect(myLibrariesPage.dataTable.getCellByColumnNameAndRowItem(adminModLib5131, consumerRole)).toBeVisible(); + }); + }); + + test.describe('[XAT-5134] Leave a library - from Search Results', () => { + test.beforeAll(async () => { + user1Lib5134Id = (await user1SitesApi.createSite(user1Lib5134)).entry.id; + await user1SitesApi.addSiteMember(user1Lib5134Id, username2, Site.RoleEnum.SiteCollaborator); + }); + + test.afterAll(async () => { + await user1SitesApi.deleteSites([user1Lib5134Id]); + }); + + test('[XAT-5134] Leave a library - from Search Results', async ({ searchPage }) => { + await searchPage.searchWithin(user1Lib5134, 'libraries'); + await expect(getRoleCellValue(searchPage, user1Lib5134, 'Collaborator')).toBeVisible(); + await searchPage.dataTable.performActionFromExpandableMenu(user1Lib5134, 'Leave Library'); + await searchPage.confirmDialogComponent.okButton.click(); + expect.soft(await searchPage.snackBar.getSnackBarMessage()).toContain('You have left the library'); + await expect(getRoleCellValue(searchPage, user1Lib5134, notMemberString)).toBeVisible(); + }); + }); + + test.describe('[XAT-5139] Cancel join - from Search Results', () => { + test.beforeAll(async () => { + adminModLib5139Id = (await adminSitesApi.createSite(adminModLib5139, Site.VisibilityEnum.MODERATED)).entry.id; + await user2SitesApi.createSiteMembershipRequestForPerson(username2, adminModLib5139Id); + }); + + test.afterAll(async () => { + await adminSitesApi.deleteSites([adminModLib5139Id]); + }); + + test('[XAT-5139] Cancel join - from Search Results', async ({ searchPage }) => { + await searchPage.searchWithin(adminModLib5139, 'libraries'); + await expect(getRoleCellValue(searchPage, adminModLib5139, notMemberString)).toBeVisible(); + await searchPage.dataTable.performActionFromExpandableMenu(adminModLib5139, 'Cancel Join Request'); + expect.soft(await searchPage.snackBar.getSnackBarMessage()).toContain('Canceled the request to join the library'); + expect(await user2SitesApi.hasMembershipRequest(username2, adminModLib5139Id)).toBe(false); + }); + }); + + test.describe('[XAT-5141] Mark a library as favorite - from Search Results', () => { + test.beforeAll(async () => { + adminLib5141Id = (await adminSitesApi.createSite(adminLib5141)).entry.id; + }); + + test.afterAll(async () => { + await adminSitesApi.deleteSites([adminLib5141Id]); + }); + + test('[XAT-5141] Mark a library as favorite - from Search Results', async ({ searchPage }) => { + await searchPage.searchWithin(adminLib5141, 'libraries'); + await expect(searchPage.dataTable.getRowByName(adminLib5141)).toBeVisible(); + await searchPage.dataTable.getRowByName(adminLib5141).click(); + await searchPage.acaHeader.clickMoreActions(); + await searchPage.matMenu.clickMenuItem('Favorite'); + await searchPage.acaHeader.clickMoreActions(); + expect(await searchPage.matMenu.isMenuItemVisible('Remove Favorite')).toBe(true); + }); + }); + + test.describe('[XAT-5144] Remove a library from favorites - from Search Results', () => { + test.beforeAll(async () => { + const user2FavoritesApi = await FavoritesPageApi.initialize(username2, username2); + user2Lib5144Id = (await user2SitesApi.createSite(user2Lib5144)).entry.id; + await user2FavoritesApi.addFavoriteById('site', user2Lib5144Id); + }); + + test.afterAll(async () => { + await user2SitesApi.deleteSites([user2Lib5144Id]); + }); + + test('[XAT-5144] Remove a library from favorites - from Search Results', async ({ searchPage }) => { + await searchPage.searchWithin(user2Lib5144, 'libraries'); + await expect(searchPage.dataTable.getRowByName(user2Lib5144)).toBeVisible(); + await searchPage.dataTable.getRowByName(user2Lib5144).click(); + + await expect(async () => { + await searchPage.page.reload(); + await searchPage.spinnerWaitForReload(); + await searchPage.dataTable.getRowByName(user2Lib5144).click(); + await searchPage.acaHeader.clickMoreActions(); + await searchPage.matMenu.clickMenuItem('Remove Favorite'); + await searchPage.matMenu.getRoot().waitFor({ state: 'detached' }); + await searchPage.acaHeader.clickMoreActions(); + expect(await searchPage.matMenu.isMenuItemVisible('Favorite')).toBe(true); + }).toPass({ + intervals: [5_000], + timeout: 50_000 + }); + }); + }); + + test.describe('[XAT-5147] Delete a library - from Search Results', () => { + test.beforeAll(async () => { + user2Lib5147Id = (await user2SitesApi.createSite(user2Lib5147)).entry.id; + }); + + test.afterAll(async () => { + await user2SitesApi.deleteSites([user2Lib5147Id]); + }); + + test('[XAT-5147] Delete a library - from Search Results', async ({ searchPage, trashPage }) => { + await searchPage.searchWithin(user2Lib5147, 'libraries'); + await expect(searchPage.dataTable.getRowByName(user2Lib5147)).toBeVisible(); + await searchPage.dataTable.getRowByName(user2Lib5147).click(); + await searchPage.acaHeader.clickMoreActions(); + await searchPage.matMenu.clickMenuItem('Delete'); + expect.soft(await searchPage.snackBar.getSnackBarMessage()).toContain('Library deleted'); + await expect(searchPage.dataTable.getRowByName(user2Lib5147)).toBeHidden(); + await trashPage.navigate({ waitUntil: 'load' }); + await expect(trashPage.dataTable.getRowByName(user2Lib5147)).toBeVisible(); + }); + }); +}); diff --git a/e2e/playwright/list-views/src/tests/favorites.e2e.ts b/e2e/playwright/list-views/src/tests/favorites.e2e.ts index a2caf1f85..e3b97883a 100644 --- a/e2e/playwright/list-views/src/tests/favorites.e2e.ts +++ b/e2e/playwright/list-views/src/tests/favorites.e2e.ts @@ -106,7 +106,7 @@ test.describe('Favorites Files', () => { await favoritesActions.addFavoriteById('file', file2Id); await Promise.all([ favoritesActions.isFavoriteWithRetry(username, folderFavId, { expect: true }), - favoritesActions.waitForApi(username, { expect: consumerFavoritesTotalItems + 4 }) + favoritesActions.waitForApi(username, { expect: consumerFavoritesTotalItems + 3 }) ]); }); diff --git a/e2e/playwright/viewer/src/tests/viewer-zoom-functionality.e2e.ts b/e2e/playwright/viewer/src/tests/viewer-zoom-functionality.e2e.ts index 4080f71b6..d332183a1 100644 --- a/e2e/playwright/viewer/src/tests/viewer-zoom-functionality.e2e.ts +++ b/e2e/playwright/viewer/src/tests/viewer-zoom-functionality.e2e.ts @@ -100,7 +100,7 @@ test.describe('viewer zoom functionality and reset', () => { await Promise.all([ favoritesActions.isFavoriteWithRetry(username, filePdfId, { expect: true }), - favoritesActions.waitForApi(username, { expect: consumerFavoritesTotalItems + 2 }) + favoritesActions.waitForApi(username, { expect: consumerFavoritesTotalItems + 1 }) ]); try { await shareActions.waitForFilesToBeShared([filePngId]); diff --git a/projects/aca-playwright-shared/src/api/favorites-api.ts b/projects/aca-playwright-shared/src/api/favorites-api.ts index 4753405f6..8e231ef2b 100755 --- a/projects/aca-playwright-shared/src/api/favorites-api.ts +++ b/projects/aca-playwright-shared/src/api/favorites-api.ts @@ -103,17 +103,25 @@ export class FavoritesPageApi { } async waitForApi(username: string, data: { expect: number }) { + let attempts = 0; try { const favoriteFiles = async () => { + attempts++; const totalItems = await this.getFavoritesTotalItems(username); + if (attempts % 7 === 0) { + logger.info(`FavoritesApi: waitForApi still waiting for ${username} - expected ${data.expect}, got ${totalItems} (attempt ${attempts})`); + } if (totalItems !== data.expect) { return Promise.reject(totalItems); - } else { - return Promise.resolve(totalItems); } + return totalItems; }; return await Utils.retryCall(favoriteFiles); - } catch {} + } catch (error) { + const errorMessage = `FavoritesApi: waitForApi failed - expected ${data.expect} favorites for ${username}, got ${error}`; + logger.error(errorMessage); + throw new Error(errorMessage); + } } async removeFavoritesByIds(username: string, ids: string[]): Promise { diff --git a/projects/aca-playwright-shared/src/api/sites-api.ts b/projects/aca-playwright-shared/src/api/sites-api.ts index 269eaffc9..9e9fdd05f 100755 --- a/projects/aca-playwright-shared/src/api/sites-api.ts +++ b/projects/aca-playwright-shared/src/api/sites-api.ts @@ -93,7 +93,7 @@ export class SitesApi { } } } catch (error) { - logger.error(`${this.constructor.name} ${this.deleteSites.name}: ${error}`); + logger.error(`SitesApi deleteSites: ${JSON.stringify(error)}`); } } diff --git a/projects/aca-playwright-shared/src/api/trashcan-api.ts b/projects/aca-playwright-shared/src/api/trashcan-api.ts index b5fe74909..30b1930b5 100644 --- a/projects/aca-playwright-shared/src/api/trashcan-api.ts +++ b/projects/aca-playwright-shared/src/api/trashcan-api.ts @@ -39,19 +39,14 @@ export class TrashcanApi { */ async emptyTrashcan(): Promise { try { - const nodes = await this.apiService.trashCan.listDeletedNodes({ - maxItems: 1000 - }); + const nodes = await this.apiService.trashCan.listDeletedNodes({ maxItems: 1000 }); + const ids = nodes?.list?.entries?.map((node) => node?.entry?.id).filter((id) => typeof id === 'string') ?? []; - 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); - } + for (const id of ids) { + await this.apiService.trashCan.deleteDeletedNode(id); } } catch (error) { - logger.error(`User Actions - emptyTrashcan failed: ${error}`); + logger.error(`User Actions - emptyTrashcan failed: ${JSON.stringify(error)}`); } } } diff --git a/projects/aca-playwright-shared/src/page-objects/components/base.component.ts b/projects/aca-playwright-shared/src/page-objects/components/base.component.ts index 74470a14a..dc66530a8 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/base.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/base.component.ts @@ -33,6 +33,10 @@ export abstract class BaseComponent extends PlaywrightBase { this.rootElement = rootElement; } + getRoot(): Locator { + return this.page.locator(this.rootElement); + } + /** * Method which should be used across the repository, while creating * reference to elements, which are in root element of component. diff --git a/projects/aca-playwright-shared/src/page-objects/components/dataTable/mat-menu.component.ts b/projects/aca-playwright-shared/src/page-objects/components/dataTable/mat-menu.component.ts index 6777b4008..d73d245e7 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/dataTable/mat-menu.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/dataTable/mat-menu.component.ts @@ -58,7 +58,7 @@ export class MatMenuComponent extends BaseComponent { } async verifyActualMoreActions(expectedToolbarMore: string[]): Promise { - await this.getChild('').waitFor(); + await this.getRoot().waitFor(); const menus = await this.getChild('[role="menuitem"]').all(); const actualMoreActions: string[] = await Promise.all( menus.map(async (button) => { diff --git a/projects/aca-playwright-shared/src/page-objects/components/manageRules/manage-rules.component.ts b/projects/aca-playwright-shared/src/page-objects/components/manageRules/manage-rules.component.ts index b95f3f9fd..6f3c2c5ee 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/manageRules/manage-rules.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/manageRules/manage-rules.component.ts @@ -33,7 +33,6 @@ export class ManageRules extends BaseComponent { public ruleToggleFalse = this.getChild('aca-rule-list-grouping aca-rule-list-item [role="switch"][aria-checked="false"]').first(); public ruleDetailsDeleteButton = this.getChild('#delete-rule-btn'); public ruleDetailsEditButton = this.getChild('#edit-rule-btn'); - public ruleDetailsPerformActionsDiv = this.getChild('adf-card-view-selectitem [data-automation-id="select-box"]'); public rulesEmptyList = this.getChild('adf-empty-content'); public ruleActions = this.getChild('aca-rule-action'); public ruleConditionsInGroup = this.getChild('aca-rule-composite-condition aca-rule-simple-condition'); @@ -43,13 +42,6 @@ export class ManageRules extends BaseComponent { super(page, ManageRules.rootElement); } - async checkAspects(aspects: string[]): Promise { - for (let i = 0; i < aspects.length; i++) { - const aspectsActions = await this.ruleDetailsPerformActionsDiv.nth(i).innerText(); - expect(aspects).toContain(aspectsActions); - } - } - async checkIfRuleListEmpty(): Promise { return this.rulesEmptyList.isVisible(); }