[ACS-5014] Migrated Copy Move actions E2Es from protractor to playwright (#3531)

* [ACS-5014] Added Playwright E2E tests for copy-move actions

* [ACS-5014] Fixed missing import in tsconfig.e2e.json

* [ACS-5014] Removed unneeded method from utils.ts

* [ACS-5014] Updated playwright.config.ts

* [ACS-5014] Copy and Move tests are now working

* [ACS-5014] Removed unneeded test.only

* [ACS-5014] Added test case IDs to E2E tests

* [ACS-6211] Removed TODO note. Removed protractor test case files

* [ACS-5014] Added E2E tests for Destination Picker in copy-move actions

* [ACS-5014] Removed unneded only from test suite

* [ACS-5014] Updated import of logger from @alfresco/adf-cli to @alfresco/adf-testing

* [ACS-5014] Addressed code review findings. Moved objects to beforeAll/beforeEach wherever applicable. Added missing await.

* [ACS-5014] Addressed code review findings. Removed unused methods/objects from content-node-selector-dialog.ts

* [ACS-5014] Addressed code review findings. Removed unused methods/objects from content-node-selector-dialog.ts

* [ACS-5014] SonarLint fix

* [ACS-5014] Fixed breaking change for other E2Es

* [ACS-5014] Updated E2Es to use correct locator for more actions button
This commit is contained in:
swapnil-verma-gl 2023-12-06 16:01:48 +05:30 committed by GitHub
parent 5062220056
commit f917a663b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 696 additions and 1137 deletions

View File

@ -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"
}
}
]
}

View File

@ -0,0 +1 @@
{}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
import { PlaywrightTestConfig } from '@playwright/test';
import { CustomConfig, getGlobalConfig, getExcludedTestsRegExpArray, timeouts } from '@alfresco/playwright-shared';
import EXCLUDED_JSON from './exclude.tests.json';
const config: PlaywrightTestConfig<CustomConfig> = {
...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;

View File

@ -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"
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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();
});
});

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
});
});

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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();
});
});

View File

@ -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"]
}

View File

@ -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"]
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<void>,
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<void>) {
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');
}
});

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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');
});
});
});

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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`);
});
});
});

View File

@ -192,20 +192,24 @@ export class DataTableComponent extends BaseComponent {
return null;
}
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];
}
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;
}
await this.pagination.getArrowLocatorFor(PaginationActionsType.NextPageSelector).isEnabled();
if (await this.pagination.getArrowLocatorFor(PaginationActionsType.NextPageSelector).isEnabled()) {
await this.pagination.getArrowLocatorFor(PaginationActionsType.NextPageSelector).click();
}
await this.spinnerWaitForReload();
}
}
}
async selectItem(name: string): Promise<void> {
const isSelected = await this.hasCheckMarkIcon(name);

View File

@ -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" });

View File

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

View File

@ -63,4 +63,9 @@ export class MyLibrariesPage extends BasePage {
await this.acaHeader.createButton.click();
await this.matMenu.createLibrary.click();
}
async clickMoreActionsButton(buttonLabel: string): Promise<void> {
await this.acaHeader.clickMoreActions();
await this.matMenu.clickMenuItem(buttonLabel);
}
}

View File

@ -71,4 +71,20 @@ export class PersonalFilesPage extends BasePage {
async waitForPageLoad() {
await this.page.waitForURL(`**/${PersonalFilesPage.pageUrl}`);
}
async clickMoreActionsButton(buttonLabel: string): Promise<void> {
await this.acaHeader.clickMoreActions();
await this.matMenu.clickMenuItem(buttonLabel);
}
async copyOrMoveContentInDatatable(sourceFileList: string[], destinationName: string, operation = 'Copy'): Promise<void> {
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();
}
}

View File

@ -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<boolean> {
return isPresentAndDisplayed(this.locationDropDown);
}
async isCopyButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.copyButton);
}
async isCancelButtonEnabled(): Promise<boolean> {
return isPresentAndEnabled(this.cancelButton);
}
async searchFor(text: string): Promise<void> {
await BrowserActions.clearWithBackSpace(this.searchInput);
await this.searchInput.sendKeys(text);
await this.searchInput.sendKeys(protractor.Key.ENTER);
}
async getToolbarTitle(): Promise<string> {
return this.toolbarTitle.getText();
}
}