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
2 changes: 1 addition & 1 deletion plugins/a11y/app/components/SummaryBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const ACTION = 'inline-flex items-center gap-1.5 text-xs color-muted bg-secondar
export function SummaryBar(props: SummaryBarProps) {
const plural = (n: number, one: string) => `${n} ${n === 1 ? one : `${one}s`}`
return (
<div class="flex flex-col gap-2 pt-3 pb-2.5 sticky top-0 z-[2] bg-base">
<div class="flex flex-col gap-2 pt-3 pb-2.5 sticky top-0 z-nav bg-base">
<Summary counts={props.counts} active={props.filter} onToggle={props.onToggleFilter} onHover={props.onHoverImpact} />

<div class="flex items-center gap-2 flex-wrap">
Expand Down
26 changes: 26 additions & 0 deletions tests/e2e/a11y-messages-hub-static.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,32 @@ test.describe('a11y-messages playground (static hub build)', () => {
await expect(page.locator('[data-df-a11y-overlay]')).toContainText('image-alt')
})

test('keeps the a11y summary controls above scrolled violations', async ({ page }) => {
await page.setViewportSize({ width: 1_000, height: 360 })
const panel = page.frameLocator('iframe[title="A11y Inspector"]')

await expect(panel.getByRole('checkbox', { name: /image-alt/ })).toBeVisible()
const scrollArea = panel.locator('#a11y-scroll')
const summary = scrollArea.locator(':scope > div').first()
await scrollArea.evaluate(element => element.scrollTo({ top: element.scrollHeight }))

expect(await scrollArea.evaluate(element => element.scrollTop)).toBeGreaterThan(0)
expect(await summary.locator('button').evaluateAll(buttons => buttons.flatMap((button) => {
const bounds = button.getBoundingClientRect()
const hitTarget = document.elementFromPoint(
bounds.left + bounds.width / 2,
bounds.top + bounds.height / 2,
)
return hitTarget != null && button.contains(hitTarget)
? []
: [button.getAttribute('aria-label') ?? button.title ?? button.textContent?.trim()]
}))).toEqual([])

const critical = panel.getByRole('button', { name: /Critical issues/ })
await critical.click()
await expect(critical).toHaveAttribute('aria-pressed', 'true')
})

test('messages panel renders the baked feed; its activate action switches docks over the BroadcastChannel', async ({ page }) => {
await page.click('button[data-dock-id="devframes_plugin_messages"]')
const panel = page.frameLocator('iframe[title="Messages"]')
Expand Down
Loading