From 69456451feb07315cf1aaed67e2731436d9e177c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=BAlia=20Jaeger=20Foresti?=
 <60678893+juliajforesti@users.noreply.github.com>
Date: Tue, 29 Oct 2024 15:53:53 -0300
Subject: [PATCH] test: add `feature-preview` tests for `Enhanced navigation`
 (#33727)

---
 apps/meteor/tests/e2e/feature-preview.spec.ts | 142 ++++++++++++++++++
 .../tests/e2e/page-objects/account-profile.ts |   8 +
 .../page-objects/fragments/home-sidenav.ts    |  26 ++++
 .../tests/e2e/page-objects/fragments/index.ts |   1 +
 .../e2e/page-objects/fragments/navbar.ts      |  21 +++
 .../tests/e2e/page-objects/home-channel.ts    |   5 +-
 6 files changed, 202 insertions(+), 1 deletion(-)
 create mode 100644 apps/meteor/tests/e2e/feature-preview.spec.ts
 create mode 100644 apps/meteor/tests/e2e/page-objects/fragments/navbar.ts

diff --git a/apps/meteor/tests/e2e/feature-preview.spec.ts b/apps/meteor/tests/e2e/feature-preview.spec.ts
new file mode 100644
index 00000000000..67f8133d8a2
--- /dev/null
+++ b/apps/meteor/tests/e2e/feature-preview.spec.ts
@@ -0,0 +1,142 @@
+import { Users } from './fixtures/userStates';
+import { AccountProfile, HomeChannel } from './page-objects';
+import { setSettingValueById } from './utils';
+import { setUserPreferences } from './utils/setUserPreferences';
+import { test, expect } from './utils/test';
+
+test.use({ storageState: Users.admin.state });
+
+test.describe.serial('feature preview', () => {
+	let poHomeChannel: HomeChannel;
+	let poAccountProfile: AccountProfile;
+
+	test.beforeAll(async ({ api }) => {
+		await setSettingValueById(api, 'Accounts_AllowFeaturePreview', true);
+	});
+
+	test.afterAll(async ({ api }) => {
+		await setSettingValueById(api, 'Accounts_AllowFeaturePreview', false);
+	});
+
+	test.beforeEach(async ({ page }) => {
+		poHomeChannel = new HomeChannel(page);
+		poAccountProfile = new AccountProfile(page);
+	});
+
+	test('should show "Message" and "Navigation" feature sections', async ({ page }) => {
+		await page.goto('/account/feature-preview');
+
+		await expect(page.getByRole('button', { name: 'Message' })).toBeVisible();
+		await expect(page.getByRole('button', { name: 'Navigation' })).toBeVisible();
+	});
+
+	test.describe('Enhanced navigation', () => {
+		test.beforeAll(async ({ api }) => {
+			await setUserPreferences(api, {
+				featuresPreview: [
+					{
+						name: 'newNavigation',
+						value: true,
+					},
+				],
+			});
+		});
+
+		test.afterAll(async ({ api }) => {
+			await setUserPreferences(api, {
+				featuresPreview: [
+					{
+						name: 'newNavigation',
+						value: false,
+					},
+				],
+			});
+		});
+
+		// After moving `Enhanced navigation` out of feature preview, move these tests to sidebar.spec.ts
+		test('should be able to toggle "Enhanced navigation" feature', async ({ page }) => {
+			await page.goto('/account/feature-preview');
+
+			await poAccountProfile.getAccordionItemByName('Navigation').click();
+			const newNavigationCheckbox = poAccountProfile.getCheckboxByLabelText('Enhanced navigation');
+			await expect(newNavigationCheckbox).toBeChecked();
+			await newNavigationCheckbox.click();
+			await expect(newNavigationCheckbox).not.toBeChecked();
+		});
+
+		test('should be rendering new UI with "Enhanced navigation"', async ({ page }) => {
+			await page.goto('/account/feature-preview');
+
+			await expect(poHomeChannel.navbar.navbar).toBeVisible();
+		});
+
+		test('should display "Recent" button on sidebar search section, and display recent chats when clicked', async ({ page }) => {
+			await page.goto('/home');
+
+			await poHomeChannel.sidenav.btnRecent.click();
+			await expect(poHomeChannel.sidenav.sidebar.getByRole('heading', { name: 'Recent' })).toBeVisible();
+		});
+
+		test('should expand/collapse sidebar groups', async ({ page }) => {
+			await page.goto('/home');
+			const collapser = poHomeChannel.sidenav.firstCollapser;
+			let isExpanded: boolean;
+
+			await collapser.click();
+			isExpanded = (await collapser.getAttribute('aria-expanded')) === 'true';
+			expect(isExpanded).toBeFalsy();
+
+			await collapser.click();
+			isExpanded = (await collapser.getAttribute('aria-expanded')) === 'true';
+			expect(isExpanded).toBeTruthy();
+		});
+
+		test('should expand/collapse sidebar groups with keyboard', async ({ page }) => {
+			await page.goto('/home');
+
+			const collapser = poHomeChannel.sidenav.firstCollapser;
+
+			await expect(async () => {
+				await collapser.focus();
+				await expect(collapser).toBeFocused();
+				await page.keyboard.press('Enter');
+				const isExpanded = (await collapser.getAttribute('aria-expanded')) === 'true';
+				expect(isExpanded).toBeFalsy();
+			}).toPass();
+
+			await expect(async () => {
+				await collapser.focus();
+				await page.keyboard.press('Space');
+				const isExpanded = (await collapser.getAttribute('aria-expanded')) === 'true';
+				expect(isExpanded).toBeTruthy();
+			}).toPass();
+		});
+
+		test('should be able to use keyboard to navigate through sidebar items', async ({ page }) => {
+			await page.goto('/home');
+
+			const collapser = poHomeChannel.sidenav.firstCollapser;
+			const dataIndex = await collapser.locator('../..').getAttribute('data-index');
+			const nextItem = page.locator(`[data-index="${Number(dataIndex) + 1}"]`).getByRole('link');
+
+			await expect(async () => {
+				await collapser.focus();
+				await page.keyboard.press('ArrowDown');
+				await expect(nextItem).toBeFocused();
+			}).toPass();
+		});
+
+		test('should persist collapsed/expanded groups after page reload', async ({ page }) => {
+			await page.goto('/home');
+
+			const collapser = poHomeChannel.sidenav.firstCollapser;
+			await collapser.click();
+			const isExpanded = await collapser.getAttribute('aria-expanded');
+
+			await page.reload();
+
+			const isExpandedAfterReload = await collapser.getAttribute('aria-expanded');
+			expect(isExpanded).toEqual(isExpandedAfterReload);
+		});
+	});
+});
diff --git a/apps/meteor/tests/e2e/page-objects/account-profile.ts b/apps/meteor/tests/e2e/page-objects/account-profile.ts
index 971b6dffc86..f7f41911e6d 100644
--- a/apps/meteor/tests/e2e/page-objects/account-profile.ts
+++ b/apps/meteor/tests/e2e/page-objects/account-profile.ts
@@ -111,4 +111,12 @@ export class AccountProfile {
 	get securityE2EEncryptionSavePasswordButton(): Locator {
 		return this.page.locator("role=button[name='Save changes']");
 	}
+
+	getAccordionItemByName(name: string): Locator {
+		return this.page.getByRole('button', { name, exact: true });
+	}
+
+	getCheckboxByLabelText(name: string): Locator {
+		return this.page.locator('label', { has: this.page.getByRole('checkbox', { name }) });
+	}
 }
diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
index 823469d02a9..8af5e8b1237 100644
--- a/apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
+++ b/apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
@@ -188,4 +188,30 @@ export class HomeSidenav {
 	getSearchChannelBadge(name: string): Locator {
 		return this.page.locator(`[data-qa="sidebar-item"][aria-label="${name}"]`).first().getByRole('status', { exact: true });
 	}
+
+	// New navigation selectors
+
+	get sidebar(): Locator {
+		return this.page.getByRole('navigation', { name: 'sidebar' });
+	}
+
+	get sidebarSearchSection(): Locator {
+		return this.sidebar.getByRole('search');
+	}
+
+	get btnRecent(): Locator {
+		return this.sidebarSearchSection.getByRole('button', { name: 'Recent' });
+	}
+
+	get channelsList(): Locator {
+		return this.sidebar.getByRole('list', { name: 'Channels' });
+	}
+
+	getCollapseGroupByName(name: string): Locator {
+		return this.channelsList.getByRole('button', { name, exact: true });
+	}
+
+	get firstCollapser(): Locator {
+		return this.channelsList.getByRole('button').first();
+	}
 }
diff --git a/apps/meteor/tests/e2e/page-objects/fragments/index.ts b/apps/meteor/tests/e2e/page-objects/fragments/index.ts
index e0d7c8e45d9..02f1769ba7e 100644
--- a/apps/meteor/tests/e2e/page-objects/fragments/index.ts
+++ b/apps/meteor/tests/e2e/page-objects/fragments/index.ts
@@ -4,3 +4,4 @@ export * from './home-flextab';
 export * from './home-sidenav';
 export * from './omnichannel-sidenav';
 export * from './omnichannel-close-chat-modal';
+export * from './navbar';
diff --git a/apps/meteor/tests/e2e/page-objects/fragments/navbar.ts b/apps/meteor/tests/e2e/page-objects/fragments/navbar.ts
new file mode 100644
index 00000000000..55cda22ed09
--- /dev/null
+++ b/apps/meteor/tests/e2e/page-objects/fragments/navbar.ts
@@ -0,0 +1,21 @@
+import type { Locator, Page } from '@playwright/test';
+
+export class Navbar {
+	private readonly page: Page;
+
+	constructor(page: Page) {
+		this.page = page;
+	}
+
+	get navbar(): Locator {
+		return this.page.getByRole('navigation', { name: 'header' });
+	}
+
+	get pagesToolbar(): Locator {
+		return this.navbar.getByRole('toolbar', { name: 'Pages' });
+	}
+
+	get homeButton(): Locator {
+		return this.pagesToolbar.getByRole('button', { name: 'Home' });
+	}
+}
diff --git a/apps/meteor/tests/e2e/page-objects/home-channel.ts b/apps/meteor/tests/e2e/page-objects/home-channel.ts
index ce51896eb44..15b471e15b4 100644
--- a/apps/meteor/tests/e2e/page-objects/home-channel.ts
+++ b/apps/meteor/tests/e2e/page-objects/home-channel.ts
@@ -1,6 +1,6 @@
 import type { Locator, Page } from '@playwright/test';
 
-import { HomeContent, HomeSidenav, HomeFlextab } from './fragments';
+import { HomeContent, HomeSidenav, HomeFlextab, Navbar } from './fragments';
 
 export class HomeChannel {
 	public readonly page: Page;
@@ -9,12 +9,15 @@ export class HomeChannel {
 
 	readonly sidenav: HomeSidenav;
 
+	readonly navbar: Navbar;
+
 	readonly tabs: HomeFlextab;
 
 	constructor(page: Page) {
 		this.page = page;
 		this.content = new HomeContent(page);
 		this.sidenav = new HomeSidenav(page);
+		this.navbar = new Navbar(page);
 		this.tabs = new HomeFlextab(page);
 	}
 
-- 
GitLab