@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
@@ -6,7 +6,50 @@
6
6
  * (e.g. an issue creator that reads `*-result.json`). They are intentionally
7
7
  * permissive (no `additionalProperties: false`) so that additive changes to a
8
8
  * result shape do not break downstream validation.
9
+ *
10
+ * Every check shares the same envelope (`source` / `url` / `timestamp` / the
11
+ * four normalized buckets / `summary` / `details` / `disclaimer`); the common
12
+ * pieces live in `$defs` and each check schema defines its own `details`.
9
13
  */
14
+ // =============================================================================
15
+ // Shared $defs
16
+ // =============================================================================
17
+ const NORMALIZED_NODE_SCHEMA = {
18
+ type: 'object',
19
+ required: ['target', 'html', 'htmlTruncated', 'failureSummary'],
20
+ properties: {
21
+ target: { type: 'array', items: { type: 'string' } },
22
+ html: { type: 'string' },
23
+ htmlTruncated: { type: 'boolean' },
24
+ failureSummary: { type: 'string' },
25
+ },
26
+ };
27
+ const NORMALIZED_RULE_RESULT_SCHEMA = {
28
+ type: 'object',
29
+ required: ['id', 'impact', 'description', 'help', 'helpUrl', 'tags', 'nodes'],
30
+ properties: {
31
+ id: { type: 'string' },
32
+ impact: {
33
+ type: ['string', 'null'],
34
+ enum: ['critical', 'serious', 'moderate', 'minor', null],
35
+ },
36
+ description: { type: 'string' },
37
+ help: { type: 'string' },
38
+ helpUrl: { type: 'string' },
39
+ tags: { type: 'array', items: { type: 'string' } },
40
+ nodes: { type: 'array', items: { $ref: '#/$defs/normalizedNode' } },
41
+ },
42
+ };
43
+ const SUMMARY_SCHEMA = {
44
+ type: 'object',
45
+ required: ['violationCount', 'incompleteCount', 'passCount'],
46
+ properties: {
47
+ violationCount: { type: 'number' },
48
+ incompleteCount: { type: 'number' },
49
+ passCount: { type: 'number' },
50
+ checkedNodes: { type: 'number' },
51
+ },
52
+ };
10
53
  const DISCLAIMER_SCHEMA = {
11
54
  type: 'object',
12
55
  properties: {
@@ -16,230 +59,405 @@ const DISCLAIMER_SCHEMA = {
16
59
  moreInfo: { type: 'string' },
17
60
  },
18
61
  };
19
- export const AXE_AUDIT_RESULT_SCHEMA = {
20
- $schema: 'https://json-schema.org/draft/2020-12/schema',
21
- $id: 'https://masup9.github.io/a11y-audit/schemas/axe-audit-result.json',
22
- title: 'AxeAuditResult',
23
- type: 'object',
24
- required: [
25
- 'url',
26
- 'timestamp',
27
- 'violations',
28
- 'passes',
29
- 'incomplete',
30
- 'inapplicable',
31
- 'violationCount',
32
- ],
33
- properties: {
34
- url: { type: 'string' },
35
- timestamp: { type: 'string' },
36
- violations: {
37
- type: 'array',
38
- items: {
39
- type: 'object',
40
- required: ['id', 'description', 'help', 'helpUrl', 'tags', 'nodes'],
41
- properties: {
42
- id: { type: 'string' },
43
- impact: { type: ['string', 'null'] },
44
- description: { type: 'string' },
45
- help: { type: 'string' },
46
- helpUrl: { type: 'string' },
47
- tags: { type: 'array', items: { type: 'string' } },
48
- nodes: {
49
- type: 'array',
50
- items: {
51
- type: 'object',
52
- required: ['html', 'target'],
53
- properties: {
54
- html: { type: 'string' },
55
- target: { type: 'array', items: { type: 'string' } },
56
- failureSummary: { type: ['string', 'null'] },
57
- },
58
- },
59
- },
60
- },
61
- },
62
+ const COMMON_DEFS = {
63
+ normalizedNode: NORMALIZED_NODE_SCHEMA,
64
+ normalizedRuleResult: NORMALIZED_RULE_RESULT_SCHEMA,
65
+ summary: SUMMARY_SCHEMA,
66
+ disclaimer: DISCLAIMER_SCHEMA,
67
+ };
68
+ const RULE_ARRAY = {
69
+ type: 'array',
70
+ items: { $ref: '#/$defs/normalizedRuleResult' },
71
+ };
72
+ /** Build the envelope schema for one check, plugging in its details schema. */
73
+ function buildEnvelopeSchema(args) {
74
+ return {
75
+ $schema: 'https://json-schema.org/draft/2020-12/schema',
76
+ $id: `https://masup9.github.io/a11y-audit/schemas/${args.id}.json`,
77
+ title: args.title,
78
+ type: 'object',
79
+ required: [
80
+ 'source',
81
+ 'url',
82
+ 'timestamp',
83
+ 'violations',
84
+ 'incomplete',
85
+ 'passes',
86
+ 'inapplicable',
87
+ 'summary',
88
+ 'details',
89
+ 'disclaimer',
90
+ ],
91
+ properties: {
92
+ source: { const: args.source },
93
+ url: { type: 'string' },
94
+ timestamp: { type: 'string' },
95
+ violations: RULE_ARRAY,
96
+ incomplete: RULE_ARRAY,
97
+ passes: RULE_ARRAY,
98
+ inapplicable: RULE_ARRAY,
99
+ summary: { $ref: '#/$defs/summary' },
100
+ details: args.details,
101
+ disclaimer: { $ref: '#/$defs/disclaimer' },
62
102
  },
63
- passes: { type: 'number' },
64
- incomplete: { type: 'number' },
65
- inapplicable: { type: 'number' },
66
- violationCount: { type: 'number' },
67
- disclaimer: DISCLAIMER_SCHEMA,
68
- },
103
+ $defs: COMMON_DEFS,
104
+ };
105
+ }
106
+ // =============================================================================
107
+ // Detail building blocks
108
+ // =============================================================================
109
+ const ELEMENT_EVIDENCE_PROPS = {
110
+ selector: { type: 'string' },
111
+ tagName: { type: 'string' },
112
+ html: { type: 'string' },
113
+ htmlTruncated: { type: 'boolean' },
69
114
  };
70
115
  const FOCUS_ELEMENT_REF_SCHEMA = {
71
116
  type: 'object',
72
- required: ['tag', 'name', 'selector'],
117
+ required: ['tag', 'name', 'selector', 'html', 'htmlTruncated'],
73
118
  properties: {
74
119
  tag: { type: 'string' },
75
120
  role: { type: ['string', 'null'] },
76
121
  name: { type: 'string' },
77
122
  selector: { type: 'string' },
123
+ html: { type: 'string' },
124
+ htmlTruncated: { type: 'boolean' },
78
125
  },
79
126
  };
80
- export const FOCUS_CHECK_RESULT_SCHEMA = {
81
- $schema: 'https://json-schema.org/draft/2020-12/schema',
82
- $id: 'https://masup9.github.io/a11y-audit/schemas/focus-check-result.json',
127
+ // =============================================================================
128
+ // Check schemas
129
+ // =============================================================================
130
+ export const AXE_AUDIT_RESULT_SCHEMA = buildEnvelopeSchema({
131
+ id: 'axe-audit-result',
132
+ title: 'AxeAuditResult',
133
+ source: 'axe-audit',
134
+ details: {
135
+ type: 'object',
136
+ required: [
137
+ 'tagsRun',
138
+ 'rulesOverride',
139
+ 'violationRuleCount',
140
+ 'passRuleCount',
141
+ 'incompleteRuleCount',
142
+ 'inapplicableRuleCount',
143
+ ],
144
+ properties: {
145
+ tagsRun: { type: 'array', items: { type: 'string' } },
146
+ rulesOverride: { type: ['object', 'null'] },
147
+ violationRuleCount: { type: 'number' },
148
+ passRuleCount: { type: 'number' },
149
+ incompleteRuleCount: { type: 'number' },
150
+ inapplicableRuleCount: { type: 'number' },
151
+ },
152
+ },
153
+ });
154
+ export const FOCUS_CHECK_RESULT_SCHEMA = buildEnvelopeSchema({
155
+ id: 'focus-check-result',
83
156
  title: 'FocusCheckResult',
84
- type: 'object',
85
- required: [
86
- 'url',
87
- 'totalFocusableElements',
88
- 'elementsWithFocusStyle',
89
- 'elementsWithoutFocusStyle',
90
- 'issues',
91
- 'onFocusViolations',
92
- 'focusObscuredIssues',
93
- 'elementsWithObscuredFocus',
94
- 'allElements',
95
- 'interrupted',
96
- 'screenshotPath',
97
- ],
98
- properties: {
99
- url: { type: 'string' },
100
- totalFocusableElements: { type: 'number' },
101
- elementsWithFocusStyle: { type: 'number' },
102
- elementsWithoutFocusStyle: { type: 'number' },
103
- issues: {
104
- type: 'array',
105
- items: {
106
- type: 'object',
107
- required: ['tag', 'name'],
108
- properties: {
109
- tag: { type: 'string' },
110
- role: { type: ['string', 'null'] },
111
- name: { type: 'string' },
157
+ source: 'focus-indicator-check',
158
+ details: {
159
+ type: 'object',
160
+ required: [
161
+ 'totalFocusableElements',
162
+ 'elementsWithFocusStyle',
163
+ 'elementsWithoutFocusStyle',
164
+ 'issues',
165
+ 'onFocusViolations',
166
+ 'focusObscuredIssues',
167
+ 'elementsWithObscuredFocus',
168
+ 'allElements',
169
+ 'interrupted',
170
+ 'screenshotPath',
171
+ ],
172
+ properties: {
173
+ totalFocusableElements: { type: 'number' },
174
+ elementsWithFocusStyle: { type: 'number' },
175
+ elementsWithoutFocusStyle: { type: 'number' },
176
+ issues: { type: 'array', items: FOCUS_ELEMENT_REF_SCHEMA },
177
+ onFocusViolations: {
178
+ type: 'array',
179
+ items: {
180
+ type: 'object',
181
+ required: ['element', 'fromUrl', 'toUrl', 'changeType'],
182
+ properties: {
183
+ element: FOCUS_ELEMENT_REF_SCHEMA,
184
+ fromUrl: { type: 'string' },
185
+ toUrl: { type: 'string' },
186
+ changeType: {
187
+ type: 'string',
188
+ enum: ['navigation', 'new-window', 'dialog'],
189
+ },
190
+ },
112
191
  },
113
192
  },
114
- },
115
- onFocusViolations: {
116
- type: 'array',
117
- items: {
118
- type: 'object',
119
- required: ['element', 'fromUrl', 'toUrl', 'changeType'],
120
- properties: {
121
- element: FOCUS_ELEMENT_REF_SCHEMA,
122
- fromUrl: { type: 'string' },
123
- toUrl: { type: 'string' },
124
- changeType: {
125
- type: 'string',
126
- enum: ['navigation', 'new-window', 'dialog'],
193
+ focusObscuredIssues: {
194
+ type: 'array',
195
+ items: {
196
+ type: 'object',
197
+ required: ['element', 'elementRect', 'overlaps', 'obscuredRatio'],
198
+ properties: {
199
+ element: FOCUS_ELEMENT_REF_SCHEMA,
200
+ elementRect: { type: 'object' },
201
+ overlaps: { type: 'array', items: { type: 'object' } },
202
+ obscuredRatio: { type: 'number' },
127
203
  },
128
204
  },
129
205
  },
206
+ elementsWithObscuredFocus: { type: 'number' },
207
+ allElements: { type: 'array', items: { type: 'object' } },
208
+ interrupted: { type: 'boolean' },
209
+ interruptedAt: { type: 'number' },
210
+ screenshotPath: { type: 'string' },
130
211
  },
131
- focusObscuredIssues: {
132
- type: 'array',
133
- items: {
212
+ },
213
+ });
214
+ export const REFLOW_CHECK_RESULT_SCHEMA = buildEnvelopeSchema({
215
+ id: 'reflow-check-result',
216
+ title: 'ReflowCheckResult',
217
+ source: 'reflow-check',
218
+ details: {
219
+ type: 'object',
220
+ required: [
221
+ 'viewport',
222
+ 'hasHorizontalScroll',
223
+ 'documentScrollWidth',
224
+ 'documentClientWidth',
225
+ 'overflowingElements',
226
+ 'clippedTextElements',
227
+ ],
228
+ properties: {
229
+ viewport: {
134
230
  type: 'object',
135
- required: ['element', 'elementRect', 'overlaps', 'obscuredRatio'],
231
+ required: ['width', 'height'],
136
232
  properties: {
137
- element: FOCUS_ELEMENT_REF_SCHEMA,
138
- elementRect: { type: 'object' },
139
- overlaps: { type: 'array', items: { type: 'object' } },
140
- obscuredRatio: { type: 'number' },
233
+ width: { type: 'number' },
234
+ height: { type: 'number' },
235
+ },
236
+ },
237
+ hasHorizontalScroll: { type: 'boolean' },
238
+ documentScrollWidth: { type: 'number' },
239
+ documentClientWidth: { type: 'number' },
240
+ overflowingElements: {
241
+ type: 'array',
242
+ items: {
243
+ type: 'object',
244
+ required: [
245
+ 'selector',
246
+ 'tagName',
247
+ 'html',
248
+ 'htmlTruncated',
249
+ 'rect',
250
+ 'viewportWidth',
251
+ 'reason',
252
+ ],
253
+ properties: {
254
+ ...ELEMENT_EVIDENCE_PROPS,
255
+ rect: { type: 'object' },
256
+ viewportWidth: { type: 'number' },
257
+ reason: {
258
+ type: 'string',
259
+ enum: ['overflow-right', 'overflow-left', 'clipped-text'],
260
+ },
261
+ },
141
262
  },
142
263
  },
264
+ clippedTextElements: { type: 'array', items: { type: 'object' } },
143
265
  },
144
- elementsWithObscuredFocus: { type: 'number' },
145
- allElements: { type: 'array', items: { type: 'object' } },
146
- interrupted: { type: 'boolean' },
147
- interruptedAt: { type: 'number' },
148
- screenshotPath: { type: 'string' },
149
- disclaimer: DISCLAIMER_SCHEMA,
150
266
  },
151
- };
152
- export const REFLOW_CHECK_RESULT_SCHEMA = {
153
- $schema: 'https://json-schema.org/draft/2020-12/schema',
154
- $id: 'https://masup9.github.io/a11y-audit/schemas/reflow-check-result.json',
155
- title: 'ReflowCheckResult',
156
- type: 'object',
157
- required: [
158
- 'url',
159
- 'viewport',
160
- 'hasHorizontalScroll',
161
- 'documentScrollWidth',
162
- 'documentClientWidth',
163
- 'overflowingElements',
164
- 'clippedTextElements',
165
- ],
166
- properties: {
167
- url: { type: 'string' },
168
- viewport: {
169
- type: 'object',
170
- required: ['width', 'height'],
171
- properties: {
172
- width: { type: 'number' },
173
- height: { type: 'number' },
267
+ });
268
+ export const TARGET_SIZE_CHECK_RESULT_SCHEMA = buildEnvelopeSchema({
269
+ id: 'target-size-check-result',
270
+ title: 'TargetSizeCheckResult',
271
+ source: 'target-size-check',
272
+ details: {
273
+ type: 'object',
274
+ required: [
275
+ 'totalTargetsChecked',
276
+ 'failAA',
277
+ 'failAAAOnly',
278
+ 'passedTargets',
279
+ 'exceptedTargets',
280
+ 'summary',
281
+ ],
282
+ properties: {
283
+ totalTargetsChecked: { type: 'number' },
284
+ failAA: {
285
+ type: 'array',
286
+ items: {
287
+ type: 'object',
288
+ required: [
289
+ 'selector',
290
+ 'tagName',
291
+ 'html',
292
+ 'htmlTruncated',
293
+ 'width',
294
+ 'height',
295
+ 'minDimension',
296
+ 'level',
297
+ 'exceptionAssessment',
298
+ ],
299
+ properties: {
300
+ ...ELEMENT_EVIDENCE_PROPS,
301
+ role: { type: ['string', 'null'] },
302
+ accessibleName: { type: ['string', 'null'] },
303
+ width: { type: 'number' },
304
+ height: { type: 'number' },
305
+ minDimension: { type: 'number' },
306
+ level: {
307
+ type: 'string',
308
+ enum: ['fail-aa', 'fail-aaa-only', 'pass'],
309
+ },
310
+ exception: { type: ['string', 'null'] },
311
+ exceptionDetails: { type: ['string', 'null'] },
312
+ exceptionAssessment: {
313
+ type: 'string',
314
+ enum: ['ruled-out', 'possible', 'not-assessed'],
315
+ },
316
+ href: { type: ['string', 'null'] },
317
+ },
318
+ },
174
319
  },
175
- },
176
- hasHorizontalScroll: { type: 'boolean' },
177
- documentScrollWidth: { type: 'number' },
178
- documentClientWidth: { type: 'number' },
179
- overflowingElements: {
180
- type: 'array',
181
- items: {
320
+ failAAAOnly: { type: 'array', items: { type: 'object' } },
321
+ passedTargets: { type: 'number' },
322
+ exceptedTargets: { type: 'array', items: { type: 'object' } },
323
+ summary: {
182
324
  type: 'object',
183
- required: ['selector', 'tagName', 'rect', 'viewportWidth', 'reason'],
325
+ required: [
326
+ 'failAACount',
327
+ 'failAAAOnlyCount',
328
+ 'passCount',
329
+ 'exceptedCount',
330
+ ],
184
331
  properties: {
185
- selector: { type: 'string' },
186
- tagName: { type: 'string' },
187
- rect: { type: 'object' },
188
- viewportWidth: { type: 'number' },
189
- reason: {
190
- type: 'string',
191
- enum: ['overflow-right', 'overflow-left', 'clipped-text'],
192
- },
332
+ failAACount: { type: 'number' },
333
+ failAAAOnlyCount: { type: 'number' },
334
+ passCount: { type: 'number' },
335
+ exceptedCount: { type: 'number' },
193
336
  },
194
337
  },
195
338
  },
196
- clippedTextElements: { type: 'array', items: { type: 'object' } },
197
- disclaimer: DISCLAIMER_SCHEMA,
198
339
  },
199
- };
200
- export const TARGET_SIZE_CHECK_RESULT_SCHEMA = {
201
- $schema: 'https://json-schema.org/draft/2020-12/schema',
202
- $id: 'https://masup9.github.io/a11y-audit/schemas/target-size-check-result.json',
203
- title: 'TargetSizeCheckResult',
204
- type: 'object',
205
- required: [
206
- 'url',
207
- 'totalTargetsChecked',
208
- 'failAA',
209
- 'failAAAOnly',
210
- 'passedTargets',
211
- 'exceptedTargets',
212
- 'summary',
213
- ],
214
- properties: {
215
- url: { type: 'string' },
216
- totalTargetsChecked: { type: 'number' },
217
- failAA: { type: 'array', items: { type: 'object' } },
218
- failAAAOnly: { type: 'array', items: { type: 'object' } },
219
- passedTargets: { type: 'number' },
220
- exceptedTargets: { type: 'array', items: { type: 'object' } },
221
- summary: {
222
- type: 'object',
223
- required: [
224
- 'failAACount',
225
- 'failAAAOnlyCount',
226
- 'passCount',
227
- 'exceptedCount',
228
- ],
229
- properties: {
230
- failAACount: { type: 'number' },
231
- failAAAOnlyCount: { type: 'number' },
232
- passCount: { type: 'number' },
233
- exceptedCount: { type: 'number' },
340
+ });
341
+ export const TEXT_SPACING_CHECK_RESULT_SCHEMA = buildEnvelopeSchema({
342
+ id: 'text-spacing-check-result',
343
+ title: 'TextSpacingCheckResult',
344
+ source: 'text-spacing-check',
345
+ details: {
346
+ type: 'object',
347
+ required: ['clippedElements', 'totalElementsChecked'],
348
+ properties: {
349
+ clippedElements: { type: 'array', items: { type: 'object' } },
350
+ totalElementsChecked: { type: 'number' },
351
+ },
352
+ },
353
+ });
354
+ export const ZOOM_CHECK_RESULT_SCHEMA = buildEnvelopeSchema({
355
+ id: 'zoom-check-result',
356
+ title: 'ZoomCheckResult',
357
+ source: 'zoom-200-check',
358
+ details: {
359
+ type: 'object',
360
+ required: [
361
+ 'zoomFactor',
362
+ 'viewport',
363
+ 'hasHorizontalScroll',
364
+ 'documentScrollWidth',
365
+ 'documentClientWidth',
366
+ 'clippedElements',
367
+ ],
368
+ properties: {
369
+ zoomFactor: { type: 'number' },
370
+ viewport: { type: 'object' },
371
+ hasHorizontalScroll: { type: 'boolean' },
372
+ documentScrollWidth: { type: 'number' },
373
+ documentClientWidth: { type: 'number' },
374
+ clippedElements: { type: 'array', items: { type: 'object' } },
375
+ },
376
+ },
377
+ });
378
+ export const ORIENTATION_CHECK_RESULT_SCHEMA = buildEnvelopeSchema({
379
+ id: 'orientation-check-result',
380
+ title: 'OrientationCheckResult',
381
+ source: 'orientation-check',
382
+ details: {
383
+ type: 'object',
384
+ required: ['portrait', 'landscape', 'hasOrientationLock', 'lockDetectedIn'],
385
+ properties: {
386
+ portrait: { type: 'object' },
387
+ landscape: { type: 'object' },
388
+ hasOrientationLock: { type: 'boolean' },
389
+ lockDetectedIn: {
390
+ type: 'string',
391
+ enum: ['portrait', 'landscape', 'both', 'none'],
234
392
  },
235
393
  },
236
- disclaimer: DISCLAIMER_SCHEMA,
237
394
  },
238
- };
395
+ });
396
+ export const AUTOCOMPLETE_AUDIT_RESULT_SCHEMA = buildEnvelopeSchema({
397
+ id: 'autocomplete-audit-result',
398
+ title: 'AutocompleteAuditResult',
399
+ source: 'autocomplete-audit',
400
+ details: {
401
+ type: 'object',
402
+ required: ['totalFieldsChecked', 'missingAutocomplete', 'invalidAutocomplete'],
403
+ properties: {
404
+ totalFieldsChecked: { type: 'number' },
405
+ missingAutocomplete: { type: 'array', items: { type: 'object' } },
406
+ invalidAutocomplete: { type: 'array', items: { type: 'object' } },
407
+ },
408
+ },
409
+ });
410
+ export const TIME_LIMIT_DETECTOR_RESULT_SCHEMA = buildEnvelopeSchema({
411
+ id: 'time-limit-detector-result',
412
+ title: 'TimeLimitDetectorResult',
413
+ source: 'time-limit-detector',
414
+ details: {
415
+ type: 'object',
416
+ required: ['metaRefresh', 'timers', 'countdownIndicators', 'hasTimeLimits'],
417
+ properties: {
418
+ metaRefresh: { type: 'array', items: { type: 'object' } },
419
+ timers: { type: 'array', items: { type: 'object' } },
420
+ countdownIndicators: { type: 'array', items: { type: 'object' } },
421
+ hasTimeLimits: { type: 'boolean' },
422
+ },
423
+ },
424
+ });
425
+ export const AUTO_PLAY_DETECTION_RESULT_SCHEMA = buildEnvelopeSchema({
426
+ id: 'auto-play-detection-result',
427
+ title: 'AutoPlayDetectionResult',
428
+ source: 'auto-play-detection',
429
+ details: {
430
+ type: 'object',
431
+ required: [
432
+ 'screenshotRecords',
433
+ 'comparisons',
434
+ 'hasAutoPlayContent',
435
+ 'stopsWithin5Seconds',
436
+ 'pauseControls',
437
+ 'pauseVerification',
438
+ 'recommendation',
439
+ ],
440
+ properties: {
441
+ screenshotRecords: { type: 'array', items: { type: 'object' } },
442
+ comparisons: { type: 'array', items: { type: 'object' } },
443
+ hasAutoPlayContent: { type: 'boolean' },
444
+ stopsWithin5Seconds: { type: 'boolean' },
445
+ pauseControls: { type: 'object' },
446
+ pauseVerification: { type: 'object' },
447
+ recommendation: { type: 'string' },
448
+ },
449
+ },
450
+ });
239
451
  /** All result schemas keyed by check id. */
240
452
  export const RESULT_SCHEMAS = {
241
453
  'axe-audit': AXE_AUDIT_RESULT_SCHEMA,
242
454
  'focus-indicator-check': FOCUS_CHECK_RESULT_SCHEMA,
243
455
  'reflow-check': REFLOW_CHECK_RESULT_SCHEMA,
244
456
  'target-size-check': TARGET_SIZE_CHECK_RESULT_SCHEMA,
457
+ 'text-spacing-check': TEXT_SPACING_CHECK_RESULT_SCHEMA,
458
+ 'zoom-200-check': ZOOM_CHECK_RESULT_SCHEMA,
459
+ 'orientation-check': ORIENTATION_CHECK_RESULT_SCHEMA,
460
+ 'autocomplete-audit': AUTOCOMPLETE_AUDIT_RESULT_SCHEMA,
461
+ 'time-limit-detector': TIME_LIMIT_DETECTOR_RESULT_SCHEMA,
462
+ 'auto-play-detection': AUTO_PLAY_DETECTION_RESULT_SCHEMA,
245
463
  };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Compatibility test entry for auto-play detection (WCAG 1.4.2 / 2.2.2).
3
+ * Run from a one-line local spec: `import "@a11y-skills/audit/test-entries/auto-play-detection";`
4
+ *
5
+ * Requires the optional `pixelmatch` + `pngjs` deps.
6
+ */
7
+ export {};