Skip to content
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5a375d3
feat: add interactive playground page for auto-scan demo
timdamen Feb 28, 2026
4ff5f53
feat: Define shared types for test-utils
timdamen Feb 28, 2026
973a8c0
feat: Implement failure message formatting
timdamen Feb 28, 2026
ddab81f
feat: Implement core runA11yScan utility
timdamen Feb 28, 2026
cc59fca
feat: Configure unbuild for test-utils output
timdamen Feb 28, 2026
5852422
feat: Update package.json exports and peer dependencies
timdamen Feb 28, 2026
77b9d9d
feat: Add unit tests for failure message formatting
timdamen Feb 28, 2026
f09bf55
feat: Add unit tests for runA11yScan and ScanResult
timdamen Feb 28, 2026
17adfb7
feat: Implement multi-route auto-scan utility with threshold support
timdamen Feb 28, 2026
4efdec0
feat: Add unit tests for auto-scan utility
timdamen Feb 28, 2026
ac5c028
feat: Implement Playwright browser helpers with auto-wait
timdamen Feb 28, 2026
98443f8
feat: Implement Vitest custom matcher toHaveNoA11yViolations
timdamen Feb 28, 2026
06b2493
feat: Add unit tests for Vitest custom matcher
timdamen Feb 28, 2026
6c94112
feat: Set up auto-scan integration test across all playground routes
timdamen Feb 28, 2026
28912ec
feat: Set up Playwright integration test for playground with test-utils
timdamen Feb 28, 2026
1c324bf
feat: Set up Vitest integration test for playground with test-utils
timdamen Feb 28, 2026
7ad78cd
feat: Add JSDoc documentation for public API
timdamen Feb 28, 2026
0957da4
fix: e2e test failure
timdamen Feb 28, 2026
4d29e65
fix: add extra utlity need for intergration
timdamen Feb 28, 2026
4584827
chore: QR comments
timdamen Feb 28, 2026
748b85a
chore: linting
timdamen Feb 28, 2026
117cb75
test: fix test case
timdamen Feb 28, 2026
627c26a
test: improve tests
timdamen Feb 28, 2026
f046bbb
chore: fix ups
timdamen Feb 28, 2026
89ad000
merge: resolve conflicts with main in interactive.vue
timdamen Feb 28, 2026
6ff37f4
feat: change name playwright to browser and add Observer mode
timdamen Mar 1, 2026
5505a5a
fix: cap axe running time
timdamen Mar 1, 2026
b16cc65
fix: throws auto-scan if already exist
timdamen Mar 1, 2026
1b7bba3
fix: accumulation axe results
timdamen Mar 2, 2026
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
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ coverage
*.iml
.idea

# Beads
.beads
.dolt
.doltcfg
beads_a11y
.ralph-tui
/tasks
/config.yml

# OSX
.DS_Store
.AppleDouble
Expand Down
18 changes: 18 additions & 0 deletions build.config.test-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { defineBuildConfig } from 'unbuild'

export default defineBuildConfig({
entries: [
'src/test-utils/index',
'src/test-utils/setup',
'src/test-utils/playwright',
],
outDir: 'dist',
clean: false,
declaration: 'node16',
externals: [
'vitest',
'playwright-core',
'axe-core',
'linkedom',
],
})
13 changes: 13 additions & 0 deletions build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineBuildConfig } from 'unbuild'

export default defineBuildConfig({
hooks: {
'build:done'(ctx) {
for (const warning of ctx.warnings) {
if (warning.includes('test-utils')) {
ctx.warnings.delete(warning)
}
}
},
},
})
2 changes: 1 addition & 1 deletion client/app/components/ControlPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ async function handleCopyReport() {
v-if="props.hasViolations"
class="flex items-center gap-2"
>
<span class="text-sm opacity-70">WCAG:</span>
<span class="text-sm opacity-70">WCAG Level Filter:</span>
<NSelect
:model-value="props.wcagFilter"
aria-label="WCAG level filter"
Expand Down
37 changes: 36 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,43 @@
".": {
"types": "./dist/types.d.mts",
"import": "./dist/module.mjs"
},
"./test-utils": {
"types": "./dist/test-utils/index.d.mts",
"import": "./dist/test-utils/index.mjs"
},
"./test-utils/setup": {
"types": "./dist/test-utils/setup.d.mts",
"import": "./dist/test-utils/setup.mjs"
},
"./test-utils/playwright": {
"types": "./dist/test-utils/playwright.d.mts",
"import": "./dist/test-utils/playwright.mjs"
}
},
"main": "./dist/module.mjs",
"typesVersions": {
"*": {
".": [
"./dist/types.d.mts"
],
"test-utils": [
"./dist/test-utils/index.d.mts"
],
"test-utils/setup": [
"./dist/test-utils/setup.d.mts"
],
"test-utils/playwright": [
"./dist/test-utils/playwright.d.mts"
]
}
},
"files": [
"dist"
],
"scripts": {
"build": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxt-module-build build && npm run client:build",
"build": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxt-module-build build && npm run build:test-utils && npm run client:build",
"build:test-utils": "unbuild --config build.config.test-utils",
"client:build": "nuxt generate client",
"client:dev": "nuxt dev client --port 3030",
"dev": "npm run play:dev",
Expand All @@ -45,6 +67,18 @@
"linkedom": "^0.18.12",
"sirv": "^3.0.2"
},
"peerDependencies": {
"vitest": ">=1.0.0",
"playwright-core": ">=1.0.0"
},
"peerDependenciesMeta": {
"vitest": {
"optional": true
},
"playwright-core": {
"optional": true
}
},
"devDependencies": {
"@iconify-json/carbon": "^1.2.18",
"@nuxt/devtools": "latest",
Expand All @@ -62,6 +96,7 @@
"pkg-pr-new": "0.0.63",
"playwright-core": "1.58.2",
"typescript": "~5.9.3",
"unbuild": "^3.6.1",
"vite": "7.3.1",
"vitest": "4.0.18",
"vue-tsc": "3.2.5"
Expand Down
16 changes: 16 additions & 0 deletions playground/A11Y-ISSUES.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ This playground app contains intentional accessibility issues for testing the Nu
- ❌ iframe without title
- ❌ FAQ not using proper disclosure pattern (button/details)

### Interactive Page (/interactive)
This page demonstrates **dynamic** a11y violations that appear on user interaction, designed to showcase the "Auto-scan on user events" feature.

- ❌ Dynamically injected images without alt text (notifications, profile preview, products)
- ❌ Low contrast text on dynamic content (#bbb, #aaa, #999, #ccc)
- ❌ Heading level skip (h1 to h4, h4 to h6 in preview)
- ❌ Form inputs without labels (placeholders only)
- ❌ Select without label
- ❌ onClick on div instead of button (product "Buy Now")
- ❌ Non-descriptive link text ("Learn More")
- ❌ Button with no accessible name (comment submit)
- ❌ Checkboxes without proper label association (filters)
- ❌ Filter toggles using div+click instead of disclosure buttons
- ❌ Icon without accessible name (comment icon)

## Testing the A11y Plugin

1. Run the playground: `pnpm run dev`
Expand All @@ -74,5 +89,6 @@ This playground app contains intentional accessibility issues for testing the Nu
- **/** - Home page with hero, services, CTA, gallery, and newsletter
- **/about-us** - About page with mission, team, values, stats, and timeline
- **/contact** - Contact page with form, info, map, and FAQ
- **/interactive** - Interactive dashboard with dynamic content for auto-scan demo

All pages include a shared header and footer with navigation.
4 changes: 4 additions & 0 deletions playground/app/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
to="/contact"
style="color: #aaa"
>Contact</nuxt-link>
<nuxt-link
to="/interactive"
style="color: #aaa"
>Interactive</nuxt-link>

<!-- Issue: Button without accessible name -->
<button
Expand Down
Loading
Loading