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();
}