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 000000000000..ea93e1d20b73 --- /dev/null +++ b/apps/meteor/tests/e2e/feature-preview.spec.ts @@ -0,0 +1,136 @@ +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 teamsCollapseGroup = poHomeChannel.sidenav.getCollapseGroupByName('Conversations'); + let isExpanded: boolean; + + await teamsCollapseGroup.click(); + isExpanded = (await teamsCollapseGroup.getAttribute('aria-expanded')) === 'true'; + expect(isExpanded).toBeFalsy(); + + await teamsCollapseGroup.click(); + isExpanded = (await teamsCollapseGroup.getAttribute('aria-expanded')) === 'true'; + expect(isExpanded).toBeTruthy(); + }); + + test('should expand/collapse sidebar groups with keyboard', async ({ page }) => { + await page.goto('/home'); + + const teamsCollapseGroup = poHomeChannel.sidenav.getCollapseGroupByName('Conversations'); + let isExpanded: boolean; + + await teamsCollapseGroup.focus(); + await page.keyboard.press('Space'); + isExpanded = (await teamsCollapseGroup.getAttribute('aria-expanded')) === 'true'; + expect(isExpanded).toBeFalsy(); + + await page.keyboard.press('Enter'); + isExpanded = (await teamsCollapseGroup.getAttribute('aria-expanded')) === 'true'; + expect(isExpanded).toBeTruthy(); + }); + + test('should be able to use keyboard to navigate through sidebar items', async ({ page }) => { + await page.goto('/home'); + + const teamsCollapseGroup = poHomeChannel.sidenav.getCollapseGroupByName('Conversations'); + await teamsCollapseGroup.focus(); + + const dataIndex = await teamsCollapseGroup.locator('../..').getAttribute('data-index'); + const nextItem = page.locator(`[data-index="${Number(dataIndex) + 1}"]`).getByRole('link'); + + await page.keyboard.press('ArrowDown'); + await expect(nextItem).toBeFocused(); + }); + + test('should persist collapsed/expanded groups after page reload', async ({ page }) => { + await page.goto('/home'); + + const teamsCollapseGroup = poHomeChannel.sidenav.getCollapseGroupByName('Conversations'); + await teamsCollapseGroup.click(); + const isExpanded = await teamsCollapseGroup.getAttribute('aria-expanded'); + + await page.reload(); + + const isExpandedAfterReload = await teamsCollapseGroup.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 971b6dffc86e..f7f41911e6d3 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 823469d02a96..dd1eb0b42f46 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,26 @@ 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 }); + } } diff --git a/apps/meteor/tests/e2e/page-objects/fragments/index.ts b/apps/meteor/tests/e2e/page-objects/fragments/index.ts index e0d7c8e45d9a..02f1769ba7ea 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 000000000000..55cda22ed09e --- /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 ce51896eb449..15b471e15b4c 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); }