diff --git a/e2e/playwright/copy-move-actions/.eslintrc.json b/e2e/playwright/copy-move-actions/.eslintrc.json
new file mode 100644
index 0000000000..4bb02c94ef
--- /dev/null
+++ b/e2e/playwright/copy-move-actions/.eslintrc.json
@@ -0,0 +1,26 @@
+{
+ "extends": "../../../.eslintrc.json",
+ "ignorePatterns": [
+ "!**/*"
+ ],
+ "overrides": [
+ {
+ "files": [
+ "*.ts"
+ ],
+ "parserOptions": {
+ "project": [
+ "e2e/playwright/copy-move-actions/tsconfig.e2e.json"
+ ],
+ "createDefaultProgram": true
+ },
+ "plugins": [
+ "rxjs",
+ "unicorn"
+ ],
+ "rules": {
+ "@typescript-eslint/no-floating-promises": "off"
+ }
+ }
+ ]
+}
diff --git a/e2e/playwright/copy-move-actions/exclude.tests.json b/e2e/playwright/copy-move-actions/exclude.tests.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/e2e/playwright/copy-move-actions/exclude.tests.json
@@ -0,0 +1 @@
+{}
diff --git a/e2e/playwright/copy-move-actions/playwright.config.ts b/e2e/playwright/copy-move-actions/playwright.config.ts
new file mode 100644
index 0000000000..f968d6f381
--- /dev/null
+++ b/e2e/playwright/copy-move-actions/playwright.config.ts
@@ -0,0 +1,45 @@
+/*!
+ * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
+ *
+ * Alfresco Example Content Application
+ *
+ * This file is part of the Alfresco Example Content Application.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The Alfresco Example Content Application is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * from Hyland Software. If not, see .
+ */
+
+import { PlaywrightTestConfig } from '@playwright/test';
+import { CustomConfig, getGlobalConfig, getExcludedTestsRegExpArray, timeouts } from '@alfresco/playwright-shared';
+import EXCLUDED_JSON from './exclude.tests.json';
+
+const config: PlaywrightTestConfig = {
+ ...getGlobalConfig,
+
+ grepInvert: getExcludedTestsRegExpArray(EXCLUDED_JSON, 'Copy Move Actions'),
+ projects: [
+ {
+ name: 'Copy Move Actions',
+ testDir: './src/tests',
+ use: {
+ users: ['hruser']
+ },
+ timeout: timeouts.extendedTest
+ }
+ ]
+};
+
+export default config;
diff --git a/e2e/playwright/copy-move-actions/project.json b/e2e/playwright/copy-move-actions/project.json
new file mode 100644
index 0000000000..227894945c
--- /dev/null
+++ b/e2e/playwright/copy-move-actions/project.json
@@ -0,0 +1,22 @@
+{
+ "name": "copy-move-actions-e2e",
+ "$schema": "../../../node_modules/nx/schemas/project-schema.json",
+ "sourceRoot": "e2e/playwright/copy-move-actions/src",
+ "projectType": "application",
+ "targets": {
+ "e2e": {
+ "executor": "nx:run-commands",
+ "options": {
+ "commands": ["npx playwright test --config=e2e/playwright/copy-move-actions/playwright.config.ts"]
+ },
+ "configurations": {
+ "production": {
+ "devServerTarget": "content-ce:serve:production"
+ }
+ }
+ },
+ "lint": {
+ "executor": "@angular-eslint/builder:lint"
+ }
+ }
+}
diff --git a/e2e/playwright/copy-move-actions/src/tests/copy.test.ts b/e2e/playwright/copy-move-actions/src/tests/copy.test.ts
new file mode 100644
index 0000000000..50c40818de
--- /dev/null
+++ b/e2e/playwright/copy-move-actions/src/tests/copy.test.ts
@@ -0,0 +1,220 @@
+/*!
+ * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
+ *
+ * Alfresco Example Content Application
+ *
+ * This file is part of the Alfresco Example Content Application.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The Alfresco Example Content Application is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * from Hyland Software. If not, see .
+ */
+
+import { ApiClientFactory, test, Utils, PersonalFilesPage, NodesApi, LoginPage } from '@alfresco/playwright-shared';
+import { expect } from '@playwright/test';
+import { Logger } from '@alfresco/adf-testing';
+
+test.describe('Copy actions', () => {
+ let nodesApi: NodesApi;
+ const username = `user-${Utils.random()}`;
+
+ let sourceFile: string;
+ let sourceFileInsideFolder: string;
+ let sourceFolder: string;
+ let destinationFolder: string;
+
+ let sourceFileId: string;
+ let sourceFileInsideFolderId: string;
+ let destinationFolderId: string;
+
+ test.beforeAll(async () => {
+ try {
+ const apiClientFactory = new ApiClientFactory();
+ await apiClientFactory.setUpAcaBackend('admin');
+ await apiClientFactory.createUser({ username });
+ nodesApi = await NodesApi.initialize(username, username);
+ } catch (error) {
+ Logger.error(`beforeAll failed : ${error}`);
+ }
+ });
+
+ test.afterAll(async ({ nodesApiAction }) => {
+ try {
+ await nodesApiAction.deleteCurrentUserNodes();
+ } catch (error) {
+ Logger.error(`afterAll failed : ${error}`);
+ }
+ });
+
+ test.beforeEach(async ({ personalFiles, page }) => {
+ sourceFile = `source-file-${Utils.random()}.txt`;
+ sourceFileInsideFolder = `source-file-inside-folder-${Utils.random()}.txt`;
+ sourceFolder = `source-folder-${Utils.random()}`;
+ destinationFolder = `destination-folder-${Utils.random()}`;
+
+ const loginPage = new LoginPage(page);
+ try {
+ await loginPage.loginUser(
+ { username, password: username },
+ {
+ withNavigation: true,
+ waitForLoading: true
+ }
+ );
+ destinationFolderId = (await nodesApi.createFolder(destinationFolder)).entry.id;
+ const sourceFolderId = (await nodesApi.createFolder(sourceFolder)).entry.id;
+ sourceFileInsideFolderId = (await nodesApi.createFile(sourceFileInsideFolder, sourceFolderId)).entry.id;
+ sourceFileId = (await nodesApi.createFile(sourceFile)).entry.id;
+
+ await personalFiles.navigate();
+ } catch (error) {
+ Logger.error(`beforeEach failed : ${error}`);
+ }
+ });
+
+ const copyContentInPersonalFiles = async (personalFilesPage: PersonalFilesPage, sourceFileList: string[], destinationName: string) => {
+ await personalFilesPage.copyOrMoveContentInDatatable(sourceFileList, destinationName, 'Copy');
+ const msg = await personalFilesPage.snackBar.message.innerText();
+ if (sourceFileList.length === 1) {
+ expect.soft(msg).toContain('Copied 1 item');
+ } else {
+ expect.soft(msg).toContain(`Copied ${sourceFileList.length} items`);
+ }
+ };
+
+ test('[C217135] Copy a file', async ({ personalFiles }) => {
+ await copyContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ await personalFiles.spinner.waitForReload();
+ expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ });
+
+ test('[C291888] Copy a folder with content', async ({ personalFiles }) => {
+ await copyContentInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ await personalFiles.spinner.waitForReload();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(sourceFolder);
+ await personalFiles.spinner.waitForReload();
+ expect(await personalFiles.dataTable.isItemPresent(sourceFileInsideFolder)).toBeTruthy();
+ });
+
+ test('[C291889] Copy multiple items', async ({ personalFiles }) => {
+ await copyContentInPersonalFiles(personalFiles, [sourceFolder, sourceFile], destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ await personalFiles.spinner.waitForReload();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ });
+
+ test('[C217137] Copy a file with a name that already exists on the destination', async ({ personalFiles }) => {
+ await nodesApi.createFile(sourceFile, destinationFolderId);
+ const expectedNameForCopiedFile = sourceFile.replace('.', '-1.');
+ await copyContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ await personalFiles.spinner.waitForReload();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ expect(await personalFiles.dataTable.isItemPresent(expectedNameForCopiedFile)).toBeTruthy();
+ });
+
+ test('[C217138] Copy a folder with a name that already exists on the destination', async ({ personalFiles }) => {
+ const existingFolderId = (await nodesApi.createFolder(sourceFolder, destinationFolderId)).entry.id;
+ await nodesApi.createFile(sourceFileInsideFolder, existingFolderId);
+ const expectedNameForCopiedFile = sourceFileInsideFolder.replace('.', '-1.');
+ await copyContentInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ await personalFiles.spinner.waitForReload();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(sourceFolder);
+ await personalFiles.spinner.waitForReload();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFileInsideFolder)).toBeTruthy();
+ expect(await personalFiles.dataTable.isItemPresent(expectedNameForCopiedFile)).toBeTruthy();
+ });
+
+ test('[C217139] Copy locked file', async ({ personalFiles }) => {
+ const lockType = 'ALLOW_OWNER_CHANGES';
+ await nodesApi.lockNodes([sourceFileId], lockType);
+ await copyContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ await personalFiles.spinner.waitForReload();
+ expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ });
+
+ test('[C217140] Copy folder that contains locked file', async ({ personalFiles }) => {
+ const lockType = 'ALLOW_OWNER_CHANGES';
+ await nodesApi.lockNodes([sourceFileInsideFolderId], lockType);
+ await copyContentInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ await personalFiles.spinner.waitForReload();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(sourceFolder);
+ await personalFiles.spinner.waitForReload();
+ expect(await personalFiles.dataTable.isItemPresent(sourceFileInsideFolder)).toBeTruthy();
+ });
+
+ test('[C217171] Undo copy of files', async ({ personalFiles }) => {
+ await copyContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
+ await personalFiles.snackBar.actionButton.click();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ await personalFiles.spinner.waitForReload();
+ expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeFalsy();
+ });
+
+ test('[C217172] Undo copy of folders', async ({ personalFiles }) => {
+ await copyContentInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
+ await personalFiles.snackBar.actionButton.click();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ await personalFiles.spinner.waitForReload();
+ expect(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeFalsy();
+ });
+
+ test('[C217173] Undo copy of a file when a file with same name already exists on the destination', async ({ personalFiles }) => {
+ await nodesApi.createFile(sourceFile, destinationFolderId);
+ const expectedNameForCopiedFile = sourceFile.replace('.', '-1.');
+ await copyContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
+ await personalFiles.snackBar.actionButton.click();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ await personalFiles.spinner.waitForReload();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ expect(await personalFiles.dataTable.isItemPresent(expectedNameForCopiedFile)).toBeFalsy();
+ });
+
+ test('[C217174] Undo copy of a folder when a folder with same name already exists on the destination', async ({ personalFiles }) => {
+ const existingFolderId = (await nodesApi.createFolder(sourceFolder, destinationFolderId)).entry.id;
+ await nodesApi.createFile(sourceFileInsideFolder, existingFolderId);
+ const expectedNameForCopiedFile = sourceFileInsideFolder.replace('.', '-1.');
+ await copyContentInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
+ await personalFiles.snackBar.actionButton.click();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ await personalFiles.spinner.waitForReload();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(sourceFolder);
+ await personalFiles.spinner.waitForReload();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFileInsideFolder)).toBeTruthy();
+ expect(await personalFiles.dataTable.isItemPresent(expectedNameForCopiedFile)).toBeFalsy();
+ });
+});
diff --git a/e2e/playwright/copy-move-actions/src/tests/destination-picker-dialog.test.ts b/e2e/playwright/copy-move-actions/src/tests/destination-picker-dialog.test.ts
new file mode 100644
index 0000000000..6164b0344e
--- /dev/null
+++ b/e2e/playwright/copy-move-actions/src/tests/destination-picker-dialog.test.ts
@@ -0,0 +1,107 @@
+/*!
+ * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
+ *
+ * Alfresco Example Content Application
+ *
+ * This file is part of the Alfresco Example Content Application.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The Alfresco Example Content Application is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * from Hyland Software. If not, see .
+ */
+
+import { ApiClientFactory, MyLibrariesPage, NodesApi, SitesApi, test, Utils } from '@alfresco/playwright-shared';
+import { expect } from '@playwright/test';
+import { Site } from '@alfresco/js-api';
+import { Logger } from '@alfresco/adf-testing';
+
+test.describe('Copy Move actions', () => {
+ let nodesApi: NodesApi;
+ let sitesApi: SitesApi;
+
+ const site = `site-${Utils.random()}`;
+ const consumerUser = `consumer-${Utils.random()}`;
+ const contributorUser = `contributor-${Utils.random()}`;
+ const collaboratorUser = `collaborator-${Utils.random()}`;
+
+ const sourceFile = `source-file-${Utils.random()}.txt`;
+ const destinationFolder = `destination-folder-${Utils.random()}`;
+
+ let siteId: string;
+
+ test.beforeAll(async () => {
+ try {
+ const apiClientFactory = new ApiClientFactory();
+ await apiClientFactory.setUpAcaBackend('admin');
+ const username = `user-${Utils.random()}`;
+ await apiClientFactory.createUser({ username });
+ nodesApi = await NodesApi.initialize(username, username);
+ sitesApi = await SitesApi.initialize(username, username);
+
+ siteId = (await sitesApi.createSite(site, Site.VisibilityEnum.PRIVATE)).entry.id;
+ const docLibId = await sitesApi.getDocLibId(siteId);
+
+ const consumerId = (await apiClientFactory.createUser({ username: consumerUser })).entry.id;
+ const contributorId = (await apiClientFactory.createUser({ username: contributorUser })).entry.id;
+ const collaboratorId = (await apiClientFactory.createUser({ username: collaboratorUser })).entry.id;
+
+ await sitesApi.addSiteMember(siteId, consumerId, Site.RoleEnum.SiteConsumer);
+ await sitesApi.addSiteMember(siteId, contributorId, Site.RoleEnum.SiteContributor);
+ await sitesApi.addSiteMember(siteId, collaboratorId, Site.RoleEnum.SiteCollaborator);
+
+ await nodesApi.createFile(sourceFile, docLibId);
+ await nodesApi.createFolder(destinationFolder, docLibId);
+ } catch (error) {
+ Logger.error(`beforeAll failed : ${error}`);
+ }
+ });
+
+ test.afterAll(async () => {
+ try {
+ await nodesApi.deleteCurrentUserNodes();
+ await sitesApi.deleteSites([siteId]);
+ } catch (error) {
+ Logger.error(`afterAll failed : ${error}`);
+ }
+ });
+
+ const copyContentInMyLibraries = async (myLibrariesPage: MyLibrariesPage) => {
+ await myLibrariesPage.dataTable.performClickFolderOrFileToOpen(site);
+ await myLibrariesPage.dataTable.selectItem(sourceFile);
+ await myLibrariesPage.clickMoreActionsButton('Copy');
+ await myLibrariesPage.contentNodeSelector.selectDestination(destinationFolder);
+ };
+
+ test('[C263876] Consumer user cannot select the folder as destination', async ({ loginPage, myLibrariesPage }) => {
+ await loginPage.loginUser({ username: consumerUser, password: consumerUser }, { withNavigation: true, waitForLoading: true });
+ await myLibrariesPage.navigate();
+ await copyContentInMyLibraries(myLibrariesPage);
+ expect(await myLibrariesPage.contentNodeSelector.actionButton.isEnabled()).toBe(false);
+ });
+
+ test('[C263877] Contributor user can select the folder as destination', async ({ loginPage, myLibrariesPage }) => {
+ await loginPage.loginUser({ username: contributorUser, password: contributorUser }, { withNavigation: true, waitForLoading: true });
+ await myLibrariesPage.navigate();
+ await copyContentInMyLibraries(myLibrariesPage);
+ expect(await myLibrariesPage.contentNodeSelector.actionButton.isEnabled()).toBe(true);
+ });
+
+ test('[C263878] Collaborator user can select the folder as destination', async ({ loginPage, myLibrariesPage }) => {
+ await loginPage.loginUser({ username: collaboratorUser, password: collaboratorUser }, { withNavigation: true, waitForLoading: true });
+ await myLibrariesPage.navigate();
+ await copyContentInMyLibraries(myLibrariesPage);
+ expect(await myLibrariesPage.contentNodeSelector.actionButton.isEnabled()).toBe(true);
+ });
+});
diff --git a/e2e/playwright/copy-move-actions/src/tests/move.test.ts b/e2e/playwright/copy-move-actions/src/tests/move.test.ts
new file mode 100644
index 0000000000..edb8ea7992
--- /dev/null
+++ b/e2e/playwright/copy-move-actions/src/tests/move.test.ts
@@ -0,0 +1,202 @@
+/*!
+ * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
+ *
+ * Alfresco Example Content Application
+ *
+ * This file is part of the Alfresco Example Content Application.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The Alfresco Example Content Application is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * from Hyland Software. If not, see .
+ */
+
+import { ApiClientFactory, test, Utils, PersonalFilesPage, NodesApi, LoginPage } from '@alfresco/playwright-shared';
+import { expect } from '@playwright/test';
+import { Logger } from '@alfresco/adf-testing';
+
+test.describe('Move actions', () => {
+ let nodesApi: NodesApi;
+ const username = `user-${Utils.random()}`;
+
+ let sourceFile: string;
+ let sourceFileInsideFolder: string;
+ let sourceFolder: string;
+ let destinationFolder: string;
+
+ let sourceFileId: string;
+ let sourceFileInsideFolderId: string;
+ let destinationFolderId: string;
+
+ test.beforeAll(async () => {
+ try {
+ const apiClientFactory = new ApiClientFactory();
+ await apiClientFactory.setUpAcaBackend('admin');
+ await apiClientFactory.createUser({ username });
+ nodesApi = await NodesApi.initialize(username, username);
+ } catch (error) {
+ Logger.error(`beforeAll failed : ${error}`);
+ }
+ });
+
+ test.afterAll(async ({ nodesApiAction }) => {
+ try {
+ await nodesApiAction.deleteCurrentUserNodes();
+ } catch (error) {
+ Logger.error(`afterAll failed : ${error}`);
+ }
+ });
+
+ test.beforeEach(async ({ personalFiles, page }) => {
+ sourceFile = `source-file-${Utils.random()}.txt`;
+ sourceFileInsideFolder = `source-file-inside-folder-${Utils.random()}.txt`;
+ sourceFolder = `source-folder-${Utils.random()}`;
+ destinationFolder = `destination-folder-${Utils.random()}`;
+
+ const loginPage = new LoginPage(page);
+ try {
+ await loginPage.loginUser(
+ { username, password: username },
+ {
+ withNavigation: true,
+ waitForLoading: true
+ }
+ );
+ destinationFolderId = (await nodesApi.createFolder(destinationFolder)).entry.id;
+ const sourceFolderId = (await nodesApi.createFolder(sourceFolder)).entry.id;
+ sourceFileInsideFolderId = (await nodesApi.createFile(sourceFileInsideFolder, sourceFolderId)).entry.id;
+ sourceFileId = (await nodesApi.createFile(sourceFile)).entry.id;
+
+ await personalFiles.navigate();
+ } catch (error) {
+ Logger.error(`beforeEach failed : ${error}`);
+ }
+ });
+
+ const moveContentInPersonalFiles = async (personalFilesPage: PersonalFilesPage, sourceFileList: string[], destinationName: string) => {
+ await personalFilesPage.copyOrMoveContentInDatatable(sourceFileList, destinationName, 'Move');
+ await personalFilesPage.spinner.waitForReload();
+ };
+
+ test('[C217316] Move a file', async ({ personalFiles }) => {
+ await moveContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
+ const msg = await personalFiles.snackBar.message.innerText();
+ expect.soft(msg).toContain('Moved 1 item.');
+ await personalFiles.snackBar.closeIcon.click();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeFalsy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ });
+
+ test('[C217317] Move a folder with content', async ({ personalFiles }) => {
+ await moveContentInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
+ const msg = await personalFiles.snackBar.message.innerText();
+ expect.soft(msg).toContain('Moved 1 item.');
+ await personalFiles.snackBar.closeIcon.click();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeFalsy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(sourceFolder);
+ expect(await personalFiles.dataTable.isItemPresent(sourceFileInsideFolder)).toBeTruthy();
+ });
+
+ test('[C291958] Move multiple items', async ({ personalFiles }) => {
+ await moveContentInPersonalFiles(personalFiles, [sourceFolder, sourceFile], destinationFolder);
+ const msg = await personalFiles.snackBar.message.innerText();
+ expect.soft(msg).toContain('Moved 2 items.');
+ await personalFiles.snackBar.closeIcon.click();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeFalsy();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeFalsy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ });
+
+ test('[C217318] Move a file with a name that already exists on the destination', async ({ personalFiles }) => {
+ await nodesApi.createFile(sourceFile, destinationFolderId);
+ const expectedNameForCopiedFile = sourceFile.replace('.', '-1.');
+ await moveContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
+ const msg = await personalFiles.snackBar.message.innerText();
+ expect.soft(msg).toContain('Move unsuccessful, a file with the same name already exists.');
+ await personalFiles.snackBar.closeIcon.click();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ expect(await personalFiles.dataTable.isItemPresent(expectedNameForCopiedFile)).toBeFalsy();
+ });
+
+ test('[C217319] Move a folder with a name that already exists on the destination', async ({ personalFiles }) => {
+ const existingFolderId = (await nodesApi.createFolder(sourceFolder, destinationFolderId)).entry.id;
+ await nodesApi.createFile(sourceFileInsideFolder, existingFolderId);
+ const expectedNameForCopiedFile = sourceFileInsideFolder.replace('.', '-1.');
+ await moveContentInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
+ const msg = await personalFiles.snackBar.message.innerText();
+ expect.soft(msg).toContain('Move unsuccessful, a file with the same name already exists.');
+ await personalFiles.snackBar.closeIcon.click();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ expect(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(sourceFolder);
+ expect(await personalFiles.dataTable.isItemPresent(sourceFileInsideFolder)).toBeTruthy();
+ expect(await personalFiles.dataTable.isItemPresent(expectedNameForCopiedFile)).toBeFalsy();
+ });
+
+ test('[C217320] Move locked file', async ({ personalFiles }) => {
+ const lockType = 'ALLOW_OWNER_CHANGES';
+ await nodesApi.lockNodes([sourceFileId], lockType);
+ await moveContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
+ const msg = await personalFiles.snackBar.message.innerText();
+ expect.soft(msg).toContain('Moved 1 item.');
+ await personalFiles.snackBar.closeIcon.click();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeFalsy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ });
+
+ test('[C217321] Move folder that contains locked file', async ({ personalFiles }) => {
+ const lockType = 'ALLOW_OWNER_CHANGES';
+ await nodesApi.lockNodes([sourceFileInsideFolderId], lockType);
+ await moveContentInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
+ const msg = await personalFiles.snackBar.message.innerText();
+ expect.soft(msg).toContain('Moved 1 item.');
+ await personalFiles.snackBar.closeIcon.click();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeFalsy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(sourceFolder);
+ expect(await personalFiles.dataTable.isItemPresent(sourceFileInsideFolder)).toBeTruthy();
+ });
+
+ test('[C217324] Undo move files', async ({ personalFiles, trashPage }) => {
+ await moveContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
+ await personalFiles.snackBar.actionButton.click();
+ await personalFiles.spinner.waitForReload();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeFalsy();
+ await trashPage.navigate();
+ expect(await trashPage.dataTable.isItemPresent(sourceFile)).toBeFalsy();
+ });
+
+ test('[C217325] Undo move of folders', async ({ personalFiles, trashPage }) => {
+ await moveContentInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
+ await personalFiles.snackBar.actionButton.click();
+ await personalFiles.spinner.waitForReload();
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
+ await personalFiles.dataTable.performClickFolderOrFileToOpen(destinationFolder);
+ expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeFalsy();
+ await trashPage.navigate();
+ expect(await trashPage.dataTable.isItemPresent(sourceFolder)).toBeFalsy();
+ });
+});
diff --git a/e2e/playwright/copy-move-actions/tsconfig.e2e.adf.json b/e2e/playwright/copy-move-actions/tsconfig.e2e.adf.json
new file mode 100644
index 0000000000..87cbcf775a
--- /dev/null
+++ b/e2e/playwright/copy-move-actions/tsconfig.e2e.adf.json
@@ -0,0 +1,15 @@
+{
+ "extends": "../../../tsconfig.adf.json",
+ "compilerOptions": {
+ "outDir": "../../out-tsc/e2e",
+ "baseUrl": "./",
+ "module": "commonjs",
+ "target": "es2017",
+ "types": ["jasmine", "jasminewd2", "node"],
+ "skipLibCheck": true,
+ "paths": {
+ "@alfresco/playwright-shared": ["../../../projects/aca-playwright-shared/src/index.ts"]
+ }
+ },
+ "exclude": ["node_modules"]
+}
diff --git a/e2e/playwright/copy-move-actions/tsconfig.e2e.json b/e2e/playwright/copy-move-actions/tsconfig.e2e.json
new file mode 100755
index 0000000000..c317985239
--- /dev/null
+++ b/e2e/playwright/copy-move-actions/tsconfig.e2e.json
@@ -0,0 +1,15 @@
+{
+ "extends": "../../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../out-tsc/e2e",
+ "baseUrl": "./",
+ "module": "commonjs",
+ "target": "es2017",
+ "types": ["jasmine", "jasminewd2", "node", "@playwright/test"],
+ "skipLibCheck": true,
+ "paths": {
+ "@alfresco/playwright-shared": ["../../../projects/aca-playwright-shared/src/index.ts"]
+ }
+ },
+ "exclude": ["node_modules"]
+}
diff --git a/e2e/protractor/suites/actions/copy-move/copy.test.ts b/e2e/protractor/suites/actions/copy-move/copy.test.ts
deleted file mode 100755
index 7df99ba4cc..0000000000
--- a/e2e/protractor/suites/actions/copy-move/copy.test.ts
+++ /dev/null
@@ -1,466 +0,0 @@
-/*!
- * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
- *
- * Alfresco Example Content Application
- *
- * This file is part of the Alfresco Example Content Application.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * The Alfresco Example Content Application is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * from Hyland Software. If not, see .
- */
-
-import { AdminActions, UserActions, LoginPage, BrowsingPage, ContentNodeSelectorDialog, RepoClient, Utils } from '@alfresco/aca-testing-shared';
-import { BrowserActions, Logger } from '@alfresco/adf-testing';
-
-describe('Copy content', () => {
- const random = Utils.random();
- const username = `user-${random}`;
- const source = `source-${random}`;
- let sourceId: string;
- const destinationPF = `destinationPersonal-${random}`;
- let destinationIdPF: string;
- const destinationRF = `destinationRecent-${random}`;
- let destinationIdRF: string;
- const destinationSF = `destinationShared-${random}`;
- let destinationIdSF: string;
- const destinationFav = `destinationFav-${random}`;
- let destinationIdFav: string;
- const destinationSearch = `destinationSearch-${random}`;
- let destinationIdSearch: string;
-
- const file1 = `copy-file1-${random}.txt`;
- const folder1 = `copy-folder1-${random}`;
- const fileInFolder = `copy-fileInFolder-${random}.txt`;
-
- const folder2 = `copy-folder2-${random}`;
- const fileInFolder2 = fileInFolder;
-
- const folderExisting = `copy-folder-existing-${random}`;
- const file1InFolderExisting = `copy-file1InFolderExisting-${random}.txt`;
- const file2InFolderExisting = `copy-file2InFolderExisting-${random}.txt`;
-
- const file2 = `copy-file2-${random}.txt`;
- const file3 = `copy-file3-${random}.txt`;
- const file4 = `copy-file4-${random}.txt`;
- const fileLocked1 = `copy-file-locked1-${random}.txt`;
- let fileLocked1Id: string;
-
- const folderWithLockedFiles = `copy-folder-locked1-${random}`;
- let folderWithLockedFilesId: string;
- const fileLockedInFolder = `copy-file-locked-${random}`;
- let fileLockedInFolderId: string;
-
- const existingFile = `copy-existing-${random}-file.txt`;
- const existingFolder = `copy-existing-${random}-folder`;
- const file2InFolder = `copy-file2InFolder-${random}.txt`;
- const file3InFolder = `copy-file3InFolder-${random}.txt`;
- const siteName = `copy-site-${random}`;
- const folderSitePF = `copy-folderSitePersonal-${random}`;
- const folderSiteRF = `copy-folderSiteRecent-${random}`;
- const folderSiteSF = `copy-folderSiteShared-${random}`;
- const folderSiteFav = `copy-folderSiteFav-${random}`;
- const folderSiteSearch = `copy-folderSiteSearch-${random}`;
-
- let locationId: string;
- let destinationId: string;
-
- const apis = new RepoClient(username, username);
-
- const loginPage = new LoginPage();
- const page = new BrowsingPage();
- const { dataTable, toolbar } = page;
- const copyDialog = new ContentNodeSelectorDialog();
-
- const adminApiActions = new AdminActions();
- const userActions = new UserActions();
-
- beforeAll(async () => {
- try {
- await adminApiActions.createUser({ username });
- await userActions.login(username, username);
-
- const initialFavoritesTotalItems = await apis.favorites.getFavoritesTotalItems();
-
- sourceId = await apis.createFolder(source);
- destinationIdPF = await apis.createFolder(destinationPF);
- destinationIdRF = await apis.createFolder(destinationRF);
- destinationIdSF = await apis.createFolder(destinationSF);
- destinationIdFav = await apis.createFolder(destinationFav);
- destinationIdSearch = await apis.createFolder(destinationSearch);
-
- const existingFileToCopyId = await apis.createFile(existingFile, sourceId);
-
- await userActions.shareNodes([existingFileToCopyId]);
- await apis.favorites.addFavoriteById('file', existingFileToCopyId);
-
- await apis.createFile(existingFile, destinationIdPF);
- await apis.createFile(existingFile, destinationIdRF);
- await apis.createFile(existingFile, destinationIdSF);
- await apis.createFile(existingFile, destinationIdFav);
- await apis.createFile(existingFile, destinationIdSearch);
-
- const existingFolderToCopyId = await apis.createFolder(existingFolder, sourceId);
-
- const existingIdPF = await apis.createFolder(existingFolder, destinationIdPF);
- await apis.createFolder(existingFolder, destinationIdRF);
- await apis.createFolder(existingFolder, destinationIdSF);
- const existingIdFav = await apis.createFolder(existingFolder, destinationIdFav);
- const existingIdSearch = await apis.createFolder(existingFolder, destinationIdSearch);
- await apis.createFile(file2InFolder, existingFolderToCopyId);
-
- await apis.createFile(file3InFolder, existingIdPF);
- await apis.createFile(file3InFolder, existingIdFav);
- await apis.createFile(file3InFolder, existingIdSearch);
-
- await apis.favorites.addFavoriteById('folder', existingFolderToCopyId);
-
- const folder1Id = await apis.createFolder(folder1, sourceId);
- const fileInFolderId = await apis.createFile(fileInFolder, folder1Id);
- await apis.favorites.addFavoriteById('folder', folder1Id);
- await apis.favorites.addFavoriteById('file', fileInFolderId);
- await userActions.shareNodes([fileInFolderId]);
-
- const folderExistingId = await apis.createFolder(folderExisting, sourceId);
- await apis.favorites.addFavoriteById('folder', folderExistingId);
- await apis.createFile(file1InFolderExisting, folderExistingId);
-
- const folderExistingPFId = await apis.createFolder(folderExisting, destinationIdPF);
- await apis.createFile(file2InFolderExisting, folderExistingPFId);
-
- const folderExistingFavId = await apis.createFolder(folderExisting, destinationIdFav);
- await apis.createFile(file2InFolderExisting, folderExistingFavId);
-
- const folderExistingSearchId = await apis.createFolder(folderExisting, destinationIdSearch);
- await apis.createFile(file2InFolderExisting, folderExistingSearchId);
-
- const folder2Id = await apis.createFolder(folder2, sourceId);
- await apis.createFile(fileInFolder2, folder2Id);
- await apis.favorites.addFavoriteById('folder', folder2Id);
-
- fileLocked1Id = await apis.createFile(fileLocked1, sourceId);
- await userActions.lockNodes([fileLocked1Id]);
-
- folderWithLockedFilesId = await apis.createFolder(folderWithLockedFiles, sourceId);
- fileLockedInFolderId = await apis.createFile(fileLockedInFolder, folderWithLockedFilesId);
- await userActions.lockNodes([fileLockedInFolderId]);
- await apis.favorites.addFavoriteById('folder', folderWithLockedFilesId);
-
- const file1Id = await apis.createFile(file1, sourceId);
- const file2Id = await apis.createFile(file2, sourceId);
- const file3Id = await apis.createFile(file3, sourceId);
- const file4Id = await apis.createFile(file4, sourceId);
-
- await userActions.shareNodes([file1Id, file2Id, file3Id, file4Id, fileLocked1Id]);
-
- await apis.favorites.addFavoritesByIds('file', [file1Id, file2Id, file3Id, file4Id, fileLocked1Id]);
-
- await apis.sites.createSite(siteName);
- const docLibId = await apis.sites.getDocLibId(siteName);
- await apis.createFolder(folderSitePF, docLibId);
- await apis.createFolder(folderSiteRF, docLibId);
- await apis.createFolder(folderSiteSF, docLibId);
- await apis.createFolder(folderSiteFav, docLibId);
- await apis.createFolder(folderSiteSearch, docLibId);
-
- await apis.shared.waitForFilesToBeShared([existingFileToCopyId, fileInFolderId, file1Id, file2Id, file3Id, file4Id, fileLocked1Id]);
- await apis.favorites.waitForApi({ expect: initialFavoritesTotalItems + 13 });
-
- await loginPage.loginWith(username);
- } catch (error) {
- Logger.error(`----- beforeAll failed : ${error}`);
- }
- });
-
- beforeEach(async () => {
- await page.closeOpenDialogs();
- });
-
- afterAll(async () => {
- try {
- await userActions.login(username, username);
- await userActions.unlockNodes([fileLocked1Id, fileLockedInFolderId]);
- await userActions.deleteNodes([sourceId, destinationIdRF, destinationIdPF, destinationIdSF, destinationIdFav, destinationIdSearch]);
- await userActions.deleteSites([siteName]);
- } catch (error) {
- Logger.error(`---- afterAll failed : ${error}`);
- }
- });
-
- describe('from Personal Files', () => {
- beforeEach(async () => {
- await Utils.pressEscape();
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(source);
- });
-
- it('[C217135] Copy a file', async () => copyFile(file1, destinationPF));
-
- it('[C291888] Copy a folder with content', async () => copyFolderWithContent(folder1, destinationPF));
-
- it('[C291889] Copy multiple items', async () => copyMultipleItems([file2, file3], destinationPF));
-
- it('[C217137] Copy a file with a name that already exists on the destination', async () =>
- copyFileWithNameThatAlreadyExists(existingFile, destinationPF));
-
- it('[C217138] Copy a folder with a name that already exists on the destination', async () =>
- copyFolderWithNameThatAlreadyExists(existingFolder, destinationPF));
-
- it('[C280282] Copy items into a library', async () => copyItemsIntoLibrary([file1, folder1], folderSitePF));
-
- it('[C217139] Copy locked file', async () =>
- copyLockedFile(fileLocked1, destinationPF, '', () => {
- locationId = sourceId;
- destinationId = destinationIdPF;
- }));
-
- it('[C217140] Copy folder that contains locked file', async () =>
- copyFolderThatContainsLockedFile(folderWithLockedFiles, destinationPF, '', () => {
- locationId = folderWithLockedFilesId;
- destinationId = destinationIdPF;
- }));
-
- it('[C217171] Undo copy of files', async () => undoCopyFile(file4, destinationPF));
-
- it('[C217172] Undo copy of folders', async () => undoCopyFolder(folder2, destinationPF));
-
- it('[C217173] Undo copy of a file when a file with same name already exists on the destination', async () =>
- undoCopyFileWithExistingName(fileInFolder, folder2, '', async () => {
- await dataTable.doubleClickOnRowByName(folder1);
- await dataTable.waitForHeader();
- }));
-
- it('[C217174] Undo copy of a folder when a folder with same name already exists on the destination', async () =>
- undoCopyFolderWithExistingName(folderExisting, destinationPF));
- });
-
- async function baseCopy(
- itemName: string | string[],
- location: string,
- destination: string,
- undo = false,
- isExisting = false,
- expectedMsg = 'Copied 1 item'
- ) {
- if (itemName instanceof Array) {
- await dataTable.selectMultipleItems(itemName, location);
- } else {
- await dataTable.selectItem(itemName, location);
- }
- await toolbar.clickMoreActionsCopy();
- await copyDialog.selectLocation('Personal Files');
- if (isExisting) {
- await copyDialog.dataTable.doubleClickOnRowByName(source);
- }
- await copyDialog.selectDestination(destination);
- await BrowserActions.click(copyDialog.copyButton);
- const msg = await page.getSnackBarMessage();
- expect(msg).toContain(expectedMsg);
- const action = await page.getSnackBarAction();
- expect(action).toContain('Undo');
- if (undo) {
- await page.clickSnackBarAction();
- await page.clickPersonalFilesAndWait();
- } else {
- await copyDialog.waitForDialogToClose();
- }
- }
-
- async function baseCopyDoBefore(
- itemName: string | string[],
- location: string,
- destination: string,
- doBefore?: () => void,
- undo?: boolean,
- expectedMsg?: string
- ) {
- if (doBefore) {
- doBefore();
- }
- await baseCopy(itemName, location, destination, undo, false, expectedMsg);
- }
-
- async function baseCopyDoBeforeAsync(
- itemName: string | string[],
- location: string,
- destination: string,
- doBefore?: () => Promise,
- undo?: boolean,
- isExisting?: boolean,
- expectedMsg?: string
- ) {
- if (doBefore) {
- await doBefore();
- }
- await baseCopy(itemName, location, destination, undo, isExisting, expectedMsg);
- }
-
- async function copyFile(fileName: string, destination: string, location = '', doBefore?: () => void) {
- await baseCopyDoBefore(fileName, location, destination, doBefore);
- expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in source folder`);
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(destination);
- expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in ${destination} folder`);
- }
-
- async function copyFolderWithContent(folderName: string, destination: string, location = '', doBefore?: () => void) {
- await baseCopyDoBefore(folderName, location, destination, doBefore);
- expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in source folder`);
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(destination);
- expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in ${destination} folder`);
- expect(await dataTable.isItemPresent(fileInFolder)).toBe(false, `${fileInFolder} is present in ${destination}`);
-
- await dataTable.doubleClickOnRowByName(folderName);
- expect(await dataTable.isItemPresent(fileInFolder)).toBe(true, `${fileInFolder} is not present in ${folderName} folder in ${destination}`);
- }
-
- async function copyMultipleItems(items: string[], destination: string, location = '', doBefore?: () => void) {
- await baseCopyDoBefore(items, location, destination, doBefore, false, 'Copied 2 items');
- expect(await dataTable.isItemPresent(items[0])).toBe(true, `${items[0]} not present in source folder`);
- expect(await dataTable.isItemPresent(items[1])).toBe(true, `${items[1]} not present in source folder`);
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(destination);
- expect(await dataTable.isItemPresent(items[0])).toBe(true, `${items[0]} not present in ${destination} folder`);
- expect(await dataTable.isItemPresent(items[1])).toBe(true, `${items[1]} not present in ${destination} folder`);
- }
-
- async function copyFileWithNameThatAlreadyExists(fileName: string, destination: string, location = '', doBefore?: () => void) {
- await baseCopyDoBefore(fileName, location, destination, doBefore);
- expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName}.txt not present in source folder`);
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(destination);
- expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName}.txt not present in ${destination} folder`);
- }
-
- async function copyFolderWithNameThatAlreadyExists(folderName: string, destination: string, location = '', doBefore?: () => void) {
- await baseCopyDoBefore(folderName, location, destination, doBefore);
- expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in source folder`);
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(destination);
- expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in ${destination} folder`);
- await dataTable.doubleClickOnRowByName(folderName);
- expect(await dataTable.isItemPresent(file2InFolder)).toBe(true, `${file2InFolder} not present in ${destination} folder in ${folderName}`);
- expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in ${destination} folder in ${folderName}`);
- }
-
- async function copyItemsIntoLibrary(items: string[], destination: string, location = '', doBefore?: () => void) {
- if (doBefore) {
- doBefore();
- }
- const noOfItems = items.length;
- await dataTable.selectMultipleItems(items, location);
- await toolbar.clickMoreActionsCopy();
- await copyDialog.selectLocation('My Libraries');
- await copyDialog.dataTable.doubleClickOnRowByName(siteName);
- await copyDialog.dataTable.doubleClickOnRowByName('documentLibrary');
- await copyDialog.selectDestination(destination);
- await BrowserActions.click(copyDialog.copyButton);
- const msg = await page.getSnackBarMessage();
- expect(msg).toContain(`Copied ${noOfItems} ${noOfItems === 1 ? 'item' : 'items'}`);
- const action = await page.getSnackBarAction();
- expect(action).toContain('Undo');
-
- await copyDialog.waitForDialogToClose();
- for (const item of items) {
- expect(await dataTable.isItemPresent(item)).toBe(true, `${item} not present in source folder`);
- }
-
- await page.goToMyLibraries();
- await dataTable.doubleClickOnRowByName(siteName);
- await dataTable.doubleClickOnRowByName(destination);
-
- for (const item of items) {
- expect(await dataTable.isItemPresent(item)).toBe(true, `${item} not present in ${destination} folder`);
- }
- }
-
- async function copyLockedFile(fileName: string, destination: string, location = '', doBefore?: () => void) {
- await baseCopyDoBefore(fileName, location, destination, doBefore);
- expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in source folder`);
- expect(await apis.nodes.isFileLockedByName(fileName, locationId)).toBe(true, `${fileName} not locked in ${location}`);
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(destination);
- expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in ${destination} folder`);
- expect(await apis.nodes.isFileLockedByName(fileName, destinationId)).toBe(false, `${fileName} is locked in ${destination}`);
- }
-
- async function copyFolderThatContainsLockedFile(folderName: string, destination: string, location = '', doBefore?: () => void) {
- await baseCopyDoBefore(folderName, location, destination, doBefore);
- expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in source folder`);
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(destination);
- expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in ${destination} folder`);
- expect(await dataTable.isItemPresent(fileLockedInFolder)).toBe(false, `${fileLockedInFolder} is present in ${destination}`);
- expect(await apis.nodes.isFileLockedByName(fileLockedInFolder, locationId)).toBe(true, `${fileLockedInFolder} not locked in ${location}`);
-
- await dataTable.doubleClickOnRowByName(folderName);
- expect(await dataTable.isItemPresent(fileLockedInFolder)).toBe(
- true,
- `${fileLockedInFolder} is not present in ${folderName} folder from ${destination}`
- );
- expect(await apis.nodes.isFileLockedByName(fileLockedInFolder, await apis.nodes.getNodeIdFromParent(folderWithLockedFiles, destinationId))).toBe(
- false,
- `${fileLockedInFolder} is locked in ${destination}`
- );
- }
-
- async function undoCopyFile(fileName: string, destination: string, location = '', doBefore?: () => void) {
- await baseCopyDoBefore(fileName, location, destination, doBefore, true);
- await dataTable.doubleClickOnRowByName(destination);
- expect(await dataTable.isItemPresent(fileName)).toBe(false, `${fileName} present in ${destination} folder`);
-
- await page.clickTrash();
- expect(await dataTable.isEmpty()).toBe(true, 'Trash is not empty');
- }
-
- async function undoCopyFolder(folderName: string, destination: string, location = '', doBefore?: () => void) {
- await baseCopyDoBefore(folderName, location, destination, doBefore, true);
- await dataTable.doubleClickOnRowByName(destination);
- expect(await dataTable.isItemPresent(folderName)).toBe(false, `${folderName} present in ${destination} folder`);
-
- await page.clickTrash();
- expect(await dataTable.isEmpty()).toBe(true, 'Trash is not empty');
- }
-
- async function undoCopyFileWithExistingName(fileName: string, destination: string, location = '', doBefore?: () => Promise) {
- await baseCopyDoBeforeAsync(fileName, location, destination, doBefore, true, true);
- await dataTable.doubleClickOnRowByName(source);
- await dataTable.doubleClickOnRowByName(folder2);
- expect(await dataTable.isItemPresent(fileInFolder2)).toBe(true, `${fileInFolder2} not present in ${destination} folder`);
- expect(await dataTable.isItemPresent(`${fileInFolder2}-1`)).toBe(false, `${fileInFolder2}-1 is present in ${destination} folder`);
-
- await page.clickTrash();
- expect(await dataTable.isEmpty()).toBe(true, 'Trash is not empty');
- }
-
- async function undoCopyFolderWithExistingName(folderName: string, destination: string, location = '', doBefore?: () => void) {
- await baseCopyDoBefore(folderName, location, destination, doBefore, true);
- await dataTable.doubleClickOnRowByName(destination);
- expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in ${destination} folder`);
- await dataTable.doubleClickOnRowByName(folderName);
- expect(await dataTable.isItemPresent(file2InFolderExisting)).toBe(
- true,
- `${file2InFolderExisting} not present in ${folderName} in ${destination} folder`
- );
- expect(await dataTable.isItemPresent(file1InFolderExisting)).toBe(
- false,
- `${file1InFolderExisting} present in ${folderName} in ${destination} folder`
- );
-
- await page.clickTrash();
- expect(await dataTable.isEmpty()).toBe(true, 'Trash is not empty');
- }
-});
diff --git a/e2e/protractor/suites/actions/copy-move/destination-picker-dialog.test.ts b/e2e/protractor/suites/actions/copy-move/destination-picker-dialog.test.ts
deleted file mode 100755
index 622709f89b..0000000000
--- a/e2e/protractor/suites/actions/copy-move/destination-picker-dialog.test.ts
+++ /dev/null
@@ -1,353 +0,0 @@
-/*!
- * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
- *
- * Alfresco Example Content Application
- *
- * This file is part of the Alfresco Example Content Application.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * The Alfresco Example Content Application is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * from Hyland Software. If not, see .
- */
-
-import {
- LoginPage,
- BrowsingPage,
- ContentNodeSelectorDialog,
- RepoClient,
- Utils,
- AdminActions,
- SITE_VISIBILITY,
- UserActions
-} from '@alfresco/aca-testing-shared';
-
-describe('Destination picker dialog : ', () => {
- const random = Utils.random();
- const username = `user-${random}`;
-
- const consumer = `consumer-${random}`;
- const contributor = `contributor-${random}`;
- const collaborator = `collaborator-${random}`;
-
- const file = `file-${random}.txt`;
- let fileId: string;
- let fileIdConsumer: string;
- let fileIdContributor: string;
- let fileIdCollaborator: string;
-
- const adminFolder = `admin-folder-${random}`;
- let adminFolderId: string;
-
- const destination = `destination-folder-${random}`;
- let destinationId: string;
- const fileInDestination = `file-in-dest-${random}.txt`;
- const folderInDestination = `folder-in-dest-${random}`;
- const folder2InDestination = `folder2-in-dest-${random}`;
- let folderLink: string;
-
- const searchFolder = `search-${random}`;
- let searchFolderId: string;
- let searchFolderSiteId: string;
- const searchSubFolder1 = `sub-folder-${random}`;
- let searchSubFolder1Id: string;
- let searchSubFolder1SiteId: string;
- const searchSubFolder2 = `sub-folder-${random}`;
-
- const site = `site-${random}`;
-
- const userApi = new RepoClient(username, username);
- const consumerApi = new RepoClient(consumer, consumer);
- const contributorApi = new RepoClient(contributor, contributor);
- const collaboratorApi = new RepoClient(collaborator, collaborator);
-
- const adminApiActions = new AdminActions();
- const userActions = new UserActions();
-
- const loginPage = new LoginPage();
- const page = new BrowsingPage();
-
- const dialog = new ContentNodeSelectorDialog();
- const breadcrumb = dialog.breadcrumb;
- const dataTable = dialog.dataTable;
-
- beforeAll(async () => {
- await adminApiActions.createUser({ username });
- await adminApiActions.createUser({ username: consumer });
- await adminApiActions.createUser({ username: contributor });
- await adminApiActions.createUser({ username: collaborator });
-
- await userActions.login(username, username);
-
- fileId = (await userApi.nodes.createFile(file)).entry.id;
-
- destinationId = (await userApi.nodes.createFolder(destination)).entry.id;
- await userApi.nodes.createFile(fileInDestination, destinationId);
- await userApi.nodes.createFolder(folderInDestination, destinationId);
- const folder2Id = (await userApi.nodes.createFolder(folder2InDestination, destinationId)).entry.id;
- folderLink = (await userApi.nodes.createFolderLink(folder2Id, destinationId)).entry.name;
- searchFolderId = (await userApi.nodes.createFolder(searchFolder, destinationId)).entry.id;
- searchSubFolder1Id = (await userApi.nodes.createFolder(searchSubFolder1, searchFolderId)).entry.id;
- await userApi.nodes.createFolder(searchSubFolder2, searchSubFolder1Id);
-
- await userApi.sites.createSite(site, SITE_VISIBILITY.PRIVATE);
- const docLibId = await userApi.sites.getDocLibId(site);
- searchFolderSiteId = (await userApi.nodes.createFolder(searchFolder, docLibId)).entry.id;
- searchSubFolder1SiteId = (await userApi.nodes.createFolder(searchSubFolder1, searchFolderSiteId)).entry.id;
- await userApi.nodes.createFolder(searchSubFolder2, searchSubFolder1SiteId);
-
- await userApi.sites.addSiteConsumer(site, consumer);
- await userApi.sites.addSiteContributor(site, contributor);
- await userApi.sites.addSiteCollaborator(site, collaborator);
-
- fileIdConsumer = (await consumerApi.nodes.createFile(file)).entry.id;
- fileIdContributor = (await contributorApi.nodes.createFile(file)).entry.id;
- fileIdCollaborator = (await collaboratorApi.nodes.createFile(file)).entry.id;
-
- await adminApiActions.login();
- adminFolderId = (await adminApiActions.nodes.createFolder(adminFolder)).entry.id;
-
- await userApi.search.waitForNodes(searchFolder, { expect: 2 });
- });
-
- afterAll(async () => {
- await userActions.login(username, username);
- await userActions.deleteNodes([fileId, destinationId]);
- await userActions.deleteSites([site]);
-
- await consumerApi.nodes.deleteNodeById(fileIdConsumer);
- await contributorApi.nodes.deleteNodeById(fileIdContributor);
- await collaboratorApi.nodes.deleteNodeById(fileIdCollaborator);
-
- await adminApiActions.login();
- await adminApiActions.deleteNodes([adminFolderId]);
- });
-
- afterEach(async () => {
- await page.closeOpenDialogs();
- await page.dataTable.clearSelection();
- });
-
- describe('general', () => {
- beforeAll(async () => {
- await loginPage.loginWith(username);
- });
-
- beforeEach(async () => {
- await page.dataTable.selectItem(file);
- await page.toolbar.clickMoreActionsCopy();
- await dialog.waitForDialogToOpen();
- });
-
- it('[C263875] Dialog UI', async () => {
- expect(await dialog.getDialogTitle()).toEqual(`Copy '${file}' to...`);
- expect(await dialog.searchInput.isPresent()).toBe(true, 'Search input is not displayed');
- expect(await dialog.isSelectLocationDropdownDisplayed()).toBe(true, 'Select Location dropdown not displayed');
- expect(await breadcrumb.currentFolder.getText()).toEqual('Personal Files');
- expect(await dataTable.isItemPresent(destination)).toBe(true, 'Personal Files content not displayed');
- expect(await dialog.isCopyButtonEnabled()).toBe(true, 'Copy button is not disabled');
- expect(await dialog.isCancelButtonEnabled()).toBe(true, 'Cancel button is not enabled');
- });
-
- it('[C263880] Files are not displayed', async () => {
- await dialog.selectLocation('Personal Files');
- expect(await dataTable.isItemPresent(destination)).toBe(true, 'destination folder not displayed');
-
- await dataTable.doubleClickOnRowByName(destination);
- expect(await dataTable.isItemPresent(folderInDestination)).toBe(true, 'folder is not displayed');
- expect(await dataTable.isItemPresent(fileInDestination)).toBe(false, 'file is displayed');
- });
-
- it('[C263881] Folder links are not displayed', async () => {
- await dialog.selectLocation('Personal Files');
- await dataTable.doubleClickOnRowByName(destination);
-
- expect(await dataTable.isItemPresent(folderInDestination)).toBe(true, `${folderInDestination} is not displayed`);
- expect(await dataTable.isItemPresent(folder2InDestination)).toBe(true, `${folder2InDestination} is not displayed`);
- expect(await dataTable.isItemPresent(folderLink)).toBe(false, 'Link to folder is displayed');
- });
-
- it('[C263885] User can see his Libraries', async () => {
- await dialog.selectLocation('My Libraries');
- expect(await dataTable.isItemPresent(site)).toBe(true, 'user site is not displayed');
- });
-
- it('[C263889] Search - No results displayed', async () => {
- await dialog.searchFor('nonexistent-folder');
-
- expect(await dataTable.isEmpty()).toBe(true, 'datatable not empty');
- expect(await dataTable.getEmptyListText()).toEqual('No results found');
- });
-
- it('[C263888] Search - results found', async () => {
- await dialog.searchFor(searchFolder);
-
- expect(await dataTable.isItemPresent(searchFolder, username)).toBe(true, 'folder from Personal Files not displayed');
- expect(await dataTable.isItemPresent(searchFolder, site)).toBe(true, 'folder from site not displayed');
- });
- });
-
- describe('multiple selection', () => {
- beforeAll(async () => {
- await loginPage.loginWith(username);
- });
-
- beforeEach(async () => {
- await page.dataTable.selectMultipleItems([file, destination]);
- await page.toolbar.clickMoreActionsCopy();
- await dialog.waitForDialogToOpen();
- });
-
- it('[C263879] Dialog title - multiple selection', async () => {
- expect(await dialog.getDialogTitle()).toEqual(`Copy 2 items to...`);
- });
- });
-
- describe('breadcrumb', () => {
- beforeAll(async () => {
- await loginPage.loginWith(username);
- });
-
- beforeEach(async () => {
- await page.dataTable.selectItem(file);
- await page.toolbar.clickMoreActionsCopy();
- await dialog.waitForDialogToOpen();
- });
-
- it('[C263890] Personal Files breadcrumb - main node', async () => {
- await dialog.selectLocation('Personal Files');
- expect(await breadcrumb.currentFolder.getText()).toEqual('Personal Files');
- });
-
- it('[C263891] File Libraries breadcrumb - main node', async () => {
- await dialog.selectLocation('My Libraries');
- expect(await breadcrumb.currentFolder.getText()).toEqual('My Libraries');
- });
-
- it('[C263899] Search results breadcrumb', async () => {
- await dialog.searchFor(searchFolder);
- expect(await dialog.getToolbarTitle()).toEqual('Search results');
- });
-
- it('[C263900] Search results breadcrumb when selecting a folder', async () => {
- await dialog.searchFor(searchFolder);
- await dataTable.selectItem(searchFolder, site);
- expect(await breadcrumb.currentFolder.getText()).toEqual(searchFolder);
- });
-
- it('[C263897] Personal Files breadcrumb - folder structure', async () => {
- await dialog.selectLocation('Personal Files');
- await dataTable.doubleClickOnRowByName(destination);
-
- expect(await breadcrumb.currentFolder.getText()).toEqual(destination);
- await dataTable.doubleClickOnRowByName(searchFolder);
- expect(await breadcrumb.currentFolder.getText()).toEqual(searchFolder);
- await dataTable.doubleClickOnRowByName(searchSubFolder1);
- expect(await breadcrumb.currentFolder.getText()).toEqual(searchSubFolder1);
- await dataTable.doubleClickOnRowByName(searchSubFolder2);
- expect(await breadcrumb.currentFolder.getText()).toEqual(searchSubFolder2);
- await breadcrumb.openPath();
- expect(await breadcrumb.getPathItems()).toEqual([searchSubFolder1, searchFolder, destination, 'Personal Files']);
- });
-
- it('[C263898] File Libraries breadcrumb - folder structure', async () => {
- await dialog.selectLocation('My Libraries');
-
- await dataTable.doubleClickOnRowByName(site);
- expect(await breadcrumb.currentFolder.getText()).toEqual(site);
-
- await dataTable.doubleClickOnRowByName('documentLibrary');
- expect(await breadcrumb.currentFolder.getText()).toEqual(site);
-
- await dataTable.doubleClickOnRowByName(searchFolder);
- expect(await breadcrumb.currentFolder.getText()).toEqual(searchFolder);
-
- await dataTable.doubleClickOnRowByName(searchSubFolder1);
- expect(await breadcrumb.currentFolder.getText()).toEqual(searchSubFolder1);
-
- await dataTable.doubleClickOnRowByName(searchSubFolder2);
- expect(await breadcrumb.currentFolder.getText()).toEqual(searchSubFolder2);
-
- await breadcrumb.openPath();
- expect(await breadcrumb.getPathItems()).toEqual([searchSubFolder1, searchFolder, site, 'My Libraries']);
- });
-
- it('[C263895] Select a node from the breadcrumb path', async () => {
- await dialog.selectLocation('Personal Files');
- await dataTable.doubleClickOnRowByName(destination);
- await dataTable.doubleClickOnRowByName(searchFolder);
- await dataTable.doubleClickOnRowByName(searchSubFolder1);
- await dataTable.doubleClickOnRowByName(searchSubFolder2);
- await breadcrumb.openPath();
-
- await breadcrumb.clickPathItem(destination);
- expect(await breadcrumb.currentFolder.getText()).toEqual(destination);
- expect(await dataTable.isItemPresent(searchFolder)).toBe(true, 'folder not displayed');
- });
- });
-
- describe('Users with different permissions', () => {
- it('[C263876] Consumer user cannot select the folder as destination', async () => {
- await loginPage.loginWith(consumer);
- await page.dataTable.selectItem(file);
- await page.toolbar.clickMoreActionsCopy();
- await dialog.waitForDialogToOpen();
-
- await dialog.selectLocation('My Libraries');
- await dataTable.doubleClickOnRowByName(site);
- await dataTable.doubleClickOnRowByName('documentLibrary');
- await dataTable.selectItem(searchFolder);
-
- expect(await dialog.isCopyButtonEnabled()).toBe(false, 'Copy should be disabled');
- });
-
- it('[C263877] Contributor user can select the folder as destination', async () => {
- await loginPage.loginWith(contributor);
- await page.dataTable.selectItem(file);
- await page.toolbar.clickMoreActionsCopy();
- await dialog.waitForDialogToOpen();
-
- await dialog.selectLocation('My Libraries');
- await dataTable.doubleClickOnRowByName(site);
- await dataTable.doubleClickOnRowByName('documentLibrary');
- await dataTable.selectItem(searchFolder);
-
- expect(await dialog.isCopyButtonEnabled()).toBe(true, 'Copy should be disabled');
- });
-
- it('[C263878] Collaborator user can select the folder as destination', async () => {
- await loginPage.loginWith(collaborator);
- await page.dataTable.selectItem(file);
- await page.toolbar.clickMoreActionsCopy();
- await dialog.waitForDialogToOpen();
-
- await dialog.selectLocation('My Libraries');
- await dataTable.doubleClickOnRowByName(site);
- await dataTable.doubleClickOnRowByName('documentLibrary');
- await dataTable.selectItem(searchFolder);
-
- expect(await dialog.isCopyButtonEnabled()).toBe(true, 'Copy should be disabled');
- });
-
- it('[C263892] Admin user - Personal Files breadcrumb main node', async () => {
- await loginPage.loginWithAdmin();
- await page.dataTable.selectItem(adminFolder);
- await page.toolbar.clickMoreActionsCopy();
- await dialog.waitForDialogToOpen();
-
- await dialog.selectLocation('Personal Files');
- expect(await breadcrumb.currentFolder.getText()).toEqual('Company Home');
- });
- });
-});
diff --git a/e2e/protractor/suites/actions/copy-move/move.test.ts b/e2e/protractor/suites/actions/copy-move/move.test.ts
deleted file mode 100755
index 366d68e82a..0000000000
--- a/e2e/protractor/suites/actions/copy-move/move.test.ts
+++ /dev/null
@@ -1,283 +0,0 @@
-/*!
- * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
- *
- * Alfresco Example Content Application
- *
- * This file is part of the Alfresco Example Content Application.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * The Alfresco Example Content Application is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * from Hyland Software. If not, see .
- */
-
-import { AdminActions, LoginPage, BrowsingPage, ContentNodeSelectorDialog, RepoClient, Utils } from '@alfresco/aca-testing-shared';
-import { BrowserActions } from '@alfresco/adf-testing';
-
-describe('Move content', () => {
- const username = `user-${Utils.random()}`;
-
- const sourcePF = `sourcePersonal-${Utils.random()}`;
- let sourceIdPF: string;
- const destinationPF = `destinationPersonal-${Utils.random()}`;
- let destinationIdPF: string;
-
- const sourceRF = `sourceRecent-${Utils.random()}`;
- let sourceIdRF: string;
- const destinationRF = `destinationRecent-${Utils.random()}`;
- let destinationIdRF: string;
-
- const sourceSF = `sourceShared-${Utils.random()}`;
- let sourceIdSF: string;
- const destinationSF = `destinationShared-${Utils.random()}`;
- let destinationIdSF: string;
-
- const sourceFav = `sourceFavorites-${Utils.random()}`;
- let sourceIdFav: string;
- const destinationFav = `destinationFavorites-${Utils.random()}`;
- let destinationIdFav: string;
-
- const siteName = `site-${Utils.random()}`;
- const folderSitePF = `folderSitePersonal-${Utils.random()}`;
- const folderSiteRF = `folderSiteRecent-${Utils.random()}`;
- const folderSiteSF = `folderSiteShared-${Utils.random()}`;
- const folderSiteFav = `folderSiteFavorites-${Utils.random()}`;
-
- const apis = new RepoClient(username, username);
-
- const loginPage = new LoginPage();
- const page = new BrowsingPage();
- const { dataTable, toolbar } = page;
- const moveDialog = new ContentNodeSelectorDialog();
-
- const adminApiActions = new AdminActions();
-
- beforeAll(async () => {
- await adminApiActions.createUser({ username });
-
- await apis.sites.createSite(siteName);
- const docLibId = await apis.sites.getDocLibId(siteName);
-
- await apis.createFolder(folderSitePF, docLibId);
- await apis.createFolder(folderSiteRF, docLibId);
- await apis.createFolder(folderSiteSF, docLibId);
- await apis.createFolder(folderSiteFav, docLibId);
-
- sourceIdPF = await apis.createFolder(sourcePF);
- destinationIdPF = await apis.createFolder(destinationPF);
-
- sourceIdRF = await apis.createFolder(sourceRF);
- destinationIdRF = await apis.createFolder(destinationRF);
-
- sourceIdSF = await apis.createFolder(sourceSF);
- destinationIdSF = await apis.createFolder(destinationSF);
-
- sourceIdFav = await apis.createFolder(sourceFav);
- destinationIdFav = await apis.createFolder(destinationFav);
-
- await loginPage.loginWith(username);
- });
-
- afterAll(async () => {
- await apis.nodes.deleteNodesById([
- sourceIdPF,
- sourceIdRF,
- sourceIdSF,
- sourceIdFav,
- destinationIdPF,
- destinationIdRF,
- destinationIdSF,
- destinationIdFav
- ]);
- await apis.sites.deleteSite(siteName);
- });
-
- describe('from Personal Files', () => {
- const file1 = `file1-${Utils.random()}.txt`;
- const folder1 = `folder1-${Utils.random()}`;
- const fileInFolder = `fileInFolder-${Utils.random()}.txt`;
- const file2 = `file2-${Utils.random()}.txt`;
- const file3 = `file3-${Utils.random()}.txt`;
- const file4 = `file4-${Utils.random()}.txt`;
- const folder2 = `folder2-${Utils.random()}`;
- const fileInFolder2 = `fileInFolder2-${Utils.random()}.txt`;
- const existingFile = `existing-${Utils.random()}`;
- const existingFolder = `existing-${Utils.random()}`;
- const file2InFolder = `file2InFolder-${Utils.random()}.txt`;
- const file3InFolder = `file3InFolder-${Utils.random()}.txt`;
-
- beforeAll(async () => {
- await apis.createFile(file1, sourceIdPF);
-
- const folder1Id = await apis.createFolder(folder1, sourceIdPF);
- await apis.createFile(fileInFolder, folder1Id);
-
- await apis.createFile(file2, sourceIdPF);
- await apis.createFile(file3, sourceIdPF);
- await apis.createFile(file4, sourceIdPF);
-
- await apis.createFile(`${existingFile}.txt`, sourceIdPF);
- await apis.createFile(`${existingFile}.txt`, destinationIdPF);
-
- const existingId1 = await apis.createFolder(existingFolder, sourceIdPF);
- await apis.createFile(file2InFolder, existingId1);
-
- const existingId2 = await apis.createFolder(existingFolder, destinationIdPF);
- await apis.createFile(file3InFolder, existingId2);
-
- const folder2Id = await apis.createFolder(folder2, sourceIdPF);
- await apis.createFile(fileInFolder2, folder2Id);
- });
-
- beforeEach(async () => {
- await Utils.pressEscape();
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(sourcePF);
- });
-
- it('[C217316] Move a file', async () => {
- await dataTable.selectItem(file1);
- await toolbar.clickMoreActionsMove();
- await moveDialog.selectLocation('Personal Files');
- await moveDialog.selectDestination(destinationPF);
- await BrowserActions.click(moveDialog.moveButton);
- const msg = await page.getSnackBarMessage();
- expect(msg).toContain('Moved 1 item');
- const action = await page.getSnackBarAction();
- expect(action).toContain('Undo');
-
- await moveDialog.waitForDialogToClose();
- expect(await dataTable.isItemPresent(file1)).toBe(false, `${file1} still present in source folder`);
-
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(destinationPF);
- expect(await dataTable.isItemPresent(file1)).toBe(true, `${file1} not present in destination folder`);
- });
-
- it('[C217317] Move a folder with content', async () => {
- await dataTable.selectItem(folder1);
- await toolbar.clickMoreActionsMove();
- await moveDialog.selectLocation('Personal Files');
- await moveDialog.selectDestination(destinationPF);
- await BrowserActions.click(moveDialog.moveButton);
- const msg = await page.getSnackBarMessage();
- expect(msg).toContain('Moved 1 item');
- const action = await page.getSnackBarAction();
- expect(action).toContain('Undo');
-
- await moveDialog.waitForDialogToClose();
- expect(await dataTable.isItemPresent(folder1)).toBe(false, `${folder1} still present in source folder`);
-
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(destinationPF);
- expect(await dataTable.isItemPresent(folder1)).toBe(true, `${folder1} not present in destination folder`);
- expect(await dataTable.isItemPresent(fileInFolder)).toBe(false, `${fileInFolder} is present in destination folder`);
-
- await dataTable.doubleClickOnRowByName(folder1);
- expect(await dataTable.isItemPresent(fileInFolder)).toBe(true, `${fileInFolder} is not present in parent folder`);
- });
-
- it('[C291958] Move multiple items', async () => {
- await dataTable.selectMultipleItems([file2, file3]);
- await toolbar.clickMoreActionsMove();
- await moveDialog.selectLocation('Personal Files');
- await moveDialog.selectDestination(destinationPF);
- await BrowserActions.click(moveDialog.moveButton);
- const msg = await page.getSnackBarMessage();
- expect(msg).toContain('Moved 2 items');
- const action = await page.getSnackBarAction();
- expect(action).toContain('Undo');
-
- await moveDialog.waitForDialogToClose();
- expect(await dataTable.isItemPresent(file2)).toBe(false, `${file2} still present in source folder`);
- expect(await dataTable.isItemPresent(file3)).toBe(false, `${file3} still present in source folder`);
-
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(destinationPF);
- expect(await dataTable.isItemPresent(file2)).toBe(true, `${file2} not present in destination folder`);
- expect(await dataTable.isItemPresent(file3)).toBe(true, `${file3} not present in destination folder`);
- });
-
- it('[C217318] Move a file with a name that already exists on the destination', async () => {
- await dataTable.selectItem(existingFile);
- await toolbar.clickMoreActionsMove();
- await moveDialog.selectLocation('Personal Files');
- await moveDialog.selectDestination(destinationPF);
- await BrowserActions.click(moveDialog.moveButton);
- const msg = await page.getSnackBarMessage();
- expect(msg).toContain('Move unsuccessful, a file with the same name already exists');
- const action = await page.getSnackBarAction();
- expect(action).not.toContain('Undo');
-
- await moveDialog.waitForDialogToClose();
- expect(await dataTable.isItemPresent(`${existingFile}.txt`)).toBe(true, `${existingFile}.txt not present in source folder`);
-
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(destinationPF);
- expect(await dataTable.isItemPresent(`${existingFile}.txt`)).toBe(true, `${existingFile}.txt not present in destination folder`);
- expect(await dataTable.isItemPresent(`${existingFile}-1.txt`)).toBe(false, `${existingFile}-1.txt is present in destination folder`);
- });
-
- it('[C217319] Move a folder with a name that already exists on the destination', async () => {
- await dataTable.selectItem(existingFolder);
- await toolbar.clickMoreActionsMove();
- await moveDialog.selectLocation('Personal Files');
- await moveDialog.selectDestination(destinationPF);
- await BrowserActions.click(moveDialog.moveButton);
- const msg = await page.getSnackBarMessage();
- expect(msg).toContain('Moved 1 item');
- const action = await page.getSnackBarAction();
- expect(action).toContain('Undo');
-
- await moveDialog.waitForDialogToClose();
- expect(await dataTable.isItemPresent(existingFolder)).toBe(false, `${existingFolder} still present in source folder`);
-
- await page.clickPersonalFilesAndWait();
- await dataTable.doubleClickOnRowByName(destinationPF);
- expect(await dataTable.isItemPresent(existingFolder)).toBe(true, `${existingFolder} not present in destination folder`);
-
- await dataTable.doubleClickOnRowByName(existingFolder);
- await dataTable.waitForBody();
- expect(await dataTable.isItemPresent(file2InFolder)).toBe(true, `${file2InFolder} not present in destination folder`);
- expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in destination folder`);
- });
-
- it('[C291969] Move items into a library', async () => {
- await dataTable.selectMultipleItems([file4, folder2]);
- await toolbar.clickMoreActionsMove();
- await moveDialog.selectLocation('My Libraries');
- await moveDialog.dataTable.doubleClickOnRowByName(siteName);
- await moveDialog.dataTable.doubleClickOnRowByName('documentLibrary');
- await moveDialog.selectDestination(folderSitePF);
- await BrowserActions.click(moveDialog.moveButton);
- const msg = await page.getSnackBarMessage();
- expect(msg).toContain('Moved 2 items');
- const action = await page.getSnackBarAction();
- expect(action).toContain('Undo');
-
- await moveDialog.waitForDialogToClose();
- expect(await dataTable.isItemPresent(file4)).toBe(false, `${file4} still present in source folder`);
- expect(await dataTable.isItemPresent(folder2)).toBe(false, `${folder2} still present in source folder`);
-
- await page.goToMyLibraries();
- await dataTable.doubleClickOnRowByName(siteName);
- await dataTable.doubleClickOnRowByName(folderSitePF);
-
- expect(await dataTable.isItemPresent(file4)).toBe(true, `${file4} not present in destination folder`);
- expect(await dataTable.isItemPresent(folder2)).toBe(true, `${folder2} not present in destination folder`);
- await dataTable.doubleClickOnRowByName(folder2);
- expect(await dataTable.isItemPresent(fileInFolder2)).toBe(true, `${fileInFolder2} not present in parent folder`);
- });
- });
-});
diff --git a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts
index 4e51de20ba..a9dee96d11 100644
--- a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts
+++ b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts
@@ -192,18 +192,22 @@ export class DataTableComponent extends BaseComponent {
return null;
}
- if ((await this.pagination.currentPageLocator.textContent()) !== ' Page 1 ') {
- await this.pagination.navigateToPage(1);
+ if (await this.pagination.currentPageLocator.isVisible()) {
+ if ((await this.pagination.currentPageLocator.textContent()) !== ' Page 1 ') {
+ await this.pagination.navigateToPage(1);
+ }
}
-
- const maxPages = (await this.pagination.totalPageLocator.textContent()).match(/\d/)[0];
- for (let page = 1; page <= Number(maxPages); page++) {
- if (await this.getRowByName(name).isVisible()) {
- break;
+ if (await this.pagination.totalPageLocator.isVisible()) {
+ const maxPages = (await this.pagination.totalPageLocator?.textContent())?.match(/\d/)[0];
+ for (let page = 1; page <= Number(maxPages); page++) {
+ if (await this.getRowByName(name).isVisible()) {
+ break;
+ }
+ if (await this.pagination.getArrowLocatorFor(PaginationActionsType.NextPageSelector).isEnabled()) {
+ await this.pagination.getArrowLocatorFor(PaginationActionsType.NextPageSelector).click();
+ }
+ await this.spinnerWaitForReload();
}
- await this.pagination.getArrowLocatorFor(PaginationActionsType.NextPageSelector).isEnabled();
- await this.pagination.getArrowLocatorFor(PaginationActionsType.NextPageSelector).click();
- await this.spinnerWaitForReload();
}
}
diff --git a/projects/aca-playwright-shared/src/page-objects/components/dialogs/content-node-selector-dialog.ts b/projects/aca-playwright-shared/src/page-objects/components/dialogs/content-node-selector-dialog.ts
index cd29aff11f..5c6006c01c 100755
--- a/projects/aca-playwright-shared/src/page-objects/components/dialogs/content-node-selector-dialog.ts
+++ b/projects/aca-playwright-shared/src/page-objects/components/dialogs/content-node-selector-dialog.ts
@@ -38,7 +38,7 @@ export class ContentNodeSelectorDialog extends BaseComponent {
private selectedRow = this.getChild('.adf-is-selected');
getOptionLocator = (optionName: string): Locator => this.page.locator('.mat-select-panel .mat-option-text', { hasText: optionName });
private getRowByName = (name: string | number): Locator => this.getChild(`adf-datatable-row`, { hasText: name.toString() });
- getDialogTitle = (text: string) => this.getChild('.mat-dialog-title', { hasText: text });
+ getDialogTitle = (text: string) => this.getChild('[data-automation-id="content-node-selector-title"]', { hasText: text });
getBreadcrumb = (text: string) => this.getChild('[data-automation-id="current-folder"]', { hasText: text });
getFolderIcon = this.getChild('mat-icon[role="img"]', { hasText: "folder" });
diff --git a/projects/aca-playwright-shared/src/page-objects/components/snackBar/snack-bar.component.ts b/projects/aca-playwright-shared/src/page-objects/components/snackBar/snack-bar.component.ts
index ac043a1ba7..05be91c888 100644
--- a/projects/aca-playwright-shared/src/page-objects/components/snackBar/snack-bar.component.ts
+++ b/projects/aca-playwright-shared/src/page-objects/components/snackBar/snack-bar.component.ts
@@ -28,7 +28,11 @@ import { BaseComponent } from '../base.component';
export class SnackBarComponent extends BaseComponent {
private static rootElement = 'adf-snackbar-content';
- public message = this.getChild(' [data-automation-id=\'adf-snackbar-message-content\']').first();
+ public message = this.getChild('[data-automation-id="adf-snackbar-message-content"]').first();
+
+ public actionButton = this.getChild('[data-automation-id="adf-snackbar-message-content-action-button"]')
+
+ public closeIcon = this.getChild('.adf-snackbar-message-content-action-icon');
public getByMessageLocator = (message: string) => this.getChild(`[data-automation-id='adf-snackbar-message-content']`,
{ hasText: message }).first();
diff --git a/projects/aca-playwright-shared/src/page-objects/pages/my-libraries.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/my-libraries.page.ts
index a6f13b4021..152bcb4bab 100644
--- a/projects/aca-playwright-shared/src/page-objects/pages/my-libraries.page.ts
+++ b/projects/aca-playwright-shared/src/page-objects/pages/my-libraries.page.ts
@@ -63,4 +63,9 @@ export class MyLibrariesPage extends BasePage {
await this.acaHeader.createButton.click();
await this.matMenu.createLibrary.click();
}
+
+ async clickMoreActionsButton(buttonLabel: string): Promise {
+ await this.acaHeader.clickMoreActions();
+ await this.matMenu.clickMenuItem(buttonLabel);
+ }
}
diff --git a/projects/aca-playwright-shared/src/page-objects/pages/personal-files.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/personal-files.page.ts
index 1f2d76ac9c..af46e02ef8 100644
--- a/projects/aca-playwright-shared/src/page-objects/pages/personal-files.page.ts
+++ b/projects/aca-playwright-shared/src/page-objects/pages/personal-files.page.ts
@@ -71,4 +71,20 @@ export class PersonalFilesPage extends BasePage {
async waitForPageLoad() {
await this.page.waitForURL(`**/${PersonalFilesPage.pageUrl}`);
}
+
+ async clickMoreActionsButton(buttonLabel: string): Promise {
+ await this.acaHeader.clickMoreActions();
+ await this.matMenu.clickMenuItem(buttonLabel);
+ }
+
+ async copyOrMoveContentInDatatable(sourceFileList: string[], destinationName: string, operation = 'Copy'): Promise {
+ await this.page.keyboard.down('Control');
+ for (const sourceName of sourceFileList) {
+ await this.dataTable.selectItem(sourceName);
+ }
+ await this.page.keyboard.up('Control');
+ await this.clickMoreActionsButton(operation);
+ await this.contentNodeSelector.selectDestination(destinationName);
+ await this.contentNodeSelector.actionButton.click();
+ }
}
diff --git a/projects/aca-testing-shared/src/components/dialog/content-node-selector-dialog.ts b/projects/aca-testing-shared/src/components/dialog/content-node-selector-dialog.ts
index fdb8162f69..895714eb7a 100755
--- a/projects/aca-testing-shared/src/components/dialog/content-node-selector-dialog.ts
+++ b/projects/aca-testing-shared/src/components/dialog/content-node-selector-dialog.ts
@@ -24,24 +24,19 @@
import { by, browser, protractor } from 'protractor';
import { GenericDialog } from '../dialog/generic-dialog';
-import { isPresentAndDisplayed, waitForStaleness, waitForPresence, isPresentAndEnabled } from '../../utilities/utils';
-import { DropDownBreadcrumb } from '../breadcrumb/dropdown-breadcrumb';
+import { waitForStaleness, waitForPresence } from '../../utilities/utils';
import { DataTable } from '../data-table/data-table';
import { BrowserActions } from '@alfresco/adf-testing';
export class ContentNodeSelectorDialog extends GenericDialog {
- cancelButton = this.childElement(by.css('[data-automation-id="content-node-selector-actions-cancel"]'));
copyButton = this.childElement(by.cssContainingText('[data-automation-id="content-node-selector-actions-choose"]', 'Copy'));
- moveButton = this.childElement(by.cssContainingText('[data-automation-id="content-node-selector-actions-choose"]', 'Move'));
locationDropDown = this.rootElem.element(by.id('site-dropdown-container'));
locationPersonalFiles = browser.element(by.cssContainingText('.mat-option .mat-option-text', 'Personal Files'));
locationFileLibraries = browser.element(by.cssContainingText('.mat-option .mat-option-text', 'My Libraries'));
searchInput = this.rootElem.element(by.css('#searchInput'));
- toolbarTitle = this.rootElem.element(by.css('.adf-toolbar-title'));
- breadcrumb = new DropDownBreadcrumb();
dataTable = new DataTable('.adf-content-node-selector-dialog');
constructor() {
@@ -74,25 +69,9 @@ export class ContentNodeSelectorDialog extends GenericDialog {
await waitForPresence(browser.element(by.css('.adf-is-selected')));
}
- async isSelectLocationDropdownDisplayed(): Promise {
- return isPresentAndDisplayed(this.locationDropDown);
- }
-
- async isCopyButtonEnabled(): Promise {
- return isPresentAndEnabled(this.copyButton);
- }
-
- async isCancelButtonEnabled(): Promise {
- return isPresentAndEnabled(this.cancelButton);
- }
-
async searchFor(text: string): Promise {
await BrowserActions.clearWithBackSpace(this.searchInput);
await this.searchInput.sendKeys(text);
await this.searchInput.sendKeys(protractor.Key.ENTER);
}
-
- async getToolbarTitle(): Promise {
- return this.toolbarTitle.getText();
- }
}