diff --git a/scripts/capture-chrome-parity.ts b/scripts/capture-chrome-parity.ts index 98e0a00c30..567a937173 100644 --- a/scripts/capture-chrome-parity.ts +++ b/scripts/capture-chrome-parity.ts @@ -82,10 +82,6 @@ const selectorGroups: Array<{ key: string; selector: string; pseudo?: string }> { key: "composer-pill-children", selector: 'form:has([data-testid="global-search-input"]) > div > *' }, { key: "composer-input", selector: '[data-testid="global-search-input"]', pseudo: "::placeholder" }, { key: "composer-buttons", selector: 'form:has([data-testid="global-search-input"]) button' }, - { key: "evidence-chip", selector: 'button[aria-label="Open evidence-backed answer sources"]' }, - { key: "evidence-chip-icon", selector: 'button[aria-label="Open evidence-backed answer sources"] svg' }, - { key: "scope-chip", selector: 'button[aria-label="Open source scope"]' }, - { key: "scope-chip-icon", selector: 'button[aria-label="Open source scope"] svg' }, { key: "viewer-header", selector: "main header, body > div > header", pseudo: "::after" }, { key: "viewer-composer", selector: 'form:has(input[placeholder^="Search or answer"])' }, { key: "viewer-composer-children", selector: 'form:has(input[placeholder^="Search or answer"]) > *' }, diff --git a/src/components/clinical-dashboard/master-search-header.tsx b/src/components/clinical-dashboard/master-search-header.tsx index 002dcf7dbf..aee03b76fe 100644 --- a/src/components/clinical-dashboard/master-search-header.tsx +++ b/src/components/clinical-dashboard/master-search-header.tsx @@ -641,11 +641,20 @@ export function MasterSearchHeader({ } } + const restoreActionMenuFocusRef = useRef(false); const closeScope = useCallback((restoreFocus = false) => { + restoreActionMenuFocusRef.current = restoreFocus; setScopeOpen(false); - if (restoreFocus) actionMenuTriggerRef.current?.focus(); }, []); + useEffect(() => { + if (scopeOpen || !restoreActionMenuFocusRef.current) return; + restoreActionMenuFocusRef.current = false; + window.requestAnimationFrame(() => { + actionMenuTriggerRef.current?.focus({ preventScroll: true }); + }); + }, [scopeOpen]); + const closeScopeSheet = useCallback(() => { setScopeSheetOpen(false); window.requestAnimationFrame(() => actionMenuTriggerRef.current?.focus()); diff --git a/src/components/use-dismissable-layer.ts b/src/components/use-dismissable-layer.ts index 05285b4177..7832940834 100644 --- a/src/components/use-dismissable-layer.ts +++ b/src/components/use-dismissable-layer.ts @@ -38,7 +38,11 @@ export function useDismissableLayer({ if (event.key !== "Escape") return; event.preventDefault(); onDismiss("escape"); - window.requestAnimationFrame(() => restoreFocusRef?.current?.focus({ preventScroll: true })); + window.requestAnimationFrame(() => { + window.requestAnimationFrame(() => { + restoreFocusRef?.current?.focus({ preventScroll: true }); + }); + }); } document.addEventListener("pointerdown", handlePointerDown, true); diff --git a/tests/ui-accessibility.spec.ts b/tests/ui-accessibility.spec.ts index f177658af2..cab9cb2385 100644 --- a/tests/ui-accessibility.spec.ts +++ b/tests/ui-accessibility.spec.ts @@ -55,17 +55,19 @@ async function expectDashboardUsable(page: Page) { } async function openScopeControl(page: Page) { - const actionMenu = page.getByRole("button", { name: "Open answer options" }); + const trigger = page.getByRole("button", { name: "Open answer options" }); + const menu = page.getByTestId("daily-actions-menu"); await expect(async () => { - await actionMenu.click(); - const actionsMenu = page.getByTestId("daily-actions-menu"); - await expect(actionsMenu).toBeVisible({ timeout: uiAssertionTimeoutMs }); - await actionsMenu.getByRole("menuitem", { name: /^Scope\b/ }).click(); - await expect(page.getByTestId("scope-command-popover")).toBeVisible({ - timeout: uiAssertionTimeoutMs, - }); + if (await menu.isVisible().catch(() => false)) return; + await trigger.click(); + await expect(menu).toBeVisible({ timeout: uiAssertionTimeoutMs }); }).toPass({ timeout: 10_000 }); + + await menu.getByRole("menuitem", { name: "Scope", exact: true }).click(); + await expect(page.locator('[data-testid="scope-command-popover"]:visible')).toBeVisible({ + timeout: uiAssertionTimeoutMs, + }); } test.describe("Clinical KB accessibility media smoke", () => { diff --git a/tests/ui-smoke.spec.ts b/tests/ui-smoke.spec.ts index 0593c8ba90..0683393677 100644 --- a/tests/ui-smoke.spec.ts +++ b/tests/ui-smoke.spec.ts @@ -1311,7 +1311,9 @@ test.describe("Clinical KB UI smoke coverage", () => { expect(popoverMetrics.height).toBeLessThanOrEqual(Math.ceil(popoverMetrics.viewportHeight * 0.72)); await page.keyboard.press("Escape"); await expect(scopePopover).toBeHidden(); - await expect(page.getByRole("button", { name: "Open answer options" })).toBeFocused(); + await expect(async () => { + await expect(page.getByRole("button", { name: "Open answer options" })).toBeFocused(); + }).toPass({ timeout: 5_000 }); await expectNoPageHorizontalOverflow(page); });