Restore gist focus to the list and stop claiming the dialog is modal.

SVG nodes are not HTMLElements and sit in an aria-hidden figure, so close returns to the matching card. The gist stays non-modal: no aria-modal, no Tab trap, and destination or outside activation dismisses it.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-27 02:17:43 +02:00
parent 334b30145e
commit 4389f3dd3c
4 changed files with 273 additions and 30 deletions

View File

@@ -68,6 +68,35 @@ test.describe('Systems Map', () => {
}
});
test('SVG node gist dialog restores focus after Escape and the close button', async ({
page,
}) => {
const copy = SIGNATURE_COPY.de.systemsMap;
await page.goto(pagePath('services', 'de'));
await page.setViewportSize({ width: 1440, height: 900 });
const svgNode = page.locator('.systems-map-figure .systems-map-node').first();
const listNode = page.locator('.systems-map-cards a').first();
await expect(page.locator('.systems-map-figure')).toBeVisible();
await svgNode.click();
const dialog = page.getByRole('dialog');
await expect(dialog).toBeVisible();
await expect(dialog).not.toHaveAttribute('aria-modal');
await page.keyboard.press('Escape');
await expect(dialog).toHaveCount(0);
await expect(listNode).toBeFocused();
expect(await page.evaluate(() => document.activeElement === document.body)).toBe(false);
await svgNode.click();
await expect(dialog).toBeVisible();
await dialog.getByRole('button', { name: copy.closeLabel }).click();
await expect(dialog).toHaveCount(0);
await expect(listNode).toBeFocused();
expect(await page.evaluate(() => document.activeElement === document.body)).toBe(false);
});
test('plain activation opens the gist dialog without navigating', async ({ page }) => {
const copy = SIGNATURE_COPY.de.systemsMap;
await page.goto(pagePath('services', 'de'));
@@ -80,6 +109,7 @@ test.describe('Systems Map', () => {
await first.click();
const dialog = page.getByRole('dialog');
await expect(dialog).toBeVisible();
await expect(dialog).not.toHaveAttribute('aria-modal');
await expect(page).toHaveURL(new RegExp(`${pagePath('services', 'de')}$`));
await expect(dialog.getByRole('link')).toHaveAttribute('href', href ?? '');
await expect(dialog.getByRole('button', { name: copy.closeLabel })).toBeVisible();
@@ -93,6 +123,29 @@ test.describe('Systems Map', () => {
await expect(first).toBeFocused();
});
test('destination and outside activation dismiss the gist and restore focus', async ({
page,
}) => {
await page.goto(pagePath('services', 'de'));
await page.setViewportSize({ width: 390, height: 844 });
const first = page.locator('.systems-map-cards a').first();
await first.click();
const dialog = page.getByRole('dialog');
await expect(dialog).toBeVisible();
await dialog.getByRole('link').click();
await expect(dialog).toHaveCount(0);
await expect(page).toHaveURL(/#infrastructure-network/);
await expect(first).toBeFocused();
await first.click();
await expect(dialog).toBeVisible();
await page.locator('.systems-map-heading').click();
await expect(dialog).toHaveCount(0);
await expect(first).toBeFocused();
expect(await page.evaluate(() => document.activeElement === document.body)).toBe(false);
});
test('a modified click follows the node href', async ({ page }) => {
await page.goto(pagePath('services', 'de'));
const first = page.locator('.systems-map-cards a').first();