@diegovelasquezweb/a11y-engine 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -26
- package/README.md +76 -215
- package/docs/api-reference.md +107 -0
- package/docs/architecture.md +83 -209
- package/docs/cli-handbook.md +4 -4
- package/docs/engine-manifest.md +58 -0
- package/docs/outputs.md +9 -11
- package/docs/testing.md +63 -0
- package/package.json +3 -6
- package/src/core/asset-loader.mjs +22 -14
- package/src/index.d.mts +29 -12
- package/src/index.mjs +49 -52
- package/src/pipeline/dom-scanner.mjs +4 -4
- package/src/reports/checklist.mjs +4 -4
- package/src/reports/html.mjs +5 -5
- package/src/reports/md.mjs +3 -3
- package/src/reports/pdf.mjs +3 -3
- package/src/reports/renderers/findings.mjs +32 -32
- package/src/reports/renderers/md.mjs +6 -4
- package/assets/source/discovery/crawler-config.json +0 -11
- package/assets/source/discovery/stack-detection.json +0 -235
- package/assets/source/engine/cdp-checks.json +0 -30
- package/assets/source/engine/pa11y-config.json +0 -53
- package/assets/source/remediation/axe-check-maps.json +0 -31
- package/assets/source/remediation/code-patterns.json +0 -109
- package/assets/source/remediation/guardrails.json +0 -24
- package/assets/source/remediation/intelligence.json +0 -4166
- package/assets/source/remediation/source-boundaries.json +0 -46
- package/assets/source/reporting/compliance-config.json +0 -173
- package/assets/source/reporting/manual-checks.json +0 -944
- package/assets/source/reporting/wcag-reference.json +0 -588
- package/src/sync-assets.mjs +0 -66
- /package/assets/{generated/discovery → discovery}/crawler-config.mjs +0 -0
- /package/assets/{generated/discovery → discovery}/stack-detection.mjs +0 -0
- /package/assets/{generated/remediation → remediation}/axe-check-maps.mjs +0 -0
- /package/assets/{generated/remediation → remediation}/code-patterns.mjs +0 -0
- /package/assets/{generated/remediation → remediation}/guardrails.mjs +0 -0
- /package/assets/{generated/remediation → remediation}/intelligence.mjs +0 -0
- /package/assets/{generated/remediation → remediation}/source-boundaries.mjs +0 -0
- /package/assets/{generated/reporting → reporting}/compliance-config.mjs +0 -0
- /package/assets/{generated/reporting → reporting}/manual-checks.mjs +0 -0
- /package/assets/{generated/reporting → reporting}/wcag-reference.mjs +0 -0
- /package/assets/{generated/engine → scanning}/cdp-checks.mjs +0 -0
- /package/assets/{generated/engine → scanning}/pa11y-config.mjs +0 -0
package/docs/architecture.md
CHANGED
|
@@ -1,240 +1,114 @@
|
|
|
1
1
|
# Engine Architecture
|
|
2
2
|
|
|
3
|
-
**Navigation**: [Home](../README.md) • [Architecture](architecture.md) • [CLI Handbook](cli-handbook.md) • [Output Artifacts](outputs.md)
|
|
3
|
+
**Navigation**: [Home](../README.md) • [Architecture](architecture.md) • [API Reference](api-reference.md) • [CLI Handbook](cli-handbook.md) • [Output Artifacts](outputs.md) • [Engine Manifest](engine-manifest.md) • [Testing](testing.md)
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## Table of Contents
|
|
8
8
|
|
|
9
|
-
- [Pipeline
|
|
10
|
-
- [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- [Merge and deduplication](#merge-and-deduplication)
|
|
15
|
-
- [Stage 1b: Source scanner](#optional-source-scanner)
|
|
16
|
-
- [Stage 2: Analyzer](#stage-2-analyzer)
|
|
17
|
-
- [Stage 3: Report builders](#stage-3-report-builders)
|
|
18
|
-
- [Assets and rule intelligence](#assets-and-rule-intelligence)
|
|
19
|
-
- [Execution model and timeouts](#execution-model-and-timeouts)
|
|
9
|
+
- [High-Level Pipeline](#high-level-pipeline)
|
|
10
|
+
- [Execution Modes](#execution-modes)
|
|
11
|
+
- [Module Responsibilities](#module-responsibilities)
|
|
12
|
+
- [Stack Detection Model](#stack-detection-model)
|
|
13
|
+
- [Data Contracts](#data-contracts)
|
|
20
14
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
The engine operates as a three-stage pipeline. Each stage is an independent Node.js process spawned by `audit.mjs`. Stages communicate through JSON files written to `.audit/`.
|
|
24
|
-
|
|
25
|
-
## Pipeline overview
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
Target URL
|
|
29
|
-
│
|
|
30
|
-
▼
|
|
31
|
-
┌─────────────────────────────────┐
|
|
32
|
-
│ Stage 1: DOM Scanner │ Three engines per route:
|
|
33
|
-
│ dom-scanner.mjs │
|
|
34
|
-
│ │
|
|
35
|
-
│ ┌──────────┐ ┌──────┐ │
|
|
36
|
-
│ │ axe-core │ │ CDP │ │ Playwright Chromium
|
|
37
|
-
│ └────┬─────┘ └──┬───┘ │
|
|
38
|
-
│ │ │ │
|
|
39
|
-
│ ┌────▼───────────▼────┐ │
|
|
40
|
-
│ │ pa11y │ │ Puppeteer Chrome
|
|
41
|
-
│ └────────┬────────────┘ │
|
|
42
|
-
│ │ │
|
|
43
|
-
│ ┌────────▼────────────┐ │
|
|
44
|
-
│ │ Merge & Dedup │ │
|
|
45
|
-
│ └────────┬────────────┘ │
|
|
46
|
-
└───────────┼─────────────────────┘
|
|
47
|
-
│ a11y-scan-results.json
|
|
48
|
-
│ progress.json
|
|
49
|
-
▼
|
|
50
|
-
┌─────────────────────────────────┐
|
|
51
|
-
│ Stage 1b: Source Scanner │ Static regex analysis
|
|
52
|
-
│ source-scanner.mjs │ (optional — requires --project-dir)
|
|
53
|
-
└───────────┬─────────────────────┘
|
|
54
|
-
│ merges into a11y-findings.json
|
|
55
|
-
▼
|
|
56
|
-
┌─────────────────────────────────┐
|
|
57
|
-
│ Stage 2: Analyzer │ Fix intelligence enrichment
|
|
58
|
-
│ analyzer.mjs │ intelligence.json + guardrails
|
|
59
|
-
└───────────┬─────────────────────┘
|
|
60
|
-
│ a11y-findings.json
|
|
61
|
-
▼
|
|
62
|
-
┌─────────────────────────────────┐
|
|
63
|
-
│ Stage 3: Report Builders │ Parallel rendering
|
|
64
|
-
│ md / html / pdf / checklist │
|
|
65
|
-
└───────────┬─────────────────────┘
|
|
66
|
-
│
|
|
67
|
-
┌───────┼──────────┬──────────────┐
|
|
68
|
-
▼ ▼ ▼ ▼
|
|
69
|
-
remediation report report checklist
|
|
70
|
-
.md .html .pdf .html
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Stage 1: DOM scanner
|
|
74
|
-
|
|
75
|
-
**Script**: `scripts/engine/dom-scanner.mjs`
|
|
76
|
-
|
|
77
|
-
Launches a Playwright-controlled Chromium browser, discovers routes, and runs three independent accessibility engines against each page. Results are merged and deduplicated before output.
|
|
78
|
-
|
|
79
|
-
### Route discovery
|
|
80
|
-
|
|
81
|
-
- If the site exposes a `sitemap.xml`, all listed URLs are scanned (up to `--max-routes`).
|
|
82
|
-
- Otherwise, BFS crawl starting from `--base-url`, following same-origin `<a href>` links up to `--crawl-depth` levels deep.
|
|
83
|
-
- Routes are deduplicated and normalized before scanning.
|
|
84
|
-
- 3 parallel browser tabs scan routes concurrently (~2-3x faster than sequential).
|
|
85
|
-
|
|
86
|
-
### axe-core
|
|
87
|
-
|
|
88
|
-
**Dependency**: `@axe-core/playwright`
|
|
15
|
+
The engine is the shared core used by CLI and applications. It runs a multi-engine scan, enriches findings, and produces report-ready outputs.
|
|
89
16
|
|
|
90
|
-
|
|
17
|
+
## High-Level Pipeline
|
|
91
18
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
19
|
+
```mermaid
|
|
20
|
+
flowchart TD
|
|
21
|
+
A[Target URL] --> B[Route Discovery]
|
|
22
|
+
B --> C[Scan Route]
|
|
95
23
|
|
|
96
|
-
|
|
24
|
+
subgraph Engines[Runtime Engines]
|
|
25
|
+
C --> AXE[axe-core]
|
|
26
|
+
C --> CDP[CDP checks]
|
|
27
|
+
C --> P11Y[pa11y]
|
|
28
|
+
end
|
|
97
29
|
|
|
98
|
-
|
|
30
|
+
AXE --> M[Merge and Dedup]
|
|
31
|
+
CDP --> M
|
|
32
|
+
P11Y --> M
|
|
99
33
|
|
|
100
|
-
|
|
34
|
+
M --> R[a11y-scan-results.json]
|
|
35
|
+
R --> AN[Analyzer]
|
|
36
|
+
AN --> F[a11y-findings.json]
|
|
101
37
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
### pa11y
|
|
108
|
-
|
|
109
|
-
**Dependency**: `pa11y` (which uses Puppeteer + Chrome internally)
|
|
110
|
-
|
|
111
|
-
Runs Squiz's HTML CodeSniffer against each page URL. Catches WCAG violations that axe and CDP may miss:
|
|
112
|
-
|
|
113
|
-
- Heading hierarchy issues
|
|
114
|
-
- Link purpose violations
|
|
115
|
-
- Form label associations
|
|
116
|
-
- Additional WCAG2AA/WCAG2AAA checks from HTML CodeSniffer's rule set
|
|
38
|
+
F --> MD[remediation.md]
|
|
39
|
+
F --> HTML[report.html]
|
|
40
|
+
F --> PDF[report.pdf]
|
|
41
|
+
F --> CHK[checklist.html]
|
|
42
|
+
```
|
|
117
43
|
|
|
118
|
-
|
|
44
|
+
## Execution Modes
|
|
45
|
+
|
|
46
|
+
```mermaid
|
|
47
|
+
flowchart LR
|
|
48
|
+
subgraph CLI[CLI Mode]
|
|
49
|
+
C1[src/cli/audit.mjs]
|
|
50
|
+
C2[src/pipeline/dom-scanner.mjs]
|
|
51
|
+
C3[src/enrichment/analyzer.mjs]
|
|
52
|
+
C4[src/reports/*.mjs]
|
|
53
|
+
C1 --> C2 --> C3 --> C4
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
subgraph API[Programmatic Mode]
|
|
57
|
+
A1[src/index.mjs]
|
|
58
|
+
A2[runAudit]
|
|
59
|
+
A3[getFindings]
|
|
60
|
+
A4[getOverview]
|
|
61
|
+
A5[get*Report functions]
|
|
62
|
+
A1 --> A2
|
|
63
|
+
A1 --> A3
|
|
64
|
+
A1 --> A4
|
|
65
|
+
A1 --> A5
|
|
66
|
+
end
|
|
67
|
+
```
|
|
119
68
|
|
|
120
|
-
|
|
69
|
+
- **CLI mode** writes artifacts to `.audit/`.
|
|
70
|
+
- **API mode** returns data in memory (objects/strings/buffers).
|
|
121
71
|
|
|
122
|
-
|
|
72
|
+
## Module Responsibilities
|
|
123
73
|
|
|
124
|
-
|
|
74
|
+
| Module | Responsibility |
|
|
75
|
+
| :--- | :--- |
|
|
76
|
+
| `src/pipeline/dom-scanner.mjs` | Route discovery, engine execution (axe/CDP/pa11y), merge/dedup, progress updates, screenshots |
|
|
77
|
+
| `src/enrichment/analyzer.mjs` | Rule enrichment, selector strategy, ownership hints, recommendations, scoring metadata |
|
|
78
|
+
| `src/source-patterns/source-scanner.mjs` | Static source pattern detection for issues runtime engines cannot see |
|
|
79
|
+
| `src/reports/*.mjs` | Report builders for markdown/html/pdf/checklist |
|
|
80
|
+
| `src/reports/renderers/*.mjs` | Shared rendering and normalization helpers |
|
|
81
|
+
| `src/core/asset-loader.mjs` | Centralized access to bundled assets |
|
|
82
|
+
| `src/index.mjs` | Public API facade (`runAudit`, `getFindings`, `getOverview`, report APIs, source patterns) |
|
|
125
83
|
|
|
126
|
-
|
|
127
|
-
2. **CDP findings** are checked against axe equivalents (e.g. `cdp-missing-accessible-name` maps to `button-name`, `link-name`, `input-name`, `aria-command-name`). Only truly new findings are added.
|
|
128
|
-
3. **pa11y findings** are checked against existing selectors. If the same element is already flagged by axe or CDP, the pa11y finding is dropped.
|
|
84
|
+
## Stack Detection Model
|
|
129
85
|
|
|
130
|
-
|
|
86
|
+
Detection combines runtime and source signals:
|
|
131
87
|
|
|
132
|
-
|
|
88
|
+
1. **Runtime signals** from scanned pages:
|
|
89
|
+
- DOM markers, globals, script URLs, and meta tags
|
|
90
|
+
2. **Project source signals** when `projectDir` is provided:
|
|
91
|
+
- package dependencies and file structure
|
|
92
|
+
3. **Merge strategy**:
|
|
93
|
+
- source-based detection has priority when present
|
|
94
|
+
- runtime detection fills missing fields
|
|
133
95
|
|
|
134
|
-
|
|
96
|
+
Output shape:
|
|
135
97
|
|
|
136
98
|
```json
|
|
137
99
|
{
|
|
138
|
-
"
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
"cdp": { "status": "done", "updatedAt": "...", "found": 3 },
|
|
142
|
-
"pa11y": { "status": "done", "updatedAt": "...", "found": 2 },
|
|
143
|
-
"merge": { "status": "done", "updatedAt": "...", "axe": 8, "cdp": 3, "pa11y": 2, "merged": 11 }
|
|
144
|
-
},
|
|
145
|
-
"currentStep": "merge"
|
|
100
|
+
"framework": "nextjs",
|
|
101
|
+
"cms": null,
|
|
102
|
+
"uiLibraries": ["radix"]
|
|
146
103
|
}
|
|
147
104
|
```
|
|
148
105
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
After merging, element screenshots are captured for each violation. Non-visible elements (`<meta>`, `<link>`, `<script>`, etc.) are automatically skipped. Screenshots are stored in `.audit/screenshots/` and referenced by each violation's `screenshot_path` field.
|
|
152
|
-
|
|
153
|
-
### Optional: Source scanner
|
|
154
|
-
|
|
155
|
-
**Script**: `scripts/engine/source-scanner.mjs` — runs when `--project-dir` is set and `--skip-patterns` is not.
|
|
156
|
-
|
|
157
|
-
Performs static analysis of source files for accessibility issues no runtime engine can detect (e.g. focus outline suppression, missing alt text in templates). Uses regex patterns from `assets/remediation/code-patterns.json` scoped to framework-specific file boundaries from `assets/remediation/source-boundaries.json`.
|
|
158
|
-
|
|
159
|
-
Findings are classified as `confirmed` (pattern unambiguously matches) or `potential` (requires human verification).
|
|
160
|
-
|
|
161
|
-
## Stage 2: Analyzer
|
|
162
|
-
|
|
163
|
-
**Script**: `scripts/engine/analyzer.mjs`
|
|
164
|
-
|
|
165
|
-
Reads `a11y-scan-results.json` (which contains merged axe + CDP + pa11y results) and enriches each violation with:
|
|
166
|
-
|
|
167
|
-
- **Fix intelligence** from `assets/remediation/intelligence.json` — 106 axe-core rules with code snippets, MDN links, framework-specific notes, and WCAG criterion mapping. CDP and pa11y findings receive generic enrichment based on their rule structure.
|
|
168
|
-
- **Selector scoring** — picks the most stable selector from axe's `nodes` list. Priority: `#id` > `[data-*]` > `[aria-*]` > `[type=]`, with penalty for Tailwind utility classes.
|
|
169
|
-
- **Framework context** — `assets/discovery/stack-detection.json` fingerprints the DOM to detect framework and CMS. Per-finding `framework_notes` and `cms_notes` are filtered to the detected stack.
|
|
170
|
-
- **Guardrails** — `assets/remediation/guardrails.json` defines scope rules that prevent agents from touching backend code, third-party scripts, or minified files.
|
|
171
|
-
- **Compliance scoring** — `assets/reporting/compliance-config.json` weights findings by severity to produce a 0-100 score with grade thresholds.
|
|
172
|
-
- **Persona impact groups** — `assets/reporting/wcag-reference.json` maps findings to disability personas (visual, motor, cognitive, etc.).
|
|
173
|
-
|
|
174
|
-
**Output**: `a11y-findings.json` — enriched findings array with all intelligence fields.
|
|
175
|
-
|
|
176
|
-
## Stage 3: Report builders
|
|
177
|
-
|
|
178
|
-
All builders run in parallel when `--with-reports` is set. Each reads `a11y-findings.json` independently.
|
|
179
|
-
|
|
180
|
-
| Builder | Script | Output | Audience |
|
|
181
|
-
| :--- | :--- | :--- | :--- |
|
|
182
|
-
| Markdown | `reports/builders/md.mjs` | `remediation.md` | AI agents |
|
|
183
|
-
| HTML | `reports/builders/html.mjs` | `report.html` | Developers |
|
|
184
|
-
| PDF | `reports/builders/pdf.mjs` | `report.pdf` | Stakeholders |
|
|
185
|
-
| Checklist | `reports/builders/checklist.mjs` | `checklist.html` | QA / Developers |
|
|
186
|
-
|
|
187
|
-
The `remediation.md` builder always runs (even without `--with-reports`) since it is the primary output for AI agent consumption.
|
|
188
|
-
|
|
189
|
-
Renderers in `scripts/reports/renderers/` contain the actual rendering logic — builders are thin orchestrators that call renderers and write output files.
|
|
190
|
-
|
|
191
|
-
## Assets and rule intelligence
|
|
192
|
-
|
|
193
|
-
Assets are static JSON files bundled with the package under `assets/`. They are read at runtime by the analyzer and report builders.
|
|
194
|
-
|
|
195
|
-
| Asset | Purpose |
|
|
196
|
-
| :--- | :--- |
|
|
197
|
-
| `reporting/compliance-config.json` | Score weights, grade thresholds, legal regulation list |
|
|
198
|
-
| `reporting/wcag-reference.json` | WCAG criterion map, persona config, persona-rule mapping |
|
|
199
|
-
| `reporting/manual-checks.json` | 41 manual checks for the WCAG checklist |
|
|
200
|
-
| `discovery/crawler-config.json` | BFS crawl defaults (timeouts, concurrency) |
|
|
201
|
-
| `discovery/stack-detection.json` | Framework/CMS DOM fingerprints |
|
|
202
|
-
| `remediation/intelligence.json` | Per-rule fix intelligence for 106 axe-core rules |
|
|
203
|
-
| `remediation/code-patterns.json` | Source code pattern definitions |
|
|
204
|
-
| `remediation/guardrails.json` | Agent fix scope guardrails |
|
|
205
|
-
| `remediation/axe-check-maps.json` | axe check-to-rule mapping |
|
|
206
|
-
| `remediation/source-boundaries.json` | Framework-specific source file locations |
|
|
207
|
-
|
|
208
|
-
## Programmatic API
|
|
209
|
-
|
|
210
|
-
In addition to the CLI pipeline, the engine exports 7 functions via `scripts/index.mjs` for direct consumption by Node.js applications (e.g. `a11y-scanner`). These functions reuse the same internal renderers, assets, and enrichment logic as the CLI — no duplication.
|
|
211
|
-
|
|
212
|
-
```
|
|
213
|
-
scripts/index.mjs (public API)
|
|
214
|
-
├── getEnrichedFindings() ← uses asset-loader, intelligence.json, pa11y-config.json
|
|
215
|
-
├── getAuditSummary() ← uses compliance-config.json, wcag-reference.json
|
|
216
|
-
├── getPDFReport() ← uses reports/renderers/pdf.mjs + Playwright
|
|
217
|
-
├── getHTMLReport() ← uses reports/renderers/html.mjs + findings.mjs
|
|
218
|
-
├── getChecklist() ← uses reports/renderers/html.mjs (manual checks)
|
|
219
|
-
├── getRemediationGuide() ← uses reports/renderers/md.mjs
|
|
220
|
-
└── getSourcePatterns() ← uses engine/source-scanner.mjs
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### Key design decisions
|
|
224
|
-
|
|
225
|
-
- **No filesystem output** — all API functions return data in memory (strings, Buffers, arrays). The consumer decides where to write.
|
|
226
|
-
- **Payload in, results out** — functions accept the raw `{ findings, metadata }` payload that `a11y-findings.json` contains. No need to resolve paths or read files.
|
|
227
|
-
- **`screenshotUrlBuilder` callback** — `getEnrichedFindings` accepts an optional function to transform raw screenshot paths (e.g. `screenshots/0-color-contrast.png`) into consumer-specific URLs (e.g. `/api/scan/{id}/screenshot?path=...`). This keeps URL construction out of the engine.
|
|
228
|
-
- **CLI unaffected** — the `audit.mjs` orchestrator and all CLI builders continue to work exactly as before. The API is additive.
|
|
229
|
-
|
|
230
|
-
## Execution model and timeouts
|
|
231
|
-
|
|
232
|
-
`audit.mjs` spawns each stage as a child process via `node:child_process`. All child processes:
|
|
106
|
+
## Data Contracts
|
|
233
107
|
|
|
234
|
-
|
|
235
|
-
- Run with `cwd` set to the package root (`SKILL_ROOT`)
|
|
236
|
-
- Have a hard timeout of **15 minutes** (configurable via the `SCRIPT_TIMEOUT_MS` constant)
|
|
108
|
+
Core artifacts generated by the pipeline:
|
|
237
109
|
|
|
238
|
-
|
|
110
|
+
- `progress.json`: step status (`page`, `axe`, `cdp`, `pa11y`, `merge`, `intelligence`)
|
|
111
|
+
- `a11y-scan-results.json`: merged runtime scan output per route
|
|
112
|
+
- `a11y-findings.json`: enriched findings payload used by reports and API consumers
|
|
239
113
|
|
|
240
|
-
|
|
114
|
+
For schemas and field-level details, see [Output Artifacts](outputs.md).
|
package/docs/cli-handbook.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CLI Handbook
|
|
2
2
|
|
|
3
|
-
**Navigation**: [Home](../README.md) • [Architecture](architecture.md) • [CLI Handbook](cli-handbook.md) • [Output Artifacts](outputs.md)
|
|
3
|
+
**Navigation**: [Home](../README.md) • [Architecture](architecture.md) • [API Reference](api-reference.md) • [CLI Handbook](cli-handbook.md) • [Output Artifacts](outputs.md) • [Engine Manifest](engine-manifest.md) • [Testing](testing.md)
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
npx a11y-audit --base-url <url> [options]
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Or
|
|
27
|
+
Or via pnpm in a project that depends on the engine:
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
|
|
30
|
+
pnpm exec a11y-audit --base-url <url> [options]
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
The only required flag is `--base-url`. All other flags are optional.
|
|
@@ -62,7 +62,7 @@ Controls what gets scanned.
|
|
|
62
62
|
| `--max-routes` | `<num>` | `10` | Maximum unique same-origin paths to discover and scan. |
|
|
63
63
|
| `--crawl-depth` | `<num>` | `2` | How deep to follow links during BFS discovery (1-3). Has no effect when `--routes` is set. |
|
|
64
64
|
| `--routes` | `<csv>` | — | Explicit paths to scan (e.g. `/,/about,/contact`). Overrides auto-discovery entirely. |
|
|
65
|
-
| `--project-dir` | `<path>` | — | Path to the audited project source. Enables the source code pattern scanner and framework auto-detection from
|
|
65
|
+
| `--project-dir` | `<path>` | — | Path to the audited project source. Enables the source code pattern scanner and framework auto-detection from package.json. |
|
|
66
66
|
|
|
67
67
|
**Route discovery logic**:
|
|
68
68
|
1. If the target has a `sitemap.xml`, all listed URLs are used (up to `--max-routes`).
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Engine Manifest
|
|
2
|
+
|
|
3
|
+
**Navigation**: [Home](../README.md) • [Architecture](architecture.md) • [CLI Handbook](cli-handbook.md) • [Output Artifacts](outputs.md) • [Engine Manifest](engine-manifest.md) • [Testing](testing.md)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
This document is the current technical inventory of the engine package.
|
|
8
|
+
|
|
9
|
+
## 1) Source Modules
|
|
10
|
+
|
|
11
|
+
| Path | Role |
|
|
12
|
+
| :--- | :--- |
|
|
13
|
+
| `src/index.mjs` | Public API entry point |
|
|
14
|
+
| `src/index.d.mts` | Public TypeScript declarations |
|
|
15
|
+
| `src/cli/audit.mjs` | CLI adapter and orchestration |
|
|
16
|
+
| `src/core/utils.mjs` | Logging, JSON I/O, shared helpers |
|
|
17
|
+
| `src/core/asset-loader.mjs` | Centralized asset map and loader |
|
|
18
|
+
| `src/core/toolchain.mjs` | Environment/toolchain checks |
|
|
19
|
+
| `src/pipeline/dom-scanner.mjs` | Runtime scan stage (axe/CDP/pa11y + merge) |
|
|
20
|
+
| `src/enrichment/analyzer.mjs` | Finding enrichment and metadata synthesis |
|
|
21
|
+
| `src/source-patterns/source-scanner.mjs` | Static source-pattern scanner |
|
|
22
|
+
| `src/reports/html.mjs` | HTML report builder |
|
|
23
|
+
| `src/reports/pdf.mjs` | PDF report builder |
|
|
24
|
+
| `src/reports/md.mjs` | Markdown remediation builder |
|
|
25
|
+
| `src/reports/checklist.mjs` | Manual checklist builder |
|
|
26
|
+
| `src/reports/renderers/*.mjs` | Shared report rendering primitives |
|
|
27
|
+
|
|
28
|
+
## 2) Asset Modules
|
|
29
|
+
|
|
30
|
+
| Path | Purpose |
|
|
31
|
+
| :--- | :--- |
|
|
32
|
+
| `assets/discovery/crawler-config.mjs` | Crawl defaults and URL filters |
|
|
33
|
+
| `assets/discovery/stack-detection.mjs` | Runtime/source stack detection rules |
|
|
34
|
+
| `assets/scanning/cdp-checks.mjs` | CDP accessibility checks |
|
|
35
|
+
| `assets/scanning/pa11y-config.mjs` | pa11y mappings, ignores, canonicalization |
|
|
36
|
+
| `assets/remediation/intelligence.mjs` | Rule-level remediation intelligence |
|
|
37
|
+
| `assets/remediation/guardrails.mjs` | Safe-fix and ownership guardrails |
|
|
38
|
+
| `assets/remediation/code-patterns.mjs` | Source code pattern definitions |
|
|
39
|
+
| `assets/remediation/source-boundaries.mjs` | Framework source boundaries |
|
|
40
|
+
| `assets/remediation/axe-check-maps.mjs` | axe check-to-rule mappings |
|
|
41
|
+
| `assets/reporting/compliance-config.mjs` | Compliance scoring configuration |
|
|
42
|
+
| `assets/reporting/wcag-reference.mjs` | WCAG + persona mapping reference |
|
|
43
|
+
| `assets/reporting/manual-checks.mjs` | Manual checklist data |
|
|
44
|
+
|
|
45
|
+
## 3) Test Suite
|
|
46
|
+
|
|
47
|
+
All tests live under `tests/` and run with Vitest.
|
|
48
|
+
|
|
49
|
+
Current files:
|
|
50
|
+
|
|
51
|
+
- `tests/asset-loader.test.mjs`
|
|
52
|
+
- `tests/audit-summary.test.mjs`
|
|
53
|
+
- `tests/enriched-findings.test.mjs`
|
|
54
|
+
- `tests/reports-api.test.mjs`
|
|
55
|
+
- `tests/reports-paths.test.mjs`
|
|
56
|
+
- `tests/run-audit.integration.test.mjs`
|
|
57
|
+
- `tests/source-patterns.test.mjs`
|
|
58
|
+
- `tests/source-scanner-utils.test.mjs`
|
package/docs/outputs.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Output Artifacts
|
|
2
2
|
|
|
3
|
-
**Navigation**: [Home](../README.md) • [Architecture](architecture.md) • [CLI Handbook](cli-handbook.md) • [Output Artifacts](outputs.md)
|
|
3
|
+
**Navigation**: [Home](../README.md) • [Architecture](architecture.md) • [API Reference](api-reference.md) • [CLI Handbook](cli-handbook.md) • [Output Artifacts](outputs.md) • [Engine Manifest](engine-manifest.md) • [Testing](testing.md)
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -34,13 +34,11 @@ All artifacts are written to `.audit/` relative to the package root (`SKILL_ROOT
|
|
|
34
34
|
└── screenshots/ # element screenshots per violation
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
> When integrating the engine as a dependency (e.g. in `a11y-scanner`), use `fs.realpathSync` on the symlink path to resolve the real `.audit/` location — pnpm uses a deep `.pnpm/` directory structure, not the `node_modules/@scope/pkg` symlink.
|
|
38
|
-
|
|
39
37
|
---
|
|
40
38
|
|
|
41
39
|
## progress.json
|
|
42
40
|
|
|
43
|
-
Real-time scan progress written by `
|
|
41
|
+
Real-time scan progress written by `src/pipeline/dom-scanner.mjs` as each engine runs. Used by integrations for live progress UI.
|
|
44
42
|
|
|
45
43
|
```json
|
|
46
44
|
{
|
|
@@ -73,7 +71,7 @@ Real-time scan progress written by `scripts/engine/dom-scanner.mjs` as each engi
|
|
|
73
71
|
|
|
74
72
|
## a11y-scan-results.json
|
|
75
73
|
|
|
76
|
-
Merged results from all three engines (axe-core + CDP + pa11y) per route. Written by `
|
|
74
|
+
Merged results from all three engines (axe-core + CDP + pa11y) per route. Written by `src/pipeline/dom-scanner.mjs`.
|
|
77
75
|
|
|
78
76
|
```json
|
|
79
77
|
{
|
|
@@ -100,7 +98,7 @@ This file is consumed by `analyzer.mjs` and also used by `--affected-only` to de
|
|
|
100
98
|
|
|
101
99
|
## a11y-findings.json
|
|
102
100
|
|
|
103
|
-
The primary enriched data artifact. Written by `
|
|
101
|
+
The primary enriched data artifact. Written by `src/enrichment/analyzer.mjs`. This is the file consumed by all report builders.
|
|
104
102
|
|
|
105
103
|
### Top-level structure
|
|
106
104
|
|
|
@@ -263,8 +261,8 @@ The engine exports functions that process scan data directly in memory — no fi
|
|
|
263
261
|
|
|
264
262
|
```ts
|
|
265
263
|
import {
|
|
266
|
-
|
|
267
|
-
|
|
264
|
+
getFindings,
|
|
265
|
+
getOverview,
|
|
268
266
|
getPDFReport,
|
|
269
267
|
getHTMLReport,
|
|
270
268
|
getChecklist,
|
|
@@ -276,12 +274,12 @@ import {
|
|
|
276
274
|
const payload = JSON.parse(fs.readFileSync(findingsPath, "utf-8"));
|
|
277
275
|
|
|
278
276
|
// Enrich findings with fix intelligence
|
|
279
|
-
const findings =
|
|
277
|
+
const findings = getFindings(payload, {
|
|
280
278
|
screenshotUrlBuilder: (path) => `/api/screenshot?path=${encodeURIComponent(path)}`,
|
|
281
279
|
});
|
|
282
280
|
|
|
283
281
|
// Get full audit summary
|
|
284
|
-
const summary =
|
|
282
|
+
const summary = getOverview(findings, payload);
|
|
285
283
|
|
|
286
284
|
// Generate reports
|
|
287
285
|
const pdf = await getPDFReport(payload, { baseUrl: "https://example.com" });
|
|
@@ -311,7 +309,7 @@ if (fs.existsSync(progressPath)) {
|
|
|
311
309
|
### Parsing stdout markers
|
|
312
310
|
|
|
313
311
|
```bash
|
|
314
|
-
OUTPUT=$(
|
|
312
|
+
OUTPUT=$(npx a11y-audit --base-url https://example.com --with-reports --output ./audit/report.html)
|
|
315
313
|
REMEDIATION_PATH=$(echo "$OUTPUT" | grep REMEDIATION_PATH | cut -d= -f2)
|
|
316
314
|
REPORT_PATH=$(echo "$OUTPUT" | grep REPORT_PATH | cut -d= -f2)
|
|
317
315
|
```
|
package/docs/testing.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Testing Strategy
|
|
2
|
+
|
|
3
|
+
**Navigation**: [Home](../README.md) • [Architecture](architecture.md) • [CLI Handbook](cli-handbook.md) • [Output Artifacts](outputs.md) • [Engine Manifest](engine-manifest.md) • [Testing](testing.md)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Overview](#overview)
|
|
10
|
+
- [Test Categories](#test-categories)
|
|
11
|
+
- [Run Commands](#run-commands)
|
|
12
|
+
|
|
13
|
+
## Overview
|
|
14
|
+
|
|
15
|
+
- **Framework**: Vitest
|
|
16
|
+
- **Command**: `pnpm test`
|
|
17
|
+
- **Current suite**: 8 files, 26 tests
|
|
18
|
+
|
|
19
|
+
The suite focuses on regression protection for architecture changes, public API contracts, and critical report-generation paths.
|
|
20
|
+
|
|
21
|
+
## Test Categories
|
|
22
|
+
|
|
23
|
+
### 1) Asset loading and compatibility
|
|
24
|
+
|
|
25
|
+
- `tests/asset-loader.test.mjs`
|
|
26
|
+
- Verifies all asset groups load correctly.
|
|
27
|
+
- Verifies compatibility alias: `ASSET_PATHS.engine` -> `ASSET_PATHS.scanning`.
|
|
28
|
+
|
|
29
|
+
### 2) Enrichment and summary contracts
|
|
30
|
+
|
|
31
|
+
- `tests/enriched-findings.test.mjs`
|
|
32
|
+
- `tests/audit-summary.test.mjs`
|
|
33
|
+
- Verifies canonicalization, normalization, sorting, effort inference, quick wins, and detected stack output.
|
|
34
|
+
|
|
35
|
+
### 3) Report API and import safety
|
|
36
|
+
|
|
37
|
+
- `tests/reports-api.test.mjs`
|
|
38
|
+
- `tests/reports-paths.test.mjs`
|
|
39
|
+
- Verifies report APIs return expected output types and protects against broken relative imports after refactors.
|
|
40
|
+
|
|
41
|
+
### 4) Source-pattern behavior
|
|
42
|
+
|
|
43
|
+
- `tests/source-patterns.test.mjs`
|
|
44
|
+
- `tests/source-scanner-utils.test.mjs`
|
|
45
|
+
- Verifies edge behavior for pattern filtering and source scanner utility functions.
|
|
46
|
+
|
|
47
|
+
### 5) Integration tests (no network)
|
|
48
|
+
|
|
49
|
+
- `tests/run-audit.integration.test.mjs`
|
|
50
|
+
- Mocks scanner/analyzer modules to verify:
|
|
51
|
+
- `runAudit` progress event order
|
|
52
|
+
- scanner/analyzer wiring
|
|
53
|
+
- output payload shape
|
|
54
|
+
|
|
55
|
+
## Run Commands
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Full suite
|
|
59
|
+
pnpm test
|
|
60
|
+
|
|
61
|
+
# Run a single file
|
|
62
|
+
pnpm vitest run tests/run-audit.integration.test.mjs
|
|
63
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegovelasquezweb/a11y-engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "WCAG 2.2 AA accessibility audit engine — scanner, analyzer, and report builders",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,17 +26,14 @@
|
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
28
|
"src/**",
|
|
29
|
-
"assets
|
|
30
|
-
"assets/generated/**",
|
|
29
|
+
"assets/**",
|
|
31
30
|
"docs/**",
|
|
32
31
|
"README.md",
|
|
33
32
|
"CHANGELOG.md",
|
|
34
33
|
"LICENSE"
|
|
35
34
|
],
|
|
36
35
|
"scripts": {
|
|
37
|
-
"
|
|
38
|
-
"test": "vitest run",
|
|
39
|
-
"prepublishOnly": "node src/sync-assets.mjs"
|
|
36
|
+
"test": "vitest run"
|
|
40
37
|
},
|
|
41
38
|
"dependencies": {
|
|
42
39
|
"@axe-core/playwright": "^4.11.1",
|
|
@@ -5,18 +5,18 @@
|
|
|
5
5
|
* This ensures bundlers (Turbopack, Webpack) can trace them automatically.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import crawlerConfig from "../../assets/
|
|
9
|
-
import stackDetection from "../../assets/
|
|
10
|
-
import cdpChecks from "../../assets/
|
|
11
|
-
import pa11yConfig from "../../assets/
|
|
12
|
-
import axeCheckMaps from "../../assets/
|
|
13
|
-
import codePatterns from "../../assets/
|
|
14
|
-
import guardrails from "../../assets/
|
|
15
|
-
import intelligence from "../../assets/
|
|
16
|
-
import sourceBoundaries from "../../assets/
|
|
17
|
-
import complianceConfig from "../../assets/
|
|
18
|
-
import manualChecks from "../../assets/
|
|
19
|
-
import wcagReference from "../../assets/
|
|
8
|
+
import crawlerConfig from "../../assets/discovery/crawler-config.mjs";
|
|
9
|
+
import stackDetection from "../../assets/discovery/stack-detection.mjs";
|
|
10
|
+
import cdpChecks from "../../assets/scanning/cdp-checks.mjs";
|
|
11
|
+
import pa11yConfig from "../../assets/scanning/pa11y-config.mjs";
|
|
12
|
+
import axeCheckMaps from "../../assets/remediation/axe-check-maps.mjs";
|
|
13
|
+
import codePatterns from "../../assets/remediation/code-patterns.mjs";
|
|
14
|
+
import guardrails from "../../assets/remediation/guardrails.mjs";
|
|
15
|
+
import intelligence from "../../assets/remediation/intelligence.mjs";
|
|
16
|
+
import sourceBoundaries from "../../assets/remediation/source-boundaries.mjs";
|
|
17
|
+
import complianceConfig from "../../assets/reporting/compliance-config.mjs";
|
|
18
|
+
import manualChecks from "../../assets/reporting/manual-checks.mjs";
|
|
19
|
+
import wcagReference from "../../assets/reporting/wcag-reference.mjs";
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Pre-loaded asset map. Each value is the parsed JSON object, ready to use.
|
|
@@ -26,6 +26,10 @@ export const ASSETS = {
|
|
|
26
26
|
crawlerConfig,
|
|
27
27
|
stackDetection,
|
|
28
28
|
},
|
|
29
|
+
scanning: {
|
|
30
|
+
cdpChecks,
|
|
31
|
+
pa11yConfig,
|
|
32
|
+
},
|
|
29
33
|
engine: {
|
|
30
34
|
cdpChecks,
|
|
31
35
|
pa11yConfig,
|
|
@@ -54,9 +58,13 @@ export const ASSET_PATHS = {
|
|
|
54
58
|
crawlerConfig: "discovery.crawlerConfig",
|
|
55
59
|
stackDetection: "discovery.stackDetection",
|
|
56
60
|
},
|
|
61
|
+
scanning: {
|
|
62
|
+
cdpChecks: "scanning.cdpChecks",
|
|
63
|
+
pa11yConfig: "scanning.pa11yConfig",
|
|
64
|
+
},
|
|
57
65
|
engine: {
|
|
58
|
-
cdpChecks: "
|
|
59
|
-
pa11yConfig: "
|
|
66
|
+
cdpChecks: "scanning.cdpChecks",
|
|
67
|
+
pa11yConfig: "scanning.pa11yConfig",
|
|
60
68
|
},
|
|
61
69
|
remediation: {
|
|
62
70
|
intelligence: "remediation.intelligence",
|