diff --git a/.gitignore b/.gitignore index 8744ee3b0f..2683e54cd2 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,7 @@ testem.log .protractor-fail-fast .protractor-smartrunner /protractorFailuresReport +/storage-state # System Files .DS_Store diff --git a/e2e/playwright/actions/src/tests/create-folder.spec.ts b/e2e/playwright/actions/src/tests/create-folder.spec.ts index 585a66d07e..f15d098e3b 100644 --- a/e2e/playwright/actions/src/tests/create-folder.spec.ts +++ b/e2e/playwright/actions/src/tests/create-folder.spec.ts @@ -23,28 +23,147 @@ */ import { expect } from '@playwright/test'; -import { getUserState, test } from '@alfresco/playwright-shared'; +import { folderErrors, getUserState, test } from '@alfresco/playwright-shared'; test.use({ storageState: getUserState('hruser') }); test.describe('Create actions', () => { let randomFolderName: string; + let randomFolderTitle: string; + let randomFolderDescription: string; test.beforeEach(async ({ personalFiles }) => { randomFolderName = `playwright-folder-${(Math.random() + 1).toString(36).substring(6)}`; + randomFolderTitle = `folder-title-${(Math.random() + 1).toString(36).substring(6)}`; + randomFolderDescription = `folder-description-${(Math.random() + 1).toString(36).substring(6)}`; await personalFiles.navigate(); }); - test.afterEach(async ({ personalFiles }) => { + test('[C216341] Create a folder with name only', async ({ personalFiles }) => { + await personalFiles.acaHeader.createButton.click(); + await personalFiles.matMenu.createFolder.click(); + await personalFiles.folderDialog.folderNameInputLocator.fill(randomFolderName); + await personalFiles.folderDialog.createButton.click(); + + await personalFiles.dataTable.goThroughPagesLookingForRowWithName(randomFolderName); + await expect(personalFiles.dataTable.getRowByName(randomFolderName)).toBeVisible(); + await personalFiles.dataTable.performActionFromExpandableMenu(randomFolderName, 'Delete'); }); - test('[C216341] Create a folder with name only', async ({ personalFiles }) => { + test('[C216340] Create a folder with name, title and description', async ({ personalFiles }) => { + await personalFiles.acaHeader.createButton.click(); + await personalFiles.matMenu.createFolder.click(); + await personalFiles.folderDialog.folderNameInputLocator.fill(randomFolderName); + await personalFiles.folderDialog.folderTitleInput.fill(randomFolderTitle); + await personalFiles.folderDialog.folderDescriptionInput.fill(randomFolderDescription); + await personalFiles.folderDialog.createButton.click(); + + await personalFiles.dataTable.goThroughPagesLookingForRowWithName(randomFolderName); + await expect( + personalFiles.dataTable + .getCellLinkByName(randomFolderName) + .and(personalFiles.page.getByTitle(randomFolderTitle)) + .and(personalFiles.page.getByTitle(randomFolderDescription)) + ).toBeVisible(); + + await personalFiles.dataTable.performActionFromExpandableMenu(randomFolderName, 'Delete'); + }); + + test('[C216345] Create new folder dialog check', async ({ personalFiles }) => { + await personalFiles.acaHeader.createButton.click(); + await personalFiles.matMenu.createFolder.click(); + + await expect(personalFiles.folderDialog.getLabelText('Name')).toBeVisible(); + await expect(personalFiles.folderDialog.getLabelText('*')).toBeVisible(); + await expect(personalFiles.folderDialog.folderNameInputLocator).toBeVisible(); + await expect(personalFiles.folderDialog.getLabelText('Title')).toBeVisible(); + await expect(personalFiles.folderDialog.folderTitleInput).toBeVisible(); + await expect(personalFiles.folderDialog.getLabelText('Description')).toBeVisible(); + await expect(personalFiles.folderDialog.folderDescriptionInput).toBeVisible(); + await expect(personalFiles.folderDialog.cancelButton).toBeEnabled(); + await expect(personalFiles.folderDialog.createButton).toBeDisabled(); + }); + + test('[C216346] Create a folder without a name', async ({ personalFiles }) => { + await personalFiles.acaHeader.createButton.click(); + await personalFiles.matMenu.createFolder.click(); + await personalFiles.folderDialog.folderNameInputLocator.fill(randomFolderName); + await expect(personalFiles.folderDialog.folderNameInputLocator).toHaveValue(randomFolderName); + await expect(personalFiles.folderDialog.createButton).toBeEnabled(); + + await personalFiles.folderDialog.folderNameInputLocator.clear(); + + await expect(personalFiles.folderDialog.folderNameInputLocator).toBeEmpty(); + await expect(personalFiles.folderDialog.folderNameInputHint).toContainText(folderErrors.folderNameIsRequired); + await expect(personalFiles.folderDialog.createButton).toBeDisabled(); + }); + + test('[C216348] Create folder when a name that ends with a dot "."', async ({ personalFiles }) => { + await personalFiles.acaHeader.createButton.click(); + await personalFiles.matMenu.createFolder.click(); + await personalFiles.folderDialog.folderNameInputLocator.fill(randomFolderName + '.'); + + await expect(personalFiles.folderDialog.createButton).toBeDisabled(); + await expect(personalFiles.folderDialog.folderNameInputHint).toContainText(folderErrors.folderNameCantEndWithAPeriod); + }); + + test('[C216347] Create folder with a name containing special characters', async ({ personalFiles }) => { + const namesWithSpecialChars = ['a*a', 'a"a', 'aa', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a']; + await personalFiles.acaHeader.createButton.click(); + await personalFiles.matMenu.createFolder.click(); + for (const folderName of namesWithSpecialChars) { + await personalFiles.folderDialog.folderNameInputLocator.fill(folderName); + + await expect(personalFiles.folderDialog.createButton).toBeDisabled(); + await expect(personalFiles.folderDialog.folderNameInputHint).toContainText(folderErrors.folderNameCantContainTheseCharacters); + } + }); + + test('[C280406] Create a folder with a name containing only spaces', async ({ personalFiles }) => { await personalFiles.acaHeader.createButton.click(); await personalFiles.matMenu.createFolder.click(); + await personalFiles.folderDialog.folderNameInputLocator.fill(' '); + + await expect(personalFiles.folderDialog.createButton).toBeDisabled(); + await expect(personalFiles.folderDialog.folderNameInputHint).toContainText(folderErrors.folderNameCantContainOnlySpaces); + }); + + test('[C216349] Cancel folder creation', async ({ personalFiles }) => { + await personalFiles.acaHeader.createButton.click(); + await personalFiles.matMenu.createFolder.click(); + await expect(personalFiles.page.getByRole('dialog', { name: 'Create new folder' })).toBeVisible(); await personalFiles.folderDialog.folderNameInputLocator.fill(randomFolderName); + await personalFiles.folderDialog.cancelButton.click(); + await expect(personalFiles.page.getByRole('dialog', { name: 'Create new folder' })).toBeHidden(); + }); + + test('[C216350] Duplicate folder name error', async ({ personalFiles }) => { + await personalFiles.acaHeader.createButton.click(); + await personalFiles.matMenu.createFolder.click(); + await personalFiles.folderDialog.folderNameInputLocator.fill(randomFolderName); + await personalFiles.folderDialog.createButton.click(); + // duplicate folder name + await personalFiles.acaHeader.createButton.click(); + await personalFiles.matMenu.createFolder.click(); + await personalFiles.folderDialog.folderNameInputLocator.fill(randomFolderName); + await personalFiles.folderDialog.createButton.click(); + + await expect(personalFiles.page.getByRole('dialog', { name: 'Create new folder' })).toBeVisible(); + await expect(personalFiles.snackBar.getByMessageLocator(folderErrors.thereIsAlreadyAFolderWithThisName)).toBeVisible(); + + await personalFiles.folderDialog.cancelButton.click(); + await personalFiles.dataTable.performActionFromExpandableMenu(randomFolderName, 'Delete'); + }); + + test('[C216351] Folder created after trimmed ending spaces from a folder name', async ({ personalFiles }) => { + await personalFiles.acaHeader.createButton.click(); + await personalFiles.matMenu.createFolder.click(); + await personalFiles.folderDialog.folderNameInputLocator.fill(randomFolderName + ' '); await personalFiles.folderDialog.createButton.click(); await personalFiles.dataTable.goThroughPagesLookingForRowWithName(randomFolderName); await expect(personalFiles.dataTable.getRowByName(randomFolderName)).toBeVisible(); + + await personalFiles.dataTable.performActionFromExpandableMenu(randomFolderName, 'Delete'); }); }); diff --git a/projects/aca-playwright-shared/src/page-objects/components/dialogs/adf-folder-dialog.component.ts b/projects/aca-playwright-shared/src/page-objects/components/dialogs/adf-folder-dialog.component.ts index bc3a97d22b..b3d3ec9cc4 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/dialogs/adf-folder-dialog.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/dialogs/adf-folder-dialog.component.ts @@ -29,9 +29,15 @@ export class AdfFolderDialogComponent extends BaseComponent { private static rootElement = 'adf-folder-dialog'; public folderNameInputLocator = this.getChild('[id="adf-folder-name-input"]'); + public folderNameInputHint = this.getChild('mat-hint'); + public folderTitleInput = this.getChild('[id="adf-folder-title-input"]'); + public folderDescriptionInput = this.getChild('[id="adf-folder-description-input"]'); public createButton = this.getChild('[id="adf-folder-create-button"]'); + public cancelButton = this.getChild('[id="adf-folder-cancel-button"]'); constructor(page: Page) { super(page, AdfFolderDialogComponent.rootElement); } + + public getLabelText = (text: string) => this.getChild('label', { hasText: text }); } diff --git a/projects/aca-playwright-shared/src/page-objects/components/snackBar/snack-bar.component.ts b/projects/aca-playwright-shared/src/page-objects/components/snackBar/snack-bar.component.ts index 0c160a03c5..ac043a1ba7 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/snackBar/snack-bar.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/snackBar/snack-bar.component.ts @@ -26,10 +26,11 @@ import { Page } from '@playwright/test'; import { BaseComponent } from '../base.component'; export class SnackBarComponent extends BaseComponent { - private static rootElement = 'simple-snack-bar'; + private static rootElement = 'adf-snackbar-content'; - public message = this.getChild(' > span'); - public getByMessageLocator = (message: string) => this.getChild('span', { hasText: message }); + public message = this.getChild(' [data-automation-id=\'adf-snackbar-message-content\']').first(); + public getByMessageLocator = (message: string) => this.getChild(`[data-automation-id='adf-snackbar-message-content']`, + { hasText: message }).first(); constructor(page: Page, rootElement = SnackBarComponent.rootElement) { super(page, rootElement); diff --git a/projects/aca-playwright-shared/src/utils/folder-errors.ts b/projects/aca-playwright-shared/src/utils/folder-errors.ts new file mode 100644 index 0000000000..cfc24295b7 --- /dev/null +++ b/projects/aca-playwright-shared/src/utils/folder-errors.ts @@ -0,0 +1,31 @@ +/*! + * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Alfresco Example Content Application + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * from Hyland Software. If not, see . + */ + +export const folderErrors = { + folderNameIsRequired: 'Folder name is required', + folderNameCantEndWithAPeriod: `Folder name can't end with a period .`, + folderNameCantContainTheseCharacters: `Folder name can't contain these characters`, + folderNameCantContainOnlySpaces: `Folder name can't contain only spaces`, + thereIsAlreadyAFolderWithThisName: `There's already a folder with this name. Try a different name.` +} diff --git a/projects/aca-playwright-shared/src/utils/index.ts b/projects/aca-playwright-shared/src/utils/index.ts index 984ce0272b..f3bdc9b5fb 100644 --- a/projects/aca-playwright-shared/src/utils/index.ts +++ b/projects/aca-playwright-shared/src/utils/index.ts @@ -26,3 +26,4 @@ export * from './paths'; export * from './timeouts'; export * from './exclude-tests'; export * from './state-helper'; +export * from './folder-errors';