mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2026-09-09 18:02:54 +00:00
[ACS-12075] more multibrowser stabilization pt 3 (#5256)
* [ACS-12075] more multibrowser stabilization pt 3 * [ACS-12075] copilot review fixes 1 * [ACS-12075] deploy local acs newest version test * [ACS-12075] deploy local acs newest version test 2 * [ACS-12075] deploy local acs newest version test 3 * [ACS-12075] Big batch of tests improvements * [ACS=12075] last batch of changes * [ACS-12075] viewer test download fixes * [ACS-12075] updated download funtionality in ACA with proper download name * [ACS-12075] reverted deploy local acs changes * [ACS-12075] updated playwright * [ACS-12075] deleted changes related to frontend + review fixes 4 * [ACS-12075] updated npm and node
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { ActionType, ApiClientFactory, test, Utils, TrashcanApi, NodesApi, Comparator, Field } from '@alfresco/aca-playwright-shared';
|
||||
|
||||
test.use({ launchOptions: { slowMo: 300 } });
|
||||
test.use({ launchOptions: { slowMo: 500 } });
|
||||
|
||||
test.describe('Folder Rules Actions', () => {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
@@ -82,29 +82,10 @@ test.describe('Folder Rules Actions', () => {
|
||||
nodesApi = await NodesApi.initialize(username, username);
|
||||
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||
} catch (error) {
|
||||
console.error(`beforeAll failed : ${error}`);
|
||||
throw error;
|
||||
const errorMessage = `beforeAll failed : ${JSON.stringify(error)}`;
|
||||
console.error(errorMessage);
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
folder883Id = (await nodesApi.createFolder(folder883)).entry.id;
|
||||
folder884Id = (await nodesApi.createFolder(folder884)).entry.id;
|
||||
folder884SecondId = (await nodesApi.createFolder(folder884Second)).entry.id;
|
||||
folder885Id = (await nodesApi.createFolder(folder885)).entry.id;
|
||||
folder885ChildId = (await nodesApi.createFolder(folder885Child, folder885Id)).entry.id;
|
||||
folder886Id = (await nodesApi.createFolder(folder886)).entry.id;
|
||||
folder887Id = (await nodesApi.createFolder(folder887)).entry.id;
|
||||
folder888Id = (await nodesApi.createFolder(folder888)).entry.id;
|
||||
folder889Id = (await nodesApi.createFolder(folder889)).entry.id;
|
||||
folder889SecondId = (await nodesApi.createFolder(folder889Second)).entry.id;
|
||||
folder890Id = (await nodesApi.createFolder(folder890)).entry.id;
|
||||
folder891Id = (await nodesApi.createFolder(folder891)).entry.id;
|
||||
folder892Id = (await nodesApi.createFolder(folder892)).entry.id;
|
||||
folder893Id = (await nodesApi.createFolder(folder893)).entry.id;
|
||||
folder894Id = (await nodesApi.createFolder(folder894)).entry.id;
|
||||
folder895Id = (await nodesApi.createFolder(folder895)).entry.id;
|
||||
folder896Id = (await nodesApi.createFolder(folder896)).entry.id;
|
||||
folder910Id = (await nodesApi.createFolder(folder910)).entry.id;
|
||||
await nodesApi.createFile(copyFileName, folder889Id);
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
@@ -116,219 +97,309 @@ test.describe('Folder Rules Actions', () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
|
||||
});
|
||||
|
||||
test('[XAT-883] Create a rule with symbols in its name and description', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder883Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(testString);
|
||||
await nodesPage.manageRulesDialog.ruleDescriptionInputLocator.fill(testString);
|
||||
test.describe('[XAT-883] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder883Id = (await nodesApi.createFolder(folder883)).entry.id;
|
||||
});
|
||||
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.IncrementCounter, 0);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
test('[XAT-883] Create a rule with symbols in its name and description', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder883Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(testString);
|
||||
await nodesPage.manageRulesDialog.ruleDescriptionInputLocator.fill(testString);
|
||||
|
||||
await expect(nodesPage.manageRules.getGroupsList(testString)).toBeVisible();
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.IncrementCounter]);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
|
||||
await expect(nodesPage.manageRules.getGroupsList(testString)).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-884] Create a rule and link it to an existing folder', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder884Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.IncrementCounter, 0);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
test.describe('[XAT-884] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder884Id = (await nodesApi.createFolder(folder884)).entry.id;
|
||||
folder884SecondId = (await nodesApi.createFolder(folder884Second)).entry.id;
|
||||
});
|
||||
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder884SecondId}/rules` });
|
||||
await nodesPage.rulesToolbar.clickLinkRulesButton();
|
||||
await nodesPage.linkRulesDialog.waitForLinkRules();
|
||||
await nodesPage.linkRulesDialog.getFolderIcon.click();
|
||||
await nodesPage.linkRulesDialog.getOptionLocator(username).click();
|
||||
await nodesPage.linkRulesDialog.selectDestination(folder884);
|
||||
await nodesPage.linkRulesDialog.selectFolderButton.click();
|
||||
test('[XAT-884] Create a rule and link it to an existing folder', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder884Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.IncrementCounter]);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
|
||||
await nodesPage.manageRules.checkIfRuleIsOnTheList(randomRuleName);
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder884SecondId}/rules` });
|
||||
await nodesPage.rulesToolbar.clickLinkRulesButton();
|
||||
await nodesPage.linkRulesDialog.waitForLinkRules();
|
||||
await nodesPage.linkRulesDialog.getFolderIcon.click();
|
||||
await nodesPage.linkRulesDialog.getOptionLocator(username).click();
|
||||
await nodesPage.linkRulesDialog.selectDestination(folder884);
|
||||
await nodesPage.linkRulesDialog.selectFolderButton.click();
|
||||
|
||||
await nodesPage.manageRules.checkIfRuleIsOnTheList(randomRuleName);
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-885] Create a rule in a folder and inherit it in a subfolder (Rule applies to subfolders)', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder885Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.IncrementCounter, 0);
|
||||
await nodesPage.manageRulesDialog.ruleSubfoldersCheckbox.click();
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
test.describe('[XAT-885] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder885Id = (await nodesApi.createFolder(folder885)).entry.id;
|
||||
folder885ChildId = (await nodesApi.createFolder(folder885Child, folder885Id)).entry.id;
|
||||
});
|
||||
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder885ChildId}/rules` });
|
||||
await nodesPage.manageRules.checkIfRuleIsOnTheList(randomRuleName);
|
||||
test('[XAT-885] Create a rule in a folder and inherit it in a subfolder (Rule applies to subfolders)', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder885Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.IncrementCounter]);
|
||||
await nodesPage.manageRulesDialog.ruleSubfoldersCheckbox.click();
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder885ChildId}/rules` });
|
||||
await nodesPage.manageRules.checkIfRuleIsOnTheList(randomRuleName);
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-886] Create a rule and press cancel', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder886Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeDisabled();
|
||||
await nodesPage.manageRulesDialog.cancelRuleButton.click();
|
||||
expect(await nodesPage.manageRules.checkIfRuleListEmpty()).toBe(true);
|
||||
test.describe('[XAT-886] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder886Id = (await nodesApi.createFolder(folder886)).entry.id;
|
||||
});
|
||||
|
||||
test('[XAT-886] Create a rule and press cancel', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder886Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeDisabled();
|
||||
await nodesPage.manageRulesDialog.cancelRuleButton.click();
|
||||
expect(await nodesPage.manageRules.checkIfRuleListEmpty()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-887] Create a disabled rule', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder887Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.IncrementCounter, 0);
|
||||
await nodesPage.manageRulesDialog.ruleDisableCheckbox.click();
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
await expect(nodesPage.manageRules.ruleToggleFalse).toBeVisible();
|
||||
test.describe('[XAT-887] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder887Id = (await nodesApi.createFolder(folder887)).entry.id;
|
||||
});
|
||||
|
||||
test('[XAT-887] Create a disabled rule', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder887Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.IncrementCounter]);
|
||||
await nodesPage.manageRulesDialog.ruleDisableCheckbox.click();
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
await expect(nodesPage.manageRules.ruleToggleFalse).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-888] Create a rule with multiple actions', async ({ personalFiles, nodesPage }) => {
|
||||
const checkInValue = 'check In Value';
|
||||
const actionValue = 'Site Container [st:siteContainer]';
|
||||
const specialiseTypeValue = 'Action Base Type [act:actionbase]';
|
||||
const simpleWorkFlow = 'accept reject';
|
||||
test.describe('[XAT-888] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder888Id = (await nodesApi.createFolder(folder888)).entry.id;
|
||||
});
|
||||
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder888Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
test('[XAT-888] Create a rule with multiple actions', async ({ personalFiles, nodesPage }) => {
|
||||
const checkInValue = 'check In Value';
|
||||
const actionValue = 'Site Container [st:siteContainer]';
|
||||
const specialiseTypeValue = 'Action Base Type [act:actionbase]';
|
||||
const simpleWorkFlow = 'accept reject';
|
||||
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.IncrementCounter, 0);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.CheckIn, 1);
|
||||
await nodesPage.actionsDropdown.insertCheckInActionValues(checkInValue, 1);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 2);
|
||||
await nodesPage.actionsDropdown.insertAddAspectActionValues(actionValue, 2);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.SpecialiseType, 3);
|
||||
await nodesPage.actionsDropdown.insertSpecialiseTypeActionValues(specialiseTypeValue, 3);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.SimpleWorkflow, 4);
|
||||
await nodesPage.actionsDropdown.insertSimpleWorkflowActionValues(simpleWorkFlow, 4);
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder888Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
await nodesPage.actionsDropdown.selectActions([
|
||||
ActionType.IncrementCounter,
|
||||
{ type: ActionType.CheckIn, value: checkInValue },
|
||||
{ type: ActionType.AddAspect, value: actionValue },
|
||||
{ type: ActionType.SpecialiseType, value: specialiseTypeValue },
|
||||
{ type: ActionType.SimpleWorkflow, value: simpleWorkFlow }
|
||||
]);
|
||||
|
||||
await nodesPage.manageRules.checkIfRuleIsOnTheList(randomRuleName);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
|
||||
await nodesPage.manageRules.checkIfRuleIsOnTheList(randomRuleName);
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-889] Create a rule which runs when items are deleted or leave a folder', async ({ nodesPage, personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder889Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.manageRulesDialog.whenCreatedCheckbox.click();
|
||||
await nodesPage.manageRulesDialog.whenDeletedCheckbox.click();
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.Copy, 0);
|
||||
await nodesPage.manageRulesDialog.destinationFolderButton.click();
|
||||
await nodesPage.contentNodeSelectorDialog.getFolderIcon.click();
|
||||
await nodesPage.contentNodeSelectorDialog.getOptionLocator(username).click();
|
||||
await nodesPage.contentNodeSelectorDialog.selectDestination(folder889Second);
|
||||
await nodesPage.contentNodeSelectorDialog.actionButton.click();
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
await nodesPage.manageRules.checkIfRuleIsOnTheList(randomRuleName);
|
||||
test.describe('[XAT-889] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder889Id = (await nodesApi.createFolder(folder889)).entry.id;
|
||||
folder889SecondId = (await nodesApi.createFolder(folder889Second)).entry.id;
|
||||
await nodesApi.createFile(copyFileName, folder889Id);
|
||||
});
|
||||
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${folder889Id}` });
|
||||
await personalFiles.dataTable.selectItems(copyFileName);
|
||||
await personalFiles.acaHeader.clickMoreActions();
|
||||
await personalFiles.acaHeader.matMenu.clickMenuItem('Delete');
|
||||
await personalFiles.snackBar.message.waitFor({ state: 'visible' });
|
||||
test('[XAT-889] Create a rule which runs when items are deleted or leave a folder', async ({ nodesPage, personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder889Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.manageRulesDialog.whenCreatedCheckbox.click();
|
||||
await nodesPage.manageRulesDialog.whenDeletedCheckbox.click();
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.Copy]);
|
||||
await nodesPage.manageRulesDialog.destinationFolderButton.click();
|
||||
await nodesPage.contentNodeSelectorDialog.getFolderIcon.click();
|
||||
await nodesPage.contentNodeSelectorDialog.getOptionLocator(username).click();
|
||||
await nodesPage.contentNodeSelectorDialog.selectDestination(folder889Second);
|
||||
await nodesPage.contentNodeSelectorDialog.actionButton.click();
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
await nodesPage.manageRules.checkIfRuleIsOnTheList(randomRuleName);
|
||||
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${folder889SecondId}` });
|
||||
await expect(personalFiles.dataTable.getRowByName(copyFileName)).toBeVisible();
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${folder889Id}` });
|
||||
await personalFiles.dataTable.selectItems(copyFileName);
|
||||
await personalFiles.acaHeader.clickMoreActions();
|
||||
await personalFiles.acaHeader.matMenu.clickMenuItem('Delete');
|
||||
await personalFiles.snackBar.message.waitFor({ state: 'visible' });
|
||||
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${folder889SecondId}` });
|
||||
await expect(personalFiles.dataTable.getRowByName(copyFileName)).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-890] Create a rule which adds multiple aspects when its ran', async ({ nodesPage, personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder890Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 0);
|
||||
await nodesPage.actionsDropdown.insertAddAspectActionValues('Classifiable', 0);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 1);
|
||||
await nodesPage.actionsDropdown.insertAddAspectActionValues('Countable', 1);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 2);
|
||||
await nodesPage.actionsDropdown.insertAddAspectActionValues('Incomplete', 2);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 3);
|
||||
await nodesPage.actionsDropdown.insertAddAspectActionValues('Site container', 3);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
await nodesPage.manageRulesDialog.createRuleButton.waitFor({ state: 'hidden' });
|
||||
await expect(nodesPage.manageRules.getGroupsList(randomRuleName)).toBeVisible();
|
||||
test.describe('[XAT-890] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder890Id = (await nodesApi.createFolder(folder890)).entry.id;
|
||||
});
|
||||
|
||||
test('[XAT-890] Create a rule which adds multiple aspects when its ran', async ({ nodesPage, personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder890Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectActions([
|
||||
{ type: ActionType.AddAspect, value: 'Classifiable' },
|
||||
{ type: ActionType.AddAspect, value: 'Countable' },
|
||||
{ type: ActionType.AddAspect, value: 'Incomplete' },
|
||||
{ type: ActionType.AddAspect, value: 'Site container' }
|
||||
]);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
await nodesPage.manageRulesDialog.createRuleButton.waitFor({ state: 'hidden' });
|
||||
await expect(nodesPage.manageRules.getGroupsList(randomRuleName)).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-891] Prevent rule creation after clicking on cancel during selecting destination folder', async ({ nodesPage, personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder891Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 0);
|
||||
await nodesPage.actionsDropdown.insertAddAspectActionValues('Classifiable', 0);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.Copy, 1);
|
||||
await nodesPage.manageRulesDialog.destinationFolderButton.click();
|
||||
await nodesPage.contentNodeSelectorDialog.cancelButton.click();
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeDisabled();
|
||||
test.describe('[XAT-891] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder891Id = (await nodesApi.createFolder(folder891)).entry.id;
|
||||
});
|
||||
|
||||
test('[XAT-891] Prevent rule creation after clicking on cancel during selecting destination folder', async ({ nodesPage, personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder891Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectActions([{ type: ActionType.AddAspect, value: 'Classifiable' }]);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.Copy]);
|
||||
await nodesPage.manageRulesDialog.destinationFolderButton.click();
|
||||
await nodesPage.contentNodeSelectorDialog.cancelButton.click();
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-892] Prevent rule creation when missing any required field for action', async ({ nodesPage, personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder892Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 0);
|
||||
await nodesPage.actionsDropdown.insertAddAspectActionValues('Classifiable', 0);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.Copy, 1);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeDisabled();
|
||||
test.describe('[XAT-892] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder892Id = (await nodesApi.createFolder(folder892)).entry.id;
|
||||
});
|
||||
|
||||
test('[XAT-892] Prevent rule creation when missing any required field for action', async ({ nodesPage, personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder892Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectActions([{ type: ActionType.AddAspect, value: 'Classifiable' }]);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.Copy]);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-893] Removing values from required fields should restore disabled state for Create button', async ({ nodesPage, personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder893Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 0);
|
||||
await nodesPage.actionsDropdown.insertAddAspectActionValues('Classifiable', 0);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
|
||||
await nodesPage.actionsDropdown.insertAddAspectActionValues('None', 0);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeDisabled();
|
||||
test.describe('[XAT-893] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder893Id = (await nodesApi.createFolder(folder893)).entry.id;
|
||||
});
|
||||
|
||||
test('[XAT-893] Removing values from required fields should restore disabled state for Create button', async ({ nodesPage, personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder893Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectActions([{ type: ActionType.AddAspect, value: 'Classifiable' }]);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
|
||||
await nodesPage.actionsDropdown.insertAddAspectActionValues('None', 0);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-894] Create rule with filled required fields and empty optional fields', async ({ nodesPage, personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder894Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 0);
|
||||
await nodesPage.actionsDropdown.insertAddAspectActionValues('Classifiable', 0);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.CheckIn, 1);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
|
||||
test.describe('[XAT-894] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder894Id = (await nodesApi.createFolder(folder894)).entry.id;
|
||||
});
|
||||
|
||||
test('[XAT-894] Create rule with filled required fields and empty optional fields', async ({ nodesPage, personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder894Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectActions([{ type: ActionType.AddAspect, value: 'Classifiable' }]);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.CheckIn]);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-895] Create a rule with multiple conditions utilising all available comparators and conditions', async ({
|
||||
personalFiles,
|
||||
nodesPage
|
||||
}) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder895Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.conditionsDropdown.addCondition(Field.Size, specialChars, 0, Comparator.Equals);
|
||||
await nodesPage.conditionsDropdown.addCondition(Field.Name, specialChars, 1, Comparator.Equals);
|
||||
await nodesPage.conditionsDropdown.addCondition(Field.Encoding, specialChars, 2);
|
||||
await nodesPage.conditionsDropdown.addCondition(Field.HasTag, specialChars, 3);
|
||||
await nodesPage.conditionsDropdown.addCondition(Field.HasAspect, specialChars, 4);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.IncrementCounter, 0);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
test.describe('[XAT-895] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder895Id = (await nodesApi.createFolder(folder895)).entry.id;
|
||||
});
|
||||
|
||||
await nodesPage.manageRules.checkIfRuleIsOnTheList(randomRuleName);
|
||||
test('[XAT-895] Create a rule with multiple conditions utilising all available comparators and conditions', async ({
|
||||
personalFiles,
|
||||
nodesPage
|
||||
}) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder895Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.conditionsDropdown.addConditions([
|
||||
{ field: Field.Size, value: specialChars, comparator: Comparator.Equals },
|
||||
{ field: Field.Name, value: specialChars, comparator: Comparator.Equals },
|
||||
{ field: Field.Encoding, value: specialChars },
|
||||
{ field: Field.HasTag, value: specialChars },
|
||||
{ field: Field.HasAspect, value: specialChars }
|
||||
]);
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.IncrementCounter]);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
|
||||
await nodesPage.manageRules.checkIfRuleIsOnTheList(randomRuleName);
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-896] Create a rule with multiple groups utilising all available comparators and conditions', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder896Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.conditionsDropdown.addConditionGroup(Field.Size, specialChars, 0, Comparator.Equals);
|
||||
await nodesPage.conditionsDropdown.addConditionGroup(Field.Name, specialChars, 1, Comparator.Equals);
|
||||
await nodesPage.conditionsDropdown.addConditionGroup(Field.Encoding, specialChars, 2);
|
||||
await nodesPage.conditionsDropdown.addConditionGroup(Field.HasTag, specialChars, 3);
|
||||
await nodesPage.conditionsDropdown.addConditionGroup(Field.HasAspect, specialChars, 4);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.IncrementCounter, 0);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
test.describe('[XAT-896] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder896Id = (await nodesApi.createFolder(folder896)).entry.id;
|
||||
});
|
||||
|
||||
await nodesPage.manageRules.checkIfRuleIsOnTheList(randomRuleName);
|
||||
test('[XAT-896] Create a rule with multiple groups utilising all available comparators and conditions', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder896Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.conditionsDropdown.addConditionGroups([
|
||||
{ field: Field.Size, value: specialChars, comparator: Comparator.Equals },
|
||||
{ field: Field.Name, value: specialChars, comparator: Comparator.Equals },
|
||||
{ field: Field.Encoding, value: specialChars },
|
||||
{ field: Field.HasTag, value: specialChars },
|
||||
{ field: Field.HasAspect, value: specialChars }
|
||||
]);
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.IncrementCounter]);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
|
||||
await nodesPage.manageRules.checkIfRuleIsOnTheList(randomRuleName);
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-910] Create a rule and disable it', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder910Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.IncrementCounter, 0);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
await nodesPage.manageRules.ruleToggle.click();
|
||||
await expect(nodesPage.manageRules.ruleToggleFalse).toBeVisible();
|
||||
test.describe('[XAT-910] - Folder Rules Actions', () => {
|
||||
test.beforeAll(async () => {
|
||||
folder910Id = (await nodesApi.createFolder(folder910)).entry.id;
|
||||
});
|
||||
|
||||
test('[XAT-910] Create a rule and disable it', async ({ personalFiles, nodesPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/nodes/${folder910Id}/rules` });
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.IncrementCounter]);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
await nodesPage.manageRules.ruleToggle.click();
|
||||
await expect(nodesPage.manageRules.ruleToggleFalse).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
import { ApiClientFactory, test, Utils, NodesApi, TrashcanApi, RulesApi } from '@alfresco/aca-playwright-shared';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
test.use({ launchOptions: { slowMo: 300 } });
|
||||
test.use({ launchOptions: { slowMo: 500 } });
|
||||
|
||||
test.describe('Rules - Manage Rules', () => {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
|
||||
@@ -63,9 +63,7 @@ async function setupTransformationTest(
|
||||
await nodesPage.rulesToolbar.clickCreateRuleButton();
|
||||
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(testString);
|
||||
await nodesPage.manageRulesDialog.ruleDescriptionInputLocator.fill(testString);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.TransformAndCopyContent, 0);
|
||||
await nodesPage.actionsDropdown.selectMimeType(mimeType, 0);
|
||||
await nodesPage.actionsDropdown.selectDestinationFolderTransformAndCopyContent(0, destinationFolderName);
|
||||
await nodesPage.actionsDropdown.selectActions([{ type: ActionType.TransformAndCopyContent, mimeType, destinationFolder: destinationFolderName }]);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
await expect(nodesPage.manageRules.getGroupsList(testString)).toBeVisible();
|
||||
return parentFolderId;
|
||||
@@ -105,7 +103,7 @@ async function verifyTransformation(
|
||||
}
|
||||
}
|
||||
|
||||
test.use({ launchOptions: { slowMo: 300 } });
|
||||
test.use({ launchOptions: { slowMo: 500 } });
|
||||
|
||||
test.describe('Folder Rules Actions', () => {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
|
||||
@@ -128,7 +128,7 @@ test.describe('Rules - Manage Rules', () => {
|
||||
await nodesPage.manageRules.getGroupsList(randomRuleName899).click();
|
||||
await nodesPage.manageRules.ruleDetailsEditButton.click();
|
||||
await nodesPage.manageRulesDialog.deleteActions(2);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.IncrementCounter, 1);
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.IncrementCounter]);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
await nodesPage.manageRulesDialog.createRuleButton.waitFor({ state: 'hidden' });
|
||||
await nodesPage.manageRules.getGroupsList(randomRuleName899).click();
|
||||
@@ -141,8 +141,7 @@ test.describe('Rules - Manage Rules', () => {
|
||||
await nodesPage.manageRules.getGroupsList(randomRuleName900).click();
|
||||
await nodesPage.manageRules.ruleDetailsEditButton.click();
|
||||
await nodesPage.manageRulesDialog.deleteActions(2);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 1);
|
||||
await nodesPage.actionsDropdown.insertAddAspectActionValues('History', 1);
|
||||
await nodesPage.actionsDropdown.selectActions([{ type: ActionType.AddAspect, value: 'History' }]);
|
||||
await nodesPage.manageRulesDialog.createRuleButton.click();
|
||||
await nodesPage.manageRulesDialog.createRuleButton.waitFor({ state: 'hidden' });
|
||||
await nodesPage.manageRules.getGroupsList(randomRuleName900).click();
|
||||
@@ -155,7 +154,7 @@ test.describe('Rules - Manage Rules', () => {
|
||||
await nodesPage.manageRules.getGroupsList(randomRuleName901).click();
|
||||
await nodesPage.manageRules.ruleDetailsEditButton.click();
|
||||
await nodesPage.manageRulesDialog.deleteActions(2);
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.Copy, 1);
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.Copy]);
|
||||
await nodesPage.manageRulesDialog.destinationFolderButton.click();
|
||||
await nodesPage.contentNodeSelectorDialog.cancelButton.click();
|
||||
await nodesPage.contentNodeSelectorDialog.cancelButton.waitFor({ state: 'hidden' });
|
||||
@@ -166,7 +165,7 @@ test.describe('Rules - Manage Rules', () => {
|
||||
await personalFiles.dataTable.performActionFromExpandableMenu(folderName902, 'Manage rules');
|
||||
await nodesPage.manageRules.getGroupsList(randomRuleName902).click();
|
||||
await nodesPage.manageRules.ruleDetailsEditButton.click();
|
||||
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 1);
|
||||
await nodesPage.actionsDropdown.selectActions([ActionType.AddAspect]);
|
||||
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeDisabled();
|
||||
});
|
||||
|
||||
|
||||
@@ -27,113 +27,151 @@ import { ApiClientFactory, TrashcanApi, NodesApi, SitesApi, test, timeouts, Util
|
||||
import { Site } from '@alfresco/js-api';
|
||||
|
||||
test.describe('viewer action file', () => {
|
||||
let nodesApi: NodesApi;
|
||||
let siteActions: SitesApi;
|
||||
let trashcanApi: TrashcanApi;
|
||||
const username = `user-${Utils.random()}`;
|
||||
const parent = `parent-viewer-${Utils.random()}`;
|
||||
let parentId: string;
|
||||
const subFolder1 = `subFolder1-${Utils.random()}`;
|
||||
let subFolder1Id: string;
|
||||
const subFolder2 = `subFolder2-${Utils.random()}`;
|
||||
let subFolder2Id: string;
|
||||
const fileName1 = `file1-${Utils.random()}.txt`;
|
||||
test.describe('Personal Files folder hierarchy', () => {
|
||||
let nodesApi: NodesApi;
|
||||
let trashcanApi: TrashcanApi;
|
||||
const username = `breadcrumb-pf-${Utils.random()}`;
|
||||
const parent = `parent-viewer-${Utils.random()}`;
|
||||
const subFolder1 = `subFolder1-${Utils.random()}`;
|
||||
const subFolder2 = `subFolder2-${Utils.random()}`;
|
||||
const fileName1 = `file1-${Utils.random()}.txt`;
|
||||
let subFolder1Id: string;
|
||||
let subFolder2Id: string;
|
||||
|
||||
const siteName = `site-breadcrumb-${Utils.random()}`;
|
||||
let docLibId: string;
|
||||
const parentFromSite = `parent-in-site-${Utils.random()}`;
|
||||
let parentFromSiteId: string;
|
||||
const subFolder1FromSite = `subFolder1-in-site-${Utils.random()}`;
|
||||
let subFolder1FromSiteId: string;
|
||||
const subFolder2FromSite = `subFolder2-in-site-${Utils.random()}`;
|
||||
let subFolder2FromSiteId: string;
|
||||
const fileName1FromSite = `file1-in-site-${Utils.random()}.txt`;
|
||||
test.beforeAll(async () => {
|
||||
test.setTimeout(timeouts.extendedTest);
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
nodesApi = await NodesApi.initialize(username, username);
|
||||
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||
const parentId = (await nodesApi.createFolder(parent)).entry.id;
|
||||
subFolder1Id = (await nodesApi.createFolder(subFolder1, parentId)).entry.id;
|
||||
subFolder2Id = (await nodesApi.createFolder(subFolder2, subFolder1Id)).entry.id;
|
||||
await nodesApi.createFile(fileName1, subFolder2Id);
|
||||
});
|
||||
|
||||
const parent2 = `parent2-${Utils.random()}`;
|
||||
let parent2Id: string;
|
||||
const folder1 = `folder1-${Utils.random()}`;
|
||||
let folder1Id: string;
|
||||
const folder1Renamed = `renamed-${Utils.random()}`;
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
});
|
||||
|
||||
test.beforeAll(async () => {
|
||||
test.setTimeout(timeouts.extendedTest);
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
nodesApi = await NodesApi.initialize(username, username);
|
||||
siteActions = await SitesApi.initialize(username, username);
|
||||
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||
const parentNode = await nodesApi.createFolder(parent);
|
||||
parentId = parentNode.entry.id;
|
||||
subFolder1Id = (await nodesApi.createFolder(subFolder1, parentId)).entry.id;
|
||||
subFolder2Id = (await nodesApi.createFolder(subFolder2, subFolder1Id)).entry.id;
|
||||
await nodesApi.createFile(fileName1, subFolder2Id);
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
|
||||
});
|
||||
|
||||
parent2Id = (await nodesApi.createFolder(parent2)).entry.id;
|
||||
folder1Id = (await nodesApi.createFolder(folder1, parent2Id)).entry.id;
|
||||
test('[XAT-4387] Personal Files breadcrumb main node', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/` });
|
||||
await expect(personalFiles.breadcrumb.items).toHaveCount(1);
|
||||
await expect(personalFiles.breadcrumb.currentItem).toHaveText('Personal Files');
|
||||
});
|
||||
|
||||
await siteActions.createSite(siteName, Site.VisibilityEnum.PUBLIC);
|
||||
docLibId = await siteActions.getDocLibId(siteName);
|
||||
parentFromSiteId = (await nodesApi.createFolder(parentFromSite, docLibId)).entry.id;
|
||||
subFolder1FromSiteId = (await nodesApi.createFolder(subFolder1FromSite, parentFromSiteId)).entry.id;
|
||||
subFolder2FromSiteId = (await nodesApi.createFolder(subFolder2FromSite, subFolder1FromSiteId)).entry.id;
|
||||
await nodesApi.createFile(fileName1FromSite, subFolder2FromSiteId);
|
||||
test('[XAT-4388] Personal Files breadcrumb for a folder hierarchy', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${subFolder2Id}` });
|
||||
const expectedBreadcrumb = ['Personal Files', parent, subFolder1, subFolder2];
|
||||
expect(await personalFiles.breadcrumb.getAllItems()).toEqual(expectedBreadcrumb);
|
||||
});
|
||||
|
||||
test('[XAT-4396] User can navigate to any location by clicking on any step from the breadcrumb', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${subFolder2Id}` });
|
||||
await personalFiles.breadcrumb.clickItem(subFolder1);
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
const expectedBreadcrumb = ['Personal Files', parent, subFolder1];
|
||||
expect(await personalFiles.breadcrumb.getAllItems()).toEqual(expectedBreadcrumb);
|
||||
});
|
||||
|
||||
test('[XAT-4397] Tooltip appears on hover on a step in breadcrumb', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${subFolder2Id}` });
|
||||
const item = personalFiles.breadcrumb.items.nth(2);
|
||||
await expect(item).toHaveAttribute('title', subFolder1);
|
||||
});
|
||||
|
||||
test('[XAT-4399] Browser back navigates to previous location regardless of breadcrumb steps', async ({ personalFiles, trashPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${subFolder2Id}` });
|
||||
await trashPage.navigate();
|
||||
await personalFiles.page.goBack();
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
const expectedBreadcrumb = ['Personal Files', parent, subFolder1, subFolder2];
|
||||
expect(await personalFiles.breadcrumb.getAllItems()).toEqual(expectedBreadcrumb);
|
||||
});
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
test.describe('My Libraries folder hierarchy', () => {
|
||||
let nodesApi: NodesApi;
|
||||
let siteActions: SitesApi;
|
||||
let trashcanApi: TrashcanApi;
|
||||
const username = `breadcrumb-lib-${Utils.random()}`;
|
||||
const siteName = `site-breadcrumb-${Utils.random()}`;
|
||||
const parentFromSite = `parent-in-site-${Utils.random()}`;
|
||||
const subFolder1FromSite = `subFolder1-in-site-${Utils.random()}`;
|
||||
const subFolder2FromSite = `subFolder2-in-site-${Utils.random()}`;
|
||||
const fileName1FromSite = `file1-in-site-${Utils.random()}.txt`;
|
||||
let docLibId: string;
|
||||
let subFolder2FromSiteId: string;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
test.setTimeout(timeouts.extendedTest);
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
nodesApi = await NodesApi.initialize(username, username);
|
||||
siteActions = await SitesApi.initialize(username, username);
|
||||
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||
await siteActions.createSite(siteName, Site.VisibilityEnum.PUBLIC);
|
||||
docLibId = await siteActions.getDocLibId(siteName);
|
||||
const parentFromSiteId = (await nodesApi.createFolder(parentFromSite, docLibId)).entry.id;
|
||||
const subFolder1FromSiteId = (await nodesApi.createFolder(subFolder1FromSite, parentFromSiteId)).entry.id;
|
||||
subFolder2FromSiteId = (await nodesApi.createFolder(subFolder2FromSite, subFolder1FromSiteId)).entry.id;
|
||||
await nodesApi.createFile(fileName1FromSite, subFolder2FromSiteId);
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', siteActions, [siteName]);
|
||||
});
|
||||
|
||||
test('[XAT-4391] My Libraries breadcrumb for a folder hierarchy', async ({ myLibrariesPage }) => {
|
||||
await myLibrariesPage.navigate({ remoteUrl: `#/libraries/${subFolder2FromSiteId}` });
|
||||
const expectedItems = ['My Libraries', siteName, parentFromSite, subFolder1FromSite, subFolder2FromSite];
|
||||
expect(await myLibrariesPage.breadcrumb.getAllItems()).toEqual(expectedItems);
|
||||
});
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', siteActions, [docLibId]);
|
||||
});
|
||||
test.describe('Folder rename', () => {
|
||||
let nodesApi: NodesApi;
|
||||
let trashcanApi: TrashcanApi;
|
||||
const username = `breadcrumb-rename-${Utils.random()}`;
|
||||
const parent2 = `parent2-${Utils.random()}`;
|
||||
const folder1 = `folder1-${Utils.random()}`;
|
||||
const folder1Renamed = `renamed-${Utils.random()}`;
|
||||
let folder1Id: string;
|
||||
|
||||
test('[XAT-4387] Personal Files breadcrumb main node', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/` });
|
||||
expect(await personalFiles.breadcrumb.items.count(), 'Breadcrumb has incorrect number of items').toEqual(1);
|
||||
await expect(personalFiles.breadcrumb.currentItem).toHaveText('Personal Files');
|
||||
});
|
||||
test.beforeAll(async () => {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
nodesApi = await NodesApi.initialize(username, username);
|
||||
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||
const parent2Id = (await nodesApi.createFolder(parent2)).entry.id;
|
||||
folder1Id = (await nodesApi.createFolder(folder1, parent2Id)).entry.id;
|
||||
});
|
||||
|
||||
test('[XAT-4388] Personal Files breadcrumb for a folder hierarchy', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${subFolder2Id}` });
|
||||
const expectedBreadcrumb = ['Personal Files', parent, subFolder1, subFolder2];
|
||||
expect(await personalFiles.breadcrumb.getAllItems()).toEqual(expectedBreadcrumb);
|
||||
});
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
});
|
||||
|
||||
test('[XAT-4391] My Libraries breadcrumb for a folder hierarchy', async ({ myLibrariesPage }) => {
|
||||
await myLibrariesPage.navigate({ remoteUrl: `#/libraries/${subFolder2FromSiteId}` });
|
||||
const expectedItems = ['My Libraries', siteName, parentFromSite, subFolder1FromSite, subFolder2FromSite];
|
||||
expect(await myLibrariesPage.breadcrumb.getAllItems()).toEqual(expectedItems);
|
||||
});
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
|
||||
});
|
||||
|
||||
test('[XAT-4396] User can navigate to any location by clicking on any step from the breadcrumb', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${subFolder2Id}` });
|
||||
await personalFiles.breadcrumb.clickItem(subFolder1);
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
const expectedBreadcrumb = ['Personal Files', parent, subFolder1];
|
||||
expect(await personalFiles.breadcrumb.getAllItems()).toEqual(expectedBreadcrumb);
|
||||
});
|
||||
|
||||
test('[XAT-4397] Tooltip appears on hover on a step in breadcrumb', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${subFolder2Id}` });
|
||||
const item = personalFiles.breadcrumb.items.nth(2);
|
||||
await expect(item).toHaveAttribute('title', subFolder1);
|
||||
});
|
||||
|
||||
test('[XAT-4398] Breadcrumb updates correctly when folder is renamed', async ({ personalFiles, nodesApiAction }) => {
|
||||
await nodesApiAction.renameNode(folder1Id, folder1Renamed);
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${folder1Id}` });
|
||||
await personalFiles.page.reload();
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
await expect(personalFiles.breadcrumb.currentItem).toHaveText(folder1Renamed);
|
||||
});
|
||||
|
||||
test('[XAT-4399] Browser back navigates to previous location regardless of breadcrumb steps', async ({ personalFiles, trashPage }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${subFolder2Id}` });
|
||||
await trashPage.navigate();
|
||||
await personalFiles.page.goBack();
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
const expectedBreadcrumb = ['Personal Files', parent, subFolder1, subFolder2];
|
||||
expect(await personalFiles.breadcrumb.getAllItems()).toEqual(expectedBreadcrumb);
|
||||
test('[XAT-4398] Breadcrumb updates correctly when folder is renamed', async ({ personalFiles, nodesApiAction }) => {
|
||||
await nodesApiAction.renameNode(folder1Id, folder1Renamed);
|
||||
await personalFiles.navigate({ remoteUrl: `#/personal-files/${folder1Id}` });
|
||||
await personalFiles.page.reload();
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
await expect(personalFiles.breadcrumb.currentItem).toHaveText(folder1Renamed);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,69 +26,99 @@ import { expect } from '@playwright/test';
|
||||
import { ApiClientFactory, APP_ROUTES, SIDEBAR_LABELS, test, Utils } from '@alfresco/aca-playwright-shared';
|
||||
|
||||
test.describe('Sidebar', () => {
|
||||
const username = `user-${Utils.random()}`;
|
||||
test.describe('Navigation from sidebar', () => {
|
||||
const username = `sidebar-nav-${Utils.random()}`;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
test.beforeAll(async () => {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
});
|
||||
|
||||
test('[XAT-5368] Navigate to My Libraries', async ({ personalFiles, myLibrariesPage }) => {
|
||||
await personalFiles.navigate();
|
||||
await personalFiles.sidenav.openPanel(SIDEBAR_LABELS.MY_LIBRARIES);
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
expect(myLibrariesPage.page.url()).toContain(APP_ROUTES.MY_LIBRARIES);
|
||||
expect(await myLibrariesPage.sidenav.isActive(SIDEBAR_LABELS.MY_LIBRARIES), 'My Libraries link not active').toBe(true);
|
||||
});
|
||||
|
||||
test('[XAT-19271] Repository / Company Home button is accessible for all users on the sidebar', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate();
|
||||
await personalFiles.sidenav.openPanel(SIDEBAR_LABELS.REPOSITORY);
|
||||
expect(await personalFiles.sidenav.isActive(SIDEBAR_LABELS.REPOSITORY), 'Repository tab not active').toBe(true);
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
expect(await personalFiles.dataTable.isEmpty()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
test.describe('Sidenav expand/collapse', () => {
|
||||
const username = `sidebar-toggle-${Utils.random()}`;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
});
|
||||
|
||||
test('[XAT-5384] Sidenav state is preserved on page refresh', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate();
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar not expanded').toBeVisible();
|
||||
await personalFiles.reload();
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar not expanded').toBeVisible();
|
||||
|
||||
await personalFiles.sidenav.collapseSideNav();
|
||||
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar expanded').toBeHidden();
|
||||
await personalFiles.reload();
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar expanded').toBeHidden();
|
||||
});
|
||||
|
||||
test('[XAT-5382] Sidenav can be collapsed and expanded', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate();
|
||||
await personalFiles.sidenav.collapseSideNav();
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar expanded').toBeHidden();
|
||||
await personalFiles.sidenav.expandSideNav();
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar not expanded').toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test('[XAT-5368] Navigate to My Libraries', async ({ personalFiles, myLibrariesPage }) => {
|
||||
await personalFiles.navigate();
|
||||
await personalFiles.sidenav.openPanel(SIDEBAR_LABELS.MY_LIBRARIES);
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
expect(myLibrariesPage.page.url()).toContain(APP_ROUTES.MY_LIBRARIES);
|
||||
expect(await myLibrariesPage.sidenav.isActive(SIDEBAR_LABELS.MY_LIBRARIES), 'My Libraries link not active').toBe(true);
|
||||
});
|
||||
test.describe('Sidenav with search results', () => {
|
||||
const username = `sidebar-search-${Utils.random()}`;
|
||||
|
||||
test('[XAT-5387] The sidenav can be collapsed when search results page is displayed', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/search;q=test` });
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar expanded').toBeVisible();
|
||||
await personalFiles.sidenav.collapseSideNav();
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar not collapsed').toBeHidden();
|
||||
});
|
||||
test.beforeAll(async () => {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
});
|
||||
|
||||
test('[XAT-5384] Sidenav state is preserved on page refresh', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate();
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar not expanded').toBeVisible();
|
||||
await personalFiles.reload();
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar not expanded').toBeVisible();
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
});
|
||||
|
||||
await personalFiles.sidenav.collapseSideNav();
|
||||
test('[XAT-5387] The sidenav can be collapsed when search results page is displayed', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/search;q=test` });
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar expanded').toBeVisible();
|
||||
await personalFiles.sidenav.collapseSideNav();
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar not collapsed').toBeHidden();
|
||||
});
|
||||
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar expanded').toBeHidden();
|
||||
await personalFiles.reload();
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar expanded').toBeHidden();
|
||||
});
|
||||
|
||||
test('[XAT-5382] Sidenav can be collapsed and expanded', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate();
|
||||
await personalFiles.sidenav.collapseSideNav();
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar expanded').toBeHidden();
|
||||
await personalFiles.sidenav.expandSideNav();
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar not expanded').toBeVisible();
|
||||
});
|
||||
|
||||
test('[XAT-5386] The sidenav returns to the default state when navigating away from the search results page', async ({
|
||||
personalFiles,
|
||||
searchPage
|
||||
}) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/search;q=test` });
|
||||
await searchPage.searchInputComponent.searchCloseButton.click();
|
||||
await searchPage.sidenav.expandedSidenav.waitFor({ state: 'attached' });
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar not expanded').toBeVisible();
|
||||
});
|
||||
|
||||
test('[XAT-19271] Repository / Company Home button is accessible for all users on the sidebar', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate();
|
||||
await personalFiles.sidenav.openPanel(SIDEBAR_LABELS.REPOSITORY);
|
||||
expect(await personalFiles.sidenav.isActive(SIDEBAR_LABELS.REPOSITORY), 'Repository tab not active').toBe(true);
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
expect(await personalFiles.dataTable.isEmpty()).toBe(false);
|
||||
test('[XAT-5386] The sidenav returns to the default state when navigating away from the search results page', async ({
|
||||
personalFiles,
|
||||
searchPage
|
||||
}) => {
|
||||
await personalFiles.navigate({ remoteUrl: `#/search;q=test` });
|
||||
await searchPage.searchInputComponent.searchCloseButton.click();
|
||||
await searchPage.sidenav.expandedSidenav.waitFor({ state: 'attached' });
|
||||
await expect(personalFiles.sidenav.expandedSidenav, 'Sidebar not expanded').toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,66 +26,107 @@ import { expect } from '@playwright/test';
|
||||
import { ApiClientFactory, TrashcanApi, NodesApi, SitesApi, test, Utils } from '@alfresco/aca-playwright-shared';
|
||||
|
||||
test.describe('Single click on item name', () => {
|
||||
let nodesApi: NodesApi;
|
||||
let trashcanApi: TrashcanApi;
|
||||
const username = `user-${Utils.random()}`;
|
||||
const folder1 = `folder1-${Utils.random()}`;
|
||||
const folderSearch = `folder1-${Utils.random()}`;
|
||||
test.describe('in Trash', () => {
|
||||
let nodesApi: NodesApi;
|
||||
let trashcanApi: TrashcanApi;
|
||||
const username = `single-click-trash-${Utils.random()}`;
|
||||
const deletedFile1 = `file1-${Utils.random()}.txt`;
|
||||
const deletedFolder1 = `folder1-${Utils.random()}`;
|
||||
|
||||
const deletedFile1 = `file1-${Utils.random()}.txt`;
|
||||
const deletedFolder1 = `folder1-${Utils.random()}`;
|
||||
test.beforeAll(async () => {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
nodesApi = await NodesApi.initialize(username, username);
|
||||
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||
await nodesApi.createFile(deletedFile1);
|
||||
await nodesApi.createFolder(deletedFolder1);
|
||||
});
|
||||
|
||||
const siteName = `site-single-${Utils.random()}`;
|
||||
const fileSite = `fileSite-${Utils.random()}.txt`;
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
});
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
nodesApi = await NodesApi.initialize(username, username);
|
||||
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||
const siteActions = await SitesApi.initialize(username, username);
|
||||
await nodesApi.createFolder(folder1);
|
||||
await nodesApi.createFolder(folderSearch);
|
||||
await nodesApi.createFile(deletedFile1);
|
||||
await nodesApi.createFolder(deletedFolder1);
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
|
||||
});
|
||||
|
||||
await siteActions.createSite(siteName);
|
||||
const docLibId = await siteActions.getDocLibId(siteName);
|
||||
await nodesApi.createFile(fileSite, docLibId);
|
||||
test('[XAT-4894] Hyperlink does not appear for items in the Trash', async ({ trashPage }) => {
|
||||
await trashPage.navigate();
|
||||
await expect(trashPage.dataTable.getCellLinkByName(deletedFile1), 'Link on name is present').toBeHidden();
|
||||
await expect(trashPage.dataTable.getCellLinkByName(deletedFolder1), 'Link on name is present').toBeHidden();
|
||||
});
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
test.describe('on Personal Files', () => {
|
||||
let nodesApi: NodesApi;
|
||||
let trashcanApi: TrashcanApi;
|
||||
const username = `single-click-pf-${Utils.random()}`;
|
||||
const folder1 = `folder1-${Utils.random()}`;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
nodesApi = await NodesApi.initialize(username, username);
|
||||
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||
await nodesApi.createFolder(folder1);
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
|
||||
});
|
||||
|
||||
test('[XAT-4897] Navigate inside the folder when clicking the hyperlink - on Personal Files', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate();
|
||||
await personalFiles.dataTable.goThroughPagesLookingForRowWithName(folder1);
|
||||
await personalFiles.dataTable.getCellLinkByName(folder1).click();
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
while ((await personalFiles.breadcrumb.currentItem.innerText()) === 'Personal Files') {
|
||||
await personalFiles.breadcrumb.currentItem.innerText();
|
||||
}
|
||||
await expect(personalFiles.breadcrumb.currentItem).toHaveText(folder1);
|
||||
});
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
|
||||
});
|
||||
test.describe('in Libraries', () => {
|
||||
let nodesApi: NodesApi;
|
||||
let trashcanApi: TrashcanApi;
|
||||
const username = `single-click-lib-${Utils.random()}`;
|
||||
const siteName = `site-single-${Utils.random()}`;
|
||||
const fileSite = `fileSite-${Utils.random()}.txt`;
|
||||
|
||||
test('[XAT-4894] Hyperlink does not appear for items in the Trash', async ({ trashPage }) => {
|
||||
await trashPage.navigate();
|
||||
await expect(trashPage.dataTable.getCellLinkByName(deletedFile1), 'Link on name is present').toBeHidden();
|
||||
await expect(trashPage.dataTable.getCellLinkByName(deletedFolder1), 'Link on name is present').toBeHidden();
|
||||
});
|
||||
test.beforeAll(async () => {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
nodesApi = await NodesApi.initialize(username, username);
|
||||
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||
const siteActions = await SitesApi.initialize(username, username);
|
||||
await siteActions.createSite(siteName);
|
||||
const docLibId = await siteActions.getDocLibId(siteName);
|
||||
await nodesApi.createFile(fileSite, docLibId);
|
||||
});
|
||||
|
||||
test('[XAT-4897] Navigate inside the folder when clicking the hyperlink - on Personal Files', async ({ personalFiles }) => {
|
||||
await personalFiles.navigate();
|
||||
await personalFiles.dataTable.goThroughPagesLookingForRowWithName(folder1);
|
||||
await personalFiles.dataTable.getCellLinkByName(folder1).click();
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
while ((await personalFiles.breadcrumb.currentItem.innerText()) === 'Personal Files') {
|
||||
await personalFiles.breadcrumb.currentItem.innerText();
|
||||
}
|
||||
await expect(personalFiles.breadcrumb.currentItem).toHaveText(folder1);
|
||||
});
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
});
|
||||
|
||||
test('[XAT-4899] Navigate inside the library when clicking the hyperlink', async ({ myLibrariesPage }) => {
|
||||
await myLibrariesPage.navigate();
|
||||
await myLibrariesPage.dataTable.goThroughPagesLookingForRowWithName(siteName);
|
||||
await myLibrariesPage.dataTable.getCellLinkByName(siteName).click();
|
||||
await myLibrariesPage.dataTable.spinnerWaitForReload();
|
||||
await expect(myLibrariesPage.breadcrumb.currentItem).toHaveText(siteName);
|
||||
await expect(myLibrariesPage.dataTable.getCellLinkByName(fileSite), `${fileSite} not displayed`).toBeVisible();
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
|
||||
});
|
||||
|
||||
test('[XAT-4899] Navigate inside the library when clicking the hyperlink', async ({ myLibrariesPage }) => {
|
||||
await myLibrariesPage.navigate();
|
||||
await myLibrariesPage.dataTable.goThroughPagesLookingForRowWithName(siteName);
|
||||
await myLibrariesPage.dataTable.getCellLinkByName(siteName).click();
|
||||
await myLibrariesPage.dataTable.spinnerWaitForReload();
|
||||
await expect(myLibrariesPage.breadcrumb.currentItem).toHaveText(siteName);
|
||||
await expect(myLibrariesPage.dataTable.getCellLinkByName(fileSite), `${fileSite} not displayed`).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
import { expect } from '@playwright/test';
|
||||
import { ApiClientFactory, Utils, test, NodesApi, TrashcanApi, TEST_FILES, FileActionsApi } from '@alfresco/aca-playwright-shared';
|
||||
import { ApiClientFactory, Utils, test, NodesApi, TrashcanApi, TEST_FILES, FileActionsApi, SearchApi } from '@alfresco/aca-playwright-shared';
|
||||
|
||||
test.use({ launchOptions: { slowMo: 500 } });
|
||||
|
||||
@@ -31,17 +31,14 @@ test.describe('Search Highlighting', () => {
|
||||
let nodesApi: NodesApi;
|
||||
let trashcanApi: TrashcanApi;
|
||||
let fileActionsApi: FileActionsApi;
|
||||
let searchApi: SearchApi;
|
||||
const randomId = Utils.random();
|
||||
const username = `user-${randomId}`;
|
||||
const fileNameHighlight = `${randomId}-file-name.jpg`;
|
||||
const fileDescriptionHighlight = `${randomId}-file-description.jpg`;
|
||||
const fileDescription = `highlight`;
|
||||
const fileContentHighlight = `${randomId}-file-content.pdf`;
|
||||
const fileContent = 'TEXT:Virtual';
|
||||
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
});
|
||||
const fileContent = 'Virtual';
|
||||
|
||||
test.beforeAll(async () => {
|
||||
try {
|
||||
@@ -51,9 +48,11 @@ test.describe('Search Highlighting', () => {
|
||||
nodesApi = await NodesApi.initialize(username, username);
|
||||
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||
fileActionsApi = await FileActionsApi.initialize(username, username);
|
||||
searchApi = await SearchApi.initialize(username, username);
|
||||
await nodesApi.createFile(fileNameHighlight, '-my-');
|
||||
await nodesApi.createFile(fileDescriptionHighlight, '-my-', undefined, fileDescription);
|
||||
await fileActionsApi.uploadFileWithRename(TEST_FILES.PDF.path, fileContentHighlight);
|
||||
await searchApi.waitFileForSearchIndexing(fileContentHighlight);
|
||||
|
||||
await fileActionsApi.waitForNodesSearchHighlight(fileContentHighlight, { expect: 1 });
|
||||
} catch (error) {
|
||||
@@ -61,6 +60,10 @@ test.describe('Search Highlighting', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ loginPage }) => {
|
||||
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
|
||||
});
|
||||
|
||||
@@ -110,7 +110,7 @@ test.describe('Unshare a file from Search Results', () => {
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', sitesApi, [docLibId]);
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', sitesApi, [sitePrivate]);
|
||||
});
|
||||
|
||||
test('[XAT-5197] Unshare dialog UI', async ({ personalFiles, searchPage }) => {
|
||||
|
||||
@@ -40,7 +40,6 @@ test.describe('viewer file', () => {
|
||||
const usernameViewer = `user-${Utils.random()}`;
|
||||
const randomDocxName = `${TEST_FILES.DOCX.name}-${Utils.random()}`;
|
||||
const siteAdmin = `siteAdmin-${Utils.random()}`;
|
||||
let docLibId: string;
|
||||
let folderId: string;
|
||||
let fileDocxId: string;
|
||||
let nodesApi: NodesApi;
|
||||
@@ -63,10 +62,8 @@ test.describe('viewer file', () => {
|
||||
const fileActionApi = await FileActionsApi.initialize(usernameViewer, usernameViewer);
|
||||
trashcanApi = await TrashcanApi.initialize(usernameViewer, usernameViewer);
|
||||
siteActionsAdmin = await SitesApi.initialize('admin');
|
||||
const node = await nodesApi.createFolder(randomFolderName);
|
||||
folderId = node.entry.id;
|
||||
const fileDoc = await fileActionApi.uploadFile(TEST_FILES.DOCX.path, randomDocxName, folderId);
|
||||
fileDocxId = fileDoc.entry.id;
|
||||
folderId = (await nodesApi.createFolder(randomFolderName)).entry.id;
|
||||
fileDocxId = (await fileActionApi.uploadFile(TEST_FILES.DOCX.path, randomDocxName, folderId)).entry.id;
|
||||
|
||||
try {
|
||||
await siteActionsAdmin.createSite(siteAdmin, Site.VisibilityEnum.PRIVATE);
|
||||
@@ -76,8 +73,6 @@ test.describe('viewer file', () => {
|
||||
}
|
||||
}
|
||||
|
||||
docLibId = await siteActionsAdmin.getDocLibId(siteAdmin);
|
||||
|
||||
await fileActionApi.waitForNodes(randomDocxName, { expect: 1 });
|
||||
});
|
||||
|
||||
@@ -88,7 +83,7 @@ test.describe('viewer file', () => {
|
||||
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', siteActionsAdmin, [docLibId]);
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', siteActionsAdmin, [siteAdmin]);
|
||||
});
|
||||
|
||||
test('[XAT-17736] Open viewer with click action', async ({ personalFiles }) => {
|
||||
|
||||
+1
-1
@@ -181,7 +181,7 @@ test.describe('Special permissions : ', () => {
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(undefined, undefined, 'afterAll failed', managerSiteActions, [docLibId]);
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(undefined, undefined, 'afterAll failed', managerSiteActions, [sitePrivate]);
|
||||
});
|
||||
|
||||
test.describe('Consumer', () => {
|
||||
|
||||
@@ -358,8 +358,10 @@ test.describe('viewer action file', () => {
|
||||
await navigateAndOpenFile(personalFiles, folder5713Id, file5713);
|
||||
await uploadVersionAndOpenHistory(personalFiles, file5713NewVersion);
|
||||
await personalFiles.manageVersionsDialog.clickListActionButtonForVersion('1.0');
|
||||
const [download] = await Promise.all([personalFiles.page.waitForEvent('download'), personalFiles.matMenu.clickMenuItem('Download')]);
|
||||
expect(download.suggestedFilename()).toBe(file5713);
|
||||
const downloadPromise = personalFiles.page.waitForEvent('download', { timeout: timeouts.medium });
|
||||
await personalFiles.matMenu.clickMenuItem('Download');
|
||||
const download = await downloadPromise;
|
||||
expect(download.suggestedFilename()).toContain(file5713);
|
||||
});
|
||||
|
||||
test('[XAT-5714] Viewer: User can restore the current version of a file to a previous version with permissions', async ({ personalFiles }) => {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { expect } from '@playwright/test';
|
||||
import { expect, Download } from '@playwright/test';
|
||||
import {
|
||||
ApiClientFactory,
|
||||
Utils,
|
||||
@@ -54,7 +54,9 @@ test.describe('Version actions', () => {
|
||||
let fileId: string;
|
||||
let fileAfterUpdateId: string;
|
||||
|
||||
async function viewFirstFileVersion(page: PersonalFilesPage | RecentFilesPage | FavoritesPage | SharedPage | SearchPage) {
|
||||
type PageWithViewer = PersonalFilesPage | RecentFilesPage | FavoritesPage | SharedPage | SearchPage;
|
||||
|
||||
async function viewFirstFileVersion(page: PageWithViewer) {
|
||||
await page.dataTable.selectItems(filenameAfterUpdate);
|
||||
await page.acaHeader.clickMoreActions();
|
||||
await page.matMenu.clickMenuItem('Manage Versions');
|
||||
@@ -62,6 +64,17 @@ test.describe('Version actions', () => {
|
||||
await page.matMenu.clickMenuItem('View');
|
||||
}
|
||||
|
||||
async function waitForViewerDocumentToRender(page: PageWithViewer): Promise<void> {
|
||||
await page.viewer.waitForViewerToOpen();
|
||||
await page.viewer.waitForViewerContentToRender('document');
|
||||
}
|
||||
|
||||
async function downloadFromViewer(page: PageWithViewer): Promise<Download> {
|
||||
const downloadPromise = page.page.waitForEvent('download');
|
||||
await page.viewer.downloadButton.click();
|
||||
return downloadPromise;
|
||||
}
|
||||
|
||||
test.beforeAll(async () => {
|
||||
try {
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
@@ -112,7 +125,8 @@ test.describe('Version actions', () => {
|
||||
});
|
||||
|
||||
test('[XAT-5498] Should be possible to download a previous document version - Personal Files', async ({ personalFiles }) => {
|
||||
const [download] = await Promise.all([personalFiles.page.waitForEvent('download'), await personalFiles.viewer.downloadButton.click()]);
|
||||
await waitForViewerDocumentToRender(personalFiles);
|
||||
const download = await downloadFromViewer(personalFiles);
|
||||
expect(download.suggestedFilename()).toContain(filenameBeforeUpdate);
|
||||
});
|
||||
|
||||
@@ -153,7 +167,8 @@ test.describe('Version actions', () => {
|
||||
});
|
||||
|
||||
test('[XAT-5501] Should be possible to download a previous document version - Recent Files', async ({ recentFilesPage }) => {
|
||||
const [download] = await Promise.all([recentFilesPage.page.waitForEvent('download'), await recentFilesPage.viewer.downloadButton.click()]);
|
||||
await waitForViewerDocumentToRender(recentFilesPage);
|
||||
const download = await downloadFromViewer(recentFilesPage);
|
||||
expect(download.suggestedFilename()).toBe(filenameBeforeUpdate);
|
||||
});
|
||||
});
|
||||
@@ -178,7 +193,8 @@ test.describe('Version actions', () => {
|
||||
});
|
||||
|
||||
test('[XAT-5504] Should be possible to download a previous document version - Favorites', async ({ favoritePage }) => {
|
||||
const [download] = await Promise.all([favoritePage.page.waitForEvent('download'), await favoritePage.viewer.downloadButton.click()]);
|
||||
await waitForViewerDocumentToRender(favoritePage);
|
||||
const download = await downloadFromViewer(favoritePage);
|
||||
expect(download.suggestedFilename()).toContain(filenameBeforeUpdate);
|
||||
});
|
||||
});
|
||||
@@ -203,7 +219,8 @@ test.describe('Version actions', () => {
|
||||
});
|
||||
|
||||
test('[XAT-5507] Should be possible to download a previous document version - Shared Files', async ({ sharedPage }) => {
|
||||
const [download] = await Promise.all([sharedPage.page.waitForEvent('download'), await sharedPage.viewer.downloadButton.click()]);
|
||||
await waitForViewerDocumentToRender(sharedPage);
|
||||
const download = await downloadFromViewer(sharedPage);
|
||||
expect(download.suggestedFilename()).toContain(filenameBeforeUpdate);
|
||||
});
|
||||
});
|
||||
@@ -228,7 +245,8 @@ test.describe('Version actions', () => {
|
||||
});
|
||||
|
||||
test('[XAT-5510] Should be possible to download a previous document version - Search Results', async ({ searchPage }) => {
|
||||
const [download] = await Promise.all([searchPage.page.waitForEvent('download'), await searchPage.viewer.downloadButton.click()]);
|
||||
await waitForViewerDocumentToRender(searchPage);
|
||||
const download = await downloadFromViewer(searchPage);
|
||||
expect(download.suggestedFilename()).toContain(filenameBeforeUpdate);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -118,7 +118,7 @@ test.describe('viewer zoom functionality and reset', () => {
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', siteActionsUser, [docLibId]);
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', siteActionsUser, [randomLibraryName]);
|
||||
});
|
||||
|
||||
async function validateZoomScaleInViewer(
|
||||
|
||||
@@ -486,7 +486,7 @@ test.describe('viewer file', () => {
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', siteActionsAdmin, [docLibId]);
|
||||
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', siteActionsAdmin, [siteAdmin]);
|
||||
});
|
||||
|
||||
test('[XAT-5477] Viewer does not open when accessing the preview URL for a file without permissions', async ({ personalFiles }) => {
|
||||
|
||||
Generated
+1
-1
@@ -60,7 +60,7 @@
|
||||
"@nx/angular": "22.7.6",
|
||||
"@nx/eslint-plugin": "22.5.4",
|
||||
"@nx/workspace": "22.5.4",
|
||||
"@playwright/test": "^1.56.1",
|
||||
"@playwright/test": "^1.61.1",
|
||||
"@reportportal/agent-js-playwright": "^5.4.0",
|
||||
"@types/event-emitter": "^0.3.3",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@
|
||||
"@nx/angular": "22.7.6",
|
||||
"@nx/eslint-plugin": "22.5.4",
|
||||
"@nx/workspace": "22.5.4",
|
||||
"@playwright/test": "^1.56.1",
|
||||
"@playwright/test": "^1.61.1",
|
||||
"@reportportal/agent-js-playwright": "^5.4.0",
|
||||
"@types/event-emitter": "^0.3.3",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
|
||||
@@ -150,7 +150,7 @@ export class ApiClientFactory {
|
||||
try {
|
||||
await this.alfrescoApi.login(user.username, user.password);
|
||||
} catch (error) {
|
||||
logger.error(`[API Client Factory] Log in user ${user.username} failed ${error}`);
|
||||
logger.error(`[API Client Factory] Log in user ${user.username} failed ${JSON.stringify(error)}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -162,7 +162,7 @@ export class ApiClientFactory {
|
||||
try {
|
||||
return await peopleApi.createPerson(person);
|
||||
} catch (error) {
|
||||
if (String(error).includes('409')) {
|
||||
if (JSON.stringify(error).includes('409')) {
|
||||
logger.warn(`[API Client Factory] createUser: user "${user.username}" already exists, skipping creation`);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ export class FileActionsApi {
|
||||
logger.info(`File uploaded successfully: ${fileName}`);
|
||||
return result;
|
||||
} catch (error) {
|
||||
logger.error(`Failed to upload file: ${fileName}: ${error}`);
|
||||
logger.error(`Failed to upload file: ${fileName}: ${JSON.stringify(error)}`);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
@@ -170,17 +170,11 @@ export class FileActionsApi {
|
||||
}
|
||||
|
||||
async waitForNodes(searchTerm: string, data: { expect: number }): Promise<void> {
|
||||
logger.info(`waitForNodes: Waiting for ${data.expect} node(s) matching "${searchTerm}"`);
|
||||
const predicate = (totalItems: number) => totalItems === data.expect;
|
||||
let pollCount = 0;
|
||||
|
||||
const apiCall = async () => {
|
||||
try {
|
||||
const totalItems = (await this.queryNodesNames(searchTerm)).list?.pagination?.totalItems || 0;
|
||||
if (pollCount++ % 4 === 0) {
|
||||
logger.info(`waitForNodes: "${searchTerm}" — found ${totalItems}, expecting ${data.expect}`);
|
||||
}
|
||||
return totalItems;
|
||||
return (await this.queryNodesNames(searchTerm)).list?.pagination?.totalItems || 0;
|
||||
} catch {
|
||||
return 0;
|
||||
}
|
||||
@@ -188,6 +182,7 @@ export class FileActionsApi {
|
||||
|
||||
try {
|
||||
await waitForApi(apiCall, predicate, 30, 2500);
|
||||
logger.info(`waitForNodes: Found ${data.expect} node(s) matching "${searchTerm}"`);
|
||||
} catch {
|
||||
const actual = await apiCall();
|
||||
const message = `waitForNodes: Timed out waiting for "${searchTerm}" — expected ${data.expect} nodes, found ${actual}`;
|
||||
|
||||
@@ -69,7 +69,7 @@ export class NodesApi {
|
||||
try {
|
||||
return await this.createNode('cm:content', name, parentId, title, description, null, author, majorVersion, aspectNames);
|
||||
} catch (error) {
|
||||
const message = `${this.constructor.name} ${this.createFile.name}: ${error}`;
|
||||
const message = `${this.constructor.name} ${this.createFile.name}: ${error instanceof Error ? error.message : JSON.stringify(error)}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
@@ -148,7 +148,16 @@ export class NodesApi {
|
||||
majorVersion
|
||||
});
|
||||
} catch (error) {
|
||||
const message = `${this.constructor.name} ${this.createNode.name}: ${error}`;
|
||||
if (JSON.stringify(error).includes('409')) {
|
||||
logger.warn(
|
||||
`${this.constructor.name} ${this.createNode.name}: node "${name}" already exists in parent "${parentId}", retrieving existing node`
|
||||
);
|
||||
const existingNodeId = await this.getNodeIdFromParent(name, parentId);
|
||||
if (existingNodeId) {
|
||||
return this.getNodeById(existingNodeId);
|
||||
}
|
||||
}
|
||||
const message = `${this.constructor.name} ${this.createNode.name}: ${error instanceof Error ? error.message : JSON.stringify(error)}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
@@ -58,6 +58,119 @@ export class SearchApi {
|
||||
}
|
||||
}
|
||||
|
||||
async searchForNode(fileName: string, options?: { maxRetries?: number }): Promise<ResultSetPaging> {
|
||||
const query = {
|
||||
query: {
|
||||
query: `cm:name:"${fileName}"`,
|
||||
language: 'afts'
|
||||
},
|
||||
include: ['path', 'allowableOperations', 'properties'],
|
||||
paging: {
|
||||
skipCount: 0,
|
||||
maxItems: 25
|
||||
},
|
||||
filterQueries: [
|
||||
{
|
||||
query: "+TYPE:'cm:folder' OR +TYPE:'cm:content'"
|
||||
},
|
||||
{
|
||||
query: "-TYPE:'cm:thumbnail' AND -TYPE:'cm:failedThumbnail' AND -TYPE:'cm:rating'"
|
||||
},
|
||||
{
|
||||
query: '-cm:creator:System'
|
||||
},
|
||||
{
|
||||
query: "-TYPE:'st:site' AND -ASPECT:'st:siteContainer' AND -ASPECT:'sys:hidden'"
|
||||
},
|
||||
{
|
||||
query: "-TYPE:'dl:dataList' AND -TYPE:'dl:todoList' AND -TYPE:'dl:issue'"
|
||||
},
|
||||
{
|
||||
query: "-TYPE:'fm:topic' AND -TYPE:'fm:post'"
|
||||
},
|
||||
{
|
||||
query: "-TYPE:'lnk:link'"
|
||||
},
|
||||
{
|
||||
query: "-PATH:'//cm:wiki/*'"
|
||||
},
|
||||
{
|
||||
query: "+TYPE:'cm:content'"
|
||||
}
|
||||
],
|
||||
facetQueries: undefined,
|
||||
facetIntervals: undefined,
|
||||
facetFields: {
|
||||
facets: [
|
||||
{
|
||||
field: 'creator',
|
||||
mincount: 1,
|
||||
label: 'SEARCH.FACET_FIELDS.CREATOR'
|
||||
},
|
||||
{
|
||||
field: 'modifier',
|
||||
mincount: 1,
|
||||
label: 'SEARCH.FACET_FIELDS.MODIFIER'
|
||||
}
|
||||
]
|
||||
},
|
||||
sort: [
|
||||
{
|
||||
type: 'SCORE',
|
||||
field: 'score',
|
||||
ascending: false
|
||||
}
|
||||
],
|
||||
highlight: {
|
||||
prefix: "<span class='aca-highlight'>",
|
||||
postfix: '</span>',
|
||||
fields: [
|
||||
{
|
||||
field: 'cm:title'
|
||||
},
|
||||
{
|
||||
field: 'cm:name'
|
||||
},
|
||||
{
|
||||
field: 'cm:description',
|
||||
snippetCount: 1
|
||||
},
|
||||
{
|
||||
field: 'cm:content',
|
||||
snippetCount: 1
|
||||
}
|
||||
]
|
||||
},
|
||||
facetFormat: 'V2'
|
||||
};
|
||||
|
||||
let result: ResultSetPaging;
|
||||
let retryCount = 0;
|
||||
const retryLimit = options?.maxRetries ?? 90;
|
||||
|
||||
do {
|
||||
try {
|
||||
result = await this.apiService.search.search(query);
|
||||
} catch {
|
||||
result = new ResultSetPaging();
|
||||
}
|
||||
if ((result.list?.entries?.length ?? 0) === 0) {
|
||||
retryCount++;
|
||||
if (retryCount % 10 === 0) {
|
||||
logger.info(`searchForNode: Still waiting for file "${fileName}" after ${retryCount} retries (max ${retryLimit}).`);
|
||||
}
|
||||
if (retryCount >= retryLimit) {
|
||||
logger.error(`searchForNode: File "${fileName}" not found after ${retryLimit} retries.`);
|
||||
throw new Error(`File with name ${fileName} not found after ${retryLimit} retries`);
|
||||
}
|
||||
await Utils.delayInSeconds(1);
|
||||
}
|
||||
} while ((result.list?.entries?.length ?? 0) === 0);
|
||||
|
||||
logger.info(`searchForNode: Search succeeded for file "${fileName}"`);
|
||||
return result;
|
||||
}
|
||||
|
||||
async getTotalItems(username: string): Promise<number> {
|
||||
return (await this.querySearchFiles(username)).list?.pagination?.totalItems ?? 0;
|
||||
}
|
||||
@@ -116,8 +229,24 @@ export class SearchApi {
|
||||
logger.info(`waitForFolderPathIndexing: Found expected ${options.nodesExpected} nodes in folder ${folderId}`);
|
||||
return result.list?.pagination?.count ?? 0;
|
||||
} catch (error) {
|
||||
logger.error(`waitForFolderPathIndexing failed for folderId "${folderId}": ${error}`);
|
||||
throw error;
|
||||
const errorMessage = `waitForFolderPathIndexing failed for folderId "${folderId}": ${JSON.stringify(error)}`;
|
||||
logger.error(errorMessage);
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
async waitFileForSearchIndexing(fileName: string, maxRetries?: number): Promise<void> {
|
||||
try {
|
||||
const result = await this.searchForNode(fileName, { maxRetries: maxRetries });
|
||||
const entryNames = (result.list?.entries ?? []).map((entry) => entry.entry?.name).filter((name): name is string => Boolean(name));
|
||||
if (!entryNames.includes(fileName)) {
|
||||
throw new Error(`File "${fileName}" not found in search results. Found: [${entryNames.join(', ')}]`);
|
||||
}
|
||||
logger.info(`waitFileForSearchIndexing: File "${fileName}" is indexed.`);
|
||||
} catch (error) {
|
||||
const errorMessage = `waitFileForSearchIndexing failed for file "${fileName}": ${JSON.stringify(error)}`;
|
||||
logger.error(errorMessage);
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,9 +85,7 @@ export class SharedLinksApi {
|
||||
const sharedFiles = (await this.getSharedLinks()).list?.entries?.map((link) => link.entry.nodeId) ?? [];
|
||||
const foundItems = fileIds.every((id) => sharedFiles.includes(id));
|
||||
if (!foundItems) {
|
||||
const message = 'Not all files are shared yet';
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
throw new Error('Not all files are shared yet');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -58,9 +58,14 @@ export class SitesApi {
|
||||
try {
|
||||
return await this.apiService.sites.createSite(site);
|
||||
} catch (error) {
|
||||
const message = `SitesApi ${this.createSite.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
if (JSON.stringify(error).includes('409')) {
|
||||
logger.warn(`[SitesApi] createSite: site "${siteId || title}" already exists, skipping creation`);
|
||||
return this.getSite(siteId || title);
|
||||
} else {
|
||||
const message = `SitesApi ${this.createSite.name}: ${JSON.stringify(error)}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ export const getGlobalConfig: PlaywrightTestConfig = {
|
||||
/* Retry on CI only */
|
||||
retries: env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: 3,
|
||||
workers: Number(env.PLAYWRIGHT_WORKERS) || 3,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: [['list'], ...getReporter()],
|
||||
globalSetup: require.resolve('./global.setup'),
|
||||
|
||||
+60
-6
@@ -59,6 +59,13 @@ export enum MimeType {
|
||||
PNGImage = 'PNG Image [image/png]'
|
||||
}
|
||||
|
||||
export interface ActionConfig {
|
||||
type: ActionType;
|
||||
value?: string;
|
||||
mimeType?: MimeType;
|
||||
destinationFolder?: string;
|
||||
}
|
||||
|
||||
export class ActionsDropdownComponent extends BaseComponent {
|
||||
private static readonly rootElement = 'aca-edit-rule-dialog aca-rule-action-list';
|
||||
|
||||
@@ -67,6 +74,7 @@ export class ActionsDropdownComponent extends BaseComponent {
|
||||
private readonly ruleActionLocator = this.getChild('aca-rule-action');
|
||||
private readonly addActionButtonLocator = this.getChild('[data-automation-id="rule-action-list-add-action-button"]');
|
||||
private readonly actionDropdownLocator = this.getChild('[data-automation-id="rule-action-select"]');
|
||||
private readonly selectActionLocator = this.actionDropdownLocator.locator('span', { hasText: 'Select an action' });
|
||||
private readonly actionAspectNameLocator = '[data-automation-id="header-aspect-name"] .adf-property-field';
|
||||
private readonly actionCheckInInputLocator = '[data-automation-id="header-description"] input';
|
||||
private readonly actionSimpleWorkflowStepInputLocator = '[data-automation-id="header-approve-step"] input';
|
||||
@@ -84,14 +92,60 @@ export class ActionsDropdownComponent extends BaseComponent {
|
||||
super(page, ActionsDropdownComponent.rootElement);
|
||||
}
|
||||
|
||||
async selectAction(action: Partial<ActionType>, index: number): Promise<void> {
|
||||
if (index > 0) {
|
||||
async selectActions(actions: (ActionType | ActionConfig)[]): Promise<void> {
|
||||
for (const action of actions) {
|
||||
await this.selectSingleAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
private normalizeAction(action: ActionType | ActionConfig): ActionConfig {
|
||||
if (typeof action === 'string') {
|
||||
return { type: action };
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
private async selectSingleAction(action: ActionType | ActionConfig): Promise<void> {
|
||||
const { type, value, mimeType, destinationFolder } = this.normalizeAction(action);
|
||||
|
||||
if (await this.selectActionLocator.isHidden()) {
|
||||
await this.addActionButtonLocator.click();
|
||||
}
|
||||
await this.actionDropdownLocator.nth(index).hover({ timeout: 1000 });
|
||||
await this.actionDropdownLocator.nth(index).click();
|
||||
const option = this.getOptionLocator(action);
|
||||
await option.click();
|
||||
await this.selectActionLocator.scrollIntoViewIfNeeded();
|
||||
await this.selectActionLocator.hover({ timeout: 1000 });
|
||||
await this.selectActionLocator.click();
|
||||
await this.getOptionLocator(type).click();
|
||||
|
||||
const actionIndex = (await this.ruleActionLocator.count()) - 1;
|
||||
|
||||
if (value) {
|
||||
await this.insertActionValues(type, value, actionIndex);
|
||||
}
|
||||
|
||||
if (mimeType) {
|
||||
await this.selectMimeType(mimeType, actionIndex);
|
||||
}
|
||||
|
||||
if (destinationFolder) {
|
||||
await this.selectDestinationFolderTransformAndCopyContent(actionIndex, destinationFolder);
|
||||
}
|
||||
}
|
||||
|
||||
private async insertActionValues(type: ActionType, value: string, actionIndex: number): Promise<void> {
|
||||
switch (type) {
|
||||
case ActionType.AddAspect:
|
||||
await this.insertAddAspectActionValues(value, actionIndex);
|
||||
break;
|
||||
case ActionType.CheckIn:
|
||||
await this.insertCheckInActionValues(value, actionIndex);
|
||||
break;
|
||||
case ActionType.SpecialiseType:
|
||||
await this.insertSpecialiseTypeActionValues(value, actionIndex);
|
||||
break;
|
||||
case ActionType.SimpleWorkflow:
|
||||
await this.insertSimpleWorkflowActionValues(value, actionIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async dropdownSelection(selectValue: string, locator: string, index: number): Promise<void> {
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ export class Breadcrumb extends BaseComponent {
|
||||
const itemTexts = await Promise.all(
|
||||
itemElements.map(async (elem) => {
|
||||
const text = await elem.innerText();
|
||||
return text.split('\nchevron_right')[0];
|
||||
return text.split('\nchevron_right')[0].trim();
|
||||
})
|
||||
);
|
||||
return itemTexts;
|
||||
|
||||
@@ -42,6 +42,12 @@ export enum Comparator {
|
||||
EndsWith = 'Ends with'
|
||||
}
|
||||
|
||||
export interface ConditionConfig {
|
||||
field: Field;
|
||||
value: string;
|
||||
comparator?: Comparator;
|
||||
}
|
||||
|
||||
export class ConditionComponent extends ManageRulesDialogComponent {
|
||||
private readonly getOptionLocator = (optionName: string): Locator =>
|
||||
this.page.locator('[role=listbox] [role=option]', { hasText: optionName }).first();
|
||||
@@ -60,6 +66,7 @@ export class ConditionComponent extends ManageRulesDialogComponent {
|
||||
}
|
||||
|
||||
async addCondition(fields: Partial<Field>, value: string, index: number, comparators?: Partial<Comparator>): Promise<void> {
|
||||
await this.addConditionButton.first().scrollIntoViewIfNeeded();
|
||||
await this.addConditionButton.first().click();
|
||||
await this.selectField(fields, index);
|
||||
if (comparators) {
|
||||
@@ -73,7 +80,9 @@ export class ConditionComponent extends ManageRulesDialogComponent {
|
||||
}
|
||||
|
||||
async addConditionGroup(fields: Partial<Field>, value: string, index: number, comparators?: Partial<Comparator>): Promise<void> {
|
||||
await this.addConditionGroupButton.last().scrollIntoViewIfNeeded();
|
||||
await this.addConditionGroupButton.last().click();
|
||||
await this.addConditionButton.nth(index).scrollIntoViewIfNeeded();
|
||||
await this.addConditionButton.nth(index).click();
|
||||
await this.selectField(fields, index);
|
||||
if (comparators) {
|
||||
@@ -81,4 +90,18 @@ export class ConditionComponent extends ManageRulesDialogComponent {
|
||||
}
|
||||
await this.valueField.nth(index).fill(value);
|
||||
}
|
||||
|
||||
async addConditions(conditions: ConditionConfig[]): Promise<void> {
|
||||
for (let i = 0; i < conditions.length; i++) {
|
||||
const { field, value, comparator } = conditions[i];
|
||||
await this.addCondition(field, value, i, comparator);
|
||||
}
|
||||
}
|
||||
|
||||
async addConditionGroups(conditions: ConditionConfig[]): Promise<void> {
|
||||
for (let i = 0; i < conditions.length; i++) {
|
||||
const { field, value, comparator } = conditions[i];
|
||||
await this.addConditionGroup(field, value, i, comparator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user