From ee5b94099a4bf51f7e7f28149ee404051b61efe6 Mon Sep 17 00:00:00 2001 From: Tudor Date: Thu, 2 Jul 2026 10:53:50 +0100 Subject: [PATCH] chore(audit): axe harness and notes template for UX audit Co-Authored-By: Claude Fable 5 --- .../2026-07-02-ux-audit-notes/TEMPLATE.md | 29 +++++++++++++++++++ .../2026-07-02-ux-audit-notes/axe-snippet.js | 27 +++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-02-ux-audit-notes/TEMPLATE.md create mode 100644 docs/superpowers/specs/2026-07-02-ux-audit-notes/axe-snippet.js diff --git a/docs/superpowers/specs/2026-07-02-ux-audit-notes/TEMPLATE.md b/docs/superpowers/specs/2026-07-02-ux-audit-notes/TEMPLATE.md new file mode 100644 index 0000000..426d7e9 --- /dev/null +++ b/docs/superpowers/specs/2026-07-02-ux-audit-notes/TEMPLATE.md @@ -0,0 +1,29 @@ +# Journey N: — audit notes + +**Pages visited:** +**Viewports:** 390×844, 1440×900 + +## Task attempt log + + +## Friction points +For each: +- **F. ** + - Evidence: + - Criterion violated: + - Argument: + - Severity guess: + +## Works well — keep +- + +## Axe results +- @ : violations — + +## Manual WCAG spot checks +- Touch targets ≥24px on interactive elements: +- Keyboard: tab order, focus visibility (desktop only): +- Zoom 200% text reflow (desktop only): + +## Screenshots +- : diff --git a/docs/superpowers/specs/2026-07-02-ux-audit-notes/axe-snippet.js b/docs/superpowers/specs/2026-07-02-ux-audit-notes/axe-snippet.js new file mode 100644 index 0000000..f3b7c6d --- /dev/null +++ b/docs/superpowers/specs/2026-07-02-ux-audit-notes/axe-snippet.js @@ -0,0 +1,27 @@ +// Body for playwright browser_evaluate: () => { ...this content... } +// Loads axe-core 4.x from CDN (skips if already present), runs WCAG A/AA scan. +return (async () => { + if (!window.axe) { + await new Promise((resolve, reject) => { + const s = document.createElement('script'); + s.src = 'https://cdn.jsdelivr.net/npm/axe-core@4.10.2/axe.min.js'; + s.onload = resolve; + s.onerror = () => reject(new Error('axe failed to load')); + document.head.appendChild(s); + }); + } + const results = await window.axe.run(document, { + runOnly: { type: 'tag', values: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa'] } + }); + return { + url: location.pathname, + violationCount: results.violations.length, + violations: results.violations.map(v => ({ + id: v.id, + impact: v.impact, + description: v.help, + nodes: v.nodes.length, + sampleTargets: v.nodes.slice(0, 3).map(n => n.target.join(' ')) + })) + }; +})();