diff --git a/frontend/e2e/routes.ts b/frontend/e2e/routes.ts index a6ef2c01..b177c2f2 100644 --- a/frontend/e2e/routes.ts +++ b/frontend/e2e/routes.ts @@ -75,7 +75,6 @@ export const ROUTE_MANIFEST: RouteManifestEntry[] = [ { rule: 'aria-progressbar-name', tabs: ['Tasks'], target: /\.bg-primary\\\/20/ }, { rule: 'button-name', tabs: ['Files'], target: /tooltip-trigger.*size-8\[data-slot="button"\]/ }, { rule: 'target-size', tabs: ['Files'], target: /text-blue-400|button\[aria-label="Select / }, - { rule: 'color-contrast', tabs: ['Screenshots'], target: /\.text-primary > \.font-semibold\.truncate/ }, // The same file-manager row metadata waived on /resources — the Files tab embeds it. { rule: 'color-contrast', tabs: ['Files'], target: /text-muted-foreground\\?\/80/ }, { diff --git a/frontend/e2e/specs/cross/contrast.spec.ts b/frontend/e2e/specs/cross/contrast.spec.ts index 723d4306..40b9d0e7 100644 --- a/frontend/e2e/specs/cross/contrast.spec.ts +++ b/frontend/e2e/specs/cross/contrast.spec.ts @@ -1,6 +1,7 @@ import { readFileSync } from 'node:fs'; import type { BadgeVariant } from '@/components/ui/badge'; +import type { ButtonVariant } from '@/components/ui/button'; import { badgeVariants } from '@/components/ui/badge'; import { buttonVariants } from '@/components/ui/button'; @@ -32,7 +33,16 @@ const declaredEditorTokens = (): string[] => { return [...new Set(css.match(/--editor-[\w-]+/g) ?? [])].map((token) => token.slice(2)); }; -// Keyed off the union so a newly added variant fails to compile until it is probed. +// Keyed off the unions so a newly added variant fails to compile until it is probed. +const BUTTON_VARIANTS = Object.keys({ + default: true, + destructive: true, + ghost: true, + link: true, + outline: true, + secondary: true, +} satisfies Record) as ButtonVariant[]; + const BADGE_VARIANTS = Object.keys({ blue: true, default: true, @@ -91,19 +101,26 @@ for (const theme of THEMES) { } }); - test('the destructive button clears AA at rest and on hover', async ({ page }) => { + test('every button variant clears AA at rest and on hover', async ({ page }) => { await page.goto('/flows'); await expect(page.getByRole('row', { name: /E2E Alpha/ })).toBeVisible(); await expect(page.locator('html')).toHaveClass(theme === 'dark' ? /dark/ : /light/); - await mountContrastProbes(page, { destructive: buttonVariants({ variant: 'destructive' }) }); + await mountContrastProbes( + page, + Object.fromEntries(BUTTON_VARIANTS.map((variant) => [variant, buttonVariants({ variant })])), + ); - expect.soft(await measureContrast(page, 'destructive'), 'button at rest').toBeGreaterThanOrEqual(AA_NORMAL); + for (const variant of BUTTON_VARIANTS) { + expect + .soft(await measureContrast(page, variant), `button ${variant} at rest`) + .toBeGreaterThanOrEqual(AA_NORMAL); - await page.locator('[data-contrast="destructive"]').hover(); - expect - .soft(await measureContrast(page, 'destructive'), 'button on hover') - .toBeGreaterThanOrEqual(AA_NORMAL); + await page.locator(`[data-contrast="${variant}"]`).hover(); + expect + .soft(await measureContrast(page, variant), `button ${variant} on hover`) + .toBeGreaterThanOrEqual(AA_NORMAL); + } }); test('editor highlight tokens clear AA on the editor surface', async ({ page }) => { diff --git a/frontend/src/components/shared/file-manager/file-manager.tsx b/frontend/src/components/shared/file-manager/file-manager.tsx index 895174f5..e576a066 100644 --- a/frontend/src/components/shared/file-manager/file-manager.tsx +++ b/frontend/src/components/shared/file-manager/file-manager.tsx @@ -365,7 +365,7 @@ export function FileManager({ return (