Skip to content
Merged
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
43 changes: 43 additions & 0 deletions tests/e2e/community-people.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,49 @@ test.describe('TAB roster profile dialog', () => {
.toBe(true);
});

test('Shift+Tab from the first focusable element wraps to the last', async ({
page,
}) => {
const { dialog } = await openProfile(page);

// useFocusTrap mounts with focus on the close button, which is the first
// element its `button, a[href]` query matches. Backwards from there is the
// only way into the `event.shiftKey && activeElement === first` arm of
// src/components/hooks/useFocusTrap.js: forwards tabbing short-circuits on
// `event.shiftKey` and never evaluates it. Without this case the dialog
// could leak focus to the roster behind it on Shift+Tab and every existing
// assertion would still pass.
const focusable = dialog.locator('button, a[href]');
const count = await focusable.count();
expect(count).toBeGreaterThan(1);

await expect(focusable.first()).toBeFocused();

await page.keyboard.press('Shift+Tab');

await expect(focusable.nth(count - 1)).toBeFocused();
});

test('a key that is neither Escape nor Tab leaves the dialog alone', async ({
page,
}) => {
const { dialog } = await openProfile(page);

const focusable = dialog.locator('button, a[href]');
await expect(focusable.first()).toBeFocused();

// The keydown listener is on `document`, so it sees every key pressed
// while the dialog is mounted, not only the two it acts on. This is the
// early `return` for everything else: an ordinary key must neither close
// the dialog nor move focus, which is what stops typing from behaving like
// Escape or Tab.
for (const key of ['a', 'ArrowDown', 'End']) {
await page.keyboard.press(key);
await expect(dialog).toBeVisible();
await expect(focusable.first()).toBeFocused();
}
});

test('offers only absolute external profile links', async ({ page }) => {
const { dialog } = await openProfile(page);

Expand Down
Loading