@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.
- package/CHANGELOG.md +65 -0
- package/README.ja.md +76 -6
- package/README.md +78 -6
- package/dist/constants.d.ts +84 -0
- package/dist/constants.js +228 -0
- package/dist/detectors/index.d.ts +1 -0
- package/dist/detectors/index.js +1 -0
- package/dist/detectors/pause-control.d.ts +18 -0
- package/dist/detectors/pause-control.js +206 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/playwright/index.d.ts +7 -1
- package/dist/playwright/index.js +7 -1
- package/dist/playwright/runAutoPlayDetection.d.ts +36 -0
- package/dist/playwright/runAutoPlayDetection.js +143 -0
- package/dist/playwright/runAutocompleteAudit.d.ts +27 -0
- package/dist/playwright/runAutocompleteAudit.js +227 -0
- package/dist/playwright/runAxeAudit.d.ts +4 -0
- package/dist/playwright/runAxeAudit.js +26 -30
- package/dist/playwright/runFocusIndicatorCheck.js +55 -12
- package/dist/playwright/runOrientationCheck.d.ts +40 -0
- package/dist/playwright/runOrientationCheck.js +170 -0
- package/dist/playwright/runReflowCheck.js +18 -11
- package/dist/playwright/runTargetSizeCheck.js +42 -10
- package/dist/playwright/runTextSpacingCheck.d.ts +25 -0
- package/dist/playwright/runTextSpacingCheck.js +285 -0
- package/dist/playwright/runTimeLimitDetector.d.ts +31 -0
- package/dist/playwright/runTimeLimitDetector.js +219 -0
- package/dist/playwright/runZoomCheck.d.ts +42 -0
- package/dist/playwright/runZoomCheck.js +174 -0
- package/dist/schemas/index.d.ts +20 -1
- package/dist/schemas/index.js +404 -186
- package/dist/test-entries/auto-play-detection.d.ts +7 -0
- package/dist/test-entries/auto-play-detection.js +13 -0
- package/dist/test-entries/autocomplete-audit.d.ts +5 -0
- package/dist/test-entries/autocomplete-audit.js +11 -0
- package/dist/test-entries/orientation-check.d.ts +8 -0
- package/dist/test-entries/orientation-check.js +12 -0
- package/dist/test-entries/text-spacing-check.d.ts +5 -0
- package/dist/test-entries/text-spacing-check.js +11 -0
- package/dist/test-entries/time-limit-detector.d.ts +8 -0
- package/dist/test-entries/time-limit-detector.js +12 -0
- package/dist/test-entries/zoom-200-check.d.ts +5 -0
- package/dist/test-entries/zoom-200-check.js +11 -0
- package/dist/types.d.ts +275 -40
- package/dist/types.js +9 -0
- package/dist/utils/axe-format.d.ts +88 -0
- package/dist/utils/axe-format.js +361 -0
- package/dist/utils/image-compare.d.ts +24 -0
- package/dist/utils/image-compare.js +49 -0
- package/dist/utils/layout.d.ts +2 -0
- package/dist/utils/layout.js +20 -1
- package/dist/utils/recommendations.d.ts +18 -0
- package/dist/utils/recommendations.js +88 -0
- package/dist/utils/rule-registry.d.ts +216 -0
- package/dist/utils/rule-registry.js +220 -0
- package/dist/utils/test-harness.d.ts +8 -2
- package/dist/utils/test-harness.js +13 -6
- 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 から機能本体を切り出したものです。
|
|
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
|
-
## 検査一覧
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
package/dist/constants.d.ts
CHANGED
|
@@ -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;
|