From 335c5ba85c367d662c3c99e436cb781c665716b6 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Wed, 20 Sep 2023 11:43:58 +0200 Subject: [PATCH 1/5] [ACS-5923] sidenav and singleclick test --- .../src/tests/breadcrumb-admin.spec.ts | 57 ++++++++ .../navigation/src/tests/sidebar.spec.ts | 125 ++++++++++++++++++ .../navigation/src/tests/single-click.spec.ts | 98 ++++++++++++++ .../breadcrumb/breadcrumb.component.ts | 3 +- .../dataTable/data-table.component.ts | 2 + .../src/page-objects/components/index.ts | 1 + .../search/search-input.component.ts | 4 +- .../components/sidenav.component.ts | 98 ++++++++++++++ .../pages/favorites-libraries.page.ts | 45 +++++++ .../src/page-objects/pages/favorites.page.ts | 3 +- .../src/page-objects/pages/index.ts | 1 + .../page-objects/pages/my-libraries.page.ts | 4 +- .../page-objects/pages/personal-files.page.ts | 3 +- .../page-objects/pages/recent-files.page.ts | 4 +- .../src/page-objects/pages/search.page.ts | 3 +- .../src/page-objects/pages/shared.page.ts | 3 +- .../src/page-objects/pages/trash.page.ts | 3 +- .../aca-playwright-shared/src/utils/config.ts | 45 +++++++ .../aca-playwright-shared/src/utils/index.ts | 1 + 19 files changed, 492 insertions(+), 11 deletions(-) create mode 100644 e2e/playwright/navigation/src/tests/breadcrumb-admin.spec.ts create mode 100644 e2e/playwright/navigation/src/tests/sidebar.spec.ts create mode 100644 e2e/playwright/navigation/src/tests/single-click.spec.ts create mode 100644 projects/aca-playwright-shared/src/page-objects/components/sidenav.component.ts create mode 100644 projects/aca-playwright-shared/src/page-objects/pages/favorites-libraries.page.ts create mode 100644 projects/aca-playwright-shared/src/utils/config.ts diff --git a/e2e/playwright/navigation/src/tests/breadcrumb-admin.spec.ts b/e2e/playwright/navigation/src/tests/breadcrumb-admin.spec.ts new file mode 100644 index 0000000000..704ccda9d8 --- /dev/null +++ b/e2e/playwright/navigation/src/tests/breadcrumb-admin.spec.ts @@ -0,0 +1,57 @@ +/*! + * 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 . + */ + +import { expect } from '@playwright/test'; +import { ApiClientFactory, getUserState, NodesApi, test, Utils } from '@alfresco/playwright-shared'; + +test.use({ storageState: getUserState('admin') }); +test.describe('as admin', () => { + const apiClientFactory = new ApiClientFactory(); + const userFolder = `userFolder-${Utils.random()}`; + const username = `userAdmin-${Utils.random()}`; + let userFolderId: string; + let nodesApi: NodesApi; + + test.beforeAll(async () => { + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username }); + nodesApi = await NodesApi.initialize(username, username); + const node = await nodesApi.createFolder(userFolder); + userFolderId = node.entry.id; + }); + + test.beforeEach(async ({ personalFiles }) => { + await personalFiles.navigate({ remoteUrl: `#/personal-files}` }); + }); + + test.afterAll(async () => { + await apiClientFactory.nodes.deleteNode(userFolderId, { permanent: true }); + }); + + test(`[C260970] Breadcrumb on navigation to a user's home`, async ({ personalFiles }) => { + await personalFiles.navigate({ remoteUrl: `#/personal-files/${userFolderId}` }); + personalFiles.breadcrumb.getItemByTitle(username).waitFor({ state: 'attached' }); + expect(await personalFiles.breadcrumb.getAllItems()).toEqual(['Personal Files', 'User Homes', username, userFolder]); + }); +}); diff --git a/e2e/playwright/navigation/src/tests/sidebar.spec.ts b/e2e/playwright/navigation/src/tests/sidebar.spec.ts new file mode 100644 index 0000000000..846d938975 --- /dev/null +++ b/e2e/playwright/navigation/src/tests/sidebar.spec.ts @@ -0,0 +1,125 @@ +/*! + * 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 . + */ + +import { expect } from '@playwright/test'; +import { ApiClientFactory, APP_ROUTES, getUserState, SIDEBAR_LABELS, test } from '@alfresco/playwright-shared'; + +test.use({ storageState: getUserState('hruser') }); +test.describe('Sidebar', () => { + const apiClientFactory = new ApiClientFactory(); + + test.beforeAll(async () => { + await apiClientFactory.setUpAcaBackend('hruser'); + }); + + test('[C289902] navigate to Favorite Libraries', async ({ personalFiles, favoritePage }) => { + await personalFiles.navigate(); + await personalFiles.sidenav.openPanel('Favorite Libraries'); + await personalFiles.dataTable.spinnerWaitForReload(); + expect(favoritePage.page.url()).toContain(APP_ROUTES.FAVORITE_LIBRARIES); + expect(await favoritePage.sidenav.isActive(SIDEBAR_LABELS.FAVORITE_LIBRARIES), 'Favorite Libraries link not active').toBe(true); + }); + + test('[C289901] navigate to My Libraries', async ({ personalFiles, myLibrariesPage }) => { + await personalFiles.navigate(); + await personalFiles.sidenav.openPanel('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('[C213110] navigates to "Shared Files"', async ({ personalFiles, sharedPage }) => { + await personalFiles.navigate(); + await personalFiles.sidenav.openPanel('Shared'); + await personalFiles.dataTable.spinnerWaitForReload(); + expect(sharedPage.page.url()).toContain(APP_ROUTES.SHARED_FILES); + expect(await sharedPage.sidenav.isActive(SIDEBAR_LABELS.SHARED_FILES), 'Shared Files link not active').toBe(true); + }); + + test('[C213166] navigates to "Recent Files"', async ({ personalFiles, recentFilesPage }) => { + await personalFiles.navigate(); + await personalFiles.sidenav.openPanel('Recent Files'); + await personalFiles.dataTable.spinnerWaitForReload(); + expect(recentFilesPage.page.url()).toContain(APP_ROUTES.RECENT_FILES); + expect(await recentFilesPage.sidenav.isActive(SIDEBAR_LABELS.RECENT_FILES), 'Recent Files link not active').toBe(true); + }); + + test('[C213225] navigates to "Favorites"', async ({ personalFiles, favoritePage }) => { + await personalFiles.navigate(); + await personalFiles.sidenav.openPanel('Favorites'); + await personalFiles.dataTable.spinnerWaitForReload(); + expect(favoritePage.page.url()).toContain(APP_ROUTES.FAVORITES); + expect(await favoritePage.sidenav.isActive(SIDEBAR_LABELS.FAVORITES), 'Favorites link not active').toBe(true); + }); + + test('[C213216] navigates to "Trash"', async ({ personalFiles, trashPage }) => { + await personalFiles.navigate(); + await personalFiles.sidenav.openPanel('Trash'); + await personalFiles.dataTable.spinnerWaitForReload(); + expect(trashPage.page.url()).toContain(APP_ROUTES.TRASHCAN); + expect(await trashPage.sidenav.isActive(SIDEBAR_LABELS.TRASH), 'Trash link not active').toBe(true); + }); + + test('[C280409] navigates to "Personal Files"', async ({ personalFiles, trashPage }) => { + await trashPage.navigate(); + await personalFiles.sidenav.openPanel('Personal Files'); + await personalFiles.dataTable.spinnerWaitForReload(); + expect(personalFiles.page.url()).toContain(APP_ROUTES.PERSONAL_FILES); + expect(await personalFiles.sidenav.isActive(SIDEBAR_LABELS.PERSONAL_FILES), 'Personal Files link not active').toBe(true); + }); + + test('[C277230] sidenav can be expanded when search results page is displayed', async ({ personalFiles }) => { + await personalFiles.navigate({ remoteUrl: `#/search;q=test` }); + expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar expanded').toBe(false); + await personalFiles.sidenav.expandSideNav(); + expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar not expanded').toBe(true); + }); + + test('[C269100] sidebar state is preserved on page refresh', async ({ personalFiles }) => { + await personalFiles.navigate(); + expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar expanded').toBe(true); + await personalFiles.reload(); + expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar expanded').toBe(true); + + await personalFiles.sidenav.collapseSideNav(); + + expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar not expanded').toBe(false); + await personalFiles.reload(); + expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar not expanded').toBe(false); + }); + + test('[C269096] sidebar toggle', async ({ personalFiles }) => { + await personalFiles.navigate(); + await personalFiles.sidenav.collapseSideNav(); + expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar not expanded').toBe(false); + await personalFiles.sidenav.expandSideNav(); + expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar not expanded').toBe(true); + }); + + test('[C277224] 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.searchInput.getIconByName('close').click(); + expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar not expanded').toBe(true); + }); +}); diff --git a/e2e/playwright/navigation/src/tests/single-click.spec.ts b/e2e/playwright/navigation/src/tests/single-click.spec.ts new file mode 100644 index 0000000000..5b3505bc49 --- /dev/null +++ b/e2e/playwright/navigation/src/tests/single-click.spec.ts @@ -0,0 +1,98 @@ +/*! + * 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 . + */ + +import { expect } from '@playwright/test'; +import { ApiClientFactory, getUserState, test, Utils } from '@alfresco/playwright-shared'; + +test.use({ storageState: getUserState('hruser') }); +test.describe('Single click on item name', () => { + const apiClientFactory = new ApiClientFactory(); + + const folder1 = `folder1-${Utils.random()}`; + let folder1Id: string; + const folderSearch = `folder1-${Utils.random()}`; + let folderSearchId: string; + + const deletedFile1 = `file1-${Utils.random()}.txt`; + let deletedFile1Id: string; + const deletedFolder1 = `folder1-${Utils.random()}`; + let deletedFolder1Id: string; + + const siteName = `site-${Utils.random()}`; + const fileSite = `fileSite-${Utils.random()}.txt`; + + test.beforeAll(async ({ nodesApiAction, sitesApiAction }) => { + await apiClientFactory.setUpAcaBackend('hruser'); + const node = await apiClientFactory.nodes.createNode('-my-', { name: folder1, nodeType: 'cm:folder', relativePath: '/' }); + folder1Id = node.entry.id; + folderSearchId = (await nodesApiAction.createFolder(folderSearch)).entry.id; + deletedFile1Id = (await nodesApiAction.createFile(deletedFile1)).entry.id; + deletedFolder1Id = (await nodesApiAction.createFolder(deletedFolder1)).entry.id; + + await sitesApiAction.createSite(siteName); + const docLibId = await sitesApiAction.getDocLibId(siteName); + await nodesApiAction.createFile(fileSite, docLibId); + }); + + test.afterAll(async ({ nodesApiAction }) => { + await nodesApiAction.deleteNodes([deletedFolder1Id, deletedFile1Id], true); + }); + + test('[C284899] Hyperlink does not appear for items in the Trash', async ({ trashPage }) => { + await trashPage.navigate(); + expect(await trashPage.dataTable.getCellLinkByName(deletedFile1).isVisible(), 'Link on name is present').toBe(false); + expect(await trashPage.dataTable.getCellLinkByName(deletedFolder1).isVisible(), 'Link on name is present').toBe(false); + }); + + test.describe('on Personal Files', () => { + test.afterAll(async ({ nodesApiAction }) => { + await nodesApiAction.deleteNodes([folder1Id, folderSearchId], true); + }); + + test('[C280034] Navigate inside the folder when clicking the hyperlink on Personal Files', async ({ personalFiles }) => { + await personalFiles.navigate(); + await personalFiles.dataTable.getCellLinkByName(folder1).click(); + await personalFiles.dataTable.spinnerWaitForReload(); + expect(await personalFiles.breadcrumb.currentItem.innerText()).toBe(folder1); + }); + + test('[C306990] Navigate inside the folder when clicking the hyperlink on Search Results', async ({ personalFiles }) => { + await personalFiles.navigate({ remoteUrl: `#/search;q=${folderSearch}` }); + await personalFiles.reload(); + await personalFiles.dataTable.spinnerWaitForReload(); + await personalFiles.dataTable.getSearchResultLinkByName(folderSearch).click(); + await personalFiles.dataTable.spinnerWaitForReload(); + expect(await personalFiles.breadcrumb.currentItem.innerText()).toBe(folderSearch); + }); + }); + + test('[C284902] Navigate inside the library when clicking the hyperlink on File Libraries', async ({ myLibrariesPage }) => { + await myLibrariesPage.navigate(); + await myLibrariesPage.dataTable.goThroughPagesLookingForRowWithName(siteName); + await myLibrariesPage.dataTable.getCellLinkByName(siteName).click(); + await myLibrariesPage.dataTable.spinnerWaitForReload(); + expect(await myLibrariesPage.breadcrumb.currentItem.innerText()).toBe(siteName); + expect(await myLibrariesPage.dataTable.getCellLinkByName(fileSite).isVisible(), `${fileSite} not displayed`).toBe(true); + }); +}); diff --git a/projects/aca-playwright-shared/src/page-objects/components/breadcrumb/breadcrumb.component.ts b/projects/aca-playwright-shared/src/page-objects/components/breadcrumb/breadcrumb.component.ts index 970cf984b4..4723cfadc8 100755 --- a/projects/aca-playwright-shared/src/page-objects/components/breadcrumb/breadcrumb.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/breadcrumb/breadcrumb.component.ts @@ -23,11 +23,12 @@ */ import { BaseComponent } from '.././base.component'; -import { Page } from '@playwright/test'; +import { Locator, Page } from '@playwright/test'; export class Breadcrumb extends BaseComponent { private static rootElement = 'adf-breadcrumb'; public items = this.getChild('.adf-breadcrumb-item'); public currentItem = this.getChild('.adf-breadcrumb-item-current'); + getItemByTitle = (name: string): Locator => this.getChild(`.adf-breadcrumb-item[title=${name}]`); constructor(page: Page) { super(page, Breadcrumb.rootElement); diff --git a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts index f32c908c81..eb66e89699 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/dataTable/data-table.component.ts @@ -113,6 +113,8 @@ export class DataTableComponent extends BaseComponent { getColumnHeaderByTitleLocator = (headerTitle: string): Locator => this.getChild('[role="columnheader"]', { hasText: headerTitle }); + getSearchResultLinkByName = (name: string): Locator => this.getChild('.aca-search-results-row span[role="link"]', { hasText: name }); + async sortBy(columnTitle: string, order: 'Ascending' | 'Descending'): Promise { const columnHeaderLocator = this.getColumnHeaderByTitleLocator(columnTitle); await this.spinnerWaitForReload(); diff --git a/projects/aca-playwright-shared/src/page-objects/components/index.ts b/projects/aca-playwright-shared/src/page-objects/components/index.ts index 5812c570dd..567c0403f3 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/index.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/index.ts @@ -36,3 +36,4 @@ export * from './viewer.component'; export * from './search/search-input.component'; export * from './search/search-overlay.components'; export * from './breadcrumb/breadcrumb.component'; +export * from './sidenav.component'; diff --git a/projects/aca-playwright-shared/src/page-objects/components/search/search-input.component.ts b/projects/aca-playwright-shared/src/page-objects/components/search/search-input.component.ts index 1f0d182ca5..78ca1fa60d 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/search/search-input.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/search/search-input.component.ts @@ -29,6 +29,7 @@ import { timeouts } from '../../../utils'; export class SearchInputComponent extends BaseComponent { private static rootElement = 'aca-page-layout'; public searchButton = this.getChild('aca-search-input .app-search-button'); + getIconByName = (name: string): Locator => this.getChild('.mat-icon[role="img"]', { hasText: name }); /** * Method used in cases where user have possibility to navigate "inside" the element (it's clickable and has link attribute). @@ -43,9 +44,8 @@ export class SearchInputComponent extends BaseComponent { } async performDoubleClickFolderOrFileToOpen(name: string): Promise { - await this.getCellLinkByName(name).waitFor({ state:'visible', timeout: timeouts.normal }); + await this.getCellLinkByName(name).waitFor({ state: 'visible', timeout: timeouts.normal }); await this.getCellLinkByName(name).dblclick(); await this.spinnerWaitForReload(); } - } diff --git a/projects/aca-playwright-shared/src/page-objects/components/sidenav.component.ts b/projects/aca-playwright-shared/src/page-objects/components/sidenav.component.ts new file mode 100644 index 0000000000..94cd7374d1 --- /dev/null +++ b/projects/aca-playwright-shared/src/page-objects/components/sidenav.component.ts @@ -0,0 +1,98 @@ +/*! + * 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 . + */ + +import { BaseComponent } from './base.component'; +import { Locator, Page } from '@playwright/test'; + +export class SidenavComponent extends BaseComponent { + private static rootElement = 'app-sidenav'; + + private personalFiles = this.getChild(`[data-automation-id='app.navbar.personalFiles']`); + private fileLibraries = this.getChild(`[data-automation-id='app.navbar.libraries.menu']`); + private myLibraries = this.getChild(`[data-automation-id='app.navbar.libraries.files']`); + private favoriteLibraries = this.getChild(`[data-automation-id='app.navbar.libraries.favorite']`); + private shared = this.getChild(`[data-automation-id='app.navbar.shared']`); + private recentFiles = this.getChild(`[data-automation-id='app.navbar.recentFiles']`); + private favorites = this.getChild(`[data-automation-id='app.navbar.favorites']`); + private trash = this.getChild(`[data-automation-id='app.navbar.trashcan']`); + private sidenavToggle = this.getChild(`.sidenav-header-title-logo`); + private sidenavExpand = this.page.getByTitle('Expand navigation menu'); + private expandedSidenav = this.page.locator(`[data-automation-id='expanded']`); + + constructor(page: Page) { + super(page, SidenavComponent.rootElement); + } + + async isActive(name: string): Promise { + const cssClass = await this.getLinkLabel(name).getAttribute('class'); + return cssClass.includes('action-button--active'); + } + + async openPanel(name: string): Promise { + await this.getLinkLabel(name).click(); + } + + private getLinkLabel(name: string): Locator { + switch (name) { + case 'Personal Files': + return this.personalFiles; + case 'File Libraries': + return this.fileLibraries; + case 'My Libraries': + return this.myLibraries; + case 'Favorite Libraries': + return this.favoriteLibraries; + case 'Shared': + return this.shared; + case 'Recent Files': + return this.recentFiles; + case 'Favorites': + return this.favorites; + case 'Trash': + return this.trash; + default: + return this.personalFiles; + } + } + + async isSidenavExpanded(): Promise { + return this.expandedSidenav.isVisible(); + } + + async expandSideNav(): Promise { + const expanded = await this.isSidenavExpanded(); + if (!expanded) { + await this.sidenavExpand.click(); + await this.expandedSidenav.waitFor({ state: 'attached' }); + } + } + + async collapseSideNav(): Promise { + const expanded = await this.isSidenavExpanded(); + if (expanded) { + await this.sidenavToggle.click(); + await this.expandedSidenav.waitFor({ state: 'detached' }); + } + } +} diff --git a/projects/aca-playwright-shared/src/page-objects/pages/favorites-libraries.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/favorites-libraries.page.ts new file mode 100644 index 0000000000..c6d57bb9ee --- /dev/null +++ b/projects/aca-playwright-shared/src/page-objects/pages/favorites-libraries.page.ts @@ -0,0 +1,45 @@ +/*! + * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Alfresco Example Content Application + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * from Hyland Software. If not, see . + */ + +import { Page } from '@playwright/test'; +import { BasePage } from './base.page'; +import { DataTableComponent, MatMenuComponent, SidenavComponent, ViewerComponent } from '../components'; +import { AcaHeader } from '../components/aca-header.component'; +import { AdfFolderDialogComponent, ViewerOverlayDialogComponent } from '../components/dialogs'; + +export class FavoritesLibrariesPage extends BasePage { + private static pageUrl = 'favorite/libraries'; + + constructor(page: Page) { + super(page, FavoritesLibrariesPage.pageUrl); + } + + public acaHeader = new AcaHeader(this.page); + public matMenu = new MatMenuComponent(this.page); + public folderDialog = new AdfFolderDialogComponent(this.page); + public dataTable = new DataTableComponent(this.page); + public viewer = new ViewerComponent(this.page); + public viewerDialog = new ViewerOverlayDialogComponent(this.page); + public sidenav = new SidenavComponent(this.page); +} diff --git a/projects/aca-playwright-shared/src/page-objects/pages/favorites.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/favorites.page.ts index 179aeed990..7b1ef705d8 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/favorites.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/favorites.page.ts @@ -24,7 +24,7 @@ import { Page } from '@playwright/test'; import { BasePage } from './base.page'; -import { DataTableComponent, MatMenuComponent, ViewerComponent } from '../components'; +import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent } from '../components'; import { AcaHeader } from '../components/aca-header.component'; import { AdfFolderDialogComponent, ViewerOverlayDialogComponent } from '../components/dialogs'; @@ -41,4 +41,5 @@ export class FavoritesPage extends BasePage { public dataTable = new DataTableComponent(this.page); public viewer = new ViewerComponent(this.page); public viewerDialog = new ViewerOverlayDialogComponent(this.page); + public sidenav = new SidenavComponent(this.page); } diff --git a/projects/aca-playwright-shared/src/page-objects/pages/index.ts b/projects/aca-playwright-shared/src/page-objects/pages/index.ts index fcee9ac8e6..d0cb866042 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/index.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/index.ts @@ -32,3 +32,4 @@ export * from './shared.page'; export * from './search.page'; export * from './favorites.page'; export * from './trash.page'; +export * from './favorites-libraries.page'; diff --git a/projects/aca-playwright-shared/src/page-objects/pages/my-libraries.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/my-libraries.page.ts index 747a8250ec..b051482080 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/my-libraries.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/my-libraries.page.ts @@ -33,7 +33,8 @@ import { ViewerComponent, ViewerOverlayDialogComponent, ContentNodeSelectorDialog, - Breadcrumb + Breadcrumb, + SidenavComponent } from '../components'; export class MyLibrariesPage extends BasePage { @@ -51,6 +52,7 @@ export class MyLibrariesPage extends BasePage { public viewerDialog = new ViewerOverlayDialogComponent(this.page); public copyMoveDialog = new ContentNodeSelectorDialog(this.page); public breadcrumb = new Breadcrumb(this.page); + public sidenav = new SidenavComponent(this.page); async selectCreateLibrary(): Promise { await this.acaHeader.createButton.click(); diff --git a/projects/aca-playwright-shared/src/page-objects/pages/personal-files.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/personal-files.page.ts index 46e3bb7982..9bae8882ba 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/personal-files.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/personal-files.page.ts @@ -24,7 +24,7 @@ import { Page } from '@playwright/test'; import { BasePage } from './base.page'; -import { Breadcrumb, DataTableComponent, MatMenuComponent, ViewerComponent } from '../components'; +import { Breadcrumb, DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent } from '../components'; import { AcaHeader } from '../components/aca-header.component'; import { AdfFolderDialogComponent, PasswordOverlayDialogComponent, ViewerOverlayDialogComponent } from '../components/dialogs'; @@ -43,6 +43,7 @@ export class PersonalFilesPage extends BasePage { public passwordDialog = new PasswordOverlayDialogComponent(this.page); public viewerDialog = new ViewerOverlayDialogComponent(this.page); public breadcrumb = new Breadcrumb(this.page); + public sidenav = new SidenavComponent(this.page); async selectCreateFolder(): Promise { await this.acaHeader.createButton.click(); diff --git a/projects/aca-playwright-shared/src/page-objects/pages/recent-files.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/recent-files.page.ts index e971c89213..2fedf41f6d 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/recent-files.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/recent-files.page.ts @@ -22,10 +22,9 @@ * from Hyland Software. If not, see . */ - import { Page } from '@playwright/test'; import { BasePage } from './base.page'; -import { DataTableComponent, MatMenuComponent, ViewerComponent } from '../components'; +import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent } from '../components'; import { AcaHeader } from '../components/aca-header.component'; import { AdfFolderDialogComponent } from '../components/dialogs'; @@ -41,4 +40,5 @@ export class RecentFilesPage extends BasePage { public folderDialog = new AdfFolderDialogComponent(this.page); public dataTable = new DataTableComponent(this.page); public viewer = new ViewerComponent(this.page); + public sidenav = new SidenavComponent(this.page); } diff --git a/projects/aca-playwright-shared/src/page-objects/pages/search.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/search.page.ts index b195a5b77c..1e72c1fcf6 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/search.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/search.page.ts @@ -24,7 +24,7 @@ import { Page } from '@playwright/test'; import { BasePage } from './base.page'; -import { DataTableComponent, MatMenuComponent, ViewerComponent, SearchInputComponent, SearchOverlayComponent } from '../components'; +import { DataTableComponent, MatMenuComponent, ViewerComponent, SearchInputComponent, SearchOverlayComponent, SidenavComponent } from '../components'; import { AcaHeader } from '../components/aca-header.component'; import { AdfFolderDialogComponent } from '../components/dialogs'; @@ -42,4 +42,5 @@ export class SearchPage extends BasePage { public viewer = new ViewerComponent(this.page); public searchInput = new SearchInputComponent(this.page); public searchOverlay = new SearchOverlayComponent(this.page); + public sidenav = new SidenavComponent(this.page); } diff --git a/projects/aca-playwright-shared/src/page-objects/pages/shared.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/shared.page.ts index 891f3336bf..88372b5e9b 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/shared.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/shared.page.ts @@ -24,7 +24,7 @@ import { Page } from '@playwright/test'; import { BasePage } from './base.page'; -import { DataTableComponent, MatMenuComponent, ViewerComponent } from '../components'; +import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent } from '../components'; import { AcaHeader } from '../components/aca-header.component'; import { AdfFolderDialogComponent, ViewerOverlayDialogComponent } from '../components/dialogs'; @@ -41,4 +41,5 @@ export class SharedPage extends BasePage { public dataTable = new DataTableComponent(this.page); public viewer = new ViewerComponent(this.page); public viewerDialog = new ViewerOverlayDialogComponent(this.page); + public sidenav = new SidenavComponent(this.page); } diff --git a/projects/aca-playwright-shared/src/page-objects/pages/trash.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/trash.page.ts index 5927404c46..b6a512a8de 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/trash.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/trash.page.ts @@ -24,7 +24,7 @@ import { Page } from '@playwright/test'; import { BasePage } from './base.page'; -import { DataTableComponent, MatMenuComponent, ViewerComponent } from '../components'; +import { DataTableComponent, MatMenuComponent, ViewerComponent, SidenavComponent } from '../components'; import { AcaHeader } from '../components/aca-header.component'; import { AdfFolderDialogComponent, ViewerOverlayDialogComponent } from '../components/dialogs'; @@ -41,4 +41,5 @@ export class TrashPage extends BasePage { public dataTable = new DataTableComponent(this.page); public viewer = new ViewerComponent(this.page); public viewerDialog = new ViewerOverlayDialogComponent(this.page); + public sidenav = new SidenavComponent(this.page); } diff --git a/projects/aca-playwright-shared/src/utils/config.ts b/projects/aca-playwright-shared/src/utils/config.ts new file mode 100644 index 0000000000..f85982bae7 --- /dev/null +++ b/projects/aca-playwright-shared/src/utils/config.ts @@ -0,0 +1,45 @@ +/*! + * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Alfresco Example Content Application + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +export const APP_ROUTES = { + FAVORITES: '/favorites', + MY_LIBRARIES: '/libraries', + FAVORITE_LIBRARIES: '/favorite/libraries', + LOGIN: '/login', + LOGOUT: '/logout', + PERSONAL_FILES: '/personal-files', + RECENT_FILES: '/recent-files', + SHARED_FILES: '/shared', + TRASHCAN: '/trashcan' +}; + +export const SIDEBAR_LABELS = { + PERSONAL_FILES: 'Personal Files', + MY_LIBRARIES: 'My Libraries', + FAVORITE_LIBRARIES: 'Favorite Libraries', + SHARED_FILES: 'Shared', + RECENT_FILES: 'Recent Files', + FAVORITES: 'Favorites', + TRASH: 'Trash' +}; diff --git a/projects/aca-playwright-shared/src/utils/index.ts b/projects/aca-playwright-shared/src/utils/index.ts index d6ac3086e5..0178ddfe69 100644 --- a/projects/aca-playwright-shared/src/utils/index.ts +++ b/projects/aca-playwright-shared/src/utils/index.ts @@ -29,3 +29,4 @@ export * from './state-helper'; export * from './folder-errors'; export * from './utils'; export * from './library-errors'; +export * from './config'; From c10fa499b29d637817650b85a86dcd764311b649 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Wed, 20 Sep 2023 12:24:33 +0200 Subject: [PATCH 2/5] remove protractor test and fix flaky test --- .../navigation/src/tests/sidebar.spec.ts | 1 + .../navigation/src/tests/single-click.spec.ts | 9 - .../suites/navigation/sidebar.test.ts | 193 ------------------ .../suites/navigation/single-click.test.ts | 90 -------- .../components/sidenav.component.ts | 2 +- 5 files changed, 2 insertions(+), 293 deletions(-) delete mode 100755 e2e/protractor/suites/navigation/sidebar.test.ts diff --git a/e2e/playwright/navigation/src/tests/sidebar.spec.ts b/e2e/playwright/navigation/src/tests/sidebar.spec.ts index 846d938975..d43d31c098 100644 --- a/e2e/playwright/navigation/src/tests/sidebar.spec.ts +++ b/e2e/playwright/navigation/src/tests/sidebar.spec.ts @@ -120,6 +120,7 @@ test.describe('Sidebar', () => { test('[C277224] 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.searchInput.getIconByName('close').click(); + await searchPage.sidenav.expandedSidenav.waitFor({ state: 'attached' }); expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar not expanded').toBe(true); }); }); diff --git a/e2e/playwright/navigation/src/tests/single-click.spec.ts b/e2e/playwright/navigation/src/tests/single-click.spec.ts index 5b3505bc49..6d48acc27c 100644 --- a/e2e/playwright/navigation/src/tests/single-click.spec.ts +++ b/e2e/playwright/navigation/src/tests/single-click.spec.ts @@ -76,15 +76,6 @@ test.describe('Single click on item name', () => { await personalFiles.dataTable.spinnerWaitForReload(); expect(await personalFiles.breadcrumb.currentItem.innerText()).toBe(folder1); }); - - test('[C306990] Navigate inside the folder when clicking the hyperlink on Search Results', async ({ personalFiles }) => { - await personalFiles.navigate({ remoteUrl: `#/search;q=${folderSearch}` }); - await personalFiles.reload(); - await personalFiles.dataTable.spinnerWaitForReload(); - await personalFiles.dataTable.getSearchResultLinkByName(folderSearch).click(); - await personalFiles.dataTable.spinnerWaitForReload(); - expect(await personalFiles.breadcrumb.currentItem.innerText()).toBe(folderSearch); - }); }); test('[C284902] Navigate inside the library when clicking the hyperlink on File Libraries', async ({ myLibrariesPage }) => { diff --git a/e2e/protractor/suites/navigation/sidebar.test.ts b/e2e/protractor/suites/navigation/sidebar.test.ts deleted file mode 100755 index 04b3475f87..0000000000 --- a/e2e/protractor/suites/navigation/sidebar.test.ts +++ /dev/null @@ -1,193 +0,0 @@ -/*! - * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * Alfresco Example Content Application - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * from Hyland Software. If not, see . - */ - -import { browser } from 'protractor'; -import { APP_ROUTES, SIDEBAR_LABELS, LoginPage, BrowsingPage, SearchResultsPage, Utils } from '@alfresco/aca-testing-shared'; - -describe('Sidebar', () => { - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { sidenav, toolbar } = page; - const searchResultsPage = new SearchResultsPage(); - const { searchInput } = searchResultsPage.pageLayoutHeader; - - beforeAll(async () => { - await loginPage.loginWithAdmin(); - }); - - beforeEach(async () => { - await Utils.pressEscape(); - await sidenav.expandSideNav(); - }); - - afterEach(async () => { - await Utils.pressEscape(); - await page.clickPersonalFiles(); - }); - - it('[C217149] has "Personal Files" as default', async () => { - expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); - expect(await sidenav.isActive(SIDEBAR_LABELS.PERSONAL_FILES)).toBe(true, 'Default active link'); - }); - - it('[C289902] navigate to Favorite Libraries', async () => { - await page.goToFavoriteLibraries(); - expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.FAVORITE_LIBRARIES); - expect(await sidenav.isActive(SIDEBAR_LABELS.FAVORITE_LIBRARIES)).toBe(true, 'Favorite Libraries link not active'); - }); - - it('[C289901] navigate to My Libraries', async () => { - await page.goToMyLibraries(); - expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.MY_LIBRARIES); - expect(await sidenav.isActive(SIDEBAR_LABELS.MY_LIBRARIES)).toBe(true, 'My Libraries link not active'); - }); - - it('[C213110] navigates to "Shared Files"', async () => { - await page.clickSharedFiles(); - expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.SHARED_FILES); - expect(await sidenav.isActive(SIDEBAR_LABELS.SHARED_FILES)).toBe(true, 'Shared Files link not active'); - }); - - it('[C213166] navigates to "Recent Files"', async () => { - await page.clickRecentFiles(); - expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.RECENT_FILES); - expect(await sidenav.isActive(SIDEBAR_LABELS.RECENT_FILES)).toBe(true, 'Recent Files link not active'); - }); - - it('[C213225] navigates to "Favorites"', async () => { - await page.clickFavorites(); - expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.FAVORITES); - expect(await sidenav.isActive(SIDEBAR_LABELS.FAVORITES)).toBe(true, 'Favorites link not active'); - }); - - it('[C213216] navigates to "Trash"', async () => { - await page.clickTrash(); - expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.TRASHCAN); - expect(await sidenav.isActive(SIDEBAR_LABELS.TRASH)).toBe(true, 'Trash link not active'); - }); - - it('[C280409] navigates to "Personal Files"', async () => { - await page.clickPersonalFiles(); - expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES); - expect(await sidenav.isActive(SIDEBAR_LABELS.PERSONAL_FILES)).toBe(true, 'Personal Files link not active'); - }); - - it('[C217151] Personal Files tooltip', async () => { - await page.clickPersonalFiles(); - expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.PERSONAL_FILES)).toContain('View your Personal Files'); - }); - - it('[C213111] Shared Files tooltip', async () => { - await page.clickSharedFiles(); - expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.SHARED_FILES)).toContain('View files that have been shared'); - }); - - it('[C213167] Recent Files tooltip', async () => { - await page.clickRecentFiles(); - expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.RECENT_FILES)).toContain('View files you recently edited'); - }); - - it('[C217153] Favorites tooltip', async () => { - await page.clickFavorites(); - expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.FAVORITES)).toContain('View your favorite files and folders'); - }); - - it('[C217154] Trash tooltip', async () => { - await page.clickTrash(); - expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.TRASH)).toContain('View deleted files in the trash'); - }); - - it('[C289916] My Libraries tooltip', async () => { - await page.goToMyLibraries(); - expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.MY_LIBRARIES)).toContain('Access my libraries'); - }); - - it('[C289917] Favorite Libraries tooltip', async () => { - await page.goToFavoriteLibraries(); - expect(await sidenav.getLinkTooltip(SIDEBAR_LABELS.FAVORITE_LIBRARIES)).toContain('Access my favorite libraries'); - }); - - it('[C269095] default state is expanded', async () => { - expect(await sidenav.isSidenavExpanded()).toBe(true, 'Sidebar not expanded'); - }); - - it('[C269096] sidebar toggle', async () => { - await sidenav.collapseSideNav(); - expect(await sidenav.isSidenavExpanded()).toBe(false, 'Sidebar not collapsed'); - - await sidenav.expandSideNav(); - expect(await sidenav.isSidenavExpanded()).toBe(true, 'Sidebar not expanded'); - }); - - it('[C269100] sidebar state is preserved on page refresh', async () => { - expect(await sidenav.isSidenavExpanded()).toBe(true, 'Sidebar not expanded'); - await page.refresh(); - expect(await sidenav.isSidenavExpanded()).toBe(true, 'Sidebar not expanded'); - - await sidenav.collapseSideNav(); - expect(await sidenav.isSidenavExpanded()).toBe(false, 'Sidebar not collapsed'); - await page.refresh(); - expect(await sidenav.isSidenavExpanded()).toBe(false, 'Sidebar not collapsed'); - }); - - it('[C269102] sidebar state is preserved after logout / login', async () => { - await sidenav.collapseSideNav(); - await page.signOut(); - await loginPage.loginWithAdmin(); - - expect(await sidenav.isSidenavExpanded()).toBe(false, 'Sidebar not collapsed'); - }); - - it('[C277223] sidebar is collapsed automatically when Search Results opens', async () => { - await toolbar.clickSearchIconButton(); - await searchInput.clickSearchButton(); - /* cspell:disable-next-line */ - await searchInput.searchFor('qwertyuiop'); - await searchResultsPage.waitForResults(); - - expect(await sidenav.isSidenavExpanded()).toBe(false, 'Sidebar not collapsed'); - }); - - it('[C277224] sidenav returns to the default state when navigating away from the Search Results page', async () => { - await toolbar.clickSearchIconButton(); - await searchInput.clickSearchButton(); - /* cspell:disable-next-line */ - await searchInput.searchFor('qwertyuiop'); - await searchResultsPage.waitForResults(); - await page.clickFavorites(); - - expect(await sidenav.isSidenavExpanded()).toBe(true, 'Sidebar not expanded'); - }); - - it('[C277230] sidenav can be expanded when search results page is displayed', async () => { - await toolbar.clickSearchIconButton(); - await searchInput.clickSearchButton(); - /* cspell:disable-next-line */ - await searchInput.searchFor('qwertyuiop'); - await searchResultsPage.waitForResults(); - await sidenav.expandSideNav(); - - expect(await sidenav.isSidenavExpanded()).toBe(true, 'Sidebar not expanded'); - }); -}); diff --git a/e2e/protractor/suites/navigation/single-click.test.ts b/e2e/protractor/suites/navigation/single-click.test.ts index b048c48a37..a91b82fbd8 100755 --- a/e2e/protractor/suites/navigation/single-click.test.ts +++ b/e2e/protractor/suites/navigation/single-click.test.ts @@ -83,96 +83,6 @@ describe('Single click on item name', () => { await userActions.emptyTrashcan(); }); - it('[C284899] Hyperlink does not appear for items in the Trash', async () => { - await page.clickTrashAndWait(); - - expect(await dataTable.hasLinkOnName(deletedFile1)).toBe(false, 'Link on name is present'); - expect(await dataTable.hasLinkOnName(deletedFolder1)).toBe(false, 'Link on name is present'); - }); - - describe('on Personal Files', () => { - beforeEach(async () => { - await page.clickPersonalFilesAndWait(); - }); - - it('[C280032] Hyperlink appears when mouse over a file/folder', async () => { - expect(await dataTable.hasLinkOnName(file1)).toBe(true, 'Link on name is missing'); - }); - - it('[C280033] File preview opens when clicking the hyperlink', async () => { - await dataTable.clickNameLink(file1); - - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); - - await Utils.pressEscape(); - }); - - it('[C280034] Navigate inside the folder when clicking the hyperlink', async () => { - await dataTable.clickNameLink(folder1); - - expect(await breadcrumb.currentItem.getText()).toBe(folder1); - }); - }); - - describe('on File Libraries', () => { - beforeEach(async () => { - await page.goToMyLibrariesAndWait(); - }); - - it('[C284901] Hyperlink appears when mouse over a library', async () => { - expect(await dataTable.hasLinkOnName(siteName)).toBe(true, 'Link on site name is missing'); - }); - - it('[C284902] Navigate inside the library when clicking the hyperlink', async () => { - await dataTable.clickNameLink(siteName); - - expect(await breadcrumb.currentItem.getText()).toBe(siteName); - expect(await dataTable.isItemPresent(fileSite)).toBe(true, `${fileSite} not displayed`); - }); - }); - - describe('on Shared Files', () => { - beforeAll(async () => { - await userActions.login(username, username); - await userActions.shareNodes([file1Id]); - await apis.user.shared.waitForFilesToBeShared([file1Id]); - }); - - beforeEach(async () => { - await page.clickSharedFilesAndWait(); - }); - - it('[C284905] Hyperlink appears when mouse over a file', async () => { - expect(await dataTable.hasLinkOnName(file1)).toBe(true, 'Link on name is missing'); - }); - - it('[C284906] File preview opens when clicking the hyperlink', async () => { - await dataTable.clickNameLink(file1); - - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); - - await Utils.pressEscape(); - }); - }); - - describe('on Recent Files', () => { - beforeEach(async () => { - await page.clickRecentFilesAndWait(); - }); - - it('[C284907] Hyperlink appears when mouse over a file', async () => { - expect(await dataTable.hasLinkOnName(file1)).toBe(true, 'Link on name is missing'); - }); - - it('[C284908] File preview opens when clicking the hyperlink', async () => { - await dataTable.clickNameLink(file1); - - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); - - await Utils.pressEscape(); - }); - }); - describe('on Favorites', () => { beforeAll(async () => { const initialFavoriteTotalItems = await apis.user.favorites.getFavoritesTotalItems(); diff --git a/projects/aca-playwright-shared/src/page-objects/components/sidenav.component.ts b/projects/aca-playwright-shared/src/page-objects/components/sidenav.component.ts index 94cd7374d1..523779283e 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/sidenav.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/sidenav.component.ts @@ -38,7 +38,7 @@ export class SidenavComponent extends BaseComponent { private trash = this.getChild(`[data-automation-id='app.navbar.trashcan']`); private sidenavToggle = this.getChild(`.sidenav-header-title-logo`); private sidenavExpand = this.page.getByTitle('Expand navigation menu'); - private expandedSidenav = this.page.locator(`[data-automation-id='expanded']`); + public expandedSidenav = this.page.locator(`[data-automation-id='expanded']`); constructor(page: Page) { super(page, SidenavComponent.rootElement); From f867ed2a51d41502d3a0babffcc699c56fcef7d5 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Thu, 21 Sep 2023 14:51:26 +0200 Subject: [PATCH 3/5] test fix --- .../navigation/src/tests/sidebar.spec.ts | 50 +------------------ .../search/search-input.component.ts | 2 +- .../components/sidenav.component.ts | 17 +++---- 3 files changed, 10 insertions(+), 59 deletions(-) diff --git a/e2e/playwright/navigation/src/tests/sidebar.spec.ts b/e2e/playwright/navigation/src/tests/sidebar.spec.ts index d43d31c098..e64a8835e5 100644 --- a/e2e/playwright/navigation/src/tests/sidebar.spec.ts +++ b/e2e/playwright/navigation/src/tests/sidebar.spec.ts @@ -33,62 +33,14 @@ test.describe('Sidebar', () => { await apiClientFactory.setUpAcaBackend('hruser'); }); - test('[C289902] navigate to Favorite Libraries', async ({ personalFiles, favoritePage }) => { - await personalFiles.navigate(); - await personalFiles.sidenav.openPanel('Favorite Libraries'); - await personalFiles.dataTable.spinnerWaitForReload(); - expect(favoritePage.page.url()).toContain(APP_ROUTES.FAVORITE_LIBRARIES); - expect(await favoritePage.sidenav.isActive(SIDEBAR_LABELS.FAVORITE_LIBRARIES), 'Favorite Libraries link not active').toBe(true); - }); - test('[C289901] navigate to My Libraries', async ({ personalFiles, myLibrariesPage }) => { await personalFiles.navigate(); - await personalFiles.sidenav.openPanel('My Libraries'); + 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('[C213110] navigates to "Shared Files"', async ({ personalFiles, sharedPage }) => { - await personalFiles.navigate(); - await personalFiles.sidenav.openPanel('Shared'); - await personalFiles.dataTable.spinnerWaitForReload(); - expect(sharedPage.page.url()).toContain(APP_ROUTES.SHARED_FILES); - expect(await sharedPage.sidenav.isActive(SIDEBAR_LABELS.SHARED_FILES), 'Shared Files link not active').toBe(true); - }); - - test('[C213166] navigates to "Recent Files"', async ({ personalFiles, recentFilesPage }) => { - await personalFiles.navigate(); - await personalFiles.sidenav.openPanel('Recent Files'); - await personalFiles.dataTable.spinnerWaitForReload(); - expect(recentFilesPage.page.url()).toContain(APP_ROUTES.RECENT_FILES); - expect(await recentFilesPage.sidenav.isActive(SIDEBAR_LABELS.RECENT_FILES), 'Recent Files link not active').toBe(true); - }); - - test('[C213225] navigates to "Favorites"', async ({ personalFiles, favoritePage }) => { - await personalFiles.navigate(); - await personalFiles.sidenav.openPanel('Favorites'); - await personalFiles.dataTable.spinnerWaitForReload(); - expect(favoritePage.page.url()).toContain(APP_ROUTES.FAVORITES); - expect(await favoritePage.sidenav.isActive(SIDEBAR_LABELS.FAVORITES), 'Favorites link not active').toBe(true); - }); - - test('[C213216] navigates to "Trash"', async ({ personalFiles, trashPage }) => { - await personalFiles.navigate(); - await personalFiles.sidenav.openPanel('Trash'); - await personalFiles.dataTable.spinnerWaitForReload(); - expect(trashPage.page.url()).toContain(APP_ROUTES.TRASHCAN); - expect(await trashPage.sidenav.isActive(SIDEBAR_LABELS.TRASH), 'Trash link not active').toBe(true); - }); - - test('[C280409] navigates to "Personal Files"', async ({ personalFiles, trashPage }) => { - await trashPage.navigate(); - await personalFiles.sidenav.openPanel('Personal Files'); - await personalFiles.dataTable.spinnerWaitForReload(); - expect(personalFiles.page.url()).toContain(APP_ROUTES.PERSONAL_FILES); - expect(await personalFiles.sidenav.isActive(SIDEBAR_LABELS.PERSONAL_FILES), 'Personal Files link not active').toBe(true); - }); - test('[C277230] sidenav can be expanded when search results page is displayed', async ({ personalFiles }) => { await personalFiles.navigate({ remoteUrl: `#/search;q=test` }); expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar expanded').toBe(false); diff --git a/projects/aca-playwright-shared/src/page-objects/components/search/search-input.component.ts b/projects/aca-playwright-shared/src/page-objects/components/search/search-input.component.ts index 78ca1fa60d..c575f423a5 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/search/search-input.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/search/search-input.component.ts @@ -29,7 +29,7 @@ import { timeouts } from '../../../utils'; export class SearchInputComponent extends BaseComponent { private static rootElement = 'aca-page-layout'; public searchButton = this.getChild('aca-search-input .app-search-button'); - getIconByName = (name: string): Locator => this.getChild('.mat-icon[role="img"]', { hasText: name }); + getIconByName = (name: string): Locator => this.getChild('.mat-icon', { hasText: name }); /** * Method used in cases where user have possibility to navigate "inside" the element (it's clickable and has link attribute). diff --git a/projects/aca-playwright-shared/src/page-objects/components/sidenav.component.ts b/projects/aca-playwright-shared/src/page-objects/components/sidenav.component.ts index 523779283e..1886414aec 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/sidenav.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/sidenav.component.ts @@ -22,6 +22,7 @@ * from Hyland Software. If not, see . */ +import { SIDEBAR_LABELS } from '../../utils'; import { BaseComponent } from './base.component'; import { Locator, Page } from '@playwright/test'; @@ -55,21 +56,19 @@ export class SidenavComponent extends BaseComponent { private getLinkLabel(name: string): Locator { switch (name) { - case 'Personal Files': + case SIDEBAR_LABELS.PERSONAL_FILES: return this.personalFiles; - case 'File Libraries': - return this.fileLibraries; - case 'My Libraries': + case SIDEBAR_LABELS.MY_LIBRARIES: return this.myLibraries; - case 'Favorite Libraries': + case SIDEBAR_LABELS.FAVORITE_LIBRARIES: return this.favoriteLibraries; - case 'Shared': + case SIDEBAR_LABELS.SHARED_FILES: return this.shared; - case 'Recent Files': + case SIDEBAR_LABELS.RECENT_FILES: return this.recentFiles; - case 'Favorites': + case SIDEBAR_LABELS.FAVORITES: return this.favorites; - case 'Trash': + case SIDEBAR_LABELS.TRASH: return this.trash; default: return this.personalFiles; From 49816b8276defb4b8d32ff07046b34cf99e9344c Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Fri, 22 Sep 2023 17:52:09 +0200 Subject: [PATCH 4/5] [ACS-5639] fix exclude test in viewer --- e2e/playwright/viewer/exclude.tests.json | 10 +- .../viewer/src/tests/viewer-action.spec.ts | 25 ++-- .../viewer/src/tests/viewer.spec.ts | 31 +--- e2e/protractor/protractor.excludes.json | 8 +- .../suites/viewer/viewer-actions.test.ts | 135 ------------------ .../src/api/favorites-api.ts | 36 +++++ .../src/api/file-actions.ts | 98 ++++++++++--- .../src/api/shared-links-api.ts | 21 +-- .../components/aca-header.component.ts | 2 +- .../components/viewer.component.ts | 1 + .../aca-playwright-shared/src/utils/utils.ts | 10 +- 11 files changed, 152 insertions(+), 225 deletions(-) diff --git a/e2e/playwright/viewer/exclude.tests.json b/e2e/playwright/viewer/exclude.tests.json index 9c00daf8b7..0967ef424b 100644 --- a/e2e/playwright/viewer/exclude.tests.json +++ b/e2e/playwright/viewer/exclude.tests.json @@ -1,9 +1 @@ -{ - "C284636" : "this have Protractor test Enabled https://alfresco.atlassian.net/browse/ACS-5639", - "C284635" : "this have Protractor test Enabled https://alfresco.atlassian.net/browse/ACS-5639", - "C279175" : "this have Protractor test Enabled https://alfresco.atlassian.net/browse/ACS-5639", - "C284634" : "this have Protractor test Enabled https://alfresco.atlassian.net/browse/ACS-5639", - "C297585" : "this have Protractor test Enabled https://alfresco.atlassian.net/browse/ACS-5639", - "C286379" : "this have Protractor test Enabled https://alfresco.atlassian.net/browse/ACS-5639", - "C286395" : "this have Protractor test Enabled https://alfresco.atlassian.net/browse/ACS-5639" -} +{} diff --git a/e2e/playwright/viewer/src/tests/viewer-action.spec.ts b/e2e/playwright/viewer/src/tests/viewer-action.spec.ts index 2b7dad58b4..5a778a24ab 100644 --- a/e2e/playwright/viewer/src/tests/viewer-action.spec.ts +++ b/e2e/playwright/viewer/src/tests/viewer-action.spec.ts @@ -37,19 +37,26 @@ test.describe('viewer action file', () => { const fileForCancelEditing = `playwright-file2-${Utils.random()}.docx`; let folderId: string; let fileDocxShareId: string; + let randomDocxNameFavoriteId: string; + let fileForCancelEditingId: string; - test.beforeAll(async ({ fileAction, shareAction }) => { + test.beforeAll(async ({ fileAction, favoritesPageAction, shareAction }) => { await apiClientFactory.setUpAcaBackend('hruser'); const node = await apiClientFactory.nodes.createNode('-my-', { name: randomFolderName, nodeType: 'cm:folder', relativePath: '/' }); folderId = node.entry.id; - await fileAction.uploadFile(TEST_FILES.DOCX.path, fileForCancelEditing, folderId); + + fileDocxShareId = (await fileAction.uploadFile(TEST_FILES.DOCX.path, randomDocxNameShare, folderId)).entry.id; + await shareAction.shareFileById(fileDocxShareId); + fileForCancelEditingId = (await fileAction.uploadFile(TEST_FILES.DOCX.path, fileForCancelEditing, folderId)).entry.id; + await fileAction.lockNodes([fileForCancelEditingId]); await fileAction.uploadFile(TEST_FILES.DOCX.path, randomDocxName, folderId); await fileAction.uploadFile(TEST_FILES.DOCX.path, randomDocxDelete, folderId); - const fileDocShare = await fileAction.uploadFile(TEST_FILES.DOCX.path, randomDocxNameShare, folderId); - fileDocxShareId = fileDocShare.entry.id; - await fileAction.uploadFile(TEST_FILES.DOCX.path, randomDocxNameFavorite, folderId); - await shareAction.shareFileById(fileDocxShareId); + const fileFavoritesNode = await fileAction.uploadFile(TEST_FILES.DOCX.path, randomDocxNameFavorite, folderId); + randomDocxNameFavoriteId = fileFavoritesNode.entry.id; await fileAction.uploadFile(TEST_FILES.DOCX.path, fileForEditOffline, folderId); + await favoritesPageAction.addFavoriteById('file', randomDocxNameFavoriteId); + await favoritesPageAction.isFavoriteWithRetry('hruser', randomDocxNameFavoriteId, { expect: true }); + await fileAction.isFileLockedWriteWithRetry(fileForCancelEditingId, true); }); test.beforeEach(async ({ personalFiles }) => { @@ -140,6 +147,7 @@ test.describe('viewer action file', () => { await favoritePage.viewerDialog.favoriteMenuButton.waitFor({ state: 'detached', timeout: timeouts.normal }); await sharedPage.acaHeader.clickViewerMoreActions(); + await favoritePage.viewerDialog.removeFavoriteMenuButton.waitFor({ state: 'attached', timeout: timeouts.normal }); expect(await sharedPage.viewerDialog.removeFavoriteMenuButton.isVisible(), 'Item should be remove favorite').toBe(true); await sharedPage.page.keyboard.press('Escape'); await favoritePage.navigate({ waitUntil: 'domcontentloaded' }); @@ -150,8 +158,9 @@ test.describe('viewer action file', () => { await favoritePage.navigate({ waitUntil: 'domcontentloaded' }); await favoritePage.dataTable.performClickFolderOrFileToOpen(randomDocxNameFavorite); expect(await favoritePage.viewer.isViewerOpened(), 'Viewer should be opened').toBe(true); - - await favoritePage.acaHeader.shareButton.click(); + await favoritePage.viewer.shareButton.waitFor({ state: 'attached', timeout: timeouts.normal }); + await favoritePage.viewer.shareButton.click(); + await favoritePage.viewerDialog.shareDialogTitle.waitFor({ state: 'attached', timeout: timeouts.normal }); expect(await favoritePage.viewerDialog.shareDialogTitle.isVisible(), 'Share dialog should be open').toBe(true); await favoritePage.viewerDialog.shareDialogClose.click(); await favoritePage.viewerDialog.shareDialogClose.waitFor({ state: 'detached', timeout: timeouts.large }); diff --git a/e2e/playwright/viewer/src/tests/viewer.spec.ts b/e2e/playwright/viewer/src/tests/viewer.spec.ts index 7a2d96889f..4cf12c2d1d 100644 --- a/e2e/playwright/viewer/src/tests/viewer.spec.ts +++ b/e2e/playwright/viewer/src/tests/viewer.spec.ts @@ -31,12 +31,17 @@ test.describe('viewer file', () => { const randomFolderName = `playwright-folder-${Utils.random()}`; const randomDocxName = `${TEST_FILES.DOCX.name}-${Utils.random()}`; let folderId: string; + let fileDocxId: string; - test.beforeAll(async ({ fileAction }) => { + test.beforeAll(async ({ fileAction, shareAction, favoritesPageAction }) => { await apiClientFactory.setUpAcaBackend('hruser'); const node = await apiClientFactory.nodes.createNode('-my-', { name: randomFolderName, nodeType: 'cm:folder', relativePath: '/' }); folderId = node.entry.id; - await fileAction.uploadFile(TEST_FILES.DOCX.path, randomDocxName, folderId); + const fileDoc = await fileAction.uploadFile(TEST_FILES.DOCX.path, randomDocxName, folderId); + fileDocxId = fileDoc.entry.id; + await shareAction.shareFileById(fileDocxId); + await favoritesPageAction.addFavoriteById('file', fileDocxId); + await favoritesPageAction.isFavoriteWithRetry('hruser', fileDocxId, { expect: true }); }); test.beforeEach(async ({ personalFiles }) => { @@ -98,28 +103,6 @@ test.describe('viewer file', () => { expect(await searchPage.viewer.isCloseButtonDisplayed(), 'Close button is not displayed').toBe(true); expect(await searchPage.viewer.isFileTitleDisplayed(), 'File title is not displayed').toBe(true); }); -}); - -test.describe('viewer file', () => { - const apiClientFactory = new ApiClientFactory(); - const randomFolderName = `playwright-folder-${Utils.random()}`; - const randomDocxName = `$(TEST_FILES.DOCX.name)-${Utils.random()}`; - let folderId: string; - let fileDocxId: string; - - test.beforeAll(async ({ fileAction, shareAction, favoritesPageAction: favoritesPageAction }) => { - await apiClientFactory.setUpAcaBackend('hruser'); - const node = await apiClientFactory.nodes.createNode('-my-', { name: randomFolderName, nodeType: 'cm:folder', relativePath: '/' }); - folderId = node.entry.id; - const fileDoc = await fileAction.uploadFile(TEST_FILES.DOCX.path, randomDocxName, folderId); - fileDocxId = fileDoc.entry.id; - await shareAction.shareFileById(fileDocxId); - await favoritesPageAction.addFavoriteById('file', fileDocxId); - }); - - test.afterAll(async () => { - await apiClientFactory.nodes.deleteNode(folderId, { permanent: true }); - }); test('[C279285] Viewer opens when accessing the preview URL for a file', async ({ personalFiles }) => { const previewURL = `#/personal-files/${folderId}/(viewer:view/${fileDocxId})`; diff --git a/e2e/protractor/protractor.excludes.json b/e2e/protractor/protractor.excludes.json index 99183958b9..2deec9cf3a 100644 --- a/e2e/protractor/protractor.excludes.json +++ b/e2e/protractor/protractor.excludes.json @@ -22,11 +22,5 @@ "C268958" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5604", "C268959" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5604", "C268960" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5604", - "C268961" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5604", - - "C286314" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5650", - "C279282" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5650", - "C297584" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5650", - "C268133" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5650", - "C268129" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5650" + "C268961" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5604" } diff --git a/e2e/protractor/suites/viewer/viewer-actions.test.ts b/e2e/protractor/suites/viewer/viewer-actions.test.ts index 6fdfbafd5a..31802f0546 100755 --- a/e2e/protractor/suites/viewer/viewer-actions.test.ts +++ b/e2e/protractor/suites/viewer/viewer-actions.test.ts @@ -64,7 +64,6 @@ describe('Viewer actions', () => { const userActions = new UserActions(); const uploadFilesDialog = new UploadFilesDialog(); - const downloadButton = element(By.css(`button[id='app.viewer.download']`)); const shareButton = element(By.css(`adf-viewer [data-automation-id="share-action-button"]`)); beforeAll(async () => { @@ -85,8 +84,6 @@ describe('Viewer actions', () => { const filePersonalFiles = docxFile2; let filePersonalFilesId: string; - const fileForEditOffline = `file1-${Utils.random()}.docx`; - let fileForEditOfflineId: string; const fileForCancelEditing = `file2-${Utils.random()}.docx`; let fileForCancelEditingId: string; const fileForUploadNewVersion = `file3-${Utils.random()}.docx`; @@ -105,7 +102,6 @@ describe('Viewer actions', () => { await apis.user.upload.uploadFileWithRename(xlsxFileForMove, parentId, xlsxPersonalFiles); await apis.user.upload.uploadFileWithRename(pdfFileForDelete, parentId, pdfPersonalFiles); - fileForEditOfflineId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, fileForEditOffline)).entry.id; fileForCancelEditingId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, fileForCancelEditing)).entry.id; fileForUploadNewVersionId = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, fileForUploadNewVersion)).entry.id; fileForUploadNewVersionId2 = (await apis.user.upload.uploadFileWithRename(docxFile, parentId, fileForUploadNewVersion2)).entry.id; @@ -142,37 +138,6 @@ describe('Viewer actions', () => { } }); - it('[C268129] Download action', async () => { - await dataTable.doubleClickOnRowByName(docxPersonalFiles); - await viewer.waitForViewerToOpen(); - - await downloadButton.click(); - - expect(await Utils.fileExistsOnOS(docxPersonalFiles)).toBe(true, 'File not found in download location'); - }); - - it('[C268133] Delete action', async () => { - await dataTable.doubleClickOnRowByName(pdfPersonalFiles); - await viewer.waitForViewerToOpen(); - - await toolbar.clickMoreActionsDelete(); - expect(await page.getSnackBarMessage()).toContain(`${pdfPersonalFiles} deleted`); - expect(await viewer.isViewerOpened()).toBe(false, 'Viewer is opened'); - await Utils.pressEscape(); - await page.clickTrashAndWait(); - expect(await dataTable.isItemPresent(pdfPersonalFiles)).toBe(true, 'Item is not present in Trash'); - }); - - it('[C297584] Edit Offline action', async () => { - await dataTable.doubleClickOnRowByName(fileForEditOffline); - await viewer.waitForViewerToOpen(); - await toolbar.clickMoreActionsEditOffline(); - - expect(await Utils.fileExistsOnOS(fileForEditOffline)).toBe(true, 'File not found in download location'); - expect(await apis.user.nodes.isFileLockedWrite(fileForEditOfflineId)).toBe(true, `${fileForEditOffline} is not locked`); - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not open'); - }); - it('[C297585] Cancel Editing action', async () => { await dataTable.doubleClickOnRowByName(fileForCancelEditing); await viewer.waitForViewerToOpen(); @@ -216,106 +181,6 @@ describe('Viewer actions', () => { expect(await toolbar.menu.cancelEditingAction.isPresent()).toBe(false, `'Cancel Editing' button shouldn't be shown`); expect(await toolbar.menu.editOfflineAction.isPresent()).toBe(true, `'Edit Offline' should be shown`); }); - - it('[C279282] Full screen action', async () => { - await dataTable.doubleClickOnRowByName(docxPersonalFiles); - await viewer.waitForViewerToOpen(); - - await toolbar.fullScreenButton.click(); - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is closed after pressing Full screen'); - }); - - it('[C286314] Pressing ESC in the viewer closes only the action dialog', async () => { - await dataTable.doubleClickOnRowByName(docxPersonalFiles); - await viewer.waitForViewerToOpen(); - - await toolbar.clickMoreActionsCopy(); - expect(await copyMoveDialog.isDialogOpen()).toBe(true, 'Dialog is not open'); - await Utils.pressEscape(); - expect(await shareDialog.isDialogOpen()).toBe(false, 'Dialog is still open'); - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); - }); - }); - - describe('from File Libraries', () => { - const siteName = `site-${Utils.random()}`; - const destination = `destFL-${Utils.random()}`; - let destinationId: string; - - const xlsxLibraries = `xlsxFL-${Utils.random()}.xlsx`; - const pdfLibraries = `pdfFL-${Utils.random()}.pdf`; - - const fileForEditOffline = `file1-${Utils.random()}.docx`; - const fileForCancelEditing = `file2-${Utils.random()}.docx`; - let fileForCancelEditingId: string; - const fileForUploadNewVersion = `file3-${Utils.random()}.docx`; - let fileForUploadNewVersionId: string; - - beforeAll(async () => { - try { - await apis.user.sites.createSite(siteName); - const docLibId = await apis.user.sites.getDocLibId(siteName); - destinationId = await apis.user.createFolder(destination); - - await apis.user.upload.uploadFile(docxFile2, docLibId); - - await apis.user.upload.uploadFileWithRename(xlsxFileForMove, docLibId, xlsxLibraries); - await apis.user.upload.uploadFileWithRename(pdfFileForDelete, docLibId, pdfLibraries); - - await apis.user.upload.uploadFileWithRename(docxFile, docLibId, fileForEditOffline); - fileForCancelEditingId = (await apis.user.upload.uploadFileWithRename(docxFile, docLibId, fileForCancelEditing)).entry.id; - fileForUploadNewVersionId = (await apis.user.upload.uploadFileWithRename(docxFile, docLibId, fileForUploadNewVersion)).entry.id; - - await userActions.lockNodes([fileForCancelEditingId, fileForUploadNewVersionId]); - - await loginPage.loginWith(username); - } catch (error) { - Logger.error(`----- beforeAll failed : ${error}`); - } - }); - - beforeEach(async () => { - try { - await page.goToMyLibrariesAndWait(); - await dataTable.doubleClickOnRowByName(siteName); - await dataTable.waitForHeader(); - } catch (error) { - Logger.error(`----- beforeEach failed : ${error}`); - } - }); - - afterEach(async () => { - await Utils.pressEscape(); - await uploadFilesDialog.closeUploadDialog(); - }); - - afterAll(async () => { - try { - await userActions.login(username, username); - await userActions.deleteSites([siteName]); - await userActions.deleteNodes([destinationId]); - await userActions.emptyTrashcan(); - } catch (error) { - Logger.error(`----- afterAll failed : ${error}`); - } - }); - - it('[C286371] Move action', async () => { - await dataTable.doubleClickOnRowByName(xlsxLibraries); - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); - - await toolbar.clickMoreActionsMove(); - expect(await copyMoveDialog.isDialogOpen()).toBe(true, 'Dialog is not open'); - await copyMoveDialog.selectLocation('Personal Files'); - await copyMoveDialog.selectDestination(destination); - await copyMoveDialog.moveButton.click(); - expect(await page.getSnackBarMessage()).toContain('Moved 1 item'); - await viewer.closeButton.click(); - expect(await dataTable.isItemPresent(xlsxLibraries)).toBe(false, 'Item was not moved'); - await page.clickPersonalFilesAndWait(); - await dataTable.doubleClickOnRowByName(destination); - expect(await dataTable.isItemPresent(xlsxLibraries)).toBe(true, 'Item is not present in destination'); - }); }); describe('from Recent Files', () => { diff --git a/projects/aca-playwright-shared/src/api/favorites-api.ts b/projects/aca-playwright-shared/src/api/favorites-api.ts index 21cae7b456..7233617447 100755 --- a/projects/aca-playwright-shared/src/api/favorites-api.ts +++ b/projects/aca-playwright-shared/src/api/favorites-api.ts @@ -24,6 +24,8 @@ import { ApiClientFactory } from './api-client-factory'; import { FavoriteEntry } from '@alfresco/js-api'; +import { Logger } from '@alfresco/adf-testing'; +import { Utils } from '../utils'; export class FavoritesPageApi { private apiService: ApiClientFactory; @@ -47,4 +49,38 @@ export class FavoritesPageApi { }; return await this.apiService.favorites.createFavorite('-me-', data); } + + private async getFavorites(username: string) { + try { + return await this.apiService.favorites.listFavorites(username); + } catch (error) { + Logger.error(`FavoritesApi getFavorites : catch : `, error); + return null; + } + } + + async isFavorite(username: string, nodeId: string) { + try { + return JSON.stringify((await this.getFavorites(username)).list.entries).includes(nodeId); + } catch (error) { + Logger.error(`FavoritesApi isFavorite : catch : `, error); + return null; + } + } + + async isFavoriteWithRetry(username: string, nodeId: string, data: { expect: boolean }) { + let isFavorite = false; + try { + const favorite = async () => { + isFavorite = await this.isFavorite(username, nodeId); + if (isFavorite !== data.expect) { + return Promise.reject(isFavorite); + } else { + return Promise.resolve(isFavorite); + } + }; + return await Utils.retryCall(favorite); + } catch (error) {} + return isFavorite; + } } diff --git a/projects/aca-playwright-shared/src/api/file-actions.ts b/projects/aca-playwright-shared/src/api/file-actions.ts index b4614522ac..615dec6286 100644 --- a/projects/aca-playwright-shared/src/api/file-actions.ts +++ b/projects/aca-playwright-shared/src/api/file-actions.ts @@ -24,32 +24,90 @@ import * as fs from 'fs'; import { ApiClientFactory } from './api-client-factory'; +import { Utils } from '../utils'; +import { logger } from '@alfresco/adf-cli/scripts/logger'; +import { NodeEntry } from '@alfresco/js-api'; export class FileActionsApi { - private apiService: ApiClientFactory; + private apiService: ApiClientFactory; - constructor() { - this.apiService = new ApiClientFactory(); + constructor() { + this.apiService = new ApiClientFactory(); + } + + static async initialize(userName: string, password?: string): Promise { + const classObj = new FileActionsApi(); + await classObj.apiService.setUpAcaBackend(userName, password); + return classObj; + } + + async uploadFile(fileLocation: string, fileName: string, parentFolderId: string): Promise { + const file = fs.createReadStream(fileLocation); + return this.apiService.upload.uploadFile(file, '', parentFolderId, null, { + name: fileName, + nodeType: 'cm:content', + renditions: 'doclib' + }); + } + + async lockNodes(nodeIds: string[], lockType: string = 'ALLOW_OWNER_CHANGES') { + try { + for (const nodeId of nodeIds) { + await this.apiService.nodes.lockNode(nodeId, { type: lockType }); + } + } catch (error) { + logger.error(`${this.constructor.name} ${this.lockNodes.name}`, error); + } + } + + async getNodeById(id: string): Promise { + try { + return await this.apiService.nodes.getNode(id); + } catch (error) { + logger.error(`${this.constructor.name} ${this.getNodeById.name}`, error); + return null; + } + } + + async getNodeProperty(nodeId: string, property: string): Promise { + try { + const node = await this.getNodeById(nodeId); + return (node.entry.properties && node.entry.properties[property]) || ''; + } catch (error) { + logger.error(`${this.constructor.name} ${this.getNodeProperty.name}`, error); + return ''; } + } - static async initialize(userName: string, password?: string): Promise { - const classObj = new FileActionsApi(); - await classObj.apiService.setUpAcaBackend(userName, password); - return classObj; + private async getLockType(nodeId: string): Promise { + try { + const lockType = await this.getNodeProperty(nodeId, 'cm:lockType'); + return lockType || ''; + } catch (error) { + logger.error(`${this.constructor.name} ${this.getLockType.name}`, error); + return ''; } + } - async uploadFile(fileLocation: string, fileName: string, parentFolderId: string): Promise { - const file = fs.createReadStream(fileLocation); - return this.apiService.upload.uploadFile( - file, - '', - parentFolderId, - null, - { - name: fileName, - nodeType: 'cm:content', - renditions: 'doclib' - } - ); + async isFileLockedWriteWithRetry(nodeId: string, expect: boolean): Promise { + const data = { + expect: expect, + retry: 5 + }; + let isLocked = false; + try { + const locked = async () => { + isLocked = (await this.getLockType(nodeId)) === 'WRITE_LOCK'; + if (isLocked !== data.expect) { + return Promise.reject(isLocked); + } else { + return Promise.resolve(isLocked); + } + }; + return await Utils.retryCall(locked, data.retry); + } catch (error) { + logger.error(`${this.constructor.name} ${this.isFileLockedWriteWithRetry.name}`, error); } + return isLocked; + } } diff --git a/projects/aca-playwright-shared/src/api/shared-links-api.ts b/projects/aca-playwright-shared/src/api/shared-links-api.ts index 188abd3d69..95310f7444 100755 --- a/projects/aca-playwright-shared/src/api/shared-links-api.ts +++ b/projects/aca-playwright-shared/src/api/shared-links-api.ts @@ -23,8 +23,7 @@ */ import { ApiClientFactory } from './api-client-factory'; -import { FavoritePaging, SharedLinkEntry } from '@alfresco/js-api'; -import { logger } from '@alfresco/adf-cli/scripts/logger'; +import { SharedLinkEntry } from '@alfresco/js-api'; export class SharedLinksApi { private apiService: ApiClientFactory; @@ -49,22 +48,4 @@ export class SharedLinksApi { return null; } } - - private async getFavorites(userName: string): Promise { - try { - return await this.apiService.favorites.listFavorites(userName); - } catch (error) { - logger.error(`\n--- Error while fetching favourites list ${error} :`); - return null; - } - } - - async isFavorite(nodeId: string, userName: string): Promise { - try { - return JSON.stringify((await this.getFavorites(userName)).list.entries).includes(nodeId); - } catch (error) { - logger.error(`\n--- Error while checking favourite node ${error} ${error} :`); - return null; - } - } } diff --git a/projects/aca-playwright-shared/src/page-objects/components/aca-header.component.ts b/projects/aca-playwright-shared/src/page-objects/components/aca-header.component.ts index 5b8ab0ddf3..bbb1d9355c 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/aca-header.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/aca-header.component.ts @@ -32,7 +32,7 @@ export class AcaHeader extends BaseComponent { public viewButton = this.getChild('button[title="View"]'); public searchButton = this.getChild('button[title="Search"]'); public fullScreenButton = this.getChild('button[id="app.viewer.fullscreen"]'); - public shareButton = this.getChild('button[id="app.viewer.fullscreen"]'); + public shareButton = this.getChild('button[id="share-action-button"]'); public downloadButton = this.getChild('button[id="app.viewer.download"]'); constructor(page: Page) { diff --git a/projects/aca-playwright-shared/src/page-objects/components/viewer.component.ts b/projects/aca-playwright-shared/src/page-objects/components/viewer.component.ts index 16b7ad4093..601899620c 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/viewer.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/viewer.component.ts @@ -34,6 +34,7 @@ export class ViewerComponent extends BaseComponent { public closeButtonLocator = this.getChild('.adf-viewer-close-button'); public fileTitleButtonLocator = this.getChild('.adf-viewer__file-title'); public pdfViewerContentPages = this.getChild('.adf-pdf-viewer__content .page'); + public shareButton = this.getChild('button[id="share-action-button"]'); toolbar = new AcaHeader(this.page); diff --git a/projects/aca-playwright-shared/src/utils/utils.ts b/projects/aca-playwright-shared/src/utils/utils.ts index 575fb9f8d4..c23779b4c5 100644 --- a/projects/aca-playwright-shared/src/utils/utils.ts +++ b/projects/aca-playwright-shared/src/utils/utils.ts @@ -25,9 +25,17 @@ const crypto = require('crypto'); export class Utils { - static random(): string { return crypto.getRandomValues(new Uint32Array(1))[0].toString(36).substring(0, 5).toLowerCase(); } + static retryCall(fn: () => Promise, retry: number = 30, delay: number = 1500): Promise { + const pause = (duration: number) => new Promise((res) => setTimeout(res, duration)); + + const run = (retries: number): Promise => { + return fn().catch((err) => (retries > 1 ? pause(delay).then(() => run(retries - 1)) : Promise.reject(err))); + }; + + return run(retry); + } } From d51f742b1ef6615f0811ed3f9090dd9cb506c0b7 Mon Sep 17 00:00:00 2001 From: "akash.rathod@hyland.com" Date: Fri, 22 Sep 2023 20:30:37 +0200 Subject: [PATCH 5/5] remove exclude test and fix test --- .../viewer/src/tests/viewer.spec.ts | 1 + e2e/protractor/protractor.excludes.json | 7 +- .../suites/viewer/viewer-general.test.ts | 35 +----- .../viewer/viewer-protected-file.test.ts | 109 ------------------ .../src/api/file-actions.ts | 47 +++++++- 5 files changed, 44 insertions(+), 155 deletions(-) delete mode 100755 e2e/protractor/suites/viewer/viewer-protected-file.test.ts diff --git a/e2e/playwright/viewer/src/tests/viewer.spec.ts b/e2e/playwright/viewer/src/tests/viewer.spec.ts index 4cf12c2d1d..4e5f06202d 100644 --- a/e2e/playwright/viewer/src/tests/viewer.spec.ts +++ b/e2e/playwright/viewer/src/tests/viewer.spec.ts @@ -42,6 +42,7 @@ test.describe('viewer file', () => { await shareAction.shareFileById(fileDocxId); await favoritesPageAction.addFavoriteById('file', fileDocxId); await favoritesPageAction.isFavoriteWithRetry('hruser', fileDocxId, { expect: true }); + await fileAction.waitForNodes(randomDocxName, { expect: 1 }); }); test.beforeEach(async ({ personalFiles }) => { diff --git a/e2e/protractor/protractor.excludes.json b/e2e/protractor/protractor.excludes.json index 2deec9cf3a..effe33632b 100644 --- a/e2e/protractor/protractor.excludes.json +++ b/e2e/protractor/protractor.excludes.json @@ -17,10 +17,5 @@ "C279220": "will be fixed after protractor to playwright migration, see https://alfresco.atlassian.net/browse/ACS-5007", "C279221": "will be fixed after protractor to playwright migration, see https://alfresco.atlassian.net/browse/ACS-5007", "C325006": "will be fixed after protractor to playwright migration, see https://alfresco.atlassiana.net/browse/ACS-5007", - "C213097": "https://alfresco.atlassian.net/browse/ACS-5479", - - "C268958" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5604", - "C268959" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5604", - "C268960" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5604", - "C268961" : "test migrated to playwright https://alfresco.atlassian.net/browse/ACS-5604" + "C213097": "https://alfresco.atlassian.net/browse/ACS-5479" } diff --git a/e2e/protractor/suites/viewer/viewer-general.test.ts b/e2e/protractor/suites/viewer/viewer-general.test.ts index 0685d5fcdc..65fd6909fe 100755 --- a/e2e/protractor/suites/viewer/viewer-general.test.ts +++ b/e2e/protractor/suites/viewer/viewer-general.test.ts @@ -48,9 +48,8 @@ describe('Viewer general', () => { const loginPage = new LoginPage(); const page = new BrowsingPage(); - const { dataTable, toolbar } = page; + const { dataTable } = page; const viewer = new Viewer(); - const { searchInput } = page.pageLayoutHeader; const adminApiActions = new AdminActions(); const userActions = new UserActions(); @@ -114,24 +113,6 @@ describe('Viewer general', () => { expect(await viewer.isFileTitleDisplayed()).toBe(true, 'File title is not displayed'); }); - it('[C284636] Viewer opens for a file from Recent Files', async () => { - await page.clickRecentFilesAndWait(); - await dataTable.doubleClickOnRowByName(xlsxFile); - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); - expect(await viewer.isViewerToolbarDisplayed()).toBe(true, 'Toolbar not displayed'); - expect(await viewer.isCloseButtonDisplayed()).toBe(true, 'Close button is not displayed'); - expect(await viewer.isFileTitleDisplayed()).toBe(true, 'File title is not displayed'); - }); - - it('[C284635] Viewer opens for a file from Shared Files', async () => { - await page.clickSharedFilesAndWait(); - await dataTable.doubleClickOnRowByName(xlsxFile); - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); - expect(await viewer.isViewerToolbarDisplayed()).toBe(true, 'Toolbar not displayed'); - expect(await viewer.isCloseButtonDisplayed()).toBe(true, 'Close button is not displayed'); - expect(await viewer.isFileTitleDisplayed()).toBe(true, 'File title is not displayed'); - }); - it('[C284634] Viewer opens for a file from Favorites', async () => { await page.clickFavoritesAndWait(); await dataTable.doubleClickOnRowByName(xlsxFile); @@ -140,18 +121,4 @@ describe('Viewer general', () => { expect(await viewer.isCloseButtonDisplayed()).toBe(true, 'Close button is not displayed'); expect(await viewer.isFileTitleDisplayed()).toBe(true, 'File title is not displayed'); }); - - it('[C279175] Viewer opens for a file from Search Results', async () => { - await toolbar.clickSearchIconButton(); - await searchInput.clickSearchButton(); - await searchInput.checkFilesAndFolders(); - await searchInput.searchFor(xlsxFile); - await dataTable.waitForBody(); - - await dataTable.doubleClickOnRowByName(xlsxFile); - expect(await viewer.isViewerOpened()).toBe(true, 'Viewer is not opened'); - expect(await viewer.isViewerToolbarDisplayed()).toBe(true, 'Toolbar not displayed'); - expect(await viewer.isCloseButtonDisplayed()).toBe(true, 'Close button is not displayed'); - expect(await viewer.isFileTitleDisplayed()).toBe(true, 'File title is not displayed'); - }); }); diff --git a/e2e/protractor/suites/viewer/viewer-protected-file.test.ts b/e2e/protractor/suites/viewer/viewer-protected-file.test.ts deleted file mode 100755 index 095e63f738..0000000000 --- a/e2e/protractor/suites/viewer/viewer-protected-file.test.ts +++ /dev/null @@ -1,109 +0,0 @@ -/*! - * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * Alfresco Example Content Application - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * from Hyland Software. If not, see . - */ - -import { AdminActions, LoginPage, BrowsingPage, FILES, RepoClient, Utils, Viewer, PasswordDialog } from '@alfresco/aca-testing-shared'; -import { BrowserActions } from '@alfresco/adf-testing'; - -describe('Viewer - password protected file', () => { - const username = `user-${Utils.random()}`; - - const parent = `parent-${Utils.random()}`; - let parentId: string; - - const protectedFile = FILES.protectedFile; - - const apis = { - user: new RepoClient(username, username) - }; - - const loginPage = new LoginPage(); - const page = new BrowsingPage(); - const { dataTable } = page; - const viewer = new Viewer(); - const passwordDialog = new PasswordDialog(); - const adminApiActions = new AdminActions(); - - beforeAll(async () => { - await adminApiActions.createUser({ username }); - parentId = (await apis.user.nodes.createFolder(parent)).entry.id; - await apis.user.upload.uploadFile(protectedFile.name, parentId); - - await loginPage.loginWith(username); - }); - - beforeEach(async () => { - await page.header.expandSideNav(); - await page.clickPersonalFilesAndWait(); - await dataTable.doubleClickOnRowByName(parent); - await dataTable.waitForHeader(); - await dataTable.doubleClickOnRowByName(protectedFile.name); - await viewer.waitForViewerToOpen(); - await passwordDialog.waitForDialogToOpen(); - }); - - afterEach(async () => { - await page.closeOpenDialogs(); - await Utils.pressEscape(); - }); - - afterAll(async () => { - await apis.user.nodes.deleteNodeById(parentId); - }); - - it('[C268958] Password dialog appears when opening a protected file', async () => { - expect(await passwordDialog.isDialogOpen()).toBe(true, 'Password dialog not open'); - expect(await passwordDialog.isPasswordInputDisplayed()).toBe(true, 'Password input not displayed'); - expect(await passwordDialog.isSubmitEnabled()).toBe(false, 'Submit button not disabled'); - expect(await passwordDialog.isCloseEnabled()).toBe(true, 'Close button not enabled'); - expect(await viewer.isPdfViewerContentDisplayed()).toBe(false, 'file content is displayed'); - }); - - it('[C268959] File content is displayed when entering the correct password', async () => { - await passwordDialog.enterPassword(protectedFile.password); - expect(await passwordDialog.isSubmitEnabled()).toBe(true, 'Submit button not enabled'); - - await BrowserActions.click(passwordDialog.submitButton); - await passwordDialog.waitForDialogToClose(); - - expect(await viewer.isPdfViewerContentDisplayed()).toBe(true, 'file content not displayed'); - }); - - it('[C268960] Error appears when entering an incorrect password', async () => { - await passwordDialog.enterPassword('incorrect'); - expect(await passwordDialog.isSubmitEnabled()).toBe(true, 'Submit button not enabled'); - await BrowserActions.click(passwordDialog.submitButton); - - expect(await passwordDialog.getErrorMessage()).toBe('Password is wrong'); - expect(await viewer.isPdfViewerContentDisplayed()).toBe(false, 'file content is displayed'); - }); - - it('[C268961] Refresh the page while Password dialog is open', async () => { - await passwordDialog.enterPassword(protectedFile.password); - await page.refresh(); - await viewer.waitForViewerToOpen(); - - expect(await viewer.isPdfViewerContentDisplayed()).toBe(false, 'file content is displayed'); - expect(await passwordDialog.isDialogOpen()).toBe(true, 'Password dialog not open'); - }); -}); diff --git a/projects/aca-playwright-shared/src/api/file-actions.ts b/projects/aca-playwright-shared/src/api/file-actions.ts index 615dec6286..865f74cb4e 100644 --- a/projects/aca-playwright-shared/src/api/file-actions.ts +++ b/projects/aca-playwright-shared/src/api/file-actions.ts @@ -25,7 +25,7 @@ import * as fs from 'fs'; import { ApiClientFactory } from './api-client-factory'; import { Utils } from '../utils'; -import { logger } from '@alfresco/adf-cli/scripts/logger'; +import { ApiUtil, Logger } from '@alfresco/adf-testing'; import { NodeEntry } from '@alfresco/js-api'; export class FileActionsApi { @@ -56,7 +56,7 @@ export class FileActionsApi { await this.apiService.nodes.lockNode(nodeId, { type: lockType }); } } catch (error) { - logger.error(`${this.constructor.name} ${this.lockNodes.name}`, error); + Logger.error(`${this.constructor.name} ${this.lockNodes.name}`, error); } } @@ -64,7 +64,7 @@ export class FileActionsApi { try { return await this.apiService.nodes.getNode(id); } catch (error) { - logger.error(`${this.constructor.name} ${this.getNodeById.name}`, error); + Logger.error(`${this.constructor.name} ${this.getNodeById.name}`, error); return null; } } @@ -74,7 +74,7 @@ export class FileActionsApi { const node = await this.getNodeById(nodeId); return (node.entry.properties && node.entry.properties[property]) || ''; } catch (error) { - logger.error(`${this.constructor.name} ${this.getNodeProperty.name}`, error); + Logger.error(`${this.constructor.name} ${this.getNodeProperty.name}`, error); return ''; } } @@ -84,7 +84,7 @@ export class FileActionsApi { const lockType = await this.getNodeProperty(nodeId, 'cm:lockType'); return lockType || ''; } catch (error) { - logger.error(`${this.constructor.name} ${this.getLockType.name}`, error); + Logger.error(`${this.constructor.name} ${this.getLockType.name}`, error); return ''; } } @@ -106,8 +106,43 @@ export class FileActionsApi { }; return await Utils.retryCall(locked, data.retry); } catch (error) { - logger.error(`${this.constructor.name} ${this.isFileLockedWriteWithRetry.name}`, error); + Logger.error(`${this.constructor.name} ${this.isFileLockedWriteWithRetry.name}`, error); } return isLocked; } + + private async queryNodesNames(searchTerm: string) { + const data = { + query: { + query: `cm:name:\"${searchTerm}*\"`, + language: 'afts' + }, + filterQueries: [{ query: `+TYPE:'cm:folder' OR +TYPE:'cm:content'` }] + }; + + try { + return this.apiService.search.search(data); + } catch (error) { + Logger.error(`SearchApi queryNodesNames : catch : `, error); + return null; + } + } + async waitForNodes(searchTerm: string, data: { expect: number }) { + const predicate = (totalItems: number) => totalItems === data.expect; + + const apiCall = async () => { + try { + return (await this.queryNodesNames(searchTerm)).list.pagination.totalItems; + } catch (error) { + return 0; + } + }; + + try { + await ApiUtil.waitForApi(apiCall, predicate, 30, 2500); + } catch (error) { + Logger.error(`SearchApi waitForNodes : catch : `); + Logger.error(`\tExpected: ${data.expect} items, but found ${error}`); + } + } }