mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2026-09-09 18:02:54 +00:00
[ACS-11871] e2e test for link document (#5281)
* [ACS-11871] e2e test for link document * [ACS-11871] fix test case name and improve test with icon check * [ACS-11871] add CI run for e2e and comment fix * [ACS-11871] add CI run for e2e * [ACS-11871] add CI run for e2e * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * add fix for comment pr review locator and try catch * [ACS-11871] test fix, remove icon logic to very in manual test * [ACS-11871] e2e test for link document * [ACS-11871] fix test case name and improve test with icon check * [ACS-11871] add CI run for e2e and comment fix * [ACS-11871] add CI run for e2e * [ACS-11871] add CI run for e2e * add fix for comment pr review locator and try catch * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * [ACS-11871] test fix, remove icon logic to very in manual test * delete link test fix * fix delete test --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot Autofix powered by AI
parent
dd2d1f8711
commit
ea8eab3986
@@ -114,6 +114,8 @@ jobs:
|
|||||||
id: 19
|
id: 19
|
||||||
- name: "viewer-actions"
|
- name: "viewer-actions"
|
||||||
id: 20
|
id: 20
|
||||||
|
- name: "create-link-actions"
|
||||||
|
id: 21
|
||||||
steps:
|
steps:
|
||||||
- name: Free hosted runner disk space
|
- name: Free hosted runner disk space
|
||||||
uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@10cea6c0b390c4f8af21d9dc1670d581bd10319f # v18.13.0
|
uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@10cea6c0b390c4f8af21d9dc1670d581bd10319f # v18.13.0
|
||||||
|
|||||||
@@ -187,6 +187,8 @@ jobs:
|
|||||||
id: 19
|
id: 19
|
||||||
- name: "viewer-actions"
|
- name: "viewer-actions"
|
||||||
id: 20
|
id: 20
|
||||||
|
- name: "create-link-actions"
|
||||||
|
id: 21
|
||||||
steps:
|
steps:
|
||||||
- name: Free hosted runner disk space
|
- name: Free hosted runner disk space
|
||||||
uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@10cea6c0b390c4f8af21d9dc1670d581bd10319f # v18.13.0
|
uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@10cea6c0b390c4f8af21d9dc1670d581bd10319f # v18.13.0
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ jobs:
|
|||||||
id: 18
|
id: 18
|
||||||
- name: "folder-information-actions"
|
- name: "folder-information-actions"
|
||||||
id: 19
|
id: 19
|
||||||
|
- name: "viewer-actions"
|
||||||
|
id: 20
|
||||||
|
- name: "create-link-actions"
|
||||||
|
id: 21
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v7
|
uses: actions/checkout@v7
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../../.eslintrc.json",
|
||||||
|
"ignorePatterns": [
|
||||||
|
"!**/*"
|
||||||
|
],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"*.ts"
|
||||||
|
],
|
||||||
|
"extends": ["../../../.eslintrc.e2e.json"],
|
||||||
|
"parserOptions": {
|
||||||
|
"project": [
|
||||||
|
"e2e/playwright/create-link-actions/tsconfig.e2e.json"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/no-floating-promises": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"all": {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*!
|
||||||
|
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Alfresco Example Content Application
|
||||||
|
*
|
||||||
|
* This file is part of the Alfresco Example Content Application.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { PlaywrightTestConfig } from '@playwright/test';
|
||||||
|
import { CustomConfig, getGlobalConfig, getExcludedTestsRegExpArray, timeouts, createSuiteProjects } from '@alfresco/aca-playwright-shared';
|
||||||
|
import EXCLUDED_JSON from './exclude.tests.json';
|
||||||
|
|
||||||
|
const config: PlaywrightTestConfig<CustomConfig> = {
|
||||||
|
...getGlobalConfig,
|
||||||
|
|
||||||
|
grepInvert: getExcludedTestsRegExpArray(EXCLUDED_JSON, 'Create Link Actions'),
|
||||||
|
projects: createSuiteProjects('Create Link Actions', './src/tests', {}, { timeout: timeouts.extendedTest })
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
{
|
||||||
|
"name": "create-link-actions-e2e",
|
||||||
|
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
||||||
|
"sourceRoot": "e2e/playwright/create-link-actions/src",
|
||||||
|
"projectType": "application",
|
||||||
|
"targets": {
|
||||||
|
"e2e": {
|
||||||
|
"executor": "nx:run-commands",
|
||||||
|
"options": {
|
||||||
|
"commands": [
|
||||||
|
"playwright test --config=e2e/playwright/create-link-actions/playwright.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"ui": {
|
||||||
|
"args": [
|
||||||
|
"--ui"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"args": [
|
||||||
|
"--debug"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"headed": {
|
||||||
|
"args": [
|
||||||
|
"--headed"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"executor": "@angular-eslint/builder:lint"
|
||||||
|
},
|
||||||
|
"e2e-multibrowser": {
|
||||||
|
"executor": "nx:run-commands",
|
||||||
|
"options": {},
|
||||||
|
"configurations": {
|
||||||
|
"webkit-headed": {
|
||||||
|
"env": {
|
||||||
|
"PLAYWRIGHT_BROWSER": "webkit"
|
||||||
|
},
|
||||||
|
"args": [
|
||||||
|
"--headed"
|
||||||
|
],
|
||||||
|
"commands": [
|
||||||
|
"playwright test --config=e2e/playwright/create-link-actions/playwright.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"webkit-headless": {
|
||||||
|
"env": {
|
||||||
|
"PLAYWRIGHT_BROWSER": "webkit",
|
||||||
|
"PLAYWRIGHT_HEADLESS": "true"
|
||||||
|
},
|
||||||
|
"commands": [
|
||||||
|
"playwright test --config=e2e/playwright/create-link-actions/playwright.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"firefox-headed": {
|
||||||
|
"env": {
|
||||||
|
"PLAYWRIGHT_BROWSER": "firefox"
|
||||||
|
},
|
||||||
|
"args": [
|
||||||
|
"--headed"
|
||||||
|
],
|
||||||
|
"commands": [
|
||||||
|
"playwright test --config=e2e/playwright/create-link-actions/playwright.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"firefox-headless": {
|
||||||
|
"env": {
|
||||||
|
"PLAYWRIGHT_BROWSER": "firefox",
|
||||||
|
"PLAYWRIGHT_HEADLESS": "true"
|
||||||
|
},
|
||||||
|
"commands": [
|
||||||
|
"playwright test --config=e2e/playwright/create-link-actions/playwright.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"chrome-headed": {
|
||||||
|
"env": {
|
||||||
|
"PLAYWRIGHT_BROWSER": "chrome"
|
||||||
|
},
|
||||||
|
"args": [
|
||||||
|
"--headed"
|
||||||
|
],
|
||||||
|
"commands": [
|
||||||
|
"playwright test --config=e2e/playwright/create-link-actions/playwright.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"chrome-headless": {
|
||||||
|
"env": {
|
||||||
|
"PLAYWRIGHT_BROWSER": "chrome",
|
||||||
|
"PLAYWRIGHT_HEADLESS": "true"
|
||||||
|
},
|
||||||
|
"commands": [
|
||||||
|
"playwright test --config=e2e/playwright/create-link-actions/playwright.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"msedge-headed": {
|
||||||
|
"env": {
|
||||||
|
"PLAYWRIGHT_BROWSER": "msedge"
|
||||||
|
},
|
||||||
|
"args": [
|
||||||
|
"--headed"
|
||||||
|
],
|
||||||
|
"commands": [
|
||||||
|
"playwright test --config=e2e/playwright/create-link-actions/playwright.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"msedge-headless": {
|
||||||
|
"env": {
|
||||||
|
"PLAYWRIGHT_BROWSER": "msedge",
|
||||||
|
"PLAYWRIGHT_HEADLESS": "true"
|
||||||
|
},
|
||||||
|
"commands": [
|
||||||
|
"playwright test --config=e2e/playwright/create-link-actions/playwright.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"all-browsers-headless": {
|
||||||
|
"env": {
|
||||||
|
"PLAYWRIGHT_BROWSER": "all",
|
||||||
|
"PLAYWRIGHT_HEADLESS": "true"
|
||||||
|
},
|
||||||
|
"commands": [
|
||||||
|
"playwright test --config=e2e/playwright/create-link-actions/playwright.config.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/*!
|
||||||
|
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Alfresco Example Content Application
|
||||||
|
*
|
||||||
|
* This file is part of the Alfresco Example Content Application.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ApiClientFactory, NodesApi, TrashcanApi, Utils, test, LoginPage, PersonalFilesPage } from '@alfresco/aca-playwright-shared';
|
||||||
|
import { expect } from '@playwright/test';
|
||||||
|
|
||||||
|
test.describe('Create Link - creation scenarios', () => {
|
||||||
|
let nodesApi: NodesApi;
|
||||||
|
let trashcanApi: TrashcanApi;
|
||||||
|
const username = `user-${Utils.random()}`;
|
||||||
|
|
||||||
|
let sourceFile: string;
|
||||||
|
let sourceFolder: string;
|
||||||
|
let destinationFolder: string;
|
||||||
|
|
||||||
|
let sourceFileId: 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);
|
||||||
|
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`beforeAll failed: ${error}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test.beforeEach(async ({ personalFiles, page }) => {
|
||||||
|
sourceFile = `source-file-${Utils.random()}.txt`;
|
||||||
|
sourceFolder = `source-folder-${Utils.random()}`;
|
||||||
|
destinationFolder = `destination-folder-${Utils.random()}`;
|
||||||
|
|
||||||
|
const loginPage = new LoginPage(page);
|
||||||
|
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||||
|
|
||||||
|
sourceFileId = (await nodesApi.createFile(sourceFile)).entry.id;
|
||||||
|
await nodesApi.createFolder(sourceFolder);
|
||||||
|
destinationFolderId = (await nodesApi.createFolder(destinationFolder)).entry.id;
|
||||||
|
|
||||||
|
await personalFiles.navigate();
|
||||||
|
});
|
||||||
|
|
||||||
|
test.afterAll(async () => {
|
||||||
|
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19624] Should create a link for a file and verify it in the destination', async ({ personalFiles }) => {
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFile);
|
||||||
|
await createLinkInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
|
||||||
|
|
||||||
|
const msg = await personalFiles.snackBar.getSnackBarMessage();
|
||||||
|
expect(msg).toContain('Link created for 1 item');
|
||||||
|
|
||||||
|
await personalFiles.navigate({ remoteUrl: `./#/personal-files/${destinationFolderId}`, waitUntil: 'load' });
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
|
||||||
|
const expectedLinkName = `Link to ${sourceFile}.url`;
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(expectedLinkName)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19625] Should create a link for a folder and verify it in the destination', async ({ personalFiles }) => {
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFolder);
|
||||||
|
await createLinkInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
|
||||||
|
|
||||||
|
const msg = await personalFiles.snackBar.getSnackBarMessage();
|
||||||
|
expect(msg).toContain('Link created for 1 item');
|
||||||
|
|
||||||
|
await personalFiles.navigate({ remoteUrl: `./#/personal-files/${destinationFolderId}`, waitUntil: 'load' });
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
|
||||||
|
const expectedLinkName = `Link to ${sourceFolder}.url`;
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(expectedLinkName)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19626] Should create links for multiple files and folders simultaneously', async ({ personalFiles }) => {
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFolder);
|
||||||
|
await createLinkInPersonalFiles(personalFiles, [sourceFile, sourceFolder], destinationFolder);
|
||||||
|
|
||||||
|
const msg = await personalFiles.snackBar.getSnackBarMessage();
|
||||||
|
expect(msg).toContain('Links created for 2 items');
|
||||||
|
|
||||||
|
await personalFiles.navigate({ remoteUrl: `./#/personal-files/${destinationFolderId}`, waitUntil: 'load' });
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(`Link to ${sourceFile}.url`)).toBe(true);
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(`Link to ${sourceFolder}.url`)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19627] Should not allow creating a duplicate link in the same destination', async ({ personalFiles }) => {
|
||||||
|
await nodesApi.createFileLink(sourceFileId, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFile);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.selectItems(sourceFile);
|
||||||
|
await personalFiles.clickMoreActionsButton('Create Link');
|
||||||
|
await personalFiles.contentNodeSelector.selectDestination(destinationFolder);
|
||||||
|
await personalFiles.contentNodeSelector.actionButton.click();
|
||||||
|
|
||||||
|
const msg = await personalFiles.snackBar.getSnackBarMessage();
|
||||||
|
expect(msg).toContain("Can't create a link, a link with the same name already exists in this location.");
|
||||||
|
});
|
||||||
|
|
||||||
|
const createLinkInPersonalFiles = async (personalFilesPage: PersonalFilesPage, itemNames: string[], destinationName: string): Promise<void> => {
|
||||||
|
await personalFilesPage.dataTable.selectItems(...itemNames);
|
||||||
|
await personalFilesPage.clickMoreActionsButton('Create Link');
|
||||||
|
await personalFilesPage.contentNodeSelector.selectDestination(destinationName);
|
||||||
|
await personalFilesPage.contentNodeSelector.actionButton.click();
|
||||||
|
await personalFilesPage.spinnerWaitForReload();
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -0,0 +1,287 @@
|
|||||||
|
/*!
|
||||||
|
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Alfresco Example Content Application
|
||||||
|
*
|
||||||
|
* This file is part of the Alfresco Example Content Application.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ApiClientFactory, NodesApi, TrashcanApi, Utils, test, LoginPage, PersonalFilesPage } from '@alfresco/aca-playwright-shared';
|
||||||
|
import { expect } from '@playwright/test';
|
||||||
|
|
||||||
|
test.describe('Create Link - actions on linked items', () => {
|
||||||
|
let nodesApi: NodesApi;
|
||||||
|
let trashcanApi: TrashcanApi;
|
||||||
|
const username = `user-${Utils.random()}`;
|
||||||
|
|
||||||
|
let sourceFile: string;
|
||||||
|
let sourceFolder: string;
|
||||||
|
let destinationFolder: string;
|
||||||
|
let copyDestinationFolder: string;
|
||||||
|
let moveDestinationFolder: string;
|
||||||
|
|
||||||
|
let sourceFileId: string;
|
||||||
|
let sourceFolderId: string;
|
||||||
|
let destinationFolderId: string;
|
||||||
|
let copyDestinationFolderId: string;
|
||||||
|
let moveDestinationFolderId: string;
|
||||||
|
|
||||||
|
let fileLinkName: string;
|
||||||
|
let folderLinkName: string;
|
||||||
|
|
||||||
|
test.beforeAll(async () => {
|
||||||
|
try {
|
||||||
|
const apiClientFactory = new ApiClientFactory();
|
||||||
|
await apiClientFactory.setUpAcaBackend('admin');
|
||||||
|
await apiClientFactory.createUser({ username });
|
||||||
|
nodesApi = await NodesApi.initialize(username, username);
|
||||||
|
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`beforeAll failed: ${error}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test.beforeEach(async ({ personalFiles, page }) => {
|
||||||
|
sourceFile = `source-file-${Utils.random()}.txt`;
|
||||||
|
sourceFolder = `source-folder-${Utils.random()}`;
|
||||||
|
destinationFolder = `destination-folder-${Utils.random()}`;
|
||||||
|
copyDestinationFolder = `copy-dest-${Utils.random()}`;
|
||||||
|
moveDestinationFolder = `move-dest-${Utils.random()}`;
|
||||||
|
|
||||||
|
const loginPage = new LoginPage(page);
|
||||||
|
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||||
|
|
||||||
|
sourceFileId = (await nodesApi.createFile(sourceFile)).entry.id;
|
||||||
|
sourceFolderId = (await nodesApi.createFolder(sourceFolder)).entry.id;
|
||||||
|
destinationFolderId = (await nodesApi.createFolder(destinationFolder)).entry.id;
|
||||||
|
copyDestinationFolderId = (await nodesApi.createFolder(copyDestinationFolder)).entry.id;
|
||||||
|
moveDestinationFolderId = (await nodesApi.createFolder(moveDestinationFolder)).entry.id;
|
||||||
|
|
||||||
|
const fileLinkEntry = await nodesApi.createFileLink(sourceFileId, destinationFolderId);
|
||||||
|
const folderLinkEntry = await nodesApi.createFolderLink(sourceFolderId, destinationFolderId);
|
||||||
|
|
||||||
|
fileLinkName = fileLinkEntry.entry.name;
|
||||||
|
folderLinkName = folderLinkEntry.entry.name;
|
||||||
|
|
||||||
|
await personalFiles.navigate();
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, destinationFolder);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.afterAll(async () => {
|
||||||
|
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19628] Should copy a linked file to another location and verify the link still exists', async ({ personalFiles }) => {
|
||||||
|
await navigateToFolderById(personalFiles, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, fileLinkName);
|
||||||
|
|
||||||
|
await copyItemInPage(personalFiles, fileLinkName, copyDestinationFolder);
|
||||||
|
|
||||||
|
const msg = await personalFiles.snackBar.getSnackBarMessage();
|
||||||
|
expect(msg).toContain('Copied 1 item');
|
||||||
|
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(fileLinkName)).toBe(true);
|
||||||
|
|
||||||
|
await navigateToFolderById(personalFiles, copyDestinationFolderId);
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(fileLinkName)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19629] Should copy a linked folder to another location and verify the link still exists', async ({ personalFiles }) => {
|
||||||
|
await navigateToFolderById(personalFiles, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, folderLinkName);
|
||||||
|
|
||||||
|
await copyItemInPage(personalFiles, folderLinkName, copyDestinationFolder);
|
||||||
|
|
||||||
|
const msg = await personalFiles.snackBar.getSnackBarMessage();
|
||||||
|
expect(msg).toContain('Copied 1 item');
|
||||||
|
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(folderLinkName)).toBe(true);
|
||||||
|
|
||||||
|
await navigateToFolderById(personalFiles, copyDestinationFolderId);
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(folderLinkName)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19630] Should move a linked file to another location and verify the link is accessible', async ({ personalFiles }) => {
|
||||||
|
await navigateToFolderById(personalFiles, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, fileLinkName);
|
||||||
|
|
||||||
|
await moveItemInPage(personalFiles, fileLinkName, moveDestinationFolder);
|
||||||
|
|
||||||
|
const msg = await personalFiles.snackBar.getSnackBarMessage();
|
||||||
|
expect(msg).toContain('Moved 1 item.');
|
||||||
|
await personalFiles.snackBar.closeIcon.click();
|
||||||
|
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(fileLinkName)).toBe(false);
|
||||||
|
|
||||||
|
await navigateToFolderById(personalFiles, moveDestinationFolderId);
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(fileLinkName)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19631] Should move a linked folder to another location and verify the link is accessible', async ({ personalFiles }) => {
|
||||||
|
await navigateToFolderById(personalFiles, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, folderLinkName);
|
||||||
|
|
||||||
|
await moveItemInPage(personalFiles, folderLinkName, moveDestinationFolder);
|
||||||
|
|
||||||
|
const msg = await personalFiles.snackBar.getSnackBarMessage();
|
||||||
|
expect(msg).toContain('Moved 1 item.');
|
||||||
|
await personalFiles.snackBar.closeIcon.click();
|
||||||
|
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(folderLinkName)).toBe(false);
|
||||||
|
|
||||||
|
await navigateToFolderById(personalFiles, moveDestinationFolderId);
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(folderLinkName)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19632] Should permanently delete a linked file without showing Undo or placing it in Trash', async ({ personalFiles, trashPage }) => {
|
||||||
|
await navigateToFolderById(personalFiles, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, fileLinkName);
|
||||||
|
|
||||||
|
const deleteAction = await personalFiles.dataTable.getActionLocatorFromExpandableMenu(fileLinkName, 'Delete');
|
||||||
|
await deleteAction.click();
|
||||||
|
await personalFiles.confirmDialog.okButton.click();
|
||||||
|
|
||||||
|
const msg = await personalFiles.snackBar.getSnackBarMessage();
|
||||||
|
expect(msg).toContain('deleted');
|
||||||
|
|
||||||
|
expect(await personalFiles.snackBar.actionButton.isVisible()).toBe(false);
|
||||||
|
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(fileLinkName)).toBe(false);
|
||||||
|
|
||||||
|
await trashPage.navigate();
|
||||||
|
await trashPage.spinnerWaitForReload();
|
||||||
|
expect(await trashPage.dataTable.isItemPresent(fileLinkName)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19633] Should permanently delete a linked folder without showing Undo or placing it in Trash', async ({ personalFiles, trashPage }) => {
|
||||||
|
await navigateToFolderById(personalFiles, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, folderLinkName);
|
||||||
|
|
||||||
|
const deleteAction = await personalFiles.dataTable.getActionLocatorFromExpandableMenu(folderLinkName, 'Delete');
|
||||||
|
await deleteAction.click();
|
||||||
|
await personalFiles.confirmDialog.okButton.click();
|
||||||
|
|
||||||
|
const msg = await personalFiles.snackBar.getSnackBarMessage();
|
||||||
|
expect(msg).toContain('deleted');
|
||||||
|
|
||||||
|
expect(await personalFiles.snackBar.actionButton.isVisible()).toBe(false);
|
||||||
|
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(folderLinkName)).toBe(false);
|
||||||
|
|
||||||
|
await trashPage.navigate();
|
||||||
|
await trashPage.spinnerWaitForReload();
|
||||||
|
expect(await trashPage.dataTable.isItemPresent(folderLinkName)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19634] Should display N/A for size in the info drawer of a linked file', async ({ personalFiles }) => {
|
||||||
|
await navigateToFolderById(personalFiles, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, fileLinkName);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.selectItems(fileLinkName);
|
||||||
|
await personalFiles.acaHeader.clickMoreActions();
|
||||||
|
await personalFiles.matMenu.clickMenuItem('Information');
|
||||||
|
|
||||||
|
await expect(personalFiles.folderInformationDialog.folderSize).toBeVisible();
|
||||||
|
const sizeText = await personalFiles.folderInformationDialog.folderSize.textContent();
|
||||||
|
expect(sizeText?.trim()).toBe('N/A');
|
||||||
|
|
||||||
|
await personalFiles.folderInformationDialog.doneButton.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19635] Should display N/A for size in the info drawer of a linked folder', async ({ personalFiles }) => {
|
||||||
|
await navigateToFolderById(personalFiles, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, folderLinkName);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.selectItems(folderLinkName);
|
||||||
|
await personalFiles.acaHeader.clickMoreActions();
|
||||||
|
await personalFiles.matMenu.clickMenuItem('Information');
|
||||||
|
|
||||||
|
await expect(personalFiles.folderInformationDialog.folderSize).toBeVisible();
|
||||||
|
const sizeText = await personalFiles.folderInformationDialog.folderSize.textContent();
|
||||||
|
expect(sizeText?.trim()).toBe('N/A');
|
||||||
|
|
||||||
|
await personalFiles.folderInformationDialog.doneButton.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19636] Should locate the original file when using Locate Linked Item on a file link', async ({ personalFiles }) => {
|
||||||
|
await navigateToFolderById(personalFiles, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, fileLinkName);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.performActionFromExpandableMenu(fileLinkName, 'Locate Linked Item');
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
|
||||||
|
await personalFiles.page.waitForURL('**/#/personal-files**');
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19637] Should locate the original folder when using Locate Linked Item on a folder link', async ({ personalFiles }) => {
|
||||||
|
await navigateToFolderById(personalFiles, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, folderLinkName);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.performActionFromExpandableMenu(folderLinkName, 'Locate Linked Item');
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
|
||||||
|
await personalFiles.page.waitForURL('**/#/personal-files**');
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19638] Should navigate to original file location when opening a file link', async ({ personalFiles }) => {
|
||||||
|
await navigateToFolderById(personalFiles, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, fileLinkName);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.performClickFolderOrFileToOpen(fileLinkName);
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
|
||||||
|
await personalFiles.page.waitForURL('**/#/personal-files**');
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19639] Should navigate inside the original folder when opening a folder link', async ({ personalFiles }) => {
|
||||||
|
await navigateToFolderById(personalFiles, destinationFolderId);
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, folderLinkName);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.performClickFolderOrFileToOpen(folderLinkName);
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
|
||||||
|
await personalFiles.page.waitForURL(`**/${sourceFolderId}**`);
|
||||||
|
await expect(personalFiles.breadcrumb.currentItem).toHaveText(sourceFolder);
|
||||||
|
});
|
||||||
|
|
||||||
|
const navigateToFolderById = async (page: PersonalFilesPage, nodeId: string): Promise<void> => {
|
||||||
|
await page.navigate({ remoteUrl: `./#/personal-files/${nodeId}`, waitUntil: 'load' });
|
||||||
|
await page.spinnerWaitForReload();
|
||||||
|
};
|
||||||
|
|
||||||
|
const copyItemInPage = (page: PersonalFilesPage, itemName: string, destinationName: string): Promise<void> =>
|
||||||
|
performNodeAction(page, itemName, 'Copy', destinationName);
|
||||||
|
|
||||||
|
const moveItemInPage = (page: PersonalFilesPage, itemName: string, destinationName: string): Promise<void> =>
|
||||||
|
performNodeAction(page, itemName, 'Move', destinationName);
|
||||||
|
|
||||||
|
const performNodeAction = async (page: PersonalFilesPage, itemName: string, action: 'Copy' | 'Move', destinationName: string): Promise<void> => {
|
||||||
|
await page.dataTable.selectItems(itemName);
|
||||||
|
await page.clickMoreActionsButton(action);
|
||||||
|
await page.contentNodeSelector.searchAndSelectDestination(destinationName);
|
||||||
|
await page.contentNodeSelector.actionButton.click();
|
||||||
|
await page.spinnerWaitForReload();
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -0,0 +1,281 @@
|
|||||||
|
/*!
|
||||||
|
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Alfresco Example Content Application
|
||||||
|
*
|
||||||
|
* This file is part of the Alfresco Example Content Application.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ApiClientFactory, NodesApi, SitesApi, TrashcanApi, Utils, test, LoginPage, PersonalFilesPage } from '@alfresco/aca-playwright-shared';
|
||||||
|
import { Site } from '@alfresco/js-api';
|
||||||
|
import { expect } from '@playwright/test';
|
||||||
|
|
||||||
|
test.describe('Create Link - comments and permissions', () => {
|
||||||
|
let ownerNodesApi: NodesApi;
|
||||||
|
let consumerNodesApi: NodesApi;
|
||||||
|
let ownerTrashcanApi: TrashcanApi;
|
||||||
|
let consumerTrashcanApi: TrashcanApi;
|
||||||
|
let sitesApi: SitesApi;
|
||||||
|
|
||||||
|
const random = Utils.random();
|
||||||
|
const ownerUsername = `owner-${random}`;
|
||||||
|
const consumerUsername = `consumer-${random}`;
|
||||||
|
|
||||||
|
let siteId: string;
|
||||||
|
let siteTitle: string;
|
||||||
|
let docLibId: string;
|
||||||
|
let sourceFile: string;
|
||||||
|
let sourceFolder: string;
|
||||||
|
let destinationFolder: string;
|
||||||
|
|
||||||
|
let sourceFileId: string;
|
||||||
|
let destinationFolderId: string;
|
||||||
|
|
||||||
|
let fileLinkName: string;
|
||||||
|
let folderLinkName: string;
|
||||||
|
|
||||||
|
test.beforeAll(async () => {
|
||||||
|
try {
|
||||||
|
const apiClientFactory = new ApiClientFactory();
|
||||||
|
await apiClientFactory.setUpAcaBackend('admin');
|
||||||
|
await apiClientFactory.createUser({ username: ownerUsername });
|
||||||
|
await apiClientFactory.createUser({ username: consumerUsername });
|
||||||
|
|
||||||
|
ownerNodesApi = await NodesApi.initialize(ownerUsername, ownerUsername);
|
||||||
|
consumerNodesApi = await NodesApi.initialize(consumerUsername, consumerUsername);
|
||||||
|
ownerTrashcanApi = await TrashcanApi.initialize(ownerUsername, ownerUsername);
|
||||||
|
consumerTrashcanApi = await TrashcanApi.initialize(consumerUsername, consumerUsername);
|
||||||
|
sitesApi = await SitesApi.initialize(ownerUsername, ownerUsername);
|
||||||
|
|
||||||
|
const site = await sitesApi.createSite(`link-perm-site-${random}`, Site.VisibilityEnum.PRIVATE);
|
||||||
|
siteId = site.entry.id;
|
||||||
|
siteTitle = site.entry.title;
|
||||||
|
docLibId = await sitesApi.getDocLibId(siteId);
|
||||||
|
await sitesApi.addSiteMember(siteId, consumerUsername, 'SiteConsumer');
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`beforeAll failed: ${error}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test.beforeEach(async ({ personalFiles, page }) => {
|
||||||
|
try {
|
||||||
|
sourceFile = `source-file-${Utils.random()}.txt`;
|
||||||
|
sourceFolder = `source-folder-${Utils.random()}`;
|
||||||
|
destinationFolder = `destination-folder-${Utils.random()}`;
|
||||||
|
|
||||||
|
const loginPage = new LoginPage(page);
|
||||||
|
await Utils.tryLoginUser(loginPage, ownerUsername, ownerUsername, 'beforeEach failed');
|
||||||
|
|
||||||
|
sourceFileId = (await ownerNodesApi.createFile(sourceFile)).entry.id;
|
||||||
|
const sourceFolderEntry = await ownerNodesApi.createFolder(sourceFolder);
|
||||||
|
destinationFolderId = (await ownerNodesApi.createFolder(destinationFolder)).entry.id;
|
||||||
|
|
||||||
|
const fileLinkEntry = await ownerNodesApi.createFileLink(sourceFileId, destinationFolderId);
|
||||||
|
const folderLinkEntry = await ownerNodesApi.createFolderLink(sourceFolderEntry.entry.id, destinationFolderId);
|
||||||
|
|
||||||
|
fileLinkName = fileLinkEntry.entry.name;
|
||||||
|
folderLinkName = folderLinkEntry.entry.name;
|
||||||
|
|
||||||
|
await personalFiles.navigate();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`beforeEach failed: ${error}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test.afterAll(async () => {
|
||||||
|
let primaryError: unknown;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Utils.deleteNodesSitesEmptyTrashcan(consumerNodesApi, consumerTrashcanApi, 'afterAll failed (consumer cleanup)');
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`afterAll failed (consumer cleanup): ${error}`);
|
||||||
|
primaryError = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Utils.deleteNodesSitesEmptyTrashcan(ownerNodesApi, ownerTrashcanApi, 'afterAll failed', sitesApi, [siteId]);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`afterAll failed: ${error}`);
|
||||||
|
primaryError ??= error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (primaryError) {
|
||||||
|
throw primaryError;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19640] Should show a comment added on a linked file in the original file info drawer', async ({ personalFiles }) => {
|
||||||
|
const commentText = `comment-${Utils.random()}`;
|
||||||
|
|
||||||
|
await personalFiles.navigate({ remoteUrl: `./#/personal-files/${destinationFolderId}`, waitUntil: 'load' });
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, fileLinkName);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.getRowByName(fileLinkName).click();
|
||||||
|
await personalFiles.acaHeader.viewDetails.click();
|
||||||
|
await personalFiles.infoDrawer.commentsTab.click();
|
||||||
|
await expect(personalFiles.infoDrawer.commentInputField).toBeVisible();
|
||||||
|
await personalFiles.infoDrawer.addCommentToNode(commentText);
|
||||||
|
|
||||||
|
await personalFiles.infoDrawer.waitForComments();
|
||||||
|
|
||||||
|
await personalFiles.navigate({ remoteUrl: `./#/personal-files`, waitUntil: 'load' });
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFile);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.getRowByName(sourceFile).click();
|
||||||
|
await personalFiles.acaHeader.viewDetails.click();
|
||||||
|
await personalFiles.infoDrawer.commentsTab.click();
|
||||||
|
await personalFiles.infoDrawer.waitForComments();
|
||||||
|
|
||||||
|
const commentsCount = await personalFiles.infoDrawer.getCommentsCountFromList();
|
||||||
|
expect(commentsCount).toBeGreaterThanOrEqual(1);
|
||||||
|
|
||||||
|
const commentContent = await personalFiles.infoDrawer.commentTextContent.first().innerText();
|
||||||
|
expect(commentContent).toContain(commentText);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19641] Should show a comment added on a linked folder in the original folder info drawer', async ({ personalFiles }) => {
|
||||||
|
const commentText = `comment-${Utils.random()}`;
|
||||||
|
|
||||||
|
await personalFiles.navigate({ remoteUrl: `./#/personal-files/${destinationFolderId}`, waitUntil: 'load' });
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, folderLinkName);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.getRowByName(folderLinkName).click();
|
||||||
|
await personalFiles.acaHeader.viewDetails.click();
|
||||||
|
await personalFiles.infoDrawer.commentsTab.click();
|
||||||
|
await expect(personalFiles.infoDrawer.commentInputField).toBeVisible();
|
||||||
|
await personalFiles.infoDrawer.addCommentToNode(commentText);
|
||||||
|
|
||||||
|
await personalFiles.infoDrawer.waitForComments();
|
||||||
|
|
||||||
|
await personalFiles.navigate({ remoteUrl: `./#/personal-files`, waitUntil: 'load' });
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFolder);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.getRowByName(sourceFolder).click();
|
||||||
|
await personalFiles.acaHeader.viewDetails.click();
|
||||||
|
await personalFiles.infoDrawer.commentsTab.click();
|
||||||
|
await personalFiles.infoDrawer.waitForComments();
|
||||||
|
|
||||||
|
const commentsCount = await personalFiles.infoDrawer.getCommentsCountFromList();
|
||||||
|
expect(commentsCount).toBeGreaterThanOrEqual(1);
|
||||||
|
|
||||||
|
const commentContent = await personalFiles.infoDrawer.commentTextContent.first().innerText();
|
||||||
|
expect(commentContent).toContain(commentText);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19642] Should show Create Link action for manager and successfully create a link from a site document library', async ({
|
||||||
|
personalFiles
|
||||||
|
}) => {
|
||||||
|
const siteFile = `site-file-${Utils.random()}.txt`;
|
||||||
|
const managerDestFolder = `manager-dest-${Utils.random()}`;
|
||||||
|
|
||||||
|
await ownerNodesApi.createFile(siteFile, docLibId);
|
||||||
|
const managerDestFolderEntry = await ownerNodesApi.createFolder(managerDestFolder);
|
||||||
|
const managerDestFolderId = managerDestFolderEntry.entry.id;
|
||||||
|
|
||||||
|
await personalFiles.navigate({ remoteUrl: `./#/libraries/${docLibId}`, waitUntil: 'load' });
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, siteFile);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.rightClickOnItem(siteFile);
|
||||||
|
const createLinkButton = personalFiles.dataTable.contextMenuActions.getButtonByText('Create Link');
|
||||||
|
await expect(createLinkButton).toBeVisible();
|
||||||
|
await createLinkButton.click();
|
||||||
|
|
||||||
|
await personalFiles.contentNodeSelector.searchAndSelectDestination(managerDestFolder);
|
||||||
|
await personalFiles.contentNodeSelector.actionButton.click();
|
||||||
|
|
||||||
|
const msg = await personalFiles.snackBar.getSnackBarMessage();
|
||||||
|
expect(msg).toContain('Link created for 1 item');
|
||||||
|
|
||||||
|
await personalFiles.navigate({ remoteUrl: `./#/personal-files/${managerDestFolderId}`, waitUntil: 'load' });
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
|
||||||
|
const expectedLinkName = `Link to ${siteFile}.url`;
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(expectedLinkName)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19643] Should allow a consumer to create a link to a site file in their own personal files', async ({ personalFiles, page }) => {
|
||||||
|
const siteFile = `site-file-consumer-${Utils.random()}.txt`;
|
||||||
|
const consumerDestFolder = `consumer-dest-${Utils.random()}`;
|
||||||
|
|
||||||
|
await ownerNodesApi.createFile(siteFile, docLibId);
|
||||||
|
const consumerDestFolderEntry = await consumerNodesApi.createFolder(consumerDestFolder);
|
||||||
|
const consumerDestFolderId = consumerDestFolderEntry.entry.id;
|
||||||
|
|
||||||
|
const loginPage = new LoginPage(page);
|
||||||
|
await loginPage.logoutUser();
|
||||||
|
await loginPage.loginUser({ username: consumerUsername, password: consumerUsername }, { withNavigation: true, waitForLoading: true });
|
||||||
|
|
||||||
|
await personalFiles.navigate({ remoteUrl: `./#/libraries/${docLibId}`, waitUntil: 'load' });
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
await Utils.reloadPageIfRowNotVisible(personalFiles, siteFile);
|
||||||
|
|
||||||
|
await personalFiles.dataTable.rightClickOnItem(siteFile);
|
||||||
|
const createLinkButton = personalFiles.dataTable.contextMenuActions.getButtonByText('Create Link');
|
||||||
|
await expect(createLinkButton).toBeVisible();
|
||||||
|
await createLinkButton.click();
|
||||||
|
|
||||||
|
await personalFiles.contentNodeSelector.searchAndSelectDestination(consumerDestFolder);
|
||||||
|
await personalFiles.contentNodeSelector.actionButton.click();
|
||||||
|
|
||||||
|
const msg = await personalFiles.snackBar.getSnackBarMessage();
|
||||||
|
expect(msg).toContain('Link created for 1 item');
|
||||||
|
|
||||||
|
await personalFiles.navigate({ remoteUrl: `./#/personal-files/${consumerDestFolderId}`, waitUntil: 'load' });
|
||||||
|
await personalFiles.spinnerWaitForReload();
|
||||||
|
|
||||||
|
const expectedLinkName = `Link to ${siteFile}.url`;
|
||||||
|
expect(await personalFiles.dataTable.isItemPresent(expectedLinkName)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[XAT-19644] Should disable the Choose button in the node selector when consumer selects a read-only library folder', async ({ page }) => {
|
||||||
|
const siteFile = `site-file-ro-${Utils.random()}.txt`;
|
||||||
|
await ownerNodesApi.createFile(siteFile, docLibId);
|
||||||
|
|
||||||
|
const loginPage = new LoginPage(page);
|
||||||
|
await loginPage.logoutUser();
|
||||||
|
await loginPage.loginUser({ username: consumerUsername, password: consumerUsername }, { withNavigation: true, waitForLoading: true });
|
||||||
|
|
||||||
|
const consumerPage = new PersonalFilesPage(page);
|
||||||
|
|
||||||
|
await consumerPage.navigate({ remoteUrl: `./#/libraries/${docLibId}`, waitUntil: 'load' });
|
||||||
|
await consumerPage.spinnerWaitForReload();
|
||||||
|
await Utils.reloadPageIfRowNotVisible(consumerPage, siteFile);
|
||||||
|
|
||||||
|
await consumerPage.dataTable.selectItems(siteFile);
|
||||||
|
await consumerPage.acaHeader.clickMoreActions();
|
||||||
|
const createLinkMenuItem = consumerPage.matMenu.getButtonByText('Create Link');
|
||||||
|
await expect(createLinkMenuItem).toBeVisible();
|
||||||
|
await createLinkMenuItem.click();
|
||||||
|
|
||||||
|
await consumerPage.contentNodeSelector.selectLocation('My Libraries');
|
||||||
|
await consumerPage.contentNodeSelector.spinnerWaitForReload();
|
||||||
|
|
||||||
|
await consumerPage.contentNodeSelector.selectDestination(siteTitle);
|
||||||
|
expect(await consumerPage.contentNodeSelector.actionButton.isDisabled()).toBe(true);
|
||||||
|
|
||||||
|
await consumerPage.contentNodeSelector.cancelButton.click();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -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/aca-playwright-shared": ["dist/@alfresco/aca-playwright-shared"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
@@ -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/aca-playwright-shared": ["dist/@alfresco/aca-playwright-shared"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user