diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 41ea55a67..329948a6d 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -146,6 +146,8 @@ jobs: id: 16 - name: "edit-actions" id: 17 + - name: "smoke-test" + id: 18 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/e2e/playwright/smoke-test/src/tests/login/login.e2e.ts b/e2e/playwright/smoke-test/src/tests/login/login.e2e.ts index 4f0e7ce1f..ca9cc61ff 100644 --- a/e2e/playwright/smoke-test/src/tests/login/login.e2e.ts +++ b/e2e/playwright/smoke-test/src/tests/login/login.e2e.ts @@ -28,13 +28,6 @@ import { ApiClientFactory, Utils, test } from '@alfresco/aca-playwright-shared'; test.describe('viewer file', () => { const apiClientFactory = new ApiClientFactory(); - const otherLanguageUser = { - /* cspell:disable-next-line */ - username: `пользвате${Utils.random()}`, - /* cspell:disable-next-line */ - password: '密碼中國' - }; - const johnDoe = { username: `user-${Utils.random()}`, get password() { @@ -46,26 +39,15 @@ test.describe('viewer file', () => { test.beforeAll(async () => { await apiClientFactory.setUpAcaBackend('admin'); - - await apiClientFactory.createUser(otherLanguageUser); await apiClientFactory.createUser(johnDoe); }); - test.describe('with invalid credentials', () => { - test('[C213106] unauthenticated user is redirected to Login page', async ({ personalFiles }) => { - await personalFiles.navigate(); - expect(personalFiles.page.url()).toContain('login'); - }); - }); - - test.describe('with valid credentials', () => { - test('[C213107] redirects to Home Page when navigating to the Login page while already logged in', async ({ loginPage }) => { + test.describe('with authenticated credentials', () => { + test('[XAT-17731] Authenticated user is able to login', async ({ loginPage }) => { const { username } = johnDoe; await loginPage.navigate(); await loginPage.loginUser({ username: username, password: username }); await loginPage.userProfileButton.waitFor({ state: 'attached' }); - await loginPage.navigate(); - await loginPage.userProfileButton.waitFor({ state: 'attached' }); expect(loginPage.page.url()).toContain('personal-files'); }); }); diff --git a/e2e/playwright/smoke-test/src/tests/search/personal-files.ts b/e2e/playwright/smoke-test/src/tests/search/personal-files.ts index 3d3564599..953a7e0aa 100644 --- a/e2e/playwright/smoke-test/src/tests/search/personal-files.ts +++ b/e2e/playwright/smoke-test/src/tests/search/personal-files.ts @@ -35,46 +35,7 @@ export function personalFilesTests(userName: string, parentName: string) { await page.waitForTimeout(timeouts.tiny); }); - test('[C280077] Pagination control default values', async ({ personalFiles }) => { - expect(await personalFiles.pagination.getRange()).toContain('Showing 1-25 of 51'); - expect(await personalFiles.pagination.getMaxItems()).toContain('25'); - expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 1'); - expect(await personalFiles.pagination.getTotalPages()).toContain('of 3'); - expect(await personalFiles.pagination.isPreviousEnabled()).toBe(false); - expect(await personalFiles.pagination.isNextEnabled()).toBe(true); - }); - - test('[C280079] current page menu items', async ({ personalFiles }) => { - await personalFiles.pagination.openMaxItemsMenu(); - expect(await personalFiles.pagination.getItemsCount()).toBe(3); - await personalFiles.pagination.clickMenuItem('25'); - await personalFiles.dataTable.spinnerWaitForReload(); - expect(await personalFiles.pagination.getMaxItems()).toContain('25'); - expect(await personalFiles.pagination.getTotalPages()).toContain('of 3'); - - await personalFiles.pagination.openMaxItemsMenu(); - await personalFiles.pagination.clickMenuItem('50'); - expect(await personalFiles.pagination.getMaxItems()).toContain('50'); - expect(await personalFiles.pagination.getTotalPages()).toContain('of 2'); - - await personalFiles.pagination.openMaxItemsMenu(); - await personalFiles.pagination.clickMenuItem('100'); - expect(await personalFiles.pagination.getMaxItems()).toContain('100'); - expect(await personalFiles.pagination.getTotalPages()).toContain('of 1'); - - await personalFiles.pagination.resetToDefaultPageSize(); - }); - - test('[C280080] change the current page from menu', async ({ personalFiles }) => { - await personalFiles.pagination.clickOnNextPage(); - expect(await personalFiles.pagination.getRange()).toContain('Showing 26-50 of 51'); - expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 2'); - expect(await personalFiles.pagination.isPreviousEnabled()).toBe(true); - expect(await personalFiles.pagination.isNextEnabled()).toBe(true); - await personalFiles.pagination.resetToDefaultPageSize(); - }); - - test('[C280083] navigate to next and previous pages', async ({ personalFiles }) => { + test('[XAT-17733] Pagination control navigate to next and previous pages', async ({ personalFiles }) => { await personalFiles.pagination.openMaxItemsMenu(); await personalFiles.pagination.clickMenuItem('25'); expect(await personalFiles.pagination.getMaxItems()).toContain('25'); @@ -85,17 +46,5 @@ export function personalFilesTests(userName: string, parentName: string) { await personalFiles.dataTable.spinnerWaitForReload(); expect(await personalFiles.pagination.getRange()).toContain('Showing 1-25 of 51'); }); - - test('[C280081] Previous button is disabled on first page', async ({ personalFiles }) => { - expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 1'); - expect(await personalFiles.pagination.isPreviousEnabled()).toBe(false); - }); - - test('[C280082] Next button is disabled on last page', async ({ personalFiles }) => { - await personalFiles.pagination.openMaxItemsMenu(); - await personalFiles.pagination.clickNthItem(3); - expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 1'); - expect(await personalFiles.pagination.isNextEnabled()).toBe(false); - }); }); } diff --git a/e2e/playwright/smoke-test/src/tests/search/search-results-general.e2e.ts b/e2e/playwright/smoke-test/src/tests/search/search-results-general.e2e.ts index a9d5055c0..7ddb48234 100644 --- a/e2e/playwright/smoke-test/src/tests/search/search-results-general.e2e.ts +++ b/e2e/playwright/smoke-test/src/tests/search/search-results-general.e2e.ts @@ -60,23 +60,7 @@ test.describe('Search Results - General', () => { await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', sitesApi, [site]); }); - test('[C290005] Only files are returned when Files option is the only one checked', async ({ searchPage }) => { - await searchPage.searchWithin(`*${random}`, 'files'); - - expect(await searchPage.dataTable.isItemPresent(file)).toBeTruthy(); - expect(await searchPage.dataTable.isItemPresent(folder)).toBeFalsy(); - expect(await searchPage.dataTable.isItemPresent(site)).toBeFalsy(); - }); - - test('[C290006] Only folders are returned when Folders option is the only one checked', async ({ searchPage }) => { - await searchPage.searchWithin(`*${random}`, 'folders'); - - expect(await searchPage.dataTable.isItemPresent(file)).toBeFalsy(); - expect(await searchPage.dataTable.isItemPresent(folder)).toBeTruthy(); - expect(await searchPage.dataTable.isItemPresent(site)).toBeFalsy(); - }); - - test('[C290007] Files and folders are returned when both Files and Folders options are checked', async ({ searchPage }) => { + test('[XAT-17734] Search with Folders options are checked', async ({ searchPage }) => { await searchPage.searchWithin(`*${random}`, 'filesAndFolders'); expect(await searchPage.dataTable.isItemPresent(file)).toBeTruthy(); @@ -84,29 +68,7 @@ test.describe('Search Results - General', () => { expect(await searchPage.dataTable.isItemPresent(site)).toBeFalsy(); }); - test('[C290008] Only libraries are returned when Libraries option is checked', async ({ searchPage }) => { - await searchPage.searchWithin(`*${random}`, 'libraries'); - - expect(await searchPage.dataTable.isItemPresent(file)).toBeFalsy(); - expect(await searchPage.dataTable.isItemPresent(folder)).toBeFalsy(); - expect(await searchPage.dataTable.isItemPresent(site)).toBeTruthy(); - }); - - test('[C279162] Results are updated automatically when changing the search term', async ({ searchPage }) => { - await searchPage.searchWithin(file, 'filesAndFolders'); - - expect(await searchPage.dataTable.isItemPresent(file)).toBeTruthy(); - expect(await searchPage.dataTable.isItemPresent(folder)).toBeFalsy(); - - await searchPage.clickSearchButton(); - await searchPage.searchOverlay.searchFor(folder); - await searchPage.dataTable.progressBarWaitForReload(); - - expect(await searchPage.dataTable.isItemPresent(file)).toBeFalsy(); - expect(await searchPage.dataTable.isItemPresent(folder)).toBeTruthy(); - }); - - test('[C279178] Results are returned when accessing an URL containing a search query', async ({ searchPage, personalFiles }) => { + test('[XAT-17735] Search with an URL containing a search query', async ({ searchPage, personalFiles }) => { await searchPage.searchWithin(site, 'libraries'); expect(await searchPage.dataTable.isItemPresent(site)).toBeTruthy(); diff --git a/e2e/playwright/smoke-test/src/tests/search/sort-list.e2e.ts b/e2e/playwright/smoke-test/src/tests/search/sort-list.e2e.ts deleted file mode 100644 index d50218d3f..000000000 --- a/e2e/playwright/smoke-test/src/tests/search/sort-list.e2e.ts +++ /dev/null @@ -1,203 +0,0 @@ -/*! - * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * Alfresco Example Content Application - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * from Hyland Software. If not, see . - */ - -import { expect } from '@playwright/test'; -import { - ApiClientFactory, - FavoritesPageApi, - FileActionsApi, - NodesApi, - PersonalFilesPage, - TEST_FILES, - Utils, - test, - timeouts -} from '@alfresco/aca-playwright-shared'; - -async function getSortState(myPersonalFiles: PersonalFilesPage): Promise<{ [key: string]: string }> { - return { - sortingColumn: await myPersonalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await myPersonalFiles.dataTable.getSortingOrder(), - firstElement: await myPersonalFiles.dataTable.getFirstElementDetail('Name') - }; -} - -test.describe('Remember sorting', () => { - const user1 = `userSort1-${Utils.random()}`; - const pdfFileNames = [...new Array(14).fill(100)].map((v, i) => `file-${v + i}.pdf`); - const jpgFileNames = [...new Array(12).fill(114)].map((v, i) => `file-${v + i}.jpg`); - const folderToMove = `folder1`; - const folderToContain = `folder2`; - const uiCreatedFolder = `folder3`; - - const testData = { - user1: { - files: { - jpg: jpgFileNames, - pdf: pdfFileNames - } - } - }; - - let initialSortState: { [key: string]: string }; - let nodeActionUser1: NodesApi; - - test.beforeAll(async () => { - try { - test.setTimeout(timeouts.extendedTest); - const apiClientFactory = new ApiClientFactory(); - await apiClientFactory.setUpAcaBackend('admin'); - await apiClientFactory.createUser({ username: user1 }); - const fileActionUser1 = await FileActionsApi.initialize(user1, user1); - const favoritesActions = await FavoritesPageApi.initialize(user1, user1); - nodeActionUser1 = await NodesApi.initialize(user1, user1); - const filesIdsUser1: { [key: string]: string } = {}; - await Promise.all( - testData.user1.files.pdf.map( - async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.PDF.path, i, '-my-')).entry.id) - ) - ); - await Promise.all( - testData.user1.files.jpg.map( - async (i) => (filesIdsUser1[i] = (await fileActionUser1.uploadFileWithRename(TEST_FILES.JPG_FILE.path, i, '-my-')).entry.id) - ) - ); - await favoritesActions.addFavoritesByIds('file', [filesIdsUser1[pdfFileNames[0]], filesIdsUser1[pdfFileNames[1]]]); - } catch (error) { - console.error(`beforeAll failed : ${error}`); - } - }); - - test.beforeEach(async ({ loginPage, personalFiles }) => { - await NodesApi.initialize(user1, user1); - await loginPage.loginUser( - { username: user1, password: user1 }, - { - withNavigation: true, - waitForLoading: true - } - ); - await personalFiles.dataTable.sortBy('Name', 'asc'); - await personalFiles.dataTable.spinnerWaitForReload(); - initialSortState = await getSortState(personalFiles); - }); - - test.afterAll(async () => { - nodeActionUser1 = await NodesApi.initialize(user1, user1); - await nodeActionUser1.deleteCurrentUserNodes(); - }); - - test('[C261136] Sort order is retained when navigating to another part of the app', async ({ personalFiles, favoritePage }) => { - await personalFiles.dataTable.sortBy('Name', 'desc'); - await personalFiles.dataTable.spinnerWaitForReload(); - - const expectedSortData = await getSortState(personalFiles); - expect(expectedSortData).not.toEqual(initialSortState); - - await favoritePage.navigate(); - await personalFiles.navigate(); - - const actualSortData = await getSortState(personalFiles); - expect(actualSortData).toEqual(expectedSortData); - }); - - test('[C589205] Size sort order is retained after viewing a file and closing the viewer', async ({ personalFiles }) => { - await personalFiles.dataTable.sortBy('Size', 'desc'); - await personalFiles.dataTable.spinnerWaitForReload(); - const expectedSortData = await getSortState(personalFiles); - - await personalFiles.dataTable.performClickFolderOrFileToOpen(expectedSortData.firstElement); - await personalFiles.viewer.closeButtonLocator.click(); - await personalFiles.waitForPageLoad(); - - const actualSortData = await getSortState(personalFiles); - expect(actualSortData).toEqual(expectedSortData); - }); - - test('[C261147] Sort order is retained when user changes the page from pagination', async ({ personalFiles }) => { - const lastFileInArray = testData.user1.files.jpg.slice(-2).pop(); - const firstFileInArray = testData.user1.files.pdf[0]; - - await personalFiles.pagination.clickOnNextPage(); - await personalFiles.dataTable.spinnerWaitForReload(); - - let expectedPersonalFilesSortDataPage2 = { - sortingColumn: 'Name', - sortingOrder: 'asc', - firstElement: lastFileInArray - }; - - let currentPersonalFilesSortDataPage2 = await getSortState(personalFiles); - expect(currentPersonalFilesSortDataPage2).toEqual(expectedPersonalFilesSortDataPage2); - - await personalFiles.dataTable.sortBy('Name', 'desc'); - await personalFiles.dataTable.spinnerWaitForReload(); - expectedPersonalFilesSortDataPage2 = { - sortingColumn: 'Name', - sortingOrder: 'desc', - firstElement: firstFileInArray - }; - - currentPersonalFilesSortDataPage2 = await getSortState(personalFiles); - expect(expectedPersonalFilesSortDataPage2).toEqual(currentPersonalFilesSortDataPage2); - }); - - test.describe('Folder actions', () => { - test.beforeAll(async () => { - const folderIds: { [key: string]: string } = {}; - folderIds[folderToContain] = (await nodeActionUser1.createFolder(folderToContain)).entry.id; - folderIds[folderToMove] = (await nodeActionUser1.createFolder(folderToMove)).entry.id; - }); - - test('[C261138] Sort order is retained when creating a new folder', async ({ personalFiles }) => { - await personalFiles.dataTable.sortBy('Name', 'desc'); - await personalFiles.dataTable.spinnerWaitForReload(); - - const expectedSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: uiCreatedFolder - }; - - await personalFiles.selectCreateFolder(); - await personalFiles.folderDialog.createNewFolderDialog(uiCreatedFolder); - await personalFiles.dataTable.isItemPresent(uiCreatedFolder); - - const actualSortData = await getSortState(personalFiles); - expect(actualSortData).toEqual(expectedSortData); - }); - - test('[C261139] Sort order is retained when moving a file', async ({ personalFiles }) => { - const expectedSortData = { - sortingColumn: await personalFiles.dataTable.getSortedColumnHeaderText(), - sortingOrder: await personalFiles.dataTable.getSortingOrder(), - firstElement: folderToContain - }; - await personalFiles.copyOrMoveContentInDatatable([folderToMove], folderToContain, 'Move'); - await personalFiles.dataTable.spinnerWaitForReload(); - const actualSortData = await getSortState(personalFiles); - expect(actualSortData).toEqual(expectedSortData); - }); - }); -}); diff --git a/e2e/playwright/smoke-test/src/tests/viewer/viewer.e2e.ts b/e2e/playwright/smoke-test/src/tests/viewer/viewer.e2e.ts index be1400a78..c19a4ef5d 100644 --- a/e2e/playwright/smoke-test/src/tests/viewer/viewer.e2e.ts +++ b/e2e/playwright/smoke-test/src/tests/viewer/viewer.e2e.ts @@ -37,11 +37,9 @@ import { import { Site } from '@alfresco/js-api'; test.describe('viewer file', () => { - const username = `user-${Utils.random()}`; + const usernameViewer = `user-${Utils.random()}`; const randomDocxName = `${TEST_FILES.DOCX.name}-${Utils.random()}`; const siteAdmin = `siteAdmin-${Utils.random()}`; - const fileAdmin = TEST_FILES.XLSX.name; - let fileAdminId: string; let docLibId: string; let folderId: string; let fileDocxId: string; @@ -50,22 +48,21 @@ test.describe('viewer file', () => { let siteActionsAdmin: SitesApi; test.beforeAll(async () => { - test.setTimeout(timeouts.extendedTest); + test.setTimeout(timeouts.globalTest); const randomFolderName = `viewer-${Utils.random()}`; const apiClientFactory = new ApiClientFactory(); await apiClientFactory.setUpAcaBackend('admin'); try { - await apiClientFactory.createUser({ username }); + await apiClientFactory.createUser({ username: usernameViewer }); } catch (exception) { if (JSON.parse(exception.message).error.statusCode !== 409) { throw new Error(`----- beforeAll failed : ${exception}`); } } - nodesApi = await NodesApi.initialize(username, username); - const fileActionApi = await FileActionsApi.initialize(username, username); - trashcanApi = await TrashcanApi.initialize(username, username); + nodesApi = await NodesApi.initialize(usernameViewer, usernameViewer); + const fileActionApi = await FileActionsApi.initialize(usernameViewer, usernameViewer); + trashcanApi = await TrashcanApi.initialize(usernameViewer, usernameViewer); siteActionsAdmin = await SitesApi.initialize('admin'); - const fileActionApiAdmin = await FileActionsApi.initialize('admin'); const node = await nodesApi.createFolder(randomFolderName); folderId = node.entry.id; const fileDoc = await fileActionApi.uploadFile(TEST_FILES.DOCX.path, randomDocxName, folderId); @@ -81,19 +78,11 @@ test.describe('viewer file', () => { docLibId = await siteActionsAdmin.getDocLibId(siteAdmin); - try { - fileAdminId = (await fileActionApiAdmin.uploadFile(TEST_FILES.DOCX.path, fileAdmin, docLibId)).entry.id; - } catch (exception) { - if (JSON.parse(exception.message).error.statusCode !== 409) { - throw new Error(`----- beforeAll failed : ${exception}`); - } - } - await fileActionApi.waitForNodes(randomDocxName, { expect: 1 }); }); test.beforeEach(async ({ personalFiles, loginPage }) => { - await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed'); + await Utils.tryLoginUser(loginPage, usernameViewer, usernameViewer, 'beforeEach failed'); await personalFiles.navigate({ remoteUrl: `#/personal-files/${folderId}` }); }); @@ -102,22 +91,14 @@ test.describe('viewer file', () => { await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', siteActionsAdmin, [docLibId]); }); - test('[C279270] Viewer opens when clicking the View action for a file', async ({ personalFiles }) => { + test('[XAT-17736] Open viewer with click action', async ({ personalFiles }) => { await personalFiles.dataTable.getRowByName(randomDocxName).click(); await personalFiles.acaHeader.viewButton.click(); await personalFiles.dataTable.spinnerWaitForReload(); expect(await personalFiles.viewer.isViewerOpened(), 'Viewer is not opened').toBe(true); }); - test('[C279283] The viewer general elements are displayed', async ({ personalFiles }) => { - await personalFiles.dataTable.performClickFolderOrFileToOpen(randomDocxName); - expect(await personalFiles.viewer.isViewerOpened()).toBe(true); - await personalFiles.dataTable.spinnerWaitForReload(); - expect(await personalFiles.viewer.isCloseButtonDisplayed(), 'Close button is not displayed').toBe(true); - expect(await personalFiles.viewer.isFileTitleDisplayed(), 'File title is not displayed').toBe(true); - }); - - test('[C279271] Close the viewer', async ({ personalFiles }) => { + test('[XAT-17737] Check action for viewer to close', async ({ personalFiles }) => { await personalFiles.dataTable.performClickFolderOrFileToOpen(randomDocxName); expect(await personalFiles.viewer.isViewerOpened(), 'Viewer is not opened').toBe(true); expect(await personalFiles.viewer.getCloseButtonTooltip()).toEqual('Close'); @@ -125,17 +106,11 @@ test.describe('viewer file', () => { await expect(personalFiles.dataTable.getCellLinkByName(randomDocxName), 'Viewer did not close').toBeVisible(); }); - test('[C279285] Viewer opens when accessing the preview URL for a file', async ({ personalFiles }) => { + test('[XAT-17738] Viewer with preview URL', async ({ personalFiles }) => { const previewURL = `#/personal-files/${folderId}/(viewer:view/${fileDocxId})`; await personalFiles.navigate({ remoteUrl: previewURL }); await personalFiles.dataTable.spinnerWaitForReload(); expect(await personalFiles.viewer.isViewerOpened(), 'Viewer is not opened').toBe(true); await expect(personalFiles.viewer.fileTitleButtonLocator).toHaveText(randomDocxName); }); - - test('[C279287] Viewer does not open when accessing the preview URL for a file without permissions', async ({ personalFiles }) => { - const previewURL = `#/libraries/${docLibId}/(viewer:view/${fileAdminId})`; - await personalFiles.navigate({ remoteUrl: `${previewURL}` }); - await expect(personalFiles.viewer.viewerLocator, 'Viewer should not be opened!').toBeHidden(); - }); });