From 335c5ba85c367d662c3c99e436cb781c665716b6 Mon Sep 17 00:00:00 2001
From: "akash.rathod@hyland.com" <akash.rathod@hyland.com>
Date: Wed, 20 Sep 2023 11:43:58 +0200
Subject: [PATCH 1/4] [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 <http://www.gnu.org/licenses/>.
+ */
+
+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 <http://www.gnu.org/licenses/>.
+ */
+
+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 <http://www.gnu.org/licenses/>.
+ */
+
+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<void> {
     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<void> {
-    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 <http://www.gnu.org/licenses/>.
+ */
+
+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<boolean> {
+    const cssClass = await this.getLinkLabel(name).getAttribute('class');
+    return cssClass.includes('action-button--active');
+  }
+
+  async openPanel(name: string): Promise<void> {
+    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<boolean> {
+    return this.expandedSidenav.isVisible();
+  }
+
+  async expandSideNav(): Promise<void> {
+    const expanded = await this.isSidenavExpanded();
+    if (!expanded) {
+      await this.sidenavExpand.click();
+      await this.expandedSidenav.waitFor({ state: 'attached' });
+    }
+  }
+
+  async collapseSideNav(): Promise<void> {
+    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 <http://www.gnu.org/licenses/>.
+ */
+
+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<void> {
     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<void> {
     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 <http://www.gnu.org/licenses/>.
  */
 
-
 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 <http://www.gnu.org/licenses/>.
+ */
+
+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" <akash.rathod@hyland.com>
Date: Wed, 20 Sep 2023 12:24:33 +0200
Subject: [PATCH 2/4] 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 <http://www.gnu.org/licenses/>.
- */
-
-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" <akash.rathod@hyland.com>
Date: Thu, 21 Sep 2023 14:51:26 +0200
Subject: [PATCH 3/4] 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 <http://www.gnu.org/licenses/>.
  */
 
+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 3a236ed4daeee9aa9cb000d4287129d933fde69c Mon Sep 17 00:00:00 2001
From: Akash Rathod <41251473+akashrathod28@users.noreply.github.com>
Date: Fri, 22 Sep 2023 13:34:12 +0200
Subject: [PATCH 4/4] Update error message for expect

---
 e2e/playwright/navigation/src/tests/sidebar.spec.ts | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/e2e/playwright/navigation/src/tests/sidebar.spec.ts b/e2e/playwright/navigation/src/tests/sidebar.spec.ts
index e64a8835e5..7fcc577f1b 100644
--- a/e2e/playwright/navigation/src/tests/sidebar.spec.ts
+++ b/e2e/playwright/navigation/src/tests/sidebar.spec.ts
@@ -50,21 +50,21 @@ test.describe('Sidebar', () => {
 
   test('[C269100] sidebar state is preserved on page refresh', async ({ personalFiles }) => {
     await personalFiles.navigate();
-    expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar expanded').toBe(true);
+    expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar not expanded').toBe(true);
     await personalFiles.reload();
-    expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar expanded').toBe(true);
+    expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar not expanded').toBe(true);
 
     await personalFiles.sidenav.collapseSideNav();
 
-    expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar not expanded').toBe(false);
+    expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar expanded').toBe(false);
     await personalFiles.reload();
-    expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar not expanded').toBe(false);
+    expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar 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);
+    expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar expanded').toBe(false);
     await personalFiles.sidenav.expandSideNav();
     expect(await personalFiles.sidenav.isSidenavExpanded(), 'Sidebar not expanded').toBe(true);
   });