@a11y-skills/audit 0.1.0 → 0.3.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.
Files changed (59) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.ja.md +76 -6
  3. package/README.md +78 -6
  4. package/dist/constants.d.ts +84 -0
  5. package/dist/constants.js +228 -0
  6. package/dist/detectors/index.d.ts +1 -0
  7. package/dist/detectors/index.js +1 -0
  8. package/dist/detectors/pause-control.d.ts +18 -0
  9. package/dist/detectors/pause-control.js +206 -0
  10. package/dist/index.d.ts +3 -1
  11. package/dist/index.js +3 -1
  12. package/dist/playwright/index.d.ts +7 -1
  13. package/dist/playwright/index.js +7 -1
  14. package/dist/playwright/runAutoPlayDetection.d.ts +36 -0
  15. package/dist/playwright/runAutoPlayDetection.js +143 -0
  16. package/dist/playwright/runAutocompleteAudit.d.ts +27 -0
  17. package/dist/playwright/runAutocompleteAudit.js +227 -0
  18. package/dist/playwright/runAxeAudit.d.ts +4 -0
  19. package/dist/playwright/runAxeAudit.js +26 -30
  20. package/dist/playwright/runFocusIndicatorCheck.js +55 -12
  21. package/dist/playwright/runOrientationCheck.d.ts +40 -0
  22. package/dist/playwright/runOrientationCheck.js +170 -0
  23. package/dist/playwright/runReflowCheck.js +18 -11
  24. package/dist/playwright/runTargetSizeCheck.js +42 -10
  25. package/dist/playwright/runTextSpacingCheck.d.ts +25 -0
  26. package/dist/playwright/runTextSpacingCheck.js +285 -0
  27. package/dist/playwright/runTimeLimitDetector.d.ts +31 -0
  28. package/dist/playwright/runTimeLimitDetector.js +219 -0
  29. package/dist/playwright/runZoomCheck.d.ts +42 -0
  30. package/dist/playwright/runZoomCheck.js +174 -0
  31. package/dist/schemas/index.d.ts +20 -1
  32. package/dist/schemas/index.js +404 -186
  33. package/dist/test-entries/auto-play-detection.d.ts +7 -0
  34. package/dist/test-entries/auto-play-detection.js +13 -0
  35. package/dist/test-entries/autocomplete-audit.d.ts +5 -0
  36. package/dist/test-entries/autocomplete-audit.js +11 -0
  37. package/dist/test-entries/orientation-check.d.ts +8 -0
  38. package/dist/test-entries/orientation-check.js +12 -0
  39. package/dist/test-entries/text-spacing-check.d.ts +5 -0
  40. package/dist/test-entries/text-spacing-check.js +11 -0
  41. package/dist/test-entries/time-limit-detector.d.ts +8 -0
  42. package/dist/test-entries/time-limit-detector.js +12 -0
  43. package/dist/test-entries/zoom-200-check.d.ts +5 -0
  44. package/dist/test-entries/zoom-200-check.js +11 -0
  45. package/dist/types.d.ts +275 -40
  46. package/dist/types.js +9 -0
  47. package/dist/utils/axe-format.d.ts +88 -0
  48. package/dist/utils/axe-format.js +361 -0
  49. package/dist/utils/image-compare.d.ts +24 -0
  50. package/dist/utils/image-compare.js +49 -0
  51. package/dist/utils/layout.d.ts +2 -0
  52. package/dist/utils/layout.js +20 -1
  53. package/dist/utils/recommendations.d.ts +18 -0
  54. package/dist/utils/recommendations.js +88 -0
  55. package/dist/utils/rule-registry.d.ts +216 -0
  56. package/dist/utils/rule-registry.js +220 -0
  57. package/dist/utils/test-harness.d.ts +8 -2
  58. package/dist/utils/test-harness.js +13 -6
  59. package/package.json +32 -2
package/CHANGELOG.md CHANGED
@@ -3,6 +3,71 @@
3
3
  All notable changes to `@a11y-skills/audit` are documented here. This project
4
4
  adheres to [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## 0.3.0
7
+
8
+ **Breaking** — every check now returns (and saves) a single axe-style envelope
9
+ instead of its own ad-hoc shape. The public API is not yet stable in `0.x`, so
10
+ this lands as a minor release.
11
+
12
+ ### Changed (breaking)
13
+
14
+ - All `runXxx()` functions return `AuditCheckResult<TDetails>`: findings are
15
+ normalized into `violations` / `incomplete` / `passes` / `inapplicable`
16
+ rule arrays (axe-style `id` / `impact` / `tags` / `helpUrl` / `nodes`), with
17
+ rule-level counts in `summary`. The former top-level fields (`issues`,
18
+ `failAA`, `overflowingElements`, `clippedElements`, ...) moved unchanged
19
+ under `details`.
20
+ - Classification is conservative: only findings whose detection has no blind
21
+ spot and where no WCAG exception can apply are `violations`
22
+ (on-focus context change, text-spacing clipping, invalid autocomplete
23
+ tokens). Everything else — reflow/zoom overflow, meta refresh, orientation
24
+ lock, missing focus styles, undersized targets — lands in `incomplete`, the
25
+ manual-review queue.
26
+ - Saved JSON files use the same envelope; the JSON Schemas were rewritten
27
+ accordingly (`$defs`-based shared envelope + per-check `details` schemas).
28
+ Pre-0.3.0 result files no longer validate.
29
+ - `saveAuditResult()` no longer appends a disclaimer (the envelope carries it).
30
+ - `runAxeAudit` builds the buckets from the raw axe results: violations and
31
+ incomplete keep their nodes, passes/inapplicable keep rule metadata only;
32
+ `details` records the execution configuration.
33
+
34
+ ### Added
35
+
36
+ - `rule-registry.ts`: per-rule metadata (`sc`, accurate per-SC `wcag*` tags,
37
+ `impact`, `scope`, classification) — target size split into
38
+ `a11y-skills/target-size-minimum` (2.5.8 AA) and
39
+ `a11y-skills/target-size-enhanced` (2.5.5 AAA).
40
+ - Pure normalization mappers (`normalize*`), `buildAuditResult()`, and the
41
+ opt-in `mergeNormalizedResults()` exported from the package root. The
42
+ buckets are re-derivable from a saved result's `details`.
43
+ - Element-level evidence: detail records now carry `html` (outerHTML, capped
44
+ at `HTML_SNIPPET_MAX_LENGTH`) and `htmlTruncated`; focus issues gained
45
+ `selector`. `TargetSizeIssue.exceptionAssessment`
46
+ (`ruled-out`/`possible`/`not-assessed`) drives the violation promotion.
47
+ - Tests: mapper unit tests, merge invariants, and ajv (draft 2020-12) schema
48
+ validation of the produced envelopes.
49
+
50
+ ## 0.2.0
51
+
52
+ Phase 2 checks added (additive). Still a `0.x` preview — the function API may
53
+ change before `1.0.0` based on downstream feedback.
54
+
55
+ ### Added
56
+
57
+ - `runTextSpacingCheck` — WCAG 1.4.12.
58
+ - `runZoomCheck` — WCAG 1.4.4.
59
+ - `runOrientationCheck` — WCAG 1.3.4 (owns navigation: takes `page` + `targetUrl`,
60
+ loads the page at portrait and landscape viewports).
61
+ - `runAutocompleteAudit` — WCAG 1.3.5.
62
+ - `runTimeLimitDetector` — WCAG 2.2.1 (owns navigation: installs a timer hook
63
+ before `goto`, so takes `page` + `targetUrl`).
64
+ - `runAutoPlayDetection` — WCAG 1.4.2 / 2.2.2. Requires the **optional**
65
+ dependencies `pixelmatch` + `pngjs` (for pixel-diffing screenshot frames);
66
+ they are loaded lazily, so importing the package without them keeps the other
67
+ nine checks working. Throws a clear error if invoked without them.
68
+ - `test-entries/*` and JSON Schemas (`RESULT_SCHEMAS`) for all six new checks.
69
+ - `getTargetUrl(defaultPath)` exported from `@a11y-skills/audit/playwright`.
70
+
6
71
  ## 0.1.0
7
72
 
8
73
  Initial preview release. The function API may change before `1.0.0` based on
package/README.ja.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Playwright + axe-core ベースの WCAG 2.2 アクセシビリティ検査関数。
4
4
 
5
5
  本パッケージは [`auditing-wcag`](https://github.com/masuP9/a11y-specialist-skills)
6
- Claude Code skill から機能本体を切り出したものです。4 つの検査を関数として提供し、
6
+ Claude Code skill から機能本体を切り出したものです。10 個の検査を関数として提供し、
7
7
  すぐ実行できる Playwright 用の互換 test entry も同梱します。
8
8
 
9
9
  > **English: see [README.md](./README.md).**
@@ -11,7 +11,7 @@ Claude Code skill から機能本体を切り出したものです。4 つの検
11
11
  > **スコープ.** 自動テストで検出できるのは WCAG 違反の約 30〜40% です。完全な準拠確認には
12
12
  > 手動テストが必須です。本パッケージはその一部を自動化します。
13
13
 
14
- ## 検査一覧 (v0.1.0)
14
+ ## 検査一覧
15
15
 
16
16
  | 関数 | WCAG |
17
17
  | --- | --- |
@@ -19,6 +19,17 @@ Claude Code skill から機能本体を切り出したものです。4 つの検
19
19
  | `runFocusIndicatorCheck` | 2.4.7 フォーカスの可視化 / 2.4.12 フォーカスの非遮蔽 / 3.2.1 オンフォーカス |
20
20
  | `runReflowCheck` | 1.4.10 リフロー |
21
21
  | `runTargetSizeCheck` | 2.5.5 / 2.5.8 ターゲットのサイズ |
22
+ | `runTextSpacingCheck` | 1.4.12 テキストの間隔 |
23
+ | `runZoomCheck` | 1.4.4 テキストのサイズ変更(200% ズーム) |
24
+ | `runOrientationCheck` | 1.3.4 表示の向き |
25
+ | `runAutocompleteAudit` | 1.3.5 入力目的の特定 |
26
+ | `runTimeLimitDetector` | 2.2.1 タイミング調整可能 |
27
+ | `runAutoPlayDetection` | 1.4.2 音声制御 / 2.2.2 一時停止、停止、非表示 |
28
+
29
+ 多くの検査は遷移済みの `page` を受けます。一部は navigation を所有し `targetUrl`
30
+ (または `TEST_PAGE`)を受けます: `runOrientationCheck` と `runTimeLimitDetector`
31
+ (`runZoomCheck` は URL 指定時)。`runFocusIndicatorCheck` は `browser` を受けます。
32
+ `runAutoPlayDetection` は optional 依存 `pixelmatch` + `pngjs` が必要です(インストール参照)。
22
33
 
23
34
  ## インストール
24
35
 
@@ -28,6 +39,14 @@ npm install -D @a11y-skills/audit @playwright/test @axe-core/playwright
28
39
 
29
40
  `@playwright/test` と `@axe-core/playwright` は **peer dependencies** です。
30
41
 
42
+ `runAutoPlayDetection` は追加で `pixelmatch` と `pngjs` を必要とします(**optional
43
+ dependencies** として宣言、既定でインストールされます)。遅延ロードされるため、
44
+ `--omit=optional` でインストールしても他の9検査は動作します:
45
+
46
+ ```sh
47
+ npm install -D pixelmatch pngjs # runAutoPlayDetection を使う場合のみ
48
+ ```
49
+
31
50
  > ESM 専用です。CommonJS ビルドは同梱しません。ESM(または ESM 出力の TypeScript)から
32
51
  > import してください。
33
52
 
@@ -48,7 +67,7 @@ test("axe audit", async ({ page }, testInfo) => {
48
67
  // outputFile: "axe-result.json", // 任意で上書き
49
68
  // tags: ["wcag2a", "wcag2aa", "wcag21aa", "wcag22aa"],
50
69
  });
51
- expect(result.violationCount).toBe(0);
70
+ expect(result.summary.violationCount).toBe(0);
52
71
  });
53
72
  ```
54
73
 
@@ -67,7 +86,7 @@ test("focus indicators", async ({ browser }, testInfo) => {
67
86
  screenshot: true, // 既定: false
68
87
  // contextOptions: { locale: "ja-JP" }, // browser.newContext() に転送
69
88
  });
70
- expect(result.elementsWithoutFocusStyle).toBe(0);
89
+ expect(result.details.elementsWithoutFocusStyle).toBe(0);
71
90
  });
72
91
  ```
73
92
 
@@ -102,6 +121,9 @@ import "@a11y-skills/audit/test-entries/focus-indicator-check";
102
121
  import "@a11y-skills/audit/test-entries/reflow-check";
103
122
  // tests/a11y/target-size.spec.ts
104
123
  import "@a11y-skills/audit/test-entries/target-size-check";
124
+ // 他にも: text-spacing-check, zoom-200-check, orientation-check,
125
+ // autocomplete-audit, time-limit-detector, auto-play-detection
126
+ import "@a11y-skills/audit/test-entries/text-spacing-check";
105
127
  ```
106
128
 
107
129
  ```sh
@@ -113,6 +135,52 @@ TEST_PAGE=https://example.com A11Y_OUTPUT_DIR=./a11y-results npx playwright test
113
135
  > を `testMatch` に指定してもテストは見つかりません。上記の 1 行 re-export spec が
114
136
  > entry を実行する正式な方法です。
115
137
 
138
+ ## 結果形式
139
+
140
+ すべての検査は同じ axe 風の envelope を返し、同じ形式で JSON に保存します:
141
+
142
+ ```ts
143
+ interface AuditCheckResult<TDetails> {
144
+ source: CheckSource; // 例: "reflow-check"
145
+ url: string;
146
+ timestamp: string;
147
+ violations: NormalizedRuleResult[]; // 確定した違反
148
+ incomplete: NormalizedRuleResult[]; // 要手動確認
149
+ passes: NormalizedRuleResult[]; // 実行して問題が見つからなかったルール
150
+ inapplicable: NormalizedRuleResult[]; // 検査対象がなかったルール
151
+ summary: { violationCount; incompleteCount; passCount; checkedNodes? };
152
+ details: TDetails; // 検査固有の証跡(測定値・スクリーンショット等)
153
+ disclaimer: { ... };
154
+ }
155
+ ```
156
+
157
+ 各ルール結果は axe と同じ形(`id` / `impact` / `description` / `help` /
158
+ `helpUrl` / `tags` / `nodes[]`、`nodes[].target` / `html` / `htmlTruncated` /
159
+ `failureSummary`)です。独自ルールは名前空間付き
160
+ (`a11y-skills/focus-visible`、`a11y-skills/target-size-minimum` など)で、
161
+ SC ごとに正確な WCAG バージョン・レベルタグ(`wcag2aa`、`wcag21aa`、
162
+ `wcag22aa`、`wcag247` 形式の SC タグ)が付きます。
163
+
164
+ **分類は保守的です。** 検出に死角がなく WCAG の例外が適用され得ない場合のみ
165
+ `violations` に入ります(フォーカスによる文脈変化、テキストスペーシングの
166
+ クリップ、autocomplete の不正トークン)。それ以外の検出 — reflow/zoom の
167
+ オーバーフロー、meta refresh、画面方向ロック、フォーカススタイル欠如、
168
+ 小さすぎるターゲット — は `incomplete` に入ります。`incomplete` はノイズでは
169
+ なく「要手動確認キュー」として扱ってください。
170
+
171
+ 同一ページに対する複数検査の結果を 1 つにまとめるには:
172
+
173
+ ```ts
174
+ import { mergeNormalizedResults } from "@a11y-skills/audit";
175
+
176
+ const merged = mergeNormalizedResults([axeResult, reflowResult, targetResult]);
177
+ ```
178
+
179
+ `mergeNormalizedResults` は URL 不一致で例外を投げ、ノードを
180
+ `target` + `failureSummary` で重複排除し、複数バケツに現れるルールは
181
+ `violations > incomplete > passes > inapplicable` の優先順位で統合します。
182
+ frame / shadow root 内の同一セレクタは区別しません。
183
+
116
184
  ## 結果型とスキーマ
117
185
 
118
186
  ```ts
@@ -120,8 +188,10 @@ import type { AxeAuditResult, FocusCheckResult } from "@a11y-skills/audit/schema
120
188
  import { RESULT_SCHEMAS } from "@a11y-skills/audit/schemas";
121
189
  ```
122
190
 
123
- `RESULT_SCHEMAS` は各検査 id に手書きの JSON Schema を対応付けており、`*-result.json`
124
- を実行時に検証できます。
191
+ `RESULT_SCHEMAS` は各検査 id に手書きの JSON Schema(draft 2020-12)を
192
+ 対応付けており、`*-result.json` を実行時に検証できます。正規化マッパー
193
+ (`normalize*`)と `buildAuditResult` はパッケージルートから export されて
194
+ いるため、保存済み結果の `details` から 4 区分をいつでも再導出できます。
125
195
 
126
196
  ## ライセンス
127
197
 
package/README.md CHANGED
@@ -4,7 +4,7 @@ Playwright + axe-core based WCAG 2.2 accessibility audit functions.
4
4
 
5
5
  This package is the functional core extracted from the
6
6
  [`auditing-wcag`](https://github.com/masuP9/a11y-specialist-skills) Claude Code
7
- skill. It ships four checks as plain functions plus ready-to-run Playwright
7
+ skill. It ships ten checks as plain functions plus ready-to-run Playwright
8
8
  test entries.
9
9
 
10
10
  > **日本語版は [README.ja.md](./README.ja.md) を参照してください。**
@@ -12,7 +12,7 @@ test entries.
12
12
  > **Scope.** Automated testing detects only ~30–40% of WCAG issues. Manual
13
13
  > testing is required for full conformance. This package automates a subset.
14
14
 
15
- ## Checks (v0.1.0)
15
+ ## Checks
16
16
 
17
17
  | Function | WCAG |
18
18
  | --- | --- |
@@ -20,6 +20,18 @@ test entries.
20
20
  | `runFocusIndicatorCheck` | 2.4.7 Focus Visible / 2.4.12 Focus Not Obscured / 3.2.1 On Focus |
21
21
  | `runReflowCheck` | 1.4.10 Reflow |
22
22
  | `runTargetSizeCheck` | 2.5.5 / 2.5.8 Target Size |
23
+ | `runTextSpacingCheck` | 1.4.12 Text Spacing |
24
+ | `runZoomCheck` | 1.4.4 Resize Text (200% zoom) |
25
+ | `runOrientationCheck` | 1.3.4 Orientation |
26
+ | `runAutocompleteAudit` | 1.3.5 Identify Input Purpose |
27
+ | `runTimeLimitDetector` | 2.2.1 Timing Adjustable |
28
+ | `runAutoPlayDetection` | 1.4.2 Audio Control / 2.2.2 Pause, Stop, Hide |
29
+
30
+ Most checks take an already-navigated `page`. A few own navigation and take a
31
+ `targetUrl` instead (or `TEST_PAGE`): `runOrientationCheck` and
32
+ `runTimeLimitDetector` (and `runZoomCheck` when a URL is given).
33
+ `runFocusIndicatorCheck` takes a `browser`. `runAutoPlayDetection` needs the
34
+ optional `pixelmatch` + `pngjs` deps (see Install).
23
35
 
24
36
  ## Install
25
37
 
@@ -29,6 +41,14 @@ npm install -D @a11y-skills/audit @playwright/test @axe-core/playwright
29
41
 
30
42
  `@playwright/test` and `@axe-core/playwright` are **peer dependencies**.
31
43
 
44
+ `runAutoPlayDetection` additionally needs `pixelmatch` and `pngjs` (declared as
45
+ **optional dependencies**, installed by default). They are loaded lazily, so
46
+ the other nine checks work even if you install with `--omit=optional`:
47
+
48
+ ```sh
49
+ npm install -D pixelmatch pngjs # only if you use runAutoPlayDetection
50
+ ```
51
+
32
52
  > ESM only. This package does not ship a CommonJS build; import it from ESM
33
53
  > (or a TypeScript project compiled to ESM).
34
54
 
@@ -49,7 +69,7 @@ test("axe audit", async ({ page }, testInfo) => {
49
69
  // outputFile: "axe-result.json", // optional override
50
70
  // tags: ["wcag2a", "wcag2aa", "wcag21aa", "wcag22aa"],
51
71
  });
52
- expect(result.violationCount).toBe(0);
72
+ expect(result.summary.violationCount).toBe(0);
53
73
  });
54
74
  ```
55
75
 
@@ -68,7 +88,7 @@ test("focus indicators", async ({ browser }, testInfo) => {
68
88
  screenshot: true, // default: false
69
89
  // contextOptions: { locale: "ja-JP" }, // forwarded to browser.newContext()
70
90
  });
71
- expect(result.elementsWithoutFocusStyle).toBe(0);
91
+ expect(result.details.elementsWithoutFocusStyle).toBe(0);
72
92
  });
73
93
  ```
74
94
 
@@ -104,6 +124,9 @@ import "@a11y-skills/audit/test-entries/focus-indicator-check";
104
124
  import "@a11y-skills/audit/test-entries/reflow-check";
105
125
  // tests/a11y/target-size.spec.ts
106
126
  import "@a11y-skills/audit/test-entries/target-size-check";
127
+ // ...also: text-spacing-check, zoom-200-check, orientation-check,
128
+ // autocomplete-audit, time-limit-detector, auto-play-detection
129
+ import "@a11y-skills/audit/test-entries/text-spacing-check";
107
130
  ```
108
131
 
109
132
  ```sh
@@ -115,6 +138,52 @@ TEST_PAGE=https://example.com A11Y_OUTPUT_DIR=./a11y-results npx playwright test
115
138
  > `**/node_modules/@a11y-skills/audit/dist/test-entries/*.js` finds no tests.
116
139
  > The one-line re-export specs above are the supported way to run the entries.
117
140
 
141
+ ## Result format
142
+
143
+ Every check returns — and saves as JSON — the same axe-style envelope:
144
+
145
+ ```ts
146
+ interface AuditCheckResult<TDetails> {
147
+ source: CheckSource; // e.g. "reflow-check"
148
+ url: string;
149
+ timestamp: string;
150
+ violations: NormalizedRuleResult[]; // confirmed findings
151
+ incomplete: NormalizedRuleResult[]; // needs manual review
152
+ passes: NormalizedRuleResult[]; // rules that ran and found nothing
153
+ inapplicable: NormalizedRuleResult[]; // nothing to examine
154
+ summary: { violationCount; incompleteCount; passCount; checkedNodes? };
155
+ details: TDetails; // check-specific evidence (measurements, screenshots, ...)
156
+ disclaimer: { ... };
157
+ }
158
+ ```
159
+
160
+ Each rule result is axe-shaped (`id` / `impact` / `description` / `help` /
161
+ `helpUrl` / `tags` / `nodes[]`, with `nodes[].target` / `html` /
162
+ `htmlTruncated` / `failureSummary`). Custom rules are namespaced
163
+ (`a11y-skills/focus-visible`, `a11y-skills/target-size-minimum`, ...) and
164
+ tagged with accurate WCAG version/level tags (`wcag2aa`, `wcag21aa`,
165
+ `wcag22aa`, `wcag247`-style SC tags).
166
+
167
+ **Classification is conservative.** A finding lands in `violations` only when
168
+ the detection has no blind spot and no WCAG exception can apply (on-focus
169
+ context change, text-spacing clipping, invalid autocomplete tokens). All other
170
+ detections — reflow/zoom overflow, meta refresh, orientation lock, missing
171
+ focus styles, undersized targets — are `incomplete`: treat that bucket as the
172
+ manual-review queue, not as noise.
173
+
174
+ To combine several checks for the same page into one view:
175
+
176
+ ```ts
177
+ import { mergeNormalizedResults } from "@a11y-skills/audit";
178
+
179
+ const merged = mergeNormalizedResults([axeResult, reflowResult, targetResult]);
180
+ ```
181
+
182
+ `mergeNormalizedResults` throws on URL mismatches, deduplicates nodes by
183
+ `target` + `failureSummary`, and resolves a rule appearing in several buckets
184
+ by priority (`violations > incomplete > passes > inapplicable`). Identical
185
+ selectors inside different frames or shadow roots are not distinguished.
186
+
118
187
  ## Result types & schemas
119
188
 
120
189
  ```ts
@@ -122,8 +191,11 @@ import type { AxeAuditResult, FocusCheckResult } from "@a11y-skills/audit/schema
122
191
  import { RESULT_SCHEMAS } from "@a11y-skills/audit/schemas";
123
192
  ```
124
193
 
125
- `RESULT_SCHEMAS` maps each check id to a hand-written JSON Schema for validating
126
- the `*-result.json` files at runtime.
194
+ `RESULT_SCHEMAS` maps each check id to a hand-written JSON Schema
195
+ (draft 2020-12) for validating the `*-result.json` files at runtime. The
196
+ normalization mappers (`normalize*`) and `buildAuditResult` are exported from
197
+ the package root, so the buckets can be re-derived from a saved result's
198
+ `details` at any time.
127
199
 
128
200
  ## License
129
201
 
@@ -14,6 +14,8 @@ export declare const AUDIT_DISCLAIMER: {
14
14
  };
15
15
  /** Console disclaimer message */
16
16
  export declare const DISCLAIMER_CONSOLE = "\nNote: Automated testing detects only ~30-40% of WCAG issues.\n Manual testing is required for complete accessibility evaluation.\n";
17
+ /** Maximum length of `NormalizedNode.html` / detail `html` snippets. */
18
+ export declare const HTML_SNIPPET_MAX_LENGTH = 300;
17
19
  /** Default axe-core tag set (WCAG 2.0/2.1/2.2 A & AA) */
18
20
  export declare const DEFAULT_AXE_TAGS: readonly ["wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "wcag22aa"];
19
21
  /** CSS properties to check for focus style changes */
@@ -86,3 +88,85 @@ export declare const UA_CONTROLLED_INPUT_TYPES: readonly ["checkbox", "radio", "
86
88
  * Minimum text length around inline link to qualify for inline exception
87
89
  */
88
90
  export declare const INLINE_CONTEXT_MIN_TEXT = 10;
91
+ /**
92
+ * CSS overrides for text spacing test per WCAG 1.4.12
93
+ * - Line height: at least 1.5 times the font size
94
+ * - Letter spacing: at least 0.12 times the font size
95
+ * - Word spacing: at least 0.16 times the font size
96
+ * - Paragraph spacing: at least 2 times the font size
97
+ */
98
+ export declare const TEXT_SPACING_CSS = "\n * {\n line-height: 1.5 !important;\n letter-spacing: 0.12em !important;\n word-spacing: 0.16em !important;\n }\n p, div, span, li, td, th, dd, dt, label, blockquote {\n margin-bottom: 2em !important;\n }\n";
99
+ /** Tolerance for detecting clipping after text spacing changes */
100
+ export declare const TEXT_SPACING_CLIP_TOLERANCE = 2;
101
+ /** Selector for text-containing elements to check */
102
+ export declare const TEXT_SPACING_CHECK_SELECTOR: string;
103
+ export declare const DEFAULT_TEXT_SPACING_RESULT_FILE = "text-spacing-result.json";
104
+ export declare const DEFAULT_TEXT_SPACING_SCREENSHOT_FILE = "text-spacing-screenshot.png";
105
+ /** Zoom factor for resize text test */
106
+ export declare const ZOOM_FACTOR = 2;
107
+ /** Base viewport size before zoom (standard desktop) */
108
+ export declare const ZOOM_BASE_VIEWPORT: {
109
+ readonly width: 1280;
110
+ readonly height: 720;
111
+ };
112
+ /** Tolerance for detecting clipping at zoom */
113
+ export declare const ZOOM_CLIP_TOLERANCE = 5;
114
+ export declare const DEFAULT_ZOOM_RESULT_FILE = "zoom-200-result.json";
115
+ export declare const DEFAULT_ZOOM_SCREENSHOT_FILE = "zoom-200-screenshot.png";
116
+ /** Viewport sizes for orientation tests */
117
+ export declare const ORIENTATION_VIEWPORTS: {
118
+ readonly portrait: {
119
+ readonly width: 375;
120
+ readonly height: 667;
121
+ };
122
+ readonly landscape: {
123
+ readonly width: 667;
124
+ readonly height: 375;
125
+ };
126
+ };
127
+ /** Keywords indicating orientation lock messages (EN/JP) */
128
+ export declare const ORIENTATION_LOCK_KEYWORDS: readonly ["rotate device", "rotate your device", "rotate your phone", "turn your device", "landscape only", "portrait only", "please rotate", "best viewed in", "for best experience", "画面を回転", "端末を回転", "デバイスを回転", "横向きにして", "縦向きにして", "横画面でご覧", "縦画面でご覧", "回転してください"];
129
+ /** Main content selectors to check visibility */
130
+ export declare const MAIN_CONTENT_SELECTORS: readonly ["main", "[role=\"main\"]", "#main", "#content", ".main-content", "article"];
131
+ export declare const DEFAULT_ORIENTATION_RESULT_FILE = "orientation-result.json";
132
+ export declare const DEFAULT_ORIENTATION_PORTRAIT_SCREENSHOT_FILE = "orientation-screenshot-portrait.png";
133
+ export declare const DEFAULT_ORIENTATION_LANDSCAPE_SCREENSHOT_FILE = "orientation-screenshot-landscape.png";
134
+ /**
135
+ * Mapping of field patterns to expected autocomplete tokens
136
+ * Based on HTML autocomplete attribute values
137
+ */
138
+ export declare const AUTOCOMPLETE_FIELD_PATTERNS: Record<string, RegExp>;
139
+ /** Valid autocomplete token values */
140
+ export declare const VALID_AUTOCOMPLETE_TOKENS: readonly ["off", "on", "name", "honorific-prefix", "given-name", "additional-name", "family-name", "honorific-suffix", "nickname", "email", "username", "new-password", "current-password", "one-time-code", "organization-title", "organization", "street-address", "address-line1", "address-line2", "address-line3", "address-level1", "address-level2", "address-level3", "address-level4", "country", "country-name", "postal-code", "cc-name", "cc-given-name", "cc-additional-name", "cc-family-name", "cc-number", "cc-exp", "cc-exp-month", "cc-exp-year", "cc-csc", "cc-type", "transaction-currency", "transaction-amount", "language", "bday", "bday-day", "bday-month", "bday-year", "sex", "tel", "tel-country-code", "tel-national", "tel-area-code", "tel-local", "tel-local-prefix", "tel-local-suffix", "tel-extension", "impp", "url", "photo"];
141
+ export declare const DEFAULT_AUTOCOMPLETE_RESULT_FILE = "autocomplete-result.json";
142
+ /** Keywords indicating countdown or time limit in visible text (EN/JP) */
143
+ export declare const TIME_LIMIT_KEYWORDS: readonly ["session expires", "session timeout", "time remaining", "time left", "countdown", "expires in", "will timeout", "auto logout", "automatic logout", "セッション終了", "セッションタイムアウト", "残り時間", "タイムアウト", "自動ログアウト", "有効期限", "制限時間", "カウントダウン"];
144
+ /** Timer threshold for reporting (10 minutes in ms) */
145
+ export declare const TIME_LIMIT_THRESHOLD_MS = 600000;
146
+ /** Minimum timer to report (10 seconds in ms, to filter out UI animations) */
147
+ export declare const TIME_LIMIT_MIN_MS = 10000;
148
+ export declare const DEFAULT_TIME_LIMIT_RESULT_FILE = "time-limit-result.json";
149
+ /** Screenshot intervals in milliseconds (0s, 2s, 4s, 6s) */
150
+ export declare const SCREENSHOT_INTERVALS: readonly [0, 2000, 4000, 6000];
151
+ /** Pixel change threshold (0.1% = significant change) */
152
+ export declare const CHANGE_THRESHOLD = 0.1;
153
+ /** Pixelmatch color difference threshold (0-1) */
154
+ export declare const PIXELMATCH_THRESHOLD = 0.1;
155
+ /** Wait time after clicking pause control (ms) */
156
+ export declare const PAUSE_CLICK_WAIT = 500;
157
+ /** Wait time between screenshots for comparison (ms) */
158
+ export declare const SCREENSHOT_COMPARISON_WAIT = 2000;
159
+ export declare const DEFAULT_AUTO_PLAY_OUTPUT_DIR = "./auto-play-screenshots";
160
+ export declare const DETECTION_RESULT_FILENAME = "detection-result.json";
161
+ /** Keywords for pause/stop controls (EN/JP) */
162
+ export declare const PAUSE_KEYWORDS: readonly ["pause", "stop", "halt", "freeze", "play", "一時停止", "停止", "ポーズ", "止める", "再生"];
163
+ /** Class name patterns indicating pause/play controls */
164
+ export declare const CONTROL_CLASS_PATTERNS: readonly ["pause", "play", "stop", "toggle", "switch", "control", "btn-pause", "btn-play", "btn-stop"];
165
+ /** Carousel-related class patterns */
166
+ export declare const CAROUSEL_PATTERNS: readonly ["carousel", "slider", "slide", "swiper", "slick", "hero", "banner", "gallery", "rotator"];
167
+ /** Navigation control keywords */
168
+ export declare const NAV_KEYWORDS: readonly ["prev", "next", "前", "次", "arrow", "dot", "indicator"];
169
+ /** SVG metadata patterns to exclude from accessible names */
170
+ export declare const SVG_METADATA_PATTERNS: readonly ["created with", "made with", "generated by", "svg", "icon", "symbol"];
171
+ /** Maximum parent levels to check for carousel context */
172
+ export declare const MAX_PARENT_LEVELS = 5;