govuk_publishing_components 31.1.2 → 32.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/govuk_publishing_components/action-link-arrow--blue.svg +8 -2
  3. data/app/assets/javascripts/govuk_publishing_components/analytics/track-click.js +1 -1
  4. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-ecommerce-tracker.js +10 -5
  5. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-event-tracker.js +2 -2
  6. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-page-views.js +10 -3
  7. data/app/assets/stylesheets/govuk_publishing_components/components/_feedback.scss +81 -73
  8. data/app/views/govuk_publishing_components/components/_layout_super_navigation_header.html.erb +25 -1
  9. data/app/views/govuk_publishing_components/components/feedback/_problem_form.html.erb +20 -11
  10. data/app/views/govuk_publishing_components/components/feedback/_survey_signup_form.html.erb +20 -10
  11. data/app/views/govuk_publishing_components/components/feedback/_yes_no_banner.html.erb +44 -39
  12. data/config/locales/en.yml +1 -1
  13. data/lib/govuk_publishing_components/version.rb +1 -1
  14. data/node_modules/axe-core/README.md +7 -6
  15. data/node_modules/axe-core/axe.d.ts +1 -0
  16. data/node_modules/axe-core/axe.js +8911 -7204
  17. data/node_modules/axe-core/axe.min.js +2 -2
  18. data/node_modules/axe-core/locales/_template.json +1067 -0
  19. data/node_modules/axe-core/locales/fr.json +1 -1
  20. data/node_modules/axe-core/locales/he.json +1015 -0
  21. data/node_modules/axe-core/locales/no_NB.json +797 -0
  22. data/node_modules/axe-core/package.json +57 -59
  23. data/node_modules/axe-core/sri-history.json +4 -0
  24. metadata +5 -2
@@ -0,0 +1,1067 @@
1
+ {
2
+ "lang": "xyz",
3
+ "rules": {
4
+ "accesskeys": {
5
+ "description": "Ensures every accesskey attribute value is unique",
6
+ "help": "accesskey attribute value should be unique"
7
+ },
8
+ "area-alt": {
9
+ "description": "Ensures <area> elements of image maps have alternate text",
10
+ "help": "Active <area> elements must have alternate text"
11
+ },
12
+ "aria-allowed-attr": {
13
+ "description": "Ensures ARIA attributes are allowed for an element's role",
14
+ "help": "Elements must only use allowed ARIA attributes"
15
+ },
16
+ "aria-allowed-role": {
17
+ "description": "Ensures role attribute has an appropriate value for the element",
18
+ "help": "ARIA role should be appropriate for the element"
19
+ },
20
+ "aria-command-name": {
21
+ "description": "Ensures every ARIA button, link and menuitem has an accessible name",
22
+ "help": "ARIA commands must have an accessible name"
23
+ },
24
+ "aria-dialog-name": {
25
+ "description": "Ensures every ARIA dialog and alertdialog node has an accessible name",
26
+ "help": "ARIA dialog and alertdialog nodes should have an accessible name"
27
+ },
28
+ "aria-hidden-body": {
29
+ "description": "Ensures aria-hidden='true' is not present on the document body.",
30
+ "help": "aria-hidden='true' must not be present on the document body"
31
+ },
32
+ "aria-hidden-focus": {
33
+ "description": "Ensures aria-hidden elements are not focusable nor contain focusable elements",
34
+ "help": "ARIA hidden element must not be focusable or contain focusable elements"
35
+ },
36
+ "aria-input-field-name": {
37
+ "description": "Ensures every ARIA input field has an accessible name",
38
+ "help": "ARIA input fields must have an accessible name"
39
+ },
40
+ "aria-meter-name": {
41
+ "description": "Ensures every ARIA meter node has an accessible name",
42
+ "help": "ARIA meter nodes must have an accessible name"
43
+ },
44
+ "aria-progressbar-name": {
45
+ "description": "Ensures every ARIA progressbar node has an accessible name",
46
+ "help": "ARIA progressbar nodes must have an accessible name"
47
+ },
48
+ "aria-required-attr": {
49
+ "description": "Ensures elements with ARIA roles have all required ARIA attributes",
50
+ "help": "Required ARIA attributes must be provided"
51
+ },
52
+ "aria-required-children": {
53
+ "description": "Ensures elements with an ARIA role that require child roles contain them",
54
+ "help": "Certain ARIA roles must contain particular children"
55
+ },
56
+ "aria-required-parent": {
57
+ "description": "Ensures elements with an ARIA role that require parent roles are contained by them",
58
+ "help": "Certain ARIA roles must be contained by particular parents"
59
+ },
60
+ "aria-roledescription": {
61
+ "description": "Ensure aria-roledescription is only used on elements with an implicit or explicit role",
62
+ "help": "aria-roledescription must be on elements with a semantic role"
63
+ },
64
+ "aria-roles": {
65
+ "description": "Ensures all elements with a role attribute use a valid value",
66
+ "help": "ARIA roles used must conform to valid values"
67
+ },
68
+ "aria-text": {
69
+ "description": "Ensures \"role=text\" is used on elements with no focusable descendants",
70
+ "help": "\"role=text\" should have no focusable descendants"
71
+ },
72
+ "aria-toggle-field-name": {
73
+ "description": "Ensures every ARIA toggle field has an accessible name",
74
+ "help": "ARIA toggle fields must have an accessible name"
75
+ },
76
+ "aria-tooltip-name": {
77
+ "description": "Ensures every ARIA tooltip node has an accessible name",
78
+ "help": "ARIA tooltip nodes must have an accessible name"
79
+ },
80
+ "aria-treeitem-name": {
81
+ "description": "Ensures every ARIA treeitem node has an accessible name",
82
+ "help": "ARIA treeitem nodes should have an accessible name"
83
+ },
84
+ "aria-valid-attr-value": {
85
+ "description": "Ensures all ARIA attributes have valid values",
86
+ "help": "ARIA attributes must conform to valid values"
87
+ },
88
+ "aria-valid-attr": {
89
+ "description": "Ensures attributes that begin with aria- are valid ARIA attributes",
90
+ "help": "ARIA attributes must conform to valid names"
91
+ },
92
+ "audio-caption": {
93
+ "description": "Ensures <audio> elements have captions",
94
+ "help": "<audio> elements must have a captions track"
95
+ },
96
+ "autocomplete-valid": {
97
+ "description": "Ensure the autocomplete attribute is correct and suitable for the form field",
98
+ "help": "autocomplete attribute must be used correctly"
99
+ },
100
+ "avoid-inline-spacing": {
101
+ "description": "Ensure that text spacing set through style attributes can be adjusted with custom stylesheets",
102
+ "help": "Inline text spacing must be adjustable with custom stylesheets"
103
+ },
104
+ "blink": {
105
+ "description": "Ensures <blink> elements are not used",
106
+ "help": "<blink> elements are deprecated and must not be used"
107
+ },
108
+ "button-name": {
109
+ "description": "Ensures buttons have discernible text",
110
+ "help": "Buttons must have discernible text"
111
+ },
112
+ "bypass": {
113
+ "description": "Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content",
114
+ "help": "Page must have means to bypass repeated blocks"
115
+ },
116
+ "color-contrast-enhanced": {
117
+ "description": "Ensures the contrast between foreground and background colors meets WCAG 2 AAA contrast ratio thresholds",
118
+ "help": "Elements must have sufficient color contrast"
119
+ },
120
+ "color-contrast": {
121
+ "description": "Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds",
122
+ "help": "Elements must have sufficient color contrast"
123
+ },
124
+ "css-orientation-lock": {
125
+ "description": "Ensures content is not locked to any specific display orientation, and the content is operable in all display orientations",
126
+ "help": "CSS Media queries must not lock display orientation"
127
+ },
128
+ "definition-list": {
129
+ "description": "Ensures <dl> elements are structured correctly",
130
+ "help": "<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script>, <template> or <div> elements"
131
+ },
132
+ "dlitem": {
133
+ "description": "Ensures <dt> and <dd> elements are contained by a <dl>",
134
+ "help": "<dt> and <dd> elements must be contained by a <dl>"
135
+ },
136
+ "document-title": {
137
+ "description": "Ensures each HTML document contains a non-empty <title> element",
138
+ "help": "Documents must have <title> element to aid in navigation"
139
+ },
140
+ "duplicate-id-active": {
141
+ "description": "Ensures every id attribute value of active elements is unique",
142
+ "help": "IDs of active elements must be unique"
143
+ },
144
+ "duplicate-id-aria": {
145
+ "description": "Ensures every id attribute value used in ARIA and in labels is unique",
146
+ "help": "IDs used in ARIA and labels must be unique"
147
+ },
148
+ "duplicate-id": {
149
+ "description": "Ensures every id attribute value is unique",
150
+ "help": "id attribute value must be unique"
151
+ },
152
+ "empty-heading": {
153
+ "description": "Ensures headings have discernible text",
154
+ "help": "Headings should not be empty"
155
+ },
156
+ "empty-table-header": {
157
+ "description": "Ensures table headers have discernible text",
158
+ "help": "Table header text should not be empty"
159
+ },
160
+ "focus-order-semantics": {
161
+ "description": "Ensures elements in the focus order have a role appropriate for interactive content",
162
+ "help": "Elements in the focus order should have an appropriate role"
163
+ },
164
+ "form-field-multiple-labels": {
165
+ "description": "Ensures form field does not have multiple label elements",
166
+ "help": "Form field must not have multiple label elements"
167
+ },
168
+ "frame-focusable-content": {
169
+ "description": "Ensures <frame> and <iframe> elements with focusable content do not have tabindex=-1",
170
+ "help": "Frames with focusable content must not have tabindex=-1"
171
+ },
172
+ "frame-tested": {
173
+ "description": "Ensures <iframe> and <frame> elements contain the axe-core script",
174
+ "help": "Frames should be tested with axe-core"
175
+ },
176
+ "frame-title-unique": {
177
+ "description": "Ensures <iframe> and <frame> elements contain a unique title attribute",
178
+ "help": "Frames must have a unique title attribute"
179
+ },
180
+ "frame-title": {
181
+ "description": "Ensures <iframe> and <frame> elements have an accessible name",
182
+ "help": "Frames must have an accessible name"
183
+ },
184
+ "heading-order": {
185
+ "description": "Ensures the order of headings is semantically correct",
186
+ "help": "Heading levels should only increase by one"
187
+ },
188
+ "hidden-content": {
189
+ "description": "Informs users about hidden content.",
190
+ "help": "Hidden content on the page should be analyzed"
191
+ },
192
+ "html-has-lang": {
193
+ "description": "Ensures every HTML document has a lang attribute",
194
+ "help": "<html> element must have a lang attribute"
195
+ },
196
+ "html-lang-valid": {
197
+ "description": "Ensures the lang attribute of the <html> element has a valid value",
198
+ "help": "<html> element must have a valid value for the lang attribute"
199
+ },
200
+ "html-xml-lang-mismatch": {
201
+ "description": "Ensure that HTML elements with both valid lang and xml:lang attributes agree on the base language of the page",
202
+ "help": "HTML elements with lang and xml:lang must have the same base language"
203
+ },
204
+ "identical-links-same-purpose": {
205
+ "description": "Ensure that links with the same accessible name serve a similar purpose",
206
+ "help": "Links with the same name must have a similar purpose"
207
+ },
208
+ "image-alt": {
209
+ "description": "Ensures <img> elements have alternate text or a role of none or presentation",
210
+ "help": "Images must have alternate text"
211
+ },
212
+ "image-redundant-alt": {
213
+ "description": "Ensure image alternative is not repeated as text",
214
+ "help": "Alternative text of images should not be repeated as text"
215
+ },
216
+ "input-button-name": {
217
+ "description": "Ensures input buttons have discernible text",
218
+ "help": "Input buttons must have discernible text"
219
+ },
220
+ "input-image-alt": {
221
+ "description": "Ensures <input type=\"image\"> elements have alternate text",
222
+ "help": "Image buttons must have alternate text"
223
+ },
224
+ "label-content-name-mismatch": {
225
+ "description": "Ensures that elements labelled through their content must have their visible text as part of their accessible name",
226
+ "help": "Elements must have their visible text as part of their accessible name"
227
+ },
228
+ "label-title-only": {
229
+ "description": "Ensures that every form element has a visible label and is not solely labeled using hidden labels, or the title or aria-describedby attributes",
230
+ "help": "Form elements should have a visible label"
231
+ },
232
+ "label": {
233
+ "description": "Ensures every form element has a label",
234
+ "help": "Form elements must have labels"
235
+ },
236
+ "landmark-banner-is-top-level": {
237
+ "description": "Ensures the banner landmark is at top level",
238
+ "help": "Banner landmark should not be contained in another landmark"
239
+ },
240
+ "landmark-complementary-is-top-level": {
241
+ "description": "Ensures the complementary landmark or aside is at top level",
242
+ "help": "Aside should not be contained in another landmark"
243
+ },
244
+ "landmark-contentinfo-is-top-level": {
245
+ "description": "Ensures the contentinfo landmark is at top level",
246
+ "help": "Contentinfo landmark should not be contained in another landmark"
247
+ },
248
+ "landmark-main-is-top-level": {
249
+ "description": "Ensures the main landmark is at top level",
250
+ "help": "Main landmark should not be contained in another landmark"
251
+ },
252
+ "landmark-no-duplicate-banner": {
253
+ "description": "Ensures the document has at most one banner landmark",
254
+ "help": "Document should not have more than one banner landmark"
255
+ },
256
+ "landmark-no-duplicate-contentinfo": {
257
+ "description": "Ensures the document has at most one contentinfo landmark",
258
+ "help": "Document should not have more than one contentinfo landmark"
259
+ },
260
+ "landmark-no-duplicate-main": {
261
+ "description": "Ensures the document has at most one main landmark",
262
+ "help": "Document should not have more than one main landmark"
263
+ },
264
+ "landmark-one-main": {
265
+ "description": "Ensures the document has a main landmark",
266
+ "help": "Document should have one main landmark"
267
+ },
268
+ "landmark-unique": {
269
+ "help": "Ensures landmarks are unique",
270
+ "description": "Landmarks should have a unique role or role/label/title (i.e. accessible name) combination"
271
+ },
272
+ "link-in-text-block": {
273
+ "description": "Ensure links are distinguished from surrounding text in a way that does not rely on color",
274
+ "help": "Links must be distinguishable without relying on color"
275
+ },
276
+ "link-name": {
277
+ "description": "Ensures links have discernible text",
278
+ "help": "Links must have discernible text"
279
+ },
280
+ "list": {
281
+ "description": "Ensures that lists are structured correctly",
282
+ "help": "<ul> and <ol> must only directly contain <li>, <script> or <template> elements"
283
+ },
284
+ "listitem": {
285
+ "description": "Ensures <li> elements are used semantically",
286
+ "help": "<li> elements must be contained in a <ul> or <ol>"
287
+ },
288
+ "marquee": {
289
+ "description": "Ensures <marquee> elements are not used",
290
+ "help": "<marquee> elements are deprecated and must not be used"
291
+ },
292
+ "meta-refresh-no-exceptions": {
293
+ "description": "Ensures <meta http-equiv=\"refresh\"> is not used for delayed refresh",
294
+ "help": "Delayed refresh must not be used"
295
+ },
296
+ "meta-refresh": {
297
+ "description": "Ensures <meta http-equiv=\"refresh\"> is not used for delayed refresh",
298
+ "help": "Delayed refresh under 20 hours must not be used"
299
+ },
300
+ "meta-viewport-large": {
301
+ "description": "Ensures <meta name=\"viewport\"> can scale a significant amount",
302
+ "help": "Users should be able to zoom and scale the text up to 500%"
303
+ },
304
+ "meta-viewport": {
305
+ "description": "Ensures <meta name=\"viewport\"> does not disable text scaling and zooming",
306
+ "help": "Zooming and scaling must not be disabled"
307
+ },
308
+ "nested-interactive": {
309
+ "description": "Ensures interactive controls are not nested as they are not always announced by screen readers or can cause focus problems for assistive technologies",
310
+ "help": "Interactive controls must not be nested"
311
+ },
312
+ "no-autoplay-audio": {
313
+ "description": "Ensures <video> or <audio> elements do not autoplay audio for more than 3 seconds without a control mechanism to stop or mute the audio",
314
+ "help": "<video> or <audio> elements must not play automatically"
315
+ },
316
+ "object-alt": {
317
+ "description": "Ensures <object> elements have alternate text",
318
+ "help": "<object> elements must have alternate text"
319
+ },
320
+ "p-as-heading": {
321
+ "description": "Ensure bold, italic text and font-size is not used to style <p> elements as a heading",
322
+ "help": "Styled <p> elements must not be used as headings"
323
+ },
324
+ "page-has-heading-one": {
325
+ "description": "Ensure that the page, or at least one of its frames contains a level-one heading",
326
+ "help": "Page should contain a level-one heading"
327
+ },
328
+ "presentation-role-conflict": {
329
+ "description": "Elements marked as presentational should not have global ARIA or tabindex to ensure all screen readers ignore them",
330
+ "help": "Ensure elements marked as presentational are consistently ignored"
331
+ },
332
+ "region": {
333
+ "description": "Ensures all page content is contained by landmarks",
334
+ "help": "All page content should be contained by landmarks"
335
+ },
336
+ "role-img-alt": {
337
+ "description": "Ensures [role='img'] elements have alternate text",
338
+ "help": "[role='img'] elements must have an alternative text"
339
+ },
340
+ "scope-attr-valid": {
341
+ "description": "Ensures the scope attribute is used correctly on tables",
342
+ "help": "scope attribute should be used correctly"
343
+ },
344
+ "scrollable-region-focusable": {
345
+ "description": "Ensure elements that have scrollable content are accessible by keyboard",
346
+ "help": "Scrollable region must have keyboard access"
347
+ },
348
+ "select-name": {
349
+ "description": "Ensures select element has an accessible name",
350
+ "help": "Select element must have an accessible name"
351
+ },
352
+ "server-side-image-map": {
353
+ "description": "Ensures that server-side image maps are not used",
354
+ "help": "Server-side image maps must not be used"
355
+ },
356
+ "skip-link": {
357
+ "description": "Ensure all skip links have a focusable target",
358
+ "help": "The skip-link target should exist and be focusable"
359
+ },
360
+ "svg-img-alt": {
361
+ "description": "Ensures <svg> elements with an img, graphics-document or graphics-symbol role have an accessible text",
362
+ "help": "<svg> elements with an img role must have an alternative text"
363
+ },
364
+ "tabindex": {
365
+ "description": "Ensures tabindex attribute values are not greater than 0",
366
+ "help": "Elements should not have tabindex greater than zero"
367
+ },
368
+ "table-duplicate-name": {
369
+ "description": "Ensure the <caption> element does not contain the same text as the summary attribute",
370
+ "help": "tables should not have the same summary and caption"
371
+ },
372
+ "table-fake-caption": {
373
+ "description": "Ensure that tables with a caption use the <caption> element.",
374
+ "help": "Data or header cells must not be used to give caption to a data table."
375
+ },
376
+ "target-size": {
377
+ "description": "Ensure touch target have sufficient size and space",
378
+ "help": "All touch targets must be 24px large, or leave sufficient space"
379
+ },
380
+ "td-has-header": {
381
+ "description": "Ensure that each non-empty data cell in a <table> larger than 3 by 3 has one or more table headers",
382
+ "help": "Non-empty <td> elements in larger <table> must have an associated table header"
383
+ },
384
+ "td-headers-attr": {
385
+ "description": "Ensure that each cell in a table that uses the headers attribute refers only to other cells in that table",
386
+ "help": "Table cells that use the headers attribute must only refer to cells in the same table"
387
+ },
388
+ "th-has-data-cells": {
389
+ "description": "Ensure that <th> elements and elements with role=columnheader/rowheader have data cells they describe",
390
+ "help": "Table headers in a data table must refer to data cells"
391
+ },
392
+ "valid-lang": {
393
+ "description": "Ensures lang attributes have valid values",
394
+ "help": "lang attribute must have a valid value"
395
+ },
396
+ "video-caption": {
397
+ "description": "Ensures <video> elements have captions",
398
+ "help": "<video> elements must have captions"
399
+ }
400
+ },
401
+ "checks": {
402
+ "abstractrole": {
403
+ "pass": "Abstract roles are not used",
404
+ "fail": {
405
+ "singular": "Abstract role cannot be directly used: ${data.values}",
406
+ "plural": "Abstract roles cannot be directly used: ${data.values}"
407
+ }
408
+ },
409
+ "aria-allowed-attr": {
410
+ "pass": "ARIA attributes are used correctly for the defined role",
411
+ "fail": {
412
+ "singular": "ARIA attribute is not allowed: ${data.values}",
413
+ "plural": "ARIA attributes are not allowed: ${data.values}"
414
+ },
415
+ "incomplete": "Check that there is no problem if the ARIA attribute is ignored on this element: ${data.values}"
416
+ },
417
+ "aria-allowed-role": {
418
+ "pass": "ARIA role is allowed for given element",
419
+ "fail": {
420
+ "singular": "ARIA role ${data.values} is not allowed for given element",
421
+ "plural": "ARIA roles ${data.values} are not allowed for given element"
422
+ },
423
+ "incomplete": {
424
+ "singular": "ARIA role ${data.values} must be removed when the element is made visible, as it is not allowed for the element",
425
+ "plural": "ARIA roles ${data.values} must be removed when the element is made visible, as they are not allowed for the element"
426
+ }
427
+ },
428
+ "aria-busy": {
429
+ "pass": "Element has an aria-busy attribute",
430
+ "fail": "Element has no aria-busy=\"true\" attribute"
431
+ },
432
+ "aria-errormessage": {
433
+ "pass": "aria-errormessage exists and references elements visible to screen readers that use a supported aria-errormessage technique",
434
+ "fail": {
435
+ "singular": "aria-errormessage value `${data.values}` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)",
436
+ "plural": "aria-errormessage values `${data.values}` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)",
437
+ "hidden": "aria-errormessage value `${data.values}` cannot reference a hidden element"
438
+ },
439
+ "incomplete": {
440
+ "singular": "ensure aria-errormessage value `${data.values}` references an existing element",
441
+ "plural": "ensure aria-errormessage values `${data.values}` reference existing elements",
442
+ "idrefs": "unable to determine if aria-errormessage element exists on the page: ${data.values}"
443
+ }
444
+ },
445
+ "aria-hidden-body": {
446
+ "pass": "No aria-hidden attribute is present on document body",
447
+ "fail": "aria-hidden=true should not be present on the document body"
448
+ },
449
+ "aria-level": {
450
+ "pass": "aria-level values are valid",
451
+ "incomplete": "aria-level values greater than 6 are not supported in all screenreader and browser combinations"
452
+ },
453
+ "aria-prohibited-attr": {
454
+ "pass": "ARIA attribute is allowed",
455
+ "fail": {
456
+ "hasRolePlural": "${data.prohibited} attributes cannot be used with role \"${data.role}\".",
457
+ "hasRoleSingular": "${data.prohibited} attribute cannot be used with role \"${data.role}\".",
458
+ "noRolePlural": "${data.prohibited} attributes cannot be used on a ${data.nodeName} with no valid role attribute.",
459
+ "noRoleSingular": "${data.prohibited} attribute cannot be used on a ${data.nodeName} with no valid role attribute."
460
+ },
461
+ "incomplete": {
462
+ "hasRoleSingular": "${data.prohibited} attribute is not well supported with role \"${data.role}\".",
463
+ "hasRolePlural": "${data.prohibited} attributes are not well supported with role \"${data.role}\".",
464
+ "noRoleSingular": "${data.prohibited} attribute is not well supported on a ${data.nodeName} with no valid role attribute.",
465
+ "noRolePlural": "${data.prohibited} attributes are not well supported on a ${data.nodeName} with no valid role attribute."
466
+ }
467
+ },
468
+ "aria-required-attr": {
469
+ "pass": "All required ARIA attributes are present",
470
+ "fail": {
471
+ "singular": "Required ARIA attribute not present: ${data.values}",
472
+ "plural": "Required ARIA attributes not present: ${data.values}"
473
+ }
474
+ },
475
+ "aria-required-children": {
476
+ "pass": "Required ARIA children are present",
477
+ "fail": {
478
+ "singular": "Required ARIA child role not present: ${data.values}",
479
+ "plural": "Required ARIA children role not present: ${data.values}",
480
+ "unallowed": "Element has children which are not allowed (see related nodes)"
481
+ },
482
+ "incomplete": {
483
+ "singular": "Expecting ARIA child role to be added: ${data.values}",
484
+ "plural": "Expecting ARIA children role to be added: ${data.values}"
485
+ }
486
+ },
487
+ "aria-required-parent": {
488
+ "pass": "Required ARIA parent role present",
489
+ "fail": {
490
+ "singular": "Required ARIA parent role not present: ${data.values}",
491
+ "plural": "Required ARIA parents role not present: ${data.values}"
492
+ }
493
+ },
494
+ "aria-roledescription": {
495
+ "pass": "aria-roledescription used on a supported semantic role",
496
+ "incomplete": "Check that the aria-roledescription is announced by supported screen readers",
497
+ "fail": "Give the element a role that supports aria-roledescription"
498
+ },
499
+ "aria-unsupported-attr": {
500
+ "pass": "ARIA attribute is supported",
501
+ "fail": "ARIA attribute is not widely supported in screen readers and assistive technologies: ${data.values}"
502
+ },
503
+ "aria-valid-attr-value": {
504
+ "pass": "ARIA attribute values are valid",
505
+ "fail": {
506
+ "singular": "Invalid ARIA attribute value: ${data.values}",
507
+ "plural": "Invalid ARIA attribute values: ${data.values}"
508
+ },
509
+ "incomplete": {
510
+ "noId": "ARIA attribute element ID does not exist on the page: ${data.needsReview}",
511
+ "noIdShadow": "ARIA attribute element ID does not exist on the page or is a descendant of a different shadow DOM tree: ${data.needsReview}",
512
+ "ariaCurrent": "ARIA attribute value is invalid and will be treated as \"aria-current=true\": ${data.needsReview}",
513
+ "idrefs": "Unable to determine if ARIA attribute element ID exists on the page: ${data.needsReview}",
514
+ "empty": "ARIA attribute value is ignored while empty: ${data.needsReview}"
515
+ }
516
+ },
517
+ "aria-valid-attr": {
518
+ "pass": "ARIA attribute name is valid",
519
+ "fail": {
520
+ "singular": "Invalid ARIA attribute name: ${data.values}",
521
+ "plural": "Invalid ARIA attribute names: ${data.values}"
522
+ }
523
+ },
524
+ "deprecatedrole": {
525
+ "pass": "ARIA role is not deprecated",
526
+ "fail": "The role used is deprecated: ${data}"
527
+ },
528
+ "fallbackrole": {
529
+ "pass": "Only one role value used",
530
+ "fail": "Use only one role value, since fallback roles are not supported in older browsers",
531
+ "incomplete": "Use only role 'presentation' or 'none' since they are synonymous."
532
+ },
533
+ "has-global-aria-attribute": {
534
+ "pass": {
535
+ "singular": "Element has global ARIA attribute: ${data.values}",
536
+ "plural": "Element has global ARIA attributes: ${data.values}"
537
+ },
538
+ "fail": "Element does not have global ARIA attribute"
539
+ },
540
+ "has-widget-role": {
541
+ "pass": "Element has a widget role.",
542
+ "fail": "Element does not have a widget role."
543
+ },
544
+ "invalidrole": {
545
+ "pass": "ARIA role is valid",
546
+ "fail": {
547
+ "singular": "Role must be one of the valid ARIA roles: ${data.values}",
548
+ "plural": "Roles must be one of the valid ARIA roles: ${data.values}"
549
+ }
550
+ },
551
+ "is-element-focusable": {
552
+ "pass": "Element is focusable.",
553
+ "fail": "Element is not focusable."
554
+ },
555
+ "no-implicit-explicit-label": {
556
+ "pass": "There is no mismatch between a <label> and accessible name",
557
+ "incomplete": "Check that the <label> does not need be part of the ARIA ${data} field's name"
558
+ },
559
+ "unsupportedrole": {
560
+ "pass": "ARIA role is supported",
561
+ "fail": "The role used is not widely supported in screen readers and assistive technologies: ${data}"
562
+ },
563
+ "valid-scrollable-semantics": {
564
+ "pass": "Element has valid semantics for an element in the focus order.",
565
+ "fail": "Element has invalid semantics for an element in the focus order."
566
+ },
567
+ "color-contrast-enhanced": {
568
+ "pass": "Element has sufficient color contrast of ${data.contrastRatio}",
569
+ "fail": {
570
+ "default": "Element has insufficient color contrast of ${data.contrastRatio} (foreground color: ${data.fgColor}, background color: ${data.bgColor}, font size: ${data.fontSize}, font weight: ${data.fontWeight}). Expected contrast ratio of ${data.expectedContrastRatio}",
571
+ "fgOnShadowColor": "Element has insufficient color contrast of ${data.contrastRatio} between the foreground and shadow color (foreground color: ${data.fgColor}, text-shadow color: ${data.shadowColor}, font size: ${data.fontSize}, font weight: ${data.fontWeight}). Expected contrast ratio of ${data.expectedContrastRatio}",
572
+ "shadowOnBgColor": "Element has insufficient color contrast of ${data.contrastRatio} between the shadow color and background color (text-shadow color: ${data.shadowColor}, background color: ${data.bgColor}, font size: ${data.fontSize}, font weight: ${data.fontWeight}). Expected contrast ratio of ${data.expectedContrastRatio}"
573
+ },
574
+ "incomplete": {
575
+ "default": "Unable to determine contrast ratio",
576
+ "bgImage": "Element's background color could not be determined due to a background image",
577
+ "bgGradient": "Element's background color could not be determined due to a background gradient",
578
+ "imgNode": "Element's background color could not be determined because element contains an image node",
579
+ "bgOverlap": "Element's background color could not be determined because it is overlapped by another element",
580
+ "fgAlpha": "Element's foreground color could not be determined because of alpha transparency",
581
+ "elmPartiallyObscured": "Element's background color could not be determined because it's partially obscured by another element",
582
+ "elmPartiallyObscuring": "Element's background color could not be determined because it partially overlaps other elements",
583
+ "outsideViewport": "Element's background color could not be determined because it's outside the viewport",
584
+ "equalRatio": "Element has a 1:1 contrast ratio with the background",
585
+ "shortTextContent": "Element content is too short to determine if it is actual text content",
586
+ "nonBmp": "Element content contains only non-text characters",
587
+ "pseudoContent": "Element's background color could not be determined due to a pseudo element"
588
+ }
589
+ },
590
+ "color-contrast": {
591
+ "pass": {
592
+ "default": "Element has sufficient color contrast of ${data.contrastRatio}",
593
+ "hidden": "Element is hidden"
594
+ },
595
+ "fail": {
596
+ "default": "Element has insufficient color contrast of ${data.contrastRatio} (foreground color: ${data.fgColor}, background color: ${data.bgColor}, font size: ${data.fontSize}, font weight: ${data.fontWeight}). Expected contrast ratio of ${data.expectedContrastRatio}",
597
+ "fgOnShadowColor": "Element has insufficient color contrast of ${data.contrastRatio} between the foreground and shadow color (foreground color: ${data.fgColor}, text-shadow color: ${data.shadowColor}, font size: ${data.fontSize}, font weight: ${data.fontWeight}). Expected contrast ratio of ${data.expectedContrastRatio}",
598
+ "shadowOnBgColor": "Element has insufficient color contrast of ${data.contrastRatio} between the shadow color and background color (text-shadow color: ${data.shadowColor}, background color: ${data.bgColor}, font size: ${data.fontSize}, font weight: ${data.fontWeight}). Expected contrast ratio of ${data.expectedContrastRatio}"
599
+ },
600
+ "incomplete": {
601
+ "default": "Unable to determine contrast ratio",
602
+ "bgImage": "Element's background color could not be determined due to a background image",
603
+ "bgGradient": "Element's background color could not be determined due to a background gradient",
604
+ "imgNode": "Element's background color could not be determined because element contains an image node",
605
+ "bgOverlap": "Element's background color could not be determined because it is overlapped by another element",
606
+ "fgAlpha": "Element's foreground color could not be determined because of alpha transparency",
607
+ "elmPartiallyObscured": "Element's background color could not be determined because it's partially obscured by another element",
608
+ "elmPartiallyObscuring": "Element's background color could not be determined because it partially overlaps other elements",
609
+ "outsideViewport": "Element's background color could not be determined because it's outside the viewport",
610
+ "equalRatio": "Element has a 1:1 contrast ratio with the background",
611
+ "shortTextContent": "Element content is too short to determine if it is actual text content",
612
+ "nonBmp": "Element content contains only non-text characters",
613
+ "pseudoContent": "Element's background color could not be determined due to a pseudo element"
614
+ }
615
+ },
616
+ "link-in-text-block-style": {
617
+ "pass": "Links can be distinguished from surrounding text by visual styling",
618
+ "fail": "The link has no styling (such as underline) to distinguish it from the surrounding text"
619
+ },
620
+ "link-in-text-block": {
621
+ "pass": "Links can be distinguished from surrounding text in some way other than by color",
622
+ "fail": {
623
+ "fgContrast": "The link has insufficient color contrast of ${data.contrastRatio}:1 with the surrounding text. (Minimum contrast is ${data.requiredContrastRatio}:1, link text: ${data.nodeColor}, surrounding text: ${data.parentColor})",
624
+ "bgContrast": "The link background has insufficient color contrast of ${data.contrastRatio} (Minimum contrast is ${data.requiredContrastRatio}:1, link background color: ${data.nodeBackgroundColor}, surrounding background color: ${data.parentBackgroundColor})"
625
+ },
626
+ "incomplete": {
627
+ "default": "Element's foreground contrast ratio could not be determined",
628
+ "bgContrast": "Element's background contrast ratio could not be determined",
629
+ "bgImage": "Element's contrast ratio could not be determined due to a background image",
630
+ "bgGradient": "Element's contrast ratio could not be determined due to a background gradient",
631
+ "imgNode": "Element's contrast ratio could not be determined because element contains an image node",
632
+ "bgOverlap": "Element's contrast ratio could not be determined because of element overlap"
633
+ }
634
+ },
635
+ "autocomplete-appropriate": {
636
+ "pass": "the autocomplete value is on an appropriate element",
637
+ "fail": "the autocomplete value is inappropriate for this type of input"
638
+ },
639
+ "autocomplete-valid": {
640
+ "pass": "the autocomplete attribute is correctly formatted",
641
+ "fail": "the autocomplete attribute is incorrectly formatted"
642
+ },
643
+ "accesskeys": {
644
+ "pass": "Accesskey attribute value is unique",
645
+ "fail": "Document has multiple elements with the same accesskey"
646
+ },
647
+ "focusable-content": {
648
+ "pass": "Element contains focusable elements",
649
+ "fail": "Element should have focusable content"
650
+ },
651
+ "focusable-disabled": {
652
+ "pass": "No focusable elements contained within element",
653
+ "incomplete": "Check if the focusable elements immediately move the focus indicator",
654
+ "fail": "Focusable content should be disabled or be removed from the DOM"
655
+ },
656
+ "focusable-element": {
657
+ "pass": "Element is focusable",
658
+ "fail": "Element should be focusable"
659
+ },
660
+ "focusable-modal-open": {
661
+ "pass": "No focusable elements while a modal is open",
662
+ "incomplete": "Check that focusable elements are not tabbable in the current state"
663
+ },
664
+ "focusable-no-name": {
665
+ "pass": "Element is not in tab order or has accessible text",
666
+ "fail": "Element is in tab order and does not have accessible text",
667
+ "incomplete": "Unable to determine if element has an accessible name"
668
+ },
669
+ "focusable-not-tabbable": {
670
+ "pass": "No focusable elements contained within element",
671
+ "incomplete": "Check if the focusable elements immediately move the focus indicator",
672
+ "fail": "Focusable content should have tabindex='-1' or be removed from the DOM"
673
+ },
674
+ "frame-focusable-content": {
675
+ "pass": "Element does not have focusable descendants",
676
+ "fail": "Element has focusable descendants",
677
+ "incomplete": "Could not determine if element has descendants"
678
+ },
679
+ "landmark-is-top-level": {
680
+ "pass": "The ${data.role} landmark is at the top level.",
681
+ "fail": "The ${data.role} landmark is contained in another landmark."
682
+ },
683
+ "no-focusable-content": {
684
+ "pass": "Element does not have focusable descendants",
685
+ "fail": {
686
+ "default": "Element has focusable descendants",
687
+ "notHidden": "Using a negative tabindex on an element inside an interactive control does not prevent assistive technologies from focusing the element (even with 'aria-hidden=true')"
688
+ },
689
+ "incomplete": "Could not determine if element has descendants"
690
+ },
691
+ "page-has-heading-one": {
692
+ "pass": "Page has at least one level-one heading",
693
+ "fail": "Page must have a level-one heading"
694
+ },
695
+ "page-has-main": {
696
+ "pass": "Document has at least one main landmark",
697
+ "fail": "Document does not have a main landmark"
698
+ },
699
+ "page-no-duplicate-banner": {
700
+ "pass": "Document does not have more than one banner landmark",
701
+ "fail": "Document has more than one banner landmark"
702
+ },
703
+ "page-no-duplicate-contentinfo": {
704
+ "pass": "Document does not have more than one contentinfo landmark",
705
+ "fail": "Document has more than one contentinfo landmark"
706
+ },
707
+ "page-no-duplicate-main": {
708
+ "pass": "Document does not have more than one main landmark",
709
+ "fail": "Document has more than one main landmark"
710
+ },
711
+ "tabindex": {
712
+ "pass": "Element does not have a tabindex greater than 0",
713
+ "fail": "Element has a tabindex greater than 0"
714
+ },
715
+ "alt-space-value": {
716
+ "pass": "Element has a valid alt attribute value",
717
+ "fail": "Element has an alt attribute containing only a space character, which is not ignored by all screen readers"
718
+ },
719
+ "duplicate-img-label": {
720
+ "pass": "Element does not duplicate existing text in <img> alt text",
721
+ "fail": "Element contains <img> element with alt text that duplicates existing text"
722
+ },
723
+ "explicit-label": {
724
+ "pass": "Form element has an explicit <label>",
725
+ "fail": "Form element does not have an explicit <label>",
726
+ "incomplete": "Unable to determine if form element has an explicit <label>"
727
+ },
728
+ "help-same-as-label": {
729
+ "pass": "Help text (title or aria-describedby) does not duplicate label text",
730
+ "fail": "Help text (title or aria-describedby) text is the same as the label text"
731
+ },
732
+ "hidden-explicit-label": {
733
+ "pass": "Form element has a visible explicit <label>",
734
+ "fail": "Form element has explicit <label> that is hidden",
735
+ "incomplete": "Unable to determine if form element has explicit <label> that is hidden"
736
+ },
737
+ "implicit-label": {
738
+ "pass": "Form element has an implicit (wrapped) <label>",
739
+ "fail": "Form element does not have an implicit (wrapped) <label>",
740
+ "incomplete": "Unable to determine if form element has an implicit (wrapped} <label>"
741
+ },
742
+ "label-content-name-mismatch": {
743
+ "pass": "Element contains visible text as part of it's accessible name",
744
+ "fail": "Text inside the element is not included in the accessible name"
745
+ },
746
+ "multiple-label": {
747
+ "pass": "Form field does not have multiple label elements",
748
+ "incomplete": "Multiple label elements is not widely supported in assistive technologies. Ensure the first label contains all necessary information."
749
+ },
750
+ "title-only": {
751
+ "pass": "Form element does not solely use title attribute for its label",
752
+ "fail": "Only title used to generate label for form element"
753
+ },
754
+ "landmark-is-unique": {
755
+ "pass": "Landmarks must have a unique role or role/label/title (i.e. accessible name) combination",
756
+ "fail": "The landmark must have a unique aria-label, aria-labelledby, or title to make landmarks distinguishable"
757
+ },
758
+ "has-lang": {
759
+ "pass": "The <html> element has a lang attribute",
760
+ "fail": {
761
+ "noXHTML": "The xml:lang attribute is not valid on HTML pages, use the lang attribute.",
762
+ "noLang": "The <html> element does not have a lang attribute"
763
+ }
764
+ },
765
+ "valid-lang": {
766
+ "pass": "Value of lang attribute is included in the list of valid languages",
767
+ "fail": "Value of lang attribute not included in the list of valid languages"
768
+ },
769
+ "xml-lang-mismatch": {
770
+ "pass": "Lang and xml:lang attributes have the same base language",
771
+ "fail": "Lang and xml:lang attributes do not have the same base language"
772
+ },
773
+ "dlitem": {
774
+ "pass": "Description list item has a <dl> parent element",
775
+ "fail": "Description list item does not have a <dl> parent element"
776
+ },
777
+ "listitem": {
778
+ "pass": "List item has a <ul>, <ol> or role=\"list\" parent element",
779
+ "fail": {
780
+ "default": "List item does not have a <ul>, <ol> parent element",
781
+ "roleNotValid": "List item does not have a <ul>, <ol> parent element without a role, or a role=\"list\""
782
+ }
783
+ },
784
+ "only-dlitems": {
785
+ "pass": "dl element only has direct children that are allowed inside; <dt>, <dd>, or <div> elements",
786
+ "fail": "dl element has direct children that are not allowed: ${data.values}"
787
+ },
788
+ "only-listitems": {
789
+ "pass": "List element only has direct children that are allowed inside <li> elements",
790
+ "fail": "List element has direct children that are not allowed: ${data.values}"
791
+ },
792
+ "structured-dlitems": {
793
+ "pass": "When not empty, element has both <dt> and <dd> elements",
794
+ "fail": "When not empty, element does not have at least one <dt> element followed by at least one <dd> element"
795
+ },
796
+ "caption": {
797
+ "pass": "The multimedia element has a captions track",
798
+ "incomplete": "Check that captions is available for the element"
799
+ },
800
+ "frame-tested": {
801
+ "pass": "The iframe was tested with axe-core",
802
+ "fail": "The iframe could not be tested with axe-core",
803
+ "incomplete": "The iframe still has to be tested with axe-core"
804
+ },
805
+ "no-autoplay-audio": {
806
+ "pass": "<video> or <audio> does not output audio for more than allowed duration or has controls mechanism",
807
+ "fail": "<video> or <audio> outputs audio for more than allowed duration and does not have a controls mechanism",
808
+ "incomplete": "Check that the <video> or <audio> does not output audio for more than allowed duration or provides a controls mechanism"
809
+ },
810
+ "css-orientation-lock": {
811
+ "pass": "Display is operable, and orientation lock does not exist",
812
+ "fail": "CSS Orientation lock is applied, and makes display inoperable",
813
+ "incomplete": "CSS Orientation lock cannot be determined"
814
+ },
815
+ "meta-viewport-large": {
816
+ "pass": "<meta> tag does not prevent significant zooming on mobile devices",
817
+ "fail": "<meta> tag limits zooming on mobile devices"
818
+ },
819
+ "meta-viewport": {
820
+ "pass": "<meta> tag does not disable zooming on mobile devices",
821
+ "fail": "${data} on <meta> tag disables zooming on mobile devices"
822
+ },
823
+ "target-offset": {
824
+ "pass": "Target has sufficient offset from its closest neighbor (${data.closestOffset}px should be at least ${data.minOffset}px)",
825
+ "fail": "Target has insufficient offset from its closest neighbor (${data.closestOffset}px should be at least ${data.minOffset}px)",
826
+ "incomplete": {
827
+ "default": "Element with negative tabindex has insufficient offset from its closest neighbor (${data.closestOffset}px should be at least ${data.minOffset}px). Is this a target?",
828
+ "nonTabbableNeighbor": "Target has insufficient offset from a neighbor with negative tabindex (${data.closestOffset}px should be at least ${data.minOffset}px). Is the neighbor a target?"
829
+ }
830
+ },
831
+ "target-size": {
832
+ "pass": {
833
+ "default": "Control has sufficient size (${data.width}px by ${data.height}px, should be at least ${data.minSize}px by ${data.minSize}px)",
834
+ "obscured": "Control is ignored because it is fully obscured and thus not clickable"
835
+ },
836
+ "fail": {
837
+ "default": "Target has insufficient size (${data.width}px by ${data.height}px, should be at least ${data.minSize}px by ${data.minSize}px)",
838
+ "partiallyObscured": "Target has insufficient size because it is partially obscured (smallest space is ${data.width}px by ${data.height}px, should be at least ${data.minSize}px by ${data.minSize}px)"
839
+ },
840
+ "incomplete": {
841
+ "default": "Element with negative tabindex has insufficient size (${data.width}px by ${data.height}px, should be at least ${data.minSize}px by ${data.minSize}px). Is this a target?",
842
+ "contentOverflow": "Element size could not be accurately determined due to overflow content",
843
+ "partiallyObscured": "Element with negative tabindex has insufficient size because it is partially obscured (smallest space is ${data.width}px by ${data.height}px, should be at least ${data.minSize}px by ${data.minSize}px). Is this a target?",
844
+ "partiallyObscuredNonTabbable": "Target has insufficient size because it is partially obscured by a neighbor with negative tabindex (smallest space is ${data.width}px by ${data.height}px, should be at least ${data.minSize}px by ${data.minSize}px). Is the neighbor a target?"
845
+ }
846
+ },
847
+ "header-present": {
848
+ "pass": "Page has a heading",
849
+ "fail": "Page does not have a heading"
850
+ },
851
+ "heading-order": {
852
+ "pass": "Heading order valid",
853
+ "fail": "Heading order invalid",
854
+ "incomplete": "Unable to determine previous heading"
855
+ },
856
+ "identical-links-same-purpose": {
857
+ "pass": "There are no other links with the same name, that go to a different URL",
858
+ "incomplete": "Check that links have the same purpose, or are intentionally ambiguous."
859
+ },
860
+ "internal-link-present": {
861
+ "pass": "Valid skip link found",
862
+ "fail": "No valid skip link found"
863
+ },
864
+ "landmark": {
865
+ "pass": "Page has a landmark region",
866
+ "fail": "Page does not have a landmark region"
867
+ },
868
+ "meta-refresh-no-exceptions": {
869
+ "pass": "<meta> tag does not immediately refresh the page",
870
+ "fail": "<meta> tag forces timed refresh of page"
871
+ },
872
+ "meta-refresh": {
873
+ "pass": "<meta> tag does not immediately refresh the page",
874
+ "fail": "<meta> tag forces timed refresh of page (less than 20 hours)"
875
+ },
876
+ "p-as-heading": {
877
+ "pass": "<p> elements are not styled as headings",
878
+ "fail": "Heading elements should be used instead of styled <p> elements",
879
+ "incomplete": "Unable to determine if <p> elements are styled as headings"
880
+ },
881
+ "region": {
882
+ "pass": "All page content is contained by landmarks",
883
+ "fail": "Some page content is not contained by landmarks"
884
+ },
885
+ "skip-link": {
886
+ "pass": "Skip link target exists",
887
+ "incomplete": "Skip link target should become visible on activation",
888
+ "fail": "No skip link target"
889
+ },
890
+ "unique-frame-title": {
891
+ "pass": "Element's title attribute is unique",
892
+ "fail": "Element's title attribute is not unique"
893
+ },
894
+ "duplicate-id-active": {
895
+ "pass": "Document has no active elements that share the same id attribute",
896
+ "fail": "Document has active elements with the same id attribute: ${data}"
897
+ },
898
+ "duplicate-id-aria": {
899
+ "pass": "Document has no elements referenced with ARIA or labels that share the same id attribute",
900
+ "fail": "Document has multiple elements referenced with ARIA with the same id attribute: ${data}"
901
+ },
902
+ "duplicate-id": {
903
+ "pass": "Document has no static elements that share the same id attribute",
904
+ "fail": "Document has multiple static elements with the same id attribute: ${data}"
905
+ },
906
+ "aria-label": {
907
+ "pass": "aria-label attribute exists and is not empty",
908
+ "fail": "aria-label attribute does not exist or is empty"
909
+ },
910
+ "aria-labelledby": {
911
+ "pass": "aria-labelledby attribute exists and references elements that are visible to screen readers",
912
+ "fail": "aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty",
913
+ "incomplete": "ensure aria-labelledby references an existing element"
914
+ },
915
+ "avoid-inline-spacing": {
916
+ "pass": "No inline styles with '!important' that affect text spacing has been specified",
917
+ "fail": {
918
+ "singular": "Remove '!important' from inline style ${data.values}, as overriding this is not supported by most browsers",
919
+ "plural": "Remove '!important' from inline styles ${data.values}, as overriding this is not supported by most browsers"
920
+ }
921
+ },
922
+ "button-has-visible-text": {
923
+ "pass": "Element has inner text that is visible to screen readers",
924
+ "fail": "Element does not have inner text that is visible to screen readers",
925
+ "incomplete": "Unable to determine if element has children"
926
+ },
927
+ "doc-has-title": {
928
+ "pass": "Document has a non-empty <title> element",
929
+ "fail": "Document does not have a non-empty <title> element"
930
+ },
931
+ "exists": {
932
+ "pass": "Element does not exist",
933
+ "incomplete": "Element exists"
934
+ },
935
+ "has-alt": {
936
+ "pass": "Element has an alt attribute",
937
+ "fail": "Element does not have an alt attribute"
938
+ },
939
+ "has-visible-text": {
940
+ "pass": "Element has text that is visible to screen readers",
941
+ "fail": "Element does not have text that is visible to screen readers",
942
+ "incomplete": "Unable to determine if element has children"
943
+ },
944
+ "important-letter-spacing": {
945
+ "pass": "Letter-spacing in the style attribute is not set to !important, or meets the minimum",
946
+ "fail": "letter-spacing in the style attribute must not use !important, or be at ${data.minValue}em (current ${data.value}em)"
947
+ },
948
+ "important-line-height": {
949
+ "pass": "line-height in the style attribute is not set to !important, or meets the minimum",
950
+ "fail": "line-height in the style attribute must not use !important, or be at ${data.minValue}em (current ${data.value}em)"
951
+ },
952
+ "important-word-spacing": {
953
+ "pass": "word-spacing in the style attribute is not set to !important, or meets the minimum",
954
+ "fail": "word-spacing in the style attribute must not use !important, or be at ${data.minValue}em (current ${data.value}em)"
955
+ },
956
+ "is-on-screen": {
957
+ "pass": "Element is not visible",
958
+ "fail": "Element is visible"
959
+ },
960
+ "non-empty-alt": {
961
+ "pass": "Element has a non-empty alt attribute",
962
+ "fail": {
963
+ "noAttr": "Element has no alt attribute",
964
+ "emptyAttr": "Element has an empty alt attribute"
965
+ }
966
+ },
967
+ "non-empty-if-present": {
968
+ "pass": {
969
+ "default": "Element does not have a value attribute",
970
+ "has-label": "Element has a non-empty value attribute"
971
+ },
972
+ "fail": "Element has a value attribute and the value attribute is empty"
973
+ },
974
+ "non-empty-placeholder": {
975
+ "pass": "Element has a placeholder attribute",
976
+ "fail": {
977
+ "noAttr": "Element has no placeholder attribute",
978
+ "emptyAttr": "Element has an empty placeholder attribute"
979
+ }
980
+ },
981
+ "non-empty-title": {
982
+ "pass": "Element has a title attribute",
983
+ "fail": {
984
+ "noAttr": "Element has no title attribute",
985
+ "emptyAttr": "Element has an empty title attribute"
986
+ }
987
+ },
988
+ "non-empty-value": {
989
+ "pass": "Element has a non-empty value attribute",
990
+ "fail": {
991
+ "noAttr": "Element has no value attribute",
992
+ "emptyAttr": "Element has an empty value attribute"
993
+ }
994
+ },
995
+ "presentational-role": {
996
+ "pass": "Element's default semantics were overriden with role=\"${data.role}\"",
997
+ "fail": {
998
+ "default": "Element's default semantics were not overridden with role=\"none\" or role=\"presentation\"",
999
+ "globalAria": "Element's role is not presentational because it has a global ARIA attribute",
1000
+ "focusable": "Element's role is not presentational because it is focusable",
1001
+ "both": "Element's role is not presentational because it has a global ARIA attribute and is focusable",
1002
+ "iframe": "Using the \"title\" attribute on an ${data.nodeName} element with a presentational role behaves inconsistently between screen readers"
1003
+ }
1004
+ },
1005
+ "role-none": {
1006
+ "pass": "Element's default semantics were overriden with role=\"none\"",
1007
+ "fail": "Element's default semantics were not overridden with role=\"none\""
1008
+ },
1009
+ "role-presentation": {
1010
+ "pass": "Element's default semantics were overriden with role=\"presentation\"",
1011
+ "fail": "Element's default semantics were not overridden with role=\"presentation\""
1012
+ },
1013
+ "svg-non-empty-title": {
1014
+ "pass": "Element has a child that is a title",
1015
+ "fail": {
1016
+ "noTitle": "Element has no child that is a title",
1017
+ "emptyTitle": "Element child title is empty"
1018
+ },
1019
+ "incomplete": "Unable to determine element has a child that is a title"
1020
+ },
1021
+ "caption-faked": {
1022
+ "pass": "The first row of a table is not used as a caption",
1023
+ "fail": "The first child of the table should be a caption instead of a table cell"
1024
+ },
1025
+ "html5-scope": {
1026
+ "pass": "Scope attribute is only used on table header elements (<th>)",
1027
+ "fail": "In HTML 5, scope attributes may only be used on table header elements (<th>)"
1028
+ },
1029
+ "same-caption-summary": {
1030
+ "pass": "Content of summary attribute and <caption> are not duplicated",
1031
+ "fail": "Content of summary attribute and <caption> element are identical",
1032
+ "incomplete": "Unable to determine if <table> element has a caption"
1033
+ },
1034
+ "scope-value": {
1035
+ "pass": "Scope attribute is used correctly",
1036
+ "fail": "The value of the scope attribute may only be 'row' or 'col'"
1037
+ },
1038
+ "td-has-header": {
1039
+ "pass": "All non-empty data cells have table headers",
1040
+ "fail": "Some non-empty data cells do not have table headers"
1041
+ },
1042
+ "td-headers-attr": {
1043
+ "pass": "The headers attribute is exclusively used to refer to other cells in the table",
1044
+ "incomplete": "The headers attribute is empty",
1045
+ "fail": "The headers attribute is not exclusively used to refer to other cells in the table"
1046
+ },
1047
+ "th-has-data-cells": {
1048
+ "pass": "All table header cells refer to data cells",
1049
+ "fail": "Not all table header cells refer to data cells",
1050
+ "incomplete": "Table data cells are missing or empty"
1051
+ },
1052
+ "hidden-content": {
1053
+ "pass": "All content on the page has been analyzed.",
1054
+ "fail": "There were problems analyzing the content on this page.",
1055
+ "incomplete": "There is hidden content on the page that was not analyzed. You will need to trigger the display of this content in order to analyze it."
1056
+ }
1057
+ },
1058
+ "failureSummaries": {
1059
+ "any": {
1060
+ "failureMessage": "Fix any of the following:{{~it:value}}\n {{=value.split('\\n').join('\\n ')}}{{~}}"
1061
+ },
1062
+ "none": {
1063
+ "failureMessage": "Fix all of the following:{{~it:value}}\n {{=value.split('\\n').join('\\n ')}}{{~}}"
1064
+ }
1065
+ },
1066
+ "incompleteFallbackMessage": "axe couldn't tell the reason. Time to break out the element inspector!"
1067
+ }