Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/olive-nails-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Enables keyboard activation for Display menu radio buttons and checkboxes
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,22 @@ export const useGroupingListItems = (): GenericMenuItemProps[] => {
id: 'unread',
content: t('Unread'),
icon: 'flag',
addon: <CheckBox onChange={handleChangeShowUnread} checked={sidebarShowUnread} />,
onClick: handleChangeShowUnread,
addon: <CheckBox checked={sidebarShowUnread} onChange={() => undefined} />,
},
!secondSidebarEnabled && {
id: 'favorites',
content: t('Favorites'),
icon: 'star',
addon: <CheckBox onChange={handleChangeShoFavorite} checked={sidebarShowFavorites} />,
onClick: handleChangeShoFavorite,
addon: <CheckBox checked={sidebarShowFavorites} onChange={() => undefined} />,
},
{
id: 'types',
content: t('Types'),
icon: 'group-by-type',
addon: <CheckBox onChange={handleChangeGroupByType} checked={sidebarGroupByType} />,
onClick: handleChangeGroupByType,
addon: <CheckBox checked={sidebarGroupByType} onChange={() => undefined} />,
},
].filter(Boolean) as GenericMenuItemProps[];
};
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ export const useSortModeItems = (): GenericMenuItemProps[] => {
id: 'activity',
content: t('Activity'),
icon: 'clock',
addon: <RadioButton onChange={setToActivity} checked={sidebarSortBy === 'activity'} />,
onClick: setToActivity,
addon: <RadioButton checked={sidebarSortBy === 'activity'} onChange={() => undefined} />,
description: sidebarSortBy === 'activity' && isOmnichannelEnabled && <OmnichannelSortingDisclaimer />,
},
{
id: 'name',
content: t('Name'),
icon: 'sort-az',
addon: <RadioButton onChange={setToAlphabetical} checked={sidebarSortBy === 'alphabetical'} />,
onClick: setToAlphabetical,
addon: <RadioButton checked={sidebarSortBy === 'alphabetical'} onChange={() => undefined} />,
description: sidebarSortBy === 'alphabetical' && isOmnichannelEnabled && <OmnichannelSortingDisclaimer />,
},
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,29 @@ export const useViewModeItems = (): GenericMenuItemProps[] => {
id: 'extended',
content: t('Extended'),
icon: 'extended-view',
addon: <RadioButton onChange={setToExtended} checked={sidebarViewMode === 'extended'} />,
onClick: setToExtended,
addon: <RadioButton checked={sidebarViewMode === 'extended'} onChange={() => undefined} />,
},
{
id: 'medium',
content: t('Medium'),
icon: 'medium-view',
addon: <RadioButton onChange={setToMedium} checked={sidebarViewMode === 'medium'} />,
onClick: setToMedium,
addon: <RadioButton checked={sidebarViewMode === 'medium'} onChange={() => undefined} />,
},
{
id: 'condensed',
content: t('Condensed'),
icon: 'condensed-view',
addon: <RadioButton onChange={setToCondensed} checked={sidebarViewMode === 'condensed'} />,
onClick: setToCondensed,
addon: <RadioButton checked={sidebarViewMode === 'condensed'} onChange={() => undefined} />,
},
{
id: 'avatars',
content: t('Avatars'),
icon: 'user-rounded',
addon: <ToggleSwitch onChange={handleChangeSidebarDisplayAvatar} checked={sidebarDisplayAvatar} />,
onClick: handleChangeSidebarDisplayAvatar,
addon: <ToggleSwitch checked={sidebarDisplayAvatar} onChange={() => undefined} />,
},
];
};
24 changes: 24 additions & 0 deletions apps/meteor/tests/e2e/page-objects/fragments/navbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,30 @@ export class Navbar {
return this.root.getByRole('menu', { name: 'Display' });
}

get groupDisplay(): Locator {
return this.menuDisplay.getByRole('group', { name: 'Display' });
}

getDisplayMenuItem(mode: 'Extended' | 'Medium' | 'Condensed' | 'Avatars'): Locator {
return this.groupDisplay.getByRole('menuitemcheckbox', { name: mode });
}

get groupSortBy(): Locator {
return this.menuDisplay.getByRole('group', { name: 'Sort by' });
}

getSortMenuItem(mode: 'Activity' | 'Name'): Locator {
return this.groupSortBy.getByRole('menuitemcheckbox', { name: mode });
}

get groupGroupBy(): Locator {
return this.menuDisplay.getByRole('group', { name: 'Group by' });
}

getGroupByMenuItem(mode: 'Unread' | 'Favorites' | 'Types'): Locator {
return this.groupGroupBy.getByRole('menuitemcheckbox', { name: mode });
}

get btnCreateNew(): Locator {
return this.pagesGroup.getByRole('button', { name: 'Create new' });
}
Expand Down
69 changes: 69 additions & 0 deletions apps/meteor/tests/e2e/sidebar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,75 @@ test.describe.serial('Sidebar', () => {
});
});

test.describe('Display menu keyboard accessibility', () => {
const defaultPreferences = {
sidebarViewMode: 'extended',
sidebarDisplayAvatar: true,
sidebarSortby: 'activity',
sidebarShowUnread: false,
};

test.beforeEach(async ({ api }) => {
await api.post('/users.setPreferences', { data: defaultPreferences });
});

test.afterEach(async ({ api }) => {
Comment thread
juliajforesti marked this conversation as resolved.
await api.post('/users.setPreferences', { data: defaultPreferences });
});
Comment thread
tassoevan marked this conversation as resolved.

test('should change view mode using keyboard', async ({ page }) => {
await poHomeChannel.navbar.btnDisplay.focus();
await page.keyboard.press('Enter');
await expect(poHomeChannel.navbar.menuDisplay).toBeVisible();

await poHomeChannel.navbar.getDisplayMenuItem('Medium').focus();

await page.keyboard.press('Space');

await expect(poHomeChannel.navbar.getDisplayMenuItem('Medium').getByRole('radio')).toBeChecked();
await page.keyboard.press('Escape');
});

test('should toggle Avatars using keyboard', async ({ page }) => {
await poHomeChannel.navbar.btnDisplay.click();
const avatarsItem = poHomeChannel.navbar.getDisplayMenuItem('Avatars');

await avatarsItem.focus();
await page.keyboard.press('Space');

const newAvatarsItem = poHomeChannel.navbar.getDisplayMenuItem('Avatars');
await expect(newAvatarsItem.getByRole('checkbox')).not.toBeChecked();
await page.keyboard.press('Escape');
});

test('should change sort mode using keyboard', async ({ page }) => {
await poHomeChannel.navbar.btnDisplay.focus();
await page.keyboard.press('Enter');
await expect(poHomeChannel.navbar.menuDisplay).toBeVisible();
await poHomeChannel.navbar.getSortMenuItem('Activity').focus();
await page.keyboard.press('ArrowDown');
await expect(poHomeChannel.navbar.getSortMenuItem('Name')).toBeFocused();
await page.keyboard.press('Space');

await expect(poHomeChannel.navbar.getSortMenuItem('Name').getByRole('radio')).toBeChecked();
await page.keyboard.press('Escape');
});

test('should toggle grouping using keyboard', async ({ page }) => {
await poHomeChannel.navbar.btnDisplay.focus();
await page.keyboard.press('Enter');

const unreadItem = poHomeChannel.navbar.getGroupByMenuItem('Unread');
await expect(unreadItem.getByRole('checkbox')).not.toBeChecked();

await unreadItem.focus();
await page.keyboard.press('Space');

await expect(poHomeChannel.navbar.getGroupByMenuItem('Unread').getByRole('checkbox')).toBeChecked();
await page.keyboard.press('Escape');
});
});

test.describe('sidebar', async () => {
test('should navigate on sidebar items using arrow keys and restore focus', async ({ page }) => {
// focus should be on the next item
Expand Down
Loading