mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
test: add axe a11y pass and device visual regression (phase 4c)
Add scoped axe accessibility audit (a11y.spec.ts, device-a11y.spec.ts)
scanning home, one tool per modality, editor, and login across desktop
chromium and mobile-chromium in EN and AR locales. Uses a committed
baseline (a11y-baseline.json) to gate on NEW critical/serious violations
while documenting existing debt.
Add device-visual.spec.ts with curated screenshots (home, resize tool,
settings dialog) on mobile-chromium and tablet-chromium. Six darwin
baselines generated; linux baselines deferred to the existing
update-visual-baselines workflow.
Trivial a11y fixes applied:
- Login page: outer div -> main (fixes landmark-one-main, reduces region)
- Editor page: outer div -> main for both desktop and mobile gate
- AppLayout main: add tabIndex={-1} for skip-link focusability
Updated DEVICE_SPECS regex to route device-visual and device-a11y specs.
Added @axe-core/playwright as a devDependency.
This commit is contained in:
@@ -37,7 +37,11 @@ export function AppLayout({ children, breadcrumb, navVariant }: AppLayoutProps)
|
||||
/>
|
||||
|
||||
{/* Main content area */}
|
||||
<main id="main-content" className={cn("flex-1 overflow-y-auto", isMobile && "pb-20")}>
|
||||
<main
|
||||
id="main-content"
|
||||
tabIndex={-1}
|
||||
className={cn("flex-1 overflow-y-auto", isMobile && "pb-20")}
|
||||
>
|
||||
{children}
|
||||
</main>
|
||||
|
||||
|
||||
@@ -143,16 +143,16 @@ export function EditorPage() {
|
||||
|
||||
if (isMobile) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center h-full p-8 text-center">
|
||||
<main className="flex flex-col items-center justify-center h-full p-8 text-center">
|
||||
<Monitor size={48} className="text-muted-foreground mb-4" />
|
||||
<h2 className="text-lg font-semibold text-foreground mb-2">{t.editor.mobile.heading}</h2>
|
||||
<p className="text-sm text-muted-foreground max-w-sm">{t.editor.mobile.description}</p>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-screen overflow-hidden bg-background text-foreground">
|
||||
<main className="flex flex-col h-screen overflow-hidden bg-background text-foreground">
|
||||
<h1 className="sr-only">{t.editor.welcome.heading}</h1>
|
||||
<EditorMenuBar
|
||||
onNewDocument={() => setShowNewDocument(true)}
|
||||
@@ -195,6 +195,6 @@ export function EditorPage() {
|
||||
<ImageResizeDialog open={showImageResize} onClose={() => setShowImageResize(false)} />
|
||||
<FillDialog open={fillDialogOpen} onClose={() => setFillDialogOpen(false)} />
|
||||
<NewDocumentDialog open={showNewDocument} onClose={() => setShowNewDocument(false)} />
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ export function LoginPage() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex h-screen bg-background">
|
||||
<main className="flex h-screen bg-background">
|
||||
<div className="flex-1 flex items-center justify-center p-8">
|
||||
<div className="w-full max-w-md space-y-8">
|
||||
<div>
|
||||
@@ -415,6 +415,6 @@ export function LoginPage() {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user