@a11y-skills/audit 0.1.0 → 0.2.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 +21 -0
- package/README.ja.md +24 -2
- package/README.md +25 -2
- package/dist/constants.d.ts +82 -0
- package/dist/constants.js +223 -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/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 +137 -0
- package/dist/playwright/runAutocompleteAudit.d.ts +27 -0
- package/dist/playwright/runAutocompleteAudit.js +197 -0
- package/dist/playwright/runOrientationCheck.d.ts +40 -0
- package/dist/playwright/runOrientationCheck.js +164 -0
- package/dist/playwright/runTextSpacingCheck.d.ts +25 -0
- package/dist/playwright/runTextSpacingCheck.js +241 -0
- package/dist/playwright/runTimeLimitDetector.d.ts +31 -0
- package/dist/playwright/runTimeLimitDetector.js +194 -0
- package/dist/playwright/runZoomCheck.d.ts +42 -0
- package/dist/playwright/runZoomCheck.js +150 -0
- package/dist/schemas/index.d.ts +13 -1
- package/dist/schemas/index.js +122 -0
- 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 +151 -0
- package/dist/utils/image-compare.d.ts +24 -0
- package/dist/utils/image-compare.js +49 -0
- package/dist/utils/recommendations.d.ts +18 -0
- package/dist/utils/recommendations.js +88 -0
- package/dist/utils/test-harness.d.ts +6 -0
- package/dist/utils/test-harness.js +8 -0
- package/package.json +31 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,27 @@
|
|
|
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.2.0
|
|
7
|
+
|
|
8
|
+
Phase 2 checks added (additive). Still a `0.x` preview — the function API may
|
|
9
|
+
change before `1.0.0` based on downstream feedback.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `runTextSpacingCheck` — WCAG 1.4.12.
|
|
14
|
+
- `runZoomCheck` — WCAG 1.4.4.
|
|
15
|
+
- `runOrientationCheck` — WCAG 1.3.4 (owns navigation: takes `page` + `targetUrl`,
|
|
16
|
+
loads the page at portrait and landscape viewports).
|
|
17
|
+
- `runAutocompleteAudit` — WCAG 1.3.5.
|
|
18
|
+
- `runTimeLimitDetector` — WCAG 2.2.1 (owns navigation: installs a timer hook
|
|
19
|
+
before `goto`, so takes `page` + `targetUrl`).
|
|
20
|
+
- `runAutoPlayDetection` — WCAG 1.4.2 / 2.2.2. Requires the **optional**
|
|
21
|
+
dependencies `pixelmatch` + `pngjs` (for pixel-diffing screenshot frames);
|
|
22
|
+
they are loaded lazily, so importing the package without them keeps the other
|
|
23
|
+
nine checks working. Throws a clear error if invoked without them.
|
|
24
|
+
- `test-entries/*` and JSON Schemas (`RESULT_SCHEMAS`) for all six new checks.
|
|
25
|
+
- `getTargetUrl(defaultPath)` exported from `@a11y-skills/audit/playwright`.
|
|
26
|
+
|
|
6
27
|
## 0.1.0
|
|
7
28
|
|
|
8
29
|
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
|
|
|
@@ -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
|
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
|
|
|
@@ -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
|
package/dist/constants.d.ts
CHANGED
|
@@ -86,3 +86,85 @@ export declare const UA_CONTROLLED_INPUT_TYPES: readonly ["checkbox", "radio", "
|
|
|
86
86
|
* Minimum text length around inline link to qualify for inline exception
|
|
87
87
|
*/
|
|
88
88
|
export declare const INLINE_CONTEXT_MIN_TEXT = 10;
|
|
89
|
+
/**
|
|
90
|
+
* CSS overrides for text spacing test per WCAG 1.4.12
|
|
91
|
+
* - Line height: at least 1.5 times the font size
|
|
92
|
+
* - Letter spacing: at least 0.12 times the font size
|
|
93
|
+
* - Word spacing: at least 0.16 times the font size
|
|
94
|
+
* - Paragraph spacing: at least 2 times the font size
|
|
95
|
+
*/
|
|
96
|
+
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";
|
|
97
|
+
/** Tolerance for detecting clipping after text spacing changes */
|
|
98
|
+
export declare const TEXT_SPACING_CLIP_TOLERANCE = 2;
|
|
99
|
+
/** Selector for text-containing elements to check */
|
|
100
|
+
export declare const TEXT_SPACING_CHECK_SELECTOR: string;
|
|
101
|
+
export declare const DEFAULT_TEXT_SPACING_RESULT_FILE = "text-spacing-result.json";
|
|
102
|
+
export declare const DEFAULT_TEXT_SPACING_SCREENSHOT_FILE = "text-spacing-screenshot.png";
|
|
103
|
+
/** Zoom factor for resize text test */
|
|
104
|
+
export declare const ZOOM_FACTOR = 2;
|
|
105
|
+
/** Base viewport size before zoom (standard desktop) */
|
|
106
|
+
export declare const ZOOM_BASE_VIEWPORT: {
|
|
107
|
+
readonly width: 1280;
|
|
108
|
+
readonly height: 720;
|
|
109
|
+
};
|
|
110
|
+
/** Tolerance for detecting clipping at zoom */
|
|
111
|
+
export declare const ZOOM_CLIP_TOLERANCE = 5;
|
|
112
|
+
export declare const DEFAULT_ZOOM_RESULT_FILE = "zoom-200-result.json";
|
|
113
|
+
export declare const DEFAULT_ZOOM_SCREENSHOT_FILE = "zoom-200-screenshot.png";
|
|
114
|
+
/** Viewport sizes for orientation tests */
|
|
115
|
+
export declare const ORIENTATION_VIEWPORTS: {
|
|
116
|
+
readonly portrait: {
|
|
117
|
+
readonly width: 375;
|
|
118
|
+
readonly height: 667;
|
|
119
|
+
};
|
|
120
|
+
readonly landscape: {
|
|
121
|
+
readonly width: 667;
|
|
122
|
+
readonly height: 375;
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
/** Keywords indicating orientation lock messages (EN/JP) */
|
|
126
|
+
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", "画面を回転", "端末を回転", "デバイスを回転", "横向きにして", "縦向きにして", "横画面でご覧", "縦画面でご覧", "回転してください"];
|
|
127
|
+
/** Main content selectors to check visibility */
|
|
128
|
+
export declare const MAIN_CONTENT_SELECTORS: readonly ["main", "[role=\"main\"]", "#main", "#content", ".main-content", "article"];
|
|
129
|
+
export declare const DEFAULT_ORIENTATION_RESULT_FILE = "orientation-result.json";
|
|
130
|
+
export declare const DEFAULT_ORIENTATION_PORTRAIT_SCREENSHOT_FILE = "orientation-screenshot-portrait.png";
|
|
131
|
+
export declare const DEFAULT_ORIENTATION_LANDSCAPE_SCREENSHOT_FILE = "orientation-screenshot-landscape.png";
|
|
132
|
+
/**
|
|
133
|
+
* Mapping of field patterns to expected autocomplete tokens
|
|
134
|
+
* Based on HTML autocomplete attribute values
|
|
135
|
+
*/
|
|
136
|
+
export declare const AUTOCOMPLETE_FIELD_PATTERNS: Record<string, RegExp>;
|
|
137
|
+
/** Valid autocomplete token values */
|
|
138
|
+
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"];
|
|
139
|
+
export declare const DEFAULT_AUTOCOMPLETE_RESULT_FILE = "autocomplete-result.json";
|
|
140
|
+
/** Keywords indicating countdown or time limit in visible text (EN/JP) */
|
|
141
|
+
export declare const TIME_LIMIT_KEYWORDS: readonly ["session expires", "session timeout", "time remaining", "time left", "countdown", "expires in", "will timeout", "auto logout", "automatic logout", "セッション終了", "セッションタイムアウト", "残り時間", "タイムアウト", "自動ログアウト", "有効期限", "制限時間", "カウントダウン"];
|
|
142
|
+
/** Timer threshold for reporting (10 minutes in ms) */
|
|
143
|
+
export declare const TIME_LIMIT_THRESHOLD_MS = 600000;
|
|
144
|
+
/** Minimum timer to report (10 seconds in ms, to filter out UI animations) */
|
|
145
|
+
export declare const TIME_LIMIT_MIN_MS = 10000;
|
|
146
|
+
export declare const DEFAULT_TIME_LIMIT_RESULT_FILE = "time-limit-result.json";
|
|
147
|
+
/** Screenshot intervals in milliseconds (0s, 2s, 4s, 6s) */
|
|
148
|
+
export declare const SCREENSHOT_INTERVALS: readonly [0, 2000, 4000, 6000];
|
|
149
|
+
/** Pixel change threshold (0.1% = significant change) */
|
|
150
|
+
export declare const CHANGE_THRESHOLD = 0.1;
|
|
151
|
+
/** Pixelmatch color difference threshold (0-1) */
|
|
152
|
+
export declare const PIXELMATCH_THRESHOLD = 0.1;
|
|
153
|
+
/** Wait time after clicking pause control (ms) */
|
|
154
|
+
export declare const PAUSE_CLICK_WAIT = 500;
|
|
155
|
+
/** Wait time between screenshots for comparison (ms) */
|
|
156
|
+
export declare const SCREENSHOT_COMPARISON_WAIT = 2000;
|
|
157
|
+
export declare const DEFAULT_AUTO_PLAY_OUTPUT_DIR = "./auto-play-screenshots";
|
|
158
|
+
export declare const DETECTION_RESULT_FILENAME = "detection-result.json";
|
|
159
|
+
/** Keywords for pause/stop controls (EN/JP) */
|
|
160
|
+
export declare const PAUSE_KEYWORDS: readonly ["pause", "stop", "halt", "freeze", "play", "一時停止", "停止", "ポーズ", "止める", "再生"];
|
|
161
|
+
/** Class name patterns indicating pause/play controls */
|
|
162
|
+
export declare const CONTROL_CLASS_PATTERNS: readonly ["pause", "play", "stop", "toggle", "switch", "control", "btn-pause", "btn-play", "btn-stop"];
|
|
163
|
+
/** Carousel-related class patterns */
|
|
164
|
+
export declare const CAROUSEL_PATTERNS: readonly ["carousel", "slider", "slide", "swiper", "slick", "hero", "banner", "gallery", "rotator"];
|
|
165
|
+
/** Navigation control keywords */
|
|
166
|
+
export declare const NAV_KEYWORDS: readonly ["prev", "next", "前", "次", "arrow", "dot", "indicator"];
|
|
167
|
+
/** SVG metadata patterns to exclude from accessible names */
|
|
168
|
+
export declare const SVG_METADATA_PATTERNS: readonly ["created with", "made with", "generated by", "svg", "icon", "symbol"];
|
|
169
|
+
/** Maximum parent levels to check for carousel context */
|
|
170
|
+
export declare const MAX_PARENT_LEVELS = 5;
|
package/dist/constants.js
CHANGED
|
@@ -182,3 +182,226 @@ export const UA_CONTROLLED_INPUT_TYPES = [
|
|
|
182
182
|
* Minimum text length around inline link to qualify for inline exception
|
|
183
183
|
*/
|
|
184
184
|
export const INLINE_CONTEXT_MIN_TEXT = 10;
|
|
185
|
+
// =============================================================================
|
|
186
|
+
// Text Spacing Check Constants (WCAG 1.4.12)
|
|
187
|
+
// =============================================================================
|
|
188
|
+
/**
|
|
189
|
+
* CSS overrides for text spacing test per WCAG 1.4.12
|
|
190
|
+
* - Line height: at least 1.5 times the font size
|
|
191
|
+
* - Letter spacing: at least 0.12 times the font size
|
|
192
|
+
* - Word spacing: at least 0.16 times the font size
|
|
193
|
+
* - Paragraph spacing: at least 2 times the font size
|
|
194
|
+
*/
|
|
195
|
+
export const TEXT_SPACING_CSS = `
|
|
196
|
+
* {
|
|
197
|
+
line-height: 1.5 !important;
|
|
198
|
+
letter-spacing: 0.12em !important;
|
|
199
|
+
word-spacing: 0.16em !important;
|
|
200
|
+
}
|
|
201
|
+
p, div, span, li, td, th, dd, dt, label, blockquote {
|
|
202
|
+
margin-bottom: 2em !important;
|
|
203
|
+
}
|
|
204
|
+
`;
|
|
205
|
+
/** Tolerance for detecting clipping after text spacing changes */
|
|
206
|
+
export const TEXT_SPACING_CLIP_TOLERANCE = 2;
|
|
207
|
+
/** Selector for text-containing elements to check */
|
|
208
|
+
export const TEXT_SPACING_CHECK_SELECTOR = `
|
|
209
|
+
p, h1, h2, h3, h4, h5, h6, li, td, th, span, div,
|
|
210
|
+
a, button, label, dd, dt, blockquote, figcaption
|
|
211
|
+
`.trim();
|
|
212
|
+
export const DEFAULT_TEXT_SPACING_RESULT_FILE = 'text-spacing-result.json';
|
|
213
|
+
export const DEFAULT_TEXT_SPACING_SCREENSHOT_FILE = 'text-spacing-screenshot.png';
|
|
214
|
+
// =============================================================================
|
|
215
|
+
// Zoom 200% Check Constants (WCAG 1.4.4)
|
|
216
|
+
// =============================================================================
|
|
217
|
+
/** Zoom factor for resize text test */
|
|
218
|
+
export const ZOOM_FACTOR = 2;
|
|
219
|
+
/** Base viewport size before zoom (standard desktop) */
|
|
220
|
+
export const ZOOM_BASE_VIEWPORT = { width: 1280, height: 720 };
|
|
221
|
+
/** Tolerance for detecting clipping at zoom */
|
|
222
|
+
export const ZOOM_CLIP_TOLERANCE = 5;
|
|
223
|
+
export const DEFAULT_ZOOM_RESULT_FILE = 'zoom-200-result.json';
|
|
224
|
+
export const DEFAULT_ZOOM_SCREENSHOT_FILE = 'zoom-200-screenshot.png';
|
|
225
|
+
// =============================================================================
|
|
226
|
+
// Orientation Check Constants (WCAG 1.3.4)
|
|
227
|
+
// =============================================================================
|
|
228
|
+
/** Viewport sizes for orientation tests */
|
|
229
|
+
export const ORIENTATION_VIEWPORTS = {
|
|
230
|
+
portrait: { width: 375, height: 667 },
|
|
231
|
+
landscape: { width: 667, height: 375 },
|
|
232
|
+
};
|
|
233
|
+
/** Keywords indicating orientation lock messages (EN/JP) */
|
|
234
|
+
export const ORIENTATION_LOCK_KEYWORDS = [
|
|
235
|
+
// English
|
|
236
|
+
'rotate device',
|
|
237
|
+
'rotate your device',
|
|
238
|
+
'rotate your phone',
|
|
239
|
+
'turn your device',
|
|
240
|
+
'landscape only',
|
|
241
|
+
'portrait only',
|
|
242
|
+
'please rotate',
|
|
243
|
+
'best viewed in',
|
|
244
|
+
'for best experience',
|
|
245
|
+
// Japanese
|
|
246
|
+
'画面を回転',
|
|
247
|
+
'端末を回転',
|
|
248
|
+
'デバイスを回転',
|
|
249
|
+
'横向きにして',
|
|
250
|
+
'縦向きにして',
|
|
251
|
+
'横画面でご覧',
|
|
252
|
+
'縦画面でご覧',
|
|
253
|
+
'回転してください',
|
|
254
|
+
];
|
|
255
|
+
/** Main content selectors to check visibility */
|
|
256
|
+
export const MAIN_CONTENT_SELECTORS = [
|
|
257
|
+
'main',
|
|
258
|
+
'[role="main"]',
|
|
259
|
+
'#main',
|
|
260
|
+
'#content',
|
|
261
|
+
'.main-content',
|
|
262
|
+
'article',
|
|
263
|
+
];
|
|
264
|
+
export const DEFAULT_ORIENTATION_RESULT_FILE = 'orientation-result.json';
|
|
265
|
+
export const DEFAULT_ORIENTATION_PORTRAIT_SCREENSHOT_FILE = 'orientation-screenshot-portrait.png';
|
|
266
|
+
export const DEFAULT_ORIENTATION_LANDSCAPE_SCREENSHOT_FILE = 'orientation-screenshot-landscape.png';
|
|
267
|
+
// =============================================================================
|
|
268
|
+
// Autocomplete Audit Constants (WCAG 1.3.5)
|
|
269
|
+
// =============================================================================
|
|
270
|
+
/**
|
|
271
|
+
* Mapping of field patterns to expected autocomplete tokens
|
|
272
|
+
* Based on HTML autocomplete attribute values
|
|
273
|
+
*/
|
|
274
|
+
export const AUTOCOMPLETE_FIELD_PATTERNS = {
|
|
275
|
+
// Name fields
|
|
276
|
+
name: /^(full.?name|your.?name|氏名|お名前|名前)$/i,
|
|
277
|
+
'given-name': /^(first.?name|given.?name|名|ファーストネーム|名前)$/i,
|
|
278
|
+
'family-name': /^(last.?name|family.?name|surname|姓|ラストネーム|苗字)$/i,
|
|
279
|
+
'honorific-prefix': /^(prefix|title|敬称)$/i,
|
|
280
|
+
'honorific-suffix': /^(suffix|様|さん)$/i,
|
|
281
|
+
// Contact fields
|
|
282
|
+
email: /^(e.?mail|メール|メールアドレス)$/i,
|
|
283
|
+
tel: /^(phone|tel|telephone|電話|電話番号|携帯)$/i,
|
|
284
|
+
'tel-national': /^(phone.?national|国内電話)$/i,
|
|
285
|
+
// Address fields
|
|
286
|
+
'street-address': /^(address|street|住所|番地)$/i,
|
|
287
|
+
'address-line1': /^(address.?1|address.?line.?1|住所1)$/i,
|
|
288
|
+
'address-line2': /^(address.?2|address.?line.?2|住所2)$/i,
|
|
289
|
+
'postal-code': /^(zip|postal|郵便番号|〒)$/i,
|
|
290
|
+
country: /^(country|国|国名)$/i,
|
|
291
|
+
'country-name': /^(country.?name|国名)$/i,
|
|
292
|
+
// Organization fields
|
|
293
|
+
organization: /^(company|org|organization|会社|組織|会社名)$/i,
|
|
294
|
+
'organization-title': /^(title|position|役職|肩書き)$/i,
|
|
295
|
+
// Username/password
|
|
296
|
+
username: /^(user.?name|login|ユーザー名|ログインID)$/i,
|
|
297
|
+
'current-password': /^(password|pass|current.?password|パスワード|現在のパスワード)$/i,
|
|
298
|
+
'new-password': /^(new.?password|新しいパスワード)$/i,
|
|
299
|
+
// Payment
|
|
300
|
+
'cc-name': /^(card.?name|cc.?name|カード名義)$/i,
|
|
301
|
+
'cc-number': /^(card.?number|cc.?number|カード番号)$/i,
|
|
302
|
+
'cc-exp': /^(expir|cc.?exp|有効期限)$/i,
|
|
303
|
+
'cc-exp-month': /^(exp.?month|有効期限.?月)$/i,
|
|
304
|
+
'cc-exp-year': /^(exp.?year|有効期限.?年)$/i,
|
|
305
|
+
'cc-csc': /^(cvc|cvv|csc|security.?code|セキュリティコード)$/i,
|
|
306
|
+
// Dates
|
|
307
|
+
bday: /^(birth.?day|birthday|dob|生年月日|誕生日)$/i,
|
|
308
|
+
'bday-day': /^(birth.?day.?day|日)$/i,
|
|
309
|
+
'bday-month': /^(birth.?day.?month|月)$/i,
|
|
310
|
+
'bday-year': /^(birth.?day.?year|年)$/i,
|
|
311
|
+
sex: /^(sex|gender|性別)$/i,
|
|
312
|
+
// Other
|
|
313
|
+
url: /^(url|website|homepage|ウェブサイト|ホームページ)$/i,
|
|
314
|
+
photo: /^(photo|avatar|写真|アバター)$/i,
|
|
315
|
+
};
|
|
316
|
+
/** Valid autocomplete token values */
|
|
317
|
+
export const VALID_AUTOCOMPLETE_TOKENS = [
|
|
318
|
+
'off', 'on',
|
|
319
|
+
'name', 'honorific-prefix', 'given-name', 'additional-name', 'family-name', 'honorific-suffix', 'nickname',
|
|
320
|
+
'email', 'username', 'new-password', 'current-password', 'one-time-code',
|
|
321
|
+
'organization-title', 'organization',
|
|
322
|
+
'street-address', 'address-line1', 'address-line2', 'address-line3',
|
|
323
|
+
'address-level1', 'address-level2', 'address-level3', 'address-level4',
|
|
324
|
+
'country', 'country-name', 'postal-code',
|
|
325
|
+
'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',
|
|
326
|
+
'transaction-currency', 'transaction-amount',
|
|
327
|
+
'language', 'bday', 'bday-day', 'bday-month', 'bday-year', 'sex',
|
|
328
|
+
'tel', 'tel-country-code', 'tel-national', 'tel-area-code', 'tel-local', 'tel-local-prefix', 'tel-local-suffix', 'tel-extension',
|
|
329
|
+
'impp', 'url', 'photo',
|
|
330
|
+
];
|
|
331
|
+
export const DEFAULT_AUTOCOMPLETE_RESULT_FILE = 'autocomplete-result.json';
|
|
332
|
+
// =============================================================================
|
|
333
|
+
// Time Limit Detector Constants (WCAG 2.2.1)
|
|
334
|
+
// =============================================================================
|
|
335
|
+
/** Keywords indicating countdown or time limit in visible text (EN/JP) */
|
|
336
|
+
export const TIME_LIMIT_KEYWORDS = [
|
|
337
|
+
// English
|
|
338
|
+
'session expires',
|
|
339
|
+
'session timeout',
|
|
340
|
+
'time remaining',
|
|
341
|
+
'time left',
|
|
342
|
+
'countdown',
|
|
343
|
+
'expires in',
|
|
344
|
+
'will timeout',
|
|
345
|
+
'auto logout',
|
|
346
|
+
'automatic logout',
|
|
347
|
+
// Japanese
|
|
348
|
+
'セッション終了',
|
|
349
|
+
'セッションタイムアウト',
|
|
350
|
+
'残り時間',
|
|
351
|
+
'タイムアウト',
|
|
352
|
+
'自動ログアウト',
|
|
353
|
+
'有効期限',
|
|
354
|
+
'制限時間',
|
|
355
|
+
'カウントダウン',
|
|
356
|
+
];
|
|
357
|
+
/** Timer threshold for reporting (10 minutes in ms) */
|
|
358
|
+
export const TIME_LIMIT_THRESHOLD_MS = 600000;
|
|
359
|
+
/** Minimum timer to report (10 seconds in ms, to filter out UI animations) */
|
|
360
|
+
export const TIME_LIMIT_MIN_MS = 10000;
|
|
361
|
+
export const DEFAULT_TIME_LIMIT_RESULT_FILE = 'time-limit-result.json';
|
|
362
|
+
// =============================================================================
|
|
363
|
+
// Auto-play Detection Constants (WCAG 1.4.2 / 2.2.2)
|
|
364
|
+
// =============================================================================
|
|
365
|
+
/** Screenshot intervals in milliseconds (0s, 2s, 4s, 6s) */
|
|
366
|
+
export const SCREENSHOT_INTERVALS = [0, 2000, 4000, 6000];
|
|
367
|
+
/** Pixel change threshold (0.1% = significant change) */
|
|
368
|
+
export const CHANGE_THRESHOLD = 0.1;
|
|
369
|
+
/** Pixelmatch color difference threshold (0-1) */
|
|
370
|
+
export const PIXELMATCH_THRESHOLD = 0.1;
|
|
371
|
+
/** Wait time after clicking pause control (ms) */
|
|
372
|
+
export const PAUSE_CLICK_WAIT = 500;
|
|
373
|
+
/** Wait time between screenshots for comparison (ms) */
|
|
374
|
+
export const SCREENSHOT_COMPARISON_WAIT = 2000;
|
|
375
|
+
export const DEFAULT_AUTO_PLAY_OUTPUT_DIR = './auto-play-screenshots';
|
|
376
|
+
export const DETECTION_RESULT_FILENAME = 'detection-result.json';
|
|
377
|
+
// =============================================================================
|
|
378
|
+
// Pause Control Detection Patterns (WCAG 1.4.2 / 2.2.2)
|
|
379
|
+
// =============================================================================
|
|
380
|
+
/** Keywords for pause/stop controls (EN/JP) */
|
|
381
|
+
export const PAUSE_KEYWORDS = [
|
|
382
|
+
// English
|
|
383
|
+
'pause', 'stop', 'halt', 'freeze', 'play',
|
|
384
|
+
// Japanese
|
|
385
|
+
'一時停止', '停止', 'ポーズ', '止める', '再生',
|
|
386
|
+
];
|
|
387
|
+
/** Class name patterns indicating pause/play controls */
|
|
388
|
+
export const CONTROL_CLASS_PATTERNS = [
|
|
389
|
+
'pause', 'play', 'stop', 'toggle', 'switch',
|
|
390
|
+
'control', 'btn-pause', 'btn-play', 'btn-stop',
|
|
391
|
+
];
|
|
392
|
+
/** Carousel-related class patterns */
|
|
393
|
+
export const CAROUSEL_PATTERNS = [
|
|
394
|
+
'carousel', 'slider', 'slide', 'swiper', 'slick',
|
|
395
|
+
'hero', 'banner', 'gallery', 'rotator',
|
|
396
|
+
];
|
|
397
|
+
/** Navigation control keywords */
|
|
398
|
+
export const NAV_KEYWORDS = [
|
|
399
|
+
'prev', 'next', '前', '次', 'arrow', 'dot', 'indicator',
|
|
400
|
+
];
|
|
401
|
+
/** SVG metadata patterns to exclude from accessible names */
|
|
402
|
+
export const SVG_METADATA_PATTERNS = [
|
|
403
|
+
'created with', 'made with', 'generated by',
|
|
404
|
+
'svg', 'icon', 'symbol',
|
|
405
|
+
];
|
|
406
|
+
/** Maximum parent levels to check for carousel context */
|
|
407
|
+
export const MAX_PARENT_LEVELS = 5;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { detectPauseControls, verifyPauseControl, createSkippedVerification, } from './pause-control.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { detectPauseControls, verifyPauseControl, createSkippedVerification, } from './pause-control.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pause/Stop control detection for auto-playing content.
|
|
3
|
+
* WCAG 1.4.2 (Audio Control) / 2.2.2 (Pause, Stop, Hide)
|
|
4
|
+
*/
|
|
5
|
+
import type { Page } from '@playwright/test';
|
|
6
|
+
import type { PauseControlInfo, PauseVerificationResult } from '../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Detect pause/stop controls in the page.
|
|
9
|
+
*/
|
|
10
|
+
export declare function detectPauseControls(page: Page): Promise<PauseControlInfo>;
|
|
11
|
+
/**
|
|
12
|
+
* Verify if clicking the pause control actually stops the auto-play.
|
|
13
|
+
*/
|
|
14
|
+
export declare function verifyPauseControl(page: Page, pauseControls: PauseControlInfo, outputDir: string, changeThreshold: number): Promise<PauseVerificationResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Create a skipped verification result.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createSkippedVerification(reason: string): PauseVerificationResult;
|