testilo 9.0.3 → 10.0.1
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/README.md +31 -7
- package/package.json +1 -1
- package/procs/score/{sp20b.js → tic21.js} +1252 -991
- package/procs/score/tsp21.js +720 -0
- package/specs/batches/orgs.json +43 -0
- package/specs/scripts/ts21.json +213 -0
- package/toolRules/qualWeb.tsv +121 -0
- package/procs/score/sp10a.js +0 -591
- package/procs/score/sp10b.js +0 -507
- package/procs/score/sp10c.js +0 -465
- package/procs/score/sp11a.js +0 -1968
- package/procs/score/sp12a.js +0 -3000
- package/procs/score/sp12b.js +0 -3315
- package/procs/score/sp14a.js +0 -4101
- package/procs/score/sp15a.js +0 -4899
- package/procs/score/sp15b.js +0 -6279
- package/procs/score/sp15c.js +0 -6282
- package/procs/score/sp16a.js +0 -6362
- package/procs/score/sp16b.js +0 -6370
- package/procs/score/sp16c.js +0 -6364
- package/procs/score/sp17a.js +0 -6099
- package/procs/score/sp18a.js +0 -6378
- package/procs/score/sp20a.js +0 -6379
- package/procs/score/spHover.js +0 -328
- package/procs/score/tsp09a.js +0 -564
- package/scoring/data/correlations.json +0 -327
- package/scoring/data/data.json +0 -26021
- package/scoring/data/dupCounts.json +0 -112
- package/scoring/data/duplications.json +0 -253
- package/scoring/data/groups.json +0 -335
- package/scoring/data/issues.json +0 -304
- package/scoring/data/rulesetData.json +0 -15
- package/scoring/data/testGroups.json +0 -1067
- package/scoring/procs/asp09.js +0 -555
- package/scoring/procs/asp09NoWAVE.js +0 -508
- package/scoring/procs/correlation.js +0 -76
- package/scoring/procs/dupCounts.js +0 -39
- package/scoring/procs/groups.js +0 -61
- package/scoring/procs/packageData.js +0 -171
- package/scoring/procs/packageIssues.js +0 -34
- package/scoring/procs/regroup.js +0 -39
- package/scoring/procs/tempgroup.js +0 -96
- /package/procs/score/{spA11yMessage.js → tspA11yMessage.js} +0 -0
- /package/procs/score/{spProductPrice.js → tspProductPrice.js} +0 -0
- /package/{scoring/data/packageRules → toolRules}/alfa.tsv +0 -0
- /package/{scoring/data/packageRules → toolRules}/axe.js +0 -0
- /package/{scoring/data/packageRules → toolRules}/htmlcs.js +0 -0
- /package/{scoring/data/packageRules → toolRules}/ibm.tsv +0 -0
- /package/{scoring/data/packageRules → toolRules}/tenon.tsv +0 -0
- /package/{scoring/data/packageRules → toolRules}/wave.json +0 -0
- /package/{scoring/data/packageRules → toolRules}/wave.tsv +0 -0
package/procs/score/sp15a.js
DELETED
|
@@ -1,4899 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
sp15a
|
|
3
|
-
Testilo score proc 15a
|
|
4
|
-
|
|
5
|
-
Computes scores from Testaro script tp15 and adds them to a report.
|
|
6
|
-
Usage examples:
|
|
7
|
-
node score sp15a 35k1r
|
|
8
|
-
node score sp15a
|
|
9
|
-
|
|
10
|
-
This proc applies specified weights to the component scores before summing them. An issue reported
|
|
11
|
-
by a test is given a score. That score is determined by:
|
|
12
|
-
Whether the issue is reported as an error or a warning.
|
|
13
|
-
How important the issue is, if the test package is pre-weighted (axe, tenon, and testaro)
|
|
14
|
-
Whether the test belongs to a group or is a solo test.
|
|
15
|
-
How heavily the group is weighted, if the test package is not pre-weighted and the test belongs
|
|
16
|
-
to a group
|
|
17
|
-
|
|
18
|
-
The scores of solo tests are added together, multiplied by the soloWeight multiplier, and
|
|
19
|
-
contributed to the total score.
|
|
20
|
-
|
|
21
|
-
The scores of grouped tests are aggregated into a group score before being contributed to the
|
|
22
|
-
total score. The group score is the sum of (1) an absolute score, assigned because the group has
|
|
23
|
-
at least one test with a non-zero score, (2) the largest score among the tests of the group
|
|
24
|
-
multiplied by a multiplier, and (3) the sum of the scores from the other tests of the group
|
|
25
|
-
multiplied by a smaller multiplier. These three amounts are given by the groupWeights object.
|
|
26
|
-
|
|
27
|
-
Browser logging produces a log score, and the prevention of tests produces a prevention score.
|
|
28
|
-
They, too, are added to the total score.
|
|
29
|
-
|
|
30
|
-
Each grouped test has a quality property, typically set to 1. The value of this property can be
|
|
31
|
-
modified when the test is found to be higher or lower in quality than usual.
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
// CONSTANTS
|
|
35
|
-
|
|
36
|
-
const scoreProcID = 'sp15a';
|
|
37
|
-
// Define the configuration disclosures.
|
|
38
|
-
const logWeights = {
|
|
39
|
-
logCount: 0.5,
|
|
40
|
-
logSize: 0.01,
|
|
41
|
-
errorLogCount: 1,
|
|
42
|
-
errorLogSize: 0.02,
|
|
43
|
-
prohibitedCount: 15,
|
|
44
|
-
visitTimeoutCount: 10,
|
|
45
|
-
visitRejectionCount: 10
|
|
46
|
-
};
|
|
47
|
-
const soloWeight = 2;
|
|
48
|
-
const groupWeights = {
|
|
49
|
-
absolute: 2,
|
|
50
|
-
largest: 1,
|
|
51
|
-
smaller: 0.4
|
|
52
|
-
};
|
|
53
|
-
const preventionWeights = {
|
|
54
|
-
testaro: 50,
|
|
55
|
-
other: 100
|
|
56
|
-
};
|
|
57
|
-
const otherPackages = ['alfa', 'axe', 'continuum', 'htmlcs', 'ibm', 'nuVal', 'tenon', 'wave'];
|
|
58
|
-
const preWeightedPackages = ['axe', 'tenon', 'testaro'];
|
|
59
|
-
const testMatchers = {
|
|
60
|
-
nuVal: [
|
|
61
|
-
/^CSS: .+: .+ is not a .+ value.*$/,
|
|
62
|
-
/^CSS: .+: Too many values or values are not recognized.+$/,
|
|
63
|
-
/^CSS: .+: Parse Error.*$/,
|
|
64
|
-
/^CSS: .+: Invalid type: .+$/,
|
|
65
|
-
/^CSS: .+: The types are incompatible.*$/,
|
|
66
|
-
/^CSS: .+: Unknown dimension.*$/,
|
|
67
|
-
/^The role attribute must not be used on a .+ element which has a table ancestor with no role attribute, or with a role attribute whose value is table, grid, or treegrid.*$/,
|
|
68
|
-
/^Bad value for attribute .+ on element .+: An ID must not be the empty string.+$/,
|
|
69
|
-
/^Bad value for attribute aria-owns on element .+: An IDREFS value must contain at least one non-whitespace character.*$/,
|
|
70
|
-
/^Bad value for attribute src on element .+: Must be non-empty.*$/,
|
|
71
|
-
/^Bad value for attribute tabindex on element .+: The empty string is not a valid integer.*$/,
|
|
72
|
-
/^The aria-hidden attribute must not be specified on the .+ element.*$/,
|
|
73
|
-
/^Element meta is missing one or more of the following attributes: .+$/,
|
|
74
|
-
/^Duplicate ID .+$|^The first occurrence of ID .* was here.*$/,
|
|
75
|
-
/^Start tag .+ seen but an element of the same type was already open.*$/,
|
|
76
|
-
/^Bad start tag in .+$/,
|
|
77
|
-
/^End tag .+ violates nesting rules.*$/,
|
|
78
|
-
/^Stray end tag .+$/,
|
|
79
|
-
/^Element name .+ cannot be represented as XML 1\.0.*$/,
|
|
80
|
-
/^Attribute .+ is not serializable as XML 1\.0.*$/,
|
|
81
|
-
/^Attribute .+ not allowed on element meta at this point.*$/,
|
|
82
|
-
/^Attribute .+ not allowed on element .+ at this point.*$/,
|
|
83
|
-
/^Bad value .+ for attribute .+ on element meta.*$/,
|
|
84
|
-
/^Bad value .+ for attribute .+ on element .+$/,
|
|
85
|
-
/^Bad value .+ for the attribute .+$/,
|
|
86
|
-
/^Attribute .+ not allowed here.*$/,
|
|
87
|
-
/^Attribute .+ is only allowed when .+$/,
|
|
88
|
-
/^The .+ attribute on the .+ element is obsolete.+$/,
|
|
89
|
-
/^The .+ role is unnecessary for element .+$/,
|
|
90
|
-
/^CSS: .+: Property .+ doesn't exist.*$/,
|
|
91
|
-
/^CSS: .+: only 0 can be a length. You must put a unit after your number.*$/,
|
|
92
|
-
/^CSS: .+: only 0 can be a unit. You must put a unit after your number.*$/,
|
|
93
|
-
/^Element .+ not allowed as child of element .+ in this context.*$/,
|
|
94
|
-
/^Forbidden code point U+.+$/,
|
|
95
|
-
/^Internal encoding declaration .+ disagrees with the actual encoding of the document.*$/,
|
|
96
|
-
/^Potentially bad value .+ for attribute sandbox on element iframe: Setting both allow-scripts and allow-same-origin is not recommended, because it effectively enables an embedded page to break out of all sandboxing.*$/
|
|
97
|
-
]
|
|
98
|
-
};
|
|
99
|
-
const groups = {
|
|
100
|
-
ignorable: {
|
|
101
|
-
weight: 0,
|
|
102
|
-
packages: {
|
|
103
|
-
nuVal: {
|
|
104
|
-
'Element mediaelementwrapper not allowed as child of element div in this context. (Suppressing further errors from this subtree.)': {
|
|
105
|
-
quality: 0,
|
|
106
|
-
what: 'Bug in nuVal'
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
duplicateID: {
|
|
112
|
-
weight: 3,
|
|
113
|
-
packages: {
|
|
114
|
-
alfa: {
|
|
115
|
-
r3: {
|
|
116
|
-
quality: 1,
|
|
117
|
-
what: 'Element id attribute value is not unique'
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
axe: {
|
|
121
|
-
'duplicate-id': {
|
|
122
|
-
quality: 1,
|
|
123
|
-
what: 'id attribute value is not unique'
|
|
124
|
-
},
|
|
125
|
-
'duplicate-id-active': {
|
|
126
|
-
quality: 1,
|
|
127
|
-
what: 'id attribute value of the active element is not unique'
|
|
128
|
-
},
|
|
129
|
-
'duplicate-id-aria': {
|
|
130
|
-
quality: 1,
|
|
131
|
-
what: 'id attribute used in ARIA or in a label has a value that is not unique'
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
continuum: {
|
|
135
|
-
94: {
|
|
136
|
-
quality: 1,
|
|
137
|
-
what: 'Elements contains an id attribute set to a value that is not unique in the DOM'
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
htmlcs: {
|
|
141
|
-
'e:AA.4_1_1.F77': {
|
|
142
|
-
quality: 1,
|
|
143
|
-
what: 'Duplicate id attribute value'
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
ibm: {
|
|
147
|
-
RPT_Elem_UniqueId: {
|
|
148
|
-
quality: 1,
|
|
149
|
-
what: 'Element id attribute value is not unique within the document'
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
nuVal: {
|
|
153
|
-
'^Duplicate ID .+$|^The first occurrence of ID .* was here.*$': {
|
|
154
|
-
quality: 1,
|
|
155
|
-
what: 'Duplicate id'
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
componentNoText: {
|
|
161
|
-
weight: 4,
|
|
162
|
-
packages: {
|
|
163
|
-
ibm: {
|
|
164
|
-
Rpt_Aria_WidgetLabels_Implicit: {
|
|
165
|
-
quality: 1,
|
|
166
|
-
what: 'Interactive component has no programmatically associated name'
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
regionNoText: {
|
|
172
|
-
weight: 4,
|
|
173
|
-
packages: {
|
|
174
|
-
alfa: {
|
|
175
|
-
r40: {
|
|
176
|
-
quality: 1,
|
|
177
|
-
what: 'Region has no accessible name'
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
continuum: {
|
|
181
|
-
1010: {
|
|
182
|
-
quality: 1,
|
|
183
|
-
what: 'Element with a region role has no mechanism that allows an accessible name to be calculated'
|
|
184
|
-
}
|
|
185
|
-
},
|
|
186
|
-
ibm: {
|
|
187
|
-
Rpt_Aria_RegionLabel_Implicit: {
|
|
188
|
-
quality: 1,
|
|
189
|
-
what: 'Element with a region role has no label that describes its purpose'
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
},
|
|
194
|
-
formFieldNoText: {
|
|
195
|
-
weight: 4,
|
|
196
|
-
packages: {
|
|
197
|
-
alfa: {
|
|
198
|
-
r8: {
|
|
199
|
-
quality: 1,
|
|
200
|
-
what: 'Form field has no accessible name'
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
|
-
inputNoText: {
|
|
206
|
-
weight: 4,
|
|
207
|
-
packages: {
|
|
208
|
-
axe: {
|
|
209
|
-
'aria-input-field-name': {
|
|
210
|
-
quality: 1,
|
|
211
|
-
what: 'ARIA input field has no accessible name'
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
continuum: {
|
|
215
|
-
118: {
|
|
216
|
-
quality: 1,
|
|
217
|
-
what: 'Text input element has no mechanism that allows an accessible name to be calculated'
|
|
218
|
-
},
|
|
219
|
-
370: {
|
|
220
|
-
quality: 1,
|
|
221
|
-
what: 'Search input element has no mechanism that allows an accessible name to be calculated'
|
|
222
|
-
},
|
|
223
|
-
509: {
|
|
224
|
-
quality: 1,
|
|
225
|
-
what: 'element with a textbox role has no mechanism that allows an accessible name to be calculated'
|
|
226
|
-
},
|
|
227
|
-
510: {
|
|
228
|
-
quality: 1,
|
|
229
|
-
what: 'element with a combobox role has no mechanism that allows an accessible name to be calculated'
|
|
230
|
-
}
|
|
231
|
-
},
|
|
232
|
-
htmlcs: {
|
|
233
|
-
'e:AA.4_1_2.H91.InputText.Name': {
|
|
234
|
-
quality: 1,
|
|
235
|
-
what: 'Text input has no accessible name'
|
|
236
|
-
},
|
|
237
|
-
'e:AA.4_1_2.H91.InputEmail.Name': {
|
|
238
|
-
quality: 1,
|
|
239
|
-
what: 'Email input has no accessible name'
|
|
240
|
-
},
|
|
241
|
-
'e:AA.4_1_2.H91.InputFile.Name': {
|
|
242
|
-
quality: 1,
|
|
243
|
-
what: 'File input element has no accessible name'
|
|
244
|
-
},
|
|
245
|
-
'e:AA.4_1_2.H91.InputTel.Name': {
|
|
246
|
-
quality: 1,
|
|
247
|
-
what: 'Telephone input has no accessible name'
|
|
248
|
-
},
|
|
249
|
-
'e:AA.4_1_2.H91.InputNumber.Name': {
|
|
250
|
-
quality: 1,
|
|
251
|
-
what: 'Number input has no accessible name'
|
|
252
|
-
},
|
|
253
|
-
'e:AA.4_1_2.H91.InputSearch.Name': {
|
|
254
|
-
quality: 1,
|
|
255
|
-
what: 'Search input has no accessible name'
|
|
256
|
-
},
|
|
257
|
-
'e:AA.4_1_2.H91.InputCheckbox.Name': {
|
|
258
|
-
quality: 1,
|
|
259
|
-
what: 'Checkbox input has no accessible name'
|
|
260
|
-
},
|
|
261
|
-
'e:AA.4_1_2.H91.InputRadio.Name': {
|
|
262
|
-
quality: 1,
|
|
263
|
-
what: 'Radio input has no accessible name'
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
},
|
|
268
|
-
inputOnlyPlaceholder: {
|
|
269
|
-
weight: 3,
|
|
270
|
-
packages: {
|
|
271
|
-
continuum: {
|
|
272
|
-
863: {
|
|
273
|
-
quality: 1,
|
|
274
|
-
what: 'input has an accessible name that depends on a placeholder'
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
},
|
|
279
|
-
imageInputNoText: {
|
|
280
|
-
weight: 4,
|
|
281
|
-
packages: {
|
|
282
|
-
alfa: {
|
|
283
|
-
r28: {
|
|
284
|
-
quality: 1,
|
|
285
|
-
what: 'Image input element has no accessible name'
|
|
286
|
-
}
|
|
287
|
-
},
|
|
288
|
-
axe: {
|
|
289
|
-
'input-image-alt': {
|
|
290
|
-
quality: 1,
|
|
291
|
-
what: 'Image button has no text alternative'
|
|
292
|
-
}
|
|
293
|
-
},
|
|
294
|
-
htmlcs: {
|
|
295
|
-
'e:H36': {
|
|
296
|
-
quality: 1,
|
|
297
|
-
what: 'Image submit button has no alt attribute'
|
|
298
|
-
}
|
|
299
|
-
},
|
|
300
|
-
ibm: {
|
|
301
|
-
WCAG20_Input_ExplicitLabelImage: {
|
|
302
|
-
quality: 1,
|
|
303
|
-
what: 'Input element of type image has no text alternative'
|
|
304
|
-
}
|
|
305
|
-
},
|
|
306
|
-
wave: {
|
|
307
|
-
'e:alt_input_missing': {
|
|
308
|
-
quality: 1,
|
|
309
|
-
what: 'Image button has no alternative text'
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
},
|
|
314
|
-
figureNoText: {
|
|
315
|
-
weight: 4,
|
|
316
|
-
packages: {
|
|
317
|
-
ibm: {
|
|
318
|
-
HAAC_Figure_label: {
|
|
319
|
-
quality: 1,
|
|
320
|
-
what: 'figure element has no associated label'
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
},
|
|
325
|
-
imageNoText: {
|
|
326
|
-
weight: 4,
|
|
327
|
-
packages: {
|
|
328
|
-
alfa: {
|
|
329
|
-
r2: {
|
|
330
|
-
quality: 1,
|
|
331
|
-
what: 'Image has no accessible name'
|
|
332
|
-
}
|
|
333
|
-
},
|
|
334
|
-
axe: {
|
|
335
|
-
'image-alt': {
|
|
336
|
-
quality: 1,
|
|
337
|
-
what: 'Image has no text alternative'
|
|
338
|
-
},
|
|
339
|
-
'role-img-alt': {
|
|
340
|
-
quality: 1,
|
|
341
|
-
what: 'Element with role img has no text alternative'
|
|
342
|
-
}
|
|
343
|
-
},
|
|
344
|
-
continuum: {
|
|
345
|
-
87: {
|
|
346
|
-
quality: 1,
|
|
347
|
-
what: 'element with an image, graphics-symbol, or graphics-document role has no mechanism to calculate an accessible name'
|
|
348
|
-
},
|
|
349
|
-
89: {
|
|
350
|
-
quality: 1,
|
|
351
|
-
what: 'img element has no mechanism that allows an accessible name to be calculated'
|
|
352
|
-
}
|
|
353
|
-
},
|
|
354
|
-
htmlcs: {
|
|
355
|
-
'e:AA.1_1_1.H37': {
|
|
356
|
-
quality: 1,
|
|
357
|
-
what: 'img element has no alt attribute'
|
|
358
|
-
}
|
|
359
|
-
},
|
|
360
|
-
ibm: {
|
|
361
|
-
HAAC_Aria_ImgAlt: {
|
|
362
|
-
quality: 1,
|
|
363
|
-
what: 'Element with an img role has no non-empty label'
|
|
364
|
-
},
|
|
365
|
-
WCAG20_Img_HasAlt: {
|
|
366
|
-
quality: 1,
|
|
367
|
-
what: 'Image has no alt attribute conveying its meaning, or alt="" if decorative'
|
|
368
|
-
}
|
|
369
|
-
},
|
|
370
|
-
nuVal: {
|
|
371
|
-
'An img element must have an alt attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images.': {
|
|
372
|
-
quality: 1,
|
|
373
|
-
what: 'img element has no alt attribute'
|
|
374
|
-
}
|
|
375
|
-
},
|
|
376
|
-
wave: {
|
|
377
|
-
'e:alt_missing': {
|
|
378
|
-
quality: 1,
|
|
379
|
-
what: 'Text alternative is missing'
|
|
380
|
-
},
|
|
381
|
-
'e:alt_spacer_missing': {
|
|
382
|
-
quality: 1,
|
|
383
|
-
what: 'Spacer image has no text alternative'
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
},
|
|
388
|
-
decorativeImageAltBad: {
|
|
389
|
-
weight: 4,
|
|
390
|
-
packages: {
|
|
391
|
-
ibm: {
|
|
392
|
-
WCAG20_Img_PresentationImgHasNonNullAlt: {
|
|
393
|
-
quality: 1,
|
|
394
|
-
what: 'Image designated as decorative has no alt=""'
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
},
|
|
399
|
-
imageTextBad: {
|
|
400
|
-
weight: 3,
|
|
401
|
-
packages: {
|
|
402
|
-
alfa: {
|
|
403
|
-
r39: {
|
|
404
|
-
quality: 1,
|
|
405
|
-
what: 'Image text alternative is the filename instead'
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
},
|
|
410
|
-
imageNoSource: {
|
|
411
|
-
weight: 4,
|
|
412
|
-
packages: {
|
|
413
|
-
nuVal: {
|
|
414
|
-
'Element img is missing required attribute src.': {
|
|
415
|
-
quality: 1,
|
|
416
|
-
what: 'img element has no src attribute'
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
},
|
|
421
|
-
sourceEmpty: {
|
|
422
|
-
weight: 4,
|
|
423
|
-
packages: {
|
|
424
|
-
nuVal: {
|
|
425
|
-
'^Bad value for attribute src on element .+: Must be non-empty.*$': {
|
|
426
|
-
quality: 1,
|
|
427
|
-
what: 'src attribute is empty'
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
},
|
|
432
|
-
backgroundBad: {
|
|
433
|
-
weight: 4,
|
|
434
|
-
packages: {
|
|
435
|
-
nuVal: {
|
|
436
|
-
'^CSS: background: .+ is not a color value.*$': {
|
|
437
|
-
quality: 1,
|
|
438
|
-
what: 'CSS background color is misdefined'
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
},
|
|
443
|
-
backgroundImageBad: {
|
|
444
|
-
weight: 4,
|
|
445
|
-
packages: {
|
|
446
|
-
nuVal: {
|
|
447
|
-
'^CSS: background-image: .+ is not a background-image value.*$': {
|
|
448
|
-
quality: 1,
|
|
449
|
-
what: 'CSS background image is misdefined'
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
},
|
|
454
|
-
inputAlt: {
|
|
455
|
-
weight: 4,
|
|
456
|
-
packages: {
|
|
457
|
-
continuum: {
|
|
458
|
-
15: {
|
|
459
|
-
quality: 1,
|
|
460
|
-
what: 'input element has an alt attribute'
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
},
|
|
465
|
-
imagesSameAlt: {
|
|
466
|
-
weight: 1,
|
|
467
|
-
packages: {
|
|
468
|
-
wave: {
|
|
469
|
-
'a:alt_duplicate': {
|
|
470
|
-
quality: 1,
|
|
471
|
-
what: 'Two images near each other have the same text alternative'
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
},
|
|
476
|
-
imageTextLong: {
|
|
477
|
-
weight: 2,
|
|
478
|
-
packages: {
|
|
479
|
-
wave: {
|
|
480
|
-
'a:alt_long': {
|
|
481
|
-
quality: 1,
|
|
482
|
-
what: 'Long text alternative'
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
},
|
|
487
|
-
imageTextRisk: {
|
|
488
|
-
weight: 1,
|
|
489
|
-
packages: {
|
|
490
|
-
continuum: {
|
|
491
|
-
234: {
|
|
492
|
-
quality: 1,
|
|
493
|
-
what: 'img element has a suspicious calculated accessible name value'
|
|
494
|
-
},
|
|
495
|
-
},
|
|
496
|
-
wave: {
|
|
497
|
-
'a:alt_suspicious': {
|
|
498
|
-
quality: 1,
|
|
499
|
-
what: 'Image text alternative is suspicious'
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
},
|
|
504
|
-
decorativeImageRisk: {
|
|
505
|
-
weight: 1,
|
|
506
|
-
packages: {
|
|
507
|
-
htmlcs: {
|
|
508
|
-
'w:AA.1_1_1.H67.2': {
|
|
509
|
-
quality: 1,
|
|
510
|
-
what: 'Image marked as decorative may be informative'
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
},
|
|
515
|
-
decorativeElementExposed: {
|
|
516
|
-
weight: 2,
|
|
517
|
-
packages: {
|
|
518
|
-
alfa: {
|
|
519
|
-
r67: {
|
|
520
|
-
quality: 1,
|
|
521
|
-
what: 'Image marked as decorative is in the accessibility tree or has no none/presentation role'
|
|
522
|
-
},
|
|
523
|
-
r86: {
|
|
524
|
-
quality: 1,
|
|
525
|
-
what: 'Element marked as decorative is in the accessibility tree or has no none/presentation role'
|
|
526
|
-
}
|
|
527
|
-
},
|
|
528
|
-
nuVal: {
|
|
529
|
-
'An img element which has an alt attribute whose value is the empty string must not have a role attribute.': {
|
|
530
|
-
quality: 1,
|
|
531
|
-
what: 'img element with alt="" has a role attribute'
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
},
|
|
536
|
-
pageLanguage: {
|
|
537
|
-
weight: 4,
|
|
538
|
-
packages: {
|
|
539
|
-
alfa: {
|
|
540
|
-
r4: {
|
|
541
|
-
quality: 1,
|
|
542
|
-
what: 'Lang attribute missing, empty, or only whitespace'
|
|
543
|
-
}
|
|
544
|
-
},
|
|
545
|
-
axe: {
|
|
546
|
-
'html-has-lang': {
|
|
547
|
-
quality: 1,
|
|
548
|
-
what: 'html element has no lang attribute'
|
|
549
|
-
}
|
|
550
|
-
},
|
|
551
|
-
continuum: {
|
|
552
|
-
101: {
|
|
553
|
-
quality: 1,
|
|
554
|
-
what: 'root html element has no lang attribute'
|
|
555
|
-
}
|
|
556
|
-
},
|
|
557
|
-
htmlcs: {
|
|
558
|
-
'e:AA.3_1_1.H57.2': {
|
|
559
|
-
quality: 1,
|
|
560
|
-
what: 'html element has no lang or xml:lang attribute'
|
|
561
|
-
}
|
|
562
|
-
},
|
|
563
|
-
ibm: {
|
|
564
|
-
WCAG20_Html_HasLang: {
|
|
565
|
-
quality: 1,
|
|
566
|
-
what: 'Page detected as HTML, but has no lang attribute'
|
|
567
|
-
}
|
|
568
|
-
},
|
|
569
|
-
nuVal: {
|
|
570
|
-
'Consider adding a lang attribute to the html start tag to declare the language of this document.': {
|
|
571
|
-
quality: 1,
|
|
572
|
-
what: 'html start tag has no lang attribute to declare the language of the page'
|
|
573
|
-
}
|
|
574
|
-
},
|
|
575
|
-
wave: {
|
|
576
|
-
'e:language_missing': {
|
|
577
|
-
quality: 1,
|
|
578
|
-
what: 'Language missing or invalid'
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
},
|
|
583
|
-
pageLanguageBad: {
|
|
584
|
-
weight: 4,
|
|
585
|
-
packages: {
|
|
586
|
-
alfa: {
|
|
587
|
-
r5: {
|
|
588
|
-
quality: 1,
|
|
589
|
-
what: 'lang attribute has no valid primary language tag'
|
|
590
|
-
}
|
|
591
|
-
},
|
|
592
|
-
axe: {
|
|
593
|
-
'html-lang-valid': {
|
|
594
|
-
quality: 1,
|
|
595
|
-
what: 'html element has no valid value for the lang attribute'
|
|
596
|
-
}
|
|
597
|
-
},
|
|
598
|
-
htmlcs: {
|
|
599
|
-
'e:AA.3_1_1.H57.3.Lang': {
|
|
600
|
-
quality: 1,
|
|
601
|
-
what: 'Language specified in the lang attribute of the document does not appear to be well-formed'
|
|
602
|
-
}
|
|
603
|
-
},
|
|
604
|
-
ibm: {
|
|
605
|
-
WCAG20_Elem_Lang_Valid: {
|
|
606
|
-
quality: 1,
|
|
607
|
-
what: 'lang attribute does not include a valid primary language'
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
},
|
|
612
|
-
elementLanguageBad: {
|
|
613
|
-
weight: 4,
|
|
614
|
-
packages: {
|
|
615
|
-
htmlcs: {
|
|
616
|
-
'e:AA.3_1_2.H58.1.Lang': {
|
|
617
|
-
quality: 1,
|
|
618
|
-
what: 'Language specified in the lang attribute of the element does not appear to be well-formed'
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
},
|
|
623
|
-
languageChange: {
|
|
624
|
-
weight: 3,
|
|
625
|
-
packages: {
|
|
626
|
-
alfa: {
|
|
627
|
-
r7: {
|
|
628
|
-
quality: 1,
|
|
629
|
-
what: 'lang attribute has no valid primary language subtag'
|
|
630
|
-
}
|
|
631
|
-
},
|
|
632
|
-
axe: {
|
|
633
|
-
'valid-lang': {
|
|
634
|
-
quality: 1,
|
|
635
|
-
what: 'lang attribute has no valid value'
|
|
636
|
-
}
|
|
637
|
-
},
|
|
638
|
-
htmlcs: {
|
|
639
|
-
'e:WCAG2AAA.Principle3.Guideline3_1.3_1_2.H58': {
|
|
640
|
-
quality: 1,
|
|
641
|
-
what: 'Change in language is not marked'
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
},
|
|
646
|
-
dialogNoText: {
|
|
647
|
-
weight: 4,
|
|
648
|
-
packages: {
|
|
649
|
-
axe: {
|
|
650
|
-
'aria-dialog-name': {
|
|
651
|
-
quality: 1,
|
|
652
|
-
what: 'ARIA dialog or alertdialog node has no accessible name'
|
|
653
|
-
}
|
|
654
|
-
},
|
|
655
|
-
continuum: {
|
|
656
|
-
736: {
|
|
657
|
-
quality: 1,
|
|
658
|
-
what: 'Element with a dialog role has no mechanism that allows an accessible name to be calculated'
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
},
|
|
663
|
-
applicationNoText: {
|
|
664
|
-
weight: 4,
|
|
665
|
-
packages: {
|
|
666
|
-
ibm: {
|
|
667
|
-
Rpt_Aria_ApplicationLandmarkLabel: {
|
|
668
|
-
quality: 1,
|
|
669
|
-
what: 'Element with an application role has no purpose label'
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
},
|
|
674
|
-
objectNoText: {
|
|
675
|
-
weight: 4,
|
|
676
|
-
packages: {
|
|
677
|
-
alfa: {
|
|
678
|
-
r63: {
|
|
679
|
-
quality: 1,
|
|
680
|
-
what: 'Object element has no accessible name'
|
|
681
|
-
}
|
|
682
|
-
},
|
|
683
|
-
axe: {
|
|
684
|
-
'object-alt': {
|
|
685
|
-
quality: 1,
|
|
686
|
-
what: 'Object element has no text alternative'
|
|
687
|
-
}
|
|
688
|
-
},
|
|
689
|
-
continuum: {
|
|
690
|
-
249: {
|
|
691
|
-
quality: 1,
|
|
692
|
-
what: 'object element has no mechanism that allows an accessible name to be calculated'
|
|
693
|
-
}
|
|
694
|
-
},
|
|
695
|
-
htmlcs: {
|
|
696
|
-
'e:ARIA6+H53': {
|
|
697
|
-
quality: 1,
|
|
698
|
-
what: 'Object element contains no text alternative'
|
|
699
|
-
}
|
|
700
|
-
},
|
|
701
|
-
ibm: {
|
|
702
|
-
WCAG20_Object_HasText: {
|
|
703
|
-
quality: 1,
|
|
704
|
-
what: 'Object element has no text alternative'
|
|
705
|
-
}
|
|
706
|
-
},
|
|
707
|
-
wave: {
|
|
708
|
-
'a:plugin': {
|
|
709
|
-
quality: 1,
|
|
710
|
-
what: 'An unidentified plugin is present'
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
},
|
|
715
|
-
videoNoText: {
|
|
716
|
-
weight: 4,
|
|
717
|
-
packages: {
|
|
718
|
-
continuum: {
|
|
719
|
-
252: {
|
|
720
|
-
quality: 1,
|
|
721
|
-
what: 'video element has no mechanism that allows an accessible name to be calculated'
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
},
|
|
726
|
-
imageMapNoText: {
|
|
727
|
-
weight: 4,
|
|
728
|
-
packages: {
|
|
729
|
-
wave: {
|
|
730
|
-
'e:alt_map_missing': {
|
|
731
|
-
quality: 1,
|
|
732
|
-
what: 'Image that has hot spots has no alt attribute'
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
},
|
|
737
|
-
imageMapAreaNoText: {
|
|
738
|
-
weight: 4,
|
|
739
|
-
packages: {
|
|
740
|
-
axe: {
|
|
741
|
-
'area-alt': {
|
|
742
|
-
quality: 1,
|
|
743
|
-
what: 'Active area element has no text alternative'
|
|
744
|
-
}
|
|
745
|
-
},
|
|
746
|
-
htmlcs: {
|
|
747
|
-
'e:AA.1_1_1.H24': {
|
|
748
|
-
quality: 1,
|
|
749
|
-
what: 'Area element in an image map has no alt attribute'
|
|
750
|
-
}
|
|
751
|
-
},
|
|
752
|
-
ibm: {
|
|
753
|
-
HAAC_Img_UsemapAlt: {
|
|
754
|
-
quality: 1,
|
|
755
|
-
what: 'Image map or child area has no text alternative'
|
|
756
|
-
},
|
|
757
|
-
'WCAG20_Area_HasAlt': {
|
|
758
|
-
quality: 1,
|
|
759
|
-
what: 'Area element in an image map has no text alternative'
|
|
760
|
-
}
|
|
761
|
-
},
|
|
762
|
-
wave: {
|
|
763
|
-
'e:alt_area_missing': {
|
|
764
|
-
quality: 1,
|
|
765
|
-
what: 'Image map area has no alternative text'
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
},
|
|
770
|
-
objectBlurKeyboardRisk: {
|
|
771
|
-
weight: 1,
|
|
772
|
-
packages: {
|
|
773
|
-
htmlcs: {
|
|
774
|
-
'w:AA.2_1_2.F10': {
|
|
775
|
-
quality: 1,
|
|
776
|
-
what: 'Applet or plugin may fail to enable moving the focus away with the keyboard'
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
},
|
|
781
|
-
keyboardAccess: {
|
|
782
|
-
weight: 4,
|
|
783
|
-
packages: {
|
|
784
|
-
tenon: {
|
|
785
|
-
180: {
|
|
786
|
-
quality: 1,
|
|
787
|
-
what: 'Element is interactive but has a negative tabindex value'
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
},
|
|
792
|
-
eventKeyboardRisk: {
|
|
793
|
-
weight: 1,
|
|
794
|
-
packages: {
|
|
795
|
-
htmlcs: {
|
|
796
|
-
'w:AA.2_1_1.G90': {
|
|
797
|
-
quality: 1,
|
|
798
|
-
what: 'Event handler functionality may not be available by keyboard'
|
|
799
|
-
},
|
|
800
|
-
'w:AA.2_1_1.SCR20.MouseOut': {
|
|
801
|
-
quality: 1,
|
|
802
|
-
what: 'Mousing-out functionality may not be available by keyboard'
|
|
803
|
-
},
|
|
804
|
-
'w:AA.2_1_1.SCR20.MouseOver': {
|
|
805
|
-
quality: 1,
|
|
806
|
-
what: 'Mousing-over functionality may not be available by keyboard'
|
|
807
|
-
},
|
|
808
|
-
'w:AA.2_1_1.SCR20.MouseDown': {
|
|
809
|
-
quality: 1,
|
|
810
|
-
what: 'Mousing-down functionality may not be available by keyboard'
|
|
811
|
-
}
|
|
812
|
-
},
|
|
813
|
-
wave: {
|
|
814
|
-
'a:event_handler': {
|
|
815
|
-
quality: 1,
|
|
816
|
-
what: 'Device-dependent event handler'
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
},
|
|
821
|
-
internalLinkBroken: {
|
|
822
|
-
weight: 4,
|
|
823
|
-
packages: {
|
|
824
|
-
htmlcs: {
|
|
825
|
-
'e:AA.2_4_1.G1,G123,G124.NoSuchID': {
|
|
826
|
-
quality: 1,
|
|
827
|
-
what: 'Internal link references a nonexistent destination'
|
|
828
|
-
}
|
|
829
|
-
},
|
|
830
|
-
wave: {
|
|
831
|
-
'a:link_internal_broken': {
|
|
832
|
-
quality: 1,
|
|
833
|
-
what: 'Broken same-page link'
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
},
|
|
838
|
-
labelForBad: {
|
|
839
|
-
weight: 3,
|
|
840
|
-
packages: {
|
|
841
|
-
htmlcs: {
|
|
842
|
-
'w:AA.1_3_1.H44.NotFormControl': {
|
|
843
|
-
quality: 1,
|
|
844
|
-
what: 'referent of the for attribute of the label is not a form control, so may be wrong'
|
|
845
|
-
}
|
|
846
|
-
},
|
|
847
|
-
nuVal: {
|
|
848
|
-
'The value of the for attribute of the label element must be the ID of a non-hidden form control.': {
|
|
849
|
-
quality: 1,
|
|
850
|
-
what: 'for attribute of the label element does not reference a non-hidden form control'
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
},
|
|
855
|
-
ariaLabelWrongRisk: {
|
|
856
|
-
weight: 1,
|
|
857
|
-
packages: {
|
|
858
|
-
nuVal: {
|
|
859
|
-
'Possible misuse of aria-label. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)': {
|
|
860
|
-
quality: 1,
|
|
861
|
-
what: 'aria-label attribute may be misused'
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
},
|
|
866
|
-
activeDescendantBadID: {
|
|
867
|
-
weight: 4,
|
|
868
|
-
packages: {
|
|
869
|
-
continuum: {
|
|
870
|
-
290: {
|
|
871
|
-
quality: 1,
|
|
872
|
-
what: 'aria-activedescendant attribute is set to an invalid or duplicate id'
|
|
873
|
-
}
|
|
874
|
-
},
|
|
875
|
-
ibm: {
|
|
876
|
-
HAAC_ActiveDescendantCheck: {
|
|
877
|
-
quality: 1,
|
|
878
|
-
what: 'aria-activedescendant property does not reference the id of a non-empty, non-hidden active child element'
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
},
|
|
883
|
-
controlleeBadID: {
|
|
884
|
-
weight: 4,
|
|
885
|
-
packages: {
|
|
886
|
-
continuum: {
|
|
887
|
-
85: {
|
|
888
|
-
quality: 1,
|
|
889
|
-
what: 'aria-controls attribute references an invalid or duplicate ID'
|
|
890
|
-
}
|
|
891
|
-
},
|
|
892
|
-
nuVal: {
|
|
893
|
-
'The aria-controls attribute must point to an element in the same document.': {
|
|
894
|
-
quality: 1,
|
|
895
|
-
what: 'aria-controls attribute references an element not in the document'
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
},
|
|
900
|
-
descriptionBadID: {
|
|
901
|
-
weight: 4,
|
|
902
|
-
packages: {
|
|
903
|
-
continuum: {
|
|
904
|
-
83: {
|
|
905
|
-
quality: 1,
|
|
906
|
-
what: 'aria-describedby attribute references an invalid or duplicate ID'
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
},
|
|
911
|
-
labelFollows: {
|
|
912
|
-
weight: 1,
|
|
913
|
-
packages: {
|
|
914
|
-
ibm: {
|
|
915
|
-
WCAG20_Input_LabelBefore: {
|
|
916
|
-
quality: 1,
|
|
917
|
-
what: 'Text input or select element label follows the input control'
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
}
|
|
921
|
-
},
|
|
922
|
-
labelBadID: {
|
|
923
|
-
weight: 4,
|
|
924
|
-
packages: {
|
|
925
|
-
continuum: {
|
|
926
|
-
95: {
|
|
927
|
-
quality: 1,
|
|
928
|
-
what: 'element has an aria-labelledby value that includes an invalid or duplicate id'
|
|
929
|
-
}
|
|
930
|
-
},
|
|
931
|
-
htmlcs: {
|
|
932
|
-
'w:AA.1_3_1.H44.NonExistentFragment': {
|
|
933
|
-
quality: 1,
|
|
934
|
-
what: 'Label for attribute references a nonexistent element'
|
|
935
|
-
},
|
|
936
|
-
'w:AA.1_3_1.ARIA16,ARIA9': {
|
|
937
|
-
quality: 1,
|
|
938
|
-
what: 'aria-labelledby attribute references a nonexistent element'
|
|
939
|
-
},
|
|
940
|
-
'w:AA.4_1_2.ARIA16,ARIA9': {
|
|
941
|
-
quality: 1,
|
|
942
|
-
what: 'aria-labelledby attribute references a nonexistent element'
|
|
943
|
-
}
|
|
944
|
-
},
|
|
945
|
-
ibm: {
|
|
946
|
-
WCAG20_Label_RefValid: {
|
|
947
|
-
quality: 1,
|
|
948
|
-
what: 'for attribute does not reference a non-empty, unique id attribute of an input element'
|
|
949
|
-
}
|
|
950
|
-
},
|
|
951
|
-
nuVal: {
|
|
952
|
-
'The aria-labelledby attribute must point to an element in the same document.': {
|
|
953
|
-
quality: 1,
|
|
954
|
-
what: 'aria-labelledby attribute references an element not in the document'
|
|
955
|
-
},
|
|
956
|
-
'The aria-describedby attribute must point to an element in the same document.': {
|
|
957
|
-
quality: 1,
|
|
958
|
-
what: 'aria-describedby attribute references an element not in the document'
|
|
959
|
-
}
|
|
960
|
-
},
|
|
961
|
-
wave: {
|
|
962
|
-
'a:label_orphaned': {
|
|
963
|
-
quality: 1,
|
|
964
|
-
what: 'Orphaned form label'
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
},
|
|
969
|
-
haspopupBad: {
|
|
970
|
-
weight: 4,
|
|
971
|
-
packages: {
|
|
972
|
-
ibm: {
|
|
973
|
-
combobox_haspopup: {
|
|
974
|
-
quality: 1,
|
|
975
|
-
what: 'aria-haspopup value is invalid for the role of the controlled or owned element'
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
},
|
|
980
|
-
ownerConflict: {
|
|
981
|
-
weight: 4,
|
|
982
|
-
packages: {
|
|
983
|
-
continuum: {
|
|
984
|
-
360: {
|
|
985
|
-
quality: 1,
|
|
986
|
-
what: 'Element and another element have aria-owns attributes with identical id values'
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
},
|
|
991
|
-
linkNoText: {
|
|
992
|
-
weight: 4,
|
|
993
|
-
packages: {
|
|
994
|
-
alfa: {
|
|
995
|
-
r11: {
|
|
996
|
-
quality: 1,
|
|
997
|
-
what: 'Link has no accessible name'
|
|
998
|
-
}
|
|
999
|
-
},
|
|
1000
|
-
axe: {
|
|
1001
|
-
'link-name': {
|
|
1002
|
-
quality: 1,
|
|
1003
|
-
what: 'Link has no discernible text'
|
|
1004
|
-
}
|
|
1005
|
-
},
|
|
1006
|
-
continuum: {
|
|
1007
|
-
237: {
|
|
1008
|
-
quality: 1,
|
|
1009
|
-
what: 'a element has no mechanism that allows an accessible name value to be calculated'
|
|
1010
|
-
}
|
|
1011
|
-
},
|
|
1012
|
-
htmlcs: {
|
|
1013
|
-
'e:AA.1_1_1.H30.2': {
|
|
1014
|
-
quality: 1,
|
|
1015
|
-
what: 'img element is the only link content but has no text alternative'
|
|
1016
|
-
},
|
|
1017
|
-
'w:AA.4_1_2.H91.A.Empty': {
|
|
1018
|
-
quality: 1,
|
|
1019
|
-
what: 'Link element has an id attribute but no href attribute or text'
|
|
1020
|
-
},
|
|
1021
|
-
'e:AA.4_1_2.H91.A.EmptyNoId': {
|
|
1022
|
-
quality: 1,
|
|
1023
|
-
what: 'Link has no name or id attribute or value'
|
|
1024
|
-
},
|
|
1025
|
-
'w:AA.4_1_2.H91.A.EmptyWithName': {
|
|
1026
|
-
quality: 1,
|
|
1027
|
-
what: 'Link has a name attribute but no href attribute or text'
|
|
1028
|
-
},
|
|
1029
|
-
'e:AA.4_1_2.H91.A.NoContent': {
|
|
1030
|
-
quality: 1,
|
|
1031
|
-
what: 'Link has an href attribute but no text'
|
|
1032
|
-
}
|
|
1033
|
-
},
|
|
1034
|
-
ibm: {
|
|
1035
|
-
WCAG20_A_HasText: {
|
|
1036
|
-
quality: 1,
|
|
1037
|
-
what: 'Hyperlink has no text description'
|
|
1038
|
-
}
|
|
1039
|
-
},
|
|
1040
|
-
nuVal: {
|
|
1041
|
-
'Bad value for attribute href on element link: Must be non-empty.': {
|
|
1042
|
-
quality: 1,
|
|
1043
|
-
what: 'link element has an empty href attribute'
|
|
1044
|
-
}
|
|
1045
|
-
},
|
|
1046
|
-
tenon: {
|
|
1047
|
-
57: {
|
|
1048
|
-
quality: 1,
|
|
1049
|
-
what: 'Link has no text inside it'
|
|
1050
|
-
},
|
|
1051
|
-
91: {
|
|
1052
|
-
quality: 1,
|
|
1053
|
-
what: 'Link has a background image but no text inside it'
|
|
1054
|
-
}
|
|
1055
|
-
},
|
|
1056
|
-
wave: {
|
|
1057
|
-
'e:link_empty': {
|
|
1058
|
-
quality: 1,
|
|
1059
|
-
what: 'Link contains no text'
|
|
1060
|
-
},
|
|
1061
|
-
'e:alt_link_missing': {
|
|
1062
|
-
quality: 1,
|
|
1063
|
-
what: 'Linked image has no text alternative'
|
|
1064
|
-
},
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
},
|
|
1068
|
-
linkBrokenRisk: {
|
|
1069
|
-
weight: 2,
|
|
1070
|
-
packages: {
|
|
1071
|
-
htmlcs: {
|
|
1072
|
-
'w:AA.4_1_2.H91.A.Placeholder': {
|
|
1073
|
-
quality: 1,
|
|
1074
|
-
what: 'Link has text but no href, id, or name attribute'
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
},
|
|
1079
|
-
acronymNoTitle: {
|
|
1080
|
-
weight: 4,
|
|
1081
|
-
packages: {
|
|
1082
|
-
tenon: {
|
|
1083
|
-
117: {
|
|
1084
|
-
quality: 1,
|
|
1085
|
-
what: 'acronym element has no useful title value (and is deprecated; use abbr)'
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
},
|
|
1090
|
-
abbreviationNoTitle: {
|
|
1091
|
-
weight: 4,
|
|
1092
|
-
packages: {
|
|
1093
|
-
tenon: {
|
|
1094
|
-
233: {
|
|
1095
|
-
quality: 1,
|
|
1096
|
-
what: 'abbr element is first for its abbreviation but has no useful title value'
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
},
|
|
1101
|
-
pdfLink: {
|
|
1102
|
-
weight: 1,
|
|
1103
|
-
packages: {
|
|
1104
|
-
wave: {
|
|
1105
|
-
'a:link_pdf': {
|
|
1106
|
-
quality: 1,
|
|
1107
|
-
what: 'Link to PDF document'
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
},
|
|
1112
|
-
destinationLink: {
|
|
1113
|
-
weight: 2,
|
|
1114
|
-
packages: {
|
|
1115
|
-
htmlcs: {
|
|
1116
|
-
'w:AA.4_1_2.H91.A.NoHref': {
|
|
1117
|
-
quality: 1,
|
|
1118
|
-
what: 'Link is misused as a link destination'
|
|
1119
|
-
}
|
|
1120
|
-
},
|
|
1121
|
-
testaro: {
|
|
1122
|
-
linkTo: {
|
|
1123
|
-
quality: 1,
|
|
1124
|
-
what: 'Link has no href attribute'
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
},
|
|
1129
|
-
textAreaNoText: {
|
|
1130
|
-
weight: 4,
|
|
1131
|
-
packages: {
|
|
1132
|
-
htmlcs: {
|
|
1133
|
-
'e:AA.4_1_2.H91.Textarea.Name': {
|
|
1134
|
-
quality: 1,
|
|
1135
|
-
what: 'textarea element has no accessible name'
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
},
|
|
1140
|
-
linkTextsSame: {
|
|
1141
|
-
weight: 2,
|
|
1142
|
-
packages: {
|
|
1143
|
-
htmlcs: {
|
|
1144
|
-
'e:AA.1_1_1.H2.EG3': {
|
|
1145
|
-
quality: 1,
|
|
1146
|
-
what: 'alt value of the link img element duplicates the text of a link beside it'
|
|
1147
|
-
}
|
|
1148
|
-
},
|
|
1149
|
-
tenon: {
|
|
1150
|
-
98: {
|
|
1151
|
-
quality: 1,
|
|
1152
|
-
what: 'Links have the same text but different destinations'
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
},
|
|
1157
|
-
nextLinkDestinationSame: {
|
|
1158
|
-
weight: 2,
|
|
1159
|
-
packages: {
|
|
1160
|
-
tenon: {
|
|
1161
|
-
184: {
|
|
1162
|
-
quality: 1,
|
|
1163
|
-
what: 'Adjacent links point to the same destination'
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
|
-
},
|
|
1168
|
-
linkDestinationsSame: {
|
|
1169
|
-
weight: 2,
|
|
1170
|
-
packages: {
|
|
1171
|
-
tenon: {
|
|
1172
|
-
132: {
|
|
1173
|
-
quality: 1,
|
|
1174
|
-
what: 'area element has the same href as another but a different alt'
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
},
|
|
1179
|
-
linkConfusionRisk: {
|
|
1180
|
-
weight: 1,
|
|
1181
|
-
packages: {
|
|
1182
|
-
axe: {
|
|
1183
|
-
'identical-links-same-purpose': {
|
|
1184
|
-
quality: 1,
|
|
1185
|
-
what: 'Links with the same accessible name may serve dissimilar purposes'
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
},
|
|
1190
|
-
linkPair: {
|
|
1191
|
-
weight: 2,
|
|
1192
|
-
packages: {
|
|
1193
|
-
wave: {
|
|
1194
|
-
'a:link_redundant': {
|
|
1195
|
-
quality: 1,
|
|
1196
|
-
what: 'Adjacent links go to the same URL'
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
},
|
|
1201
|
-
formNewWindow: {
|
|
1202
|
-
weight: 2,
|
|
1203
|
-
packages: {
|
|
1204
|
-
tenon: {
|
|
1205
|
-
214: {
|
|
1206
|
-
quality: 1,
|
|
1207
|
-
what: 'Form submission opens a new window'
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
},
|
|
1212
|
-
linkForcesNewWindow: {
|
|
1213
|
-
weight: 3,
|
|
1214
|
-
packages: {
|
|
1215
|
-
tenon: {
|
|
1216
|
-
218: {
|
|
1217
|
-
quality: 1,
|
|
1218
|
-
what: 'Link opens in a new window without user control'
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
|
-
},
|
|
1223
|
-
linkWindowSurpriseRisk: {
|
|
1224
|
-
weight: 1,
|
|
1225
|
-
packages: {
|
|
1226
|
-
htmlcs: {
|
|
1227
|
-
'w:WCAG2AAA.Principle3.Guideline3_2.3_2_5.H83.3': {
|
|
1228
|
-
quality: 1,
|
|
1229
|
-
what: 'Link may open in a new window without notice'
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
},
|
|
1234
|
-
selectNavSurpriseRisk: {
|
|
1235
|
-
weight: 1,
|
|
1236
|
-
packages: {
|
|
1237
|
-
wave: {
|
|
1238
|
-
'a:javascript_jumpmenu': {
|
|
1239
|
-
quality: 1,
|
|
1240
|
-
what: 'selection change may navigate to another page without notice'
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
},
|
|
1245
|
-
buttonAlt: {
|
|
1246
|
-
weight: 4,
|
|
1247
|
-
packages: {
|
|
1248
|
-
nuVal: {
|
|
1249
|
-
'Attribute alt not allowed on element button at this point.': {
|
|
1250
|
-
quality: 1,
|
|
1251
|
-
what: 'button element has an alt attribute'
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
}
|
|
1255
|
-
},
|
|
1256
|
-
buttonNoText: {
|
|
1257
|
-
weight: 4,
|
|
1258
|
-
packages: {
|
|
1259
|
-
alfa: {
|
|
1260
|
-
r12: {
|
|
1261
|
-
quality: 1,
|
|
1262
|
-
what: 'Button has no accessible name'
|
|
1263
|
-
}
|
|
1264
|
-
},
|
|
1265
|
-
axe: {
|
|
1266
|
-
'aria-command-name': {
|
|
1267
|
-
quality: 1,
|
|
1268
|
-
what: 'ARIA command has no accessible name'
|
|
1269
|
-
},
|
|
1270
|
-
'button-name': {
|
|
1271
|
-
quality: 1,
|
|
1272
|
-
what: 'Button has no discernible text'
|
|
1273
|
-
},
|
|
1274
|
-
'input-button-name': {
|
|
1275
|
-
quality: 1,
|
|
1276
|
-
what: 'Input button has no discernible text'
|
|
1277
|
-
}
|
|
1278
|
-
},
|
|
1279
|
-
continuum: {
|
|
1280
|
-
224: {
|
|
1281
|
-
quality: 1,
|
|
1282
|
-
what: 'button element has no mechanism that allows an accessible name to be calculated'
|
|
1283
|
-
}
|
|
1284
|
-
},
|
|
1285
|
-
htmlcs: {
|
|
1286
|
-
'e:AA.4_1_2.H91.A.Name': {
|
|
1287
|
-
quality: 1,
|
|
1288
|
-
what: 'Link with button role has no accessible name'
|
|
1289
|
-
},
|
|
1290
|
-
'e:AA.4_1_2.H91.Div.Name': {
|
|
1291
|
-
quality: 1,
|
|
1292
|
-
what: 'div element with button role has no accessible name'
|
|
1293
|
-
},
|
|
1294
|
-
'e:AA.4_1_2.H91.Button.Name': {
|
|
1295
|
-
quality: 1,
|
|
1296
|
-
what: 'Button element has no accessible name'
|
|
1297
|
-
},
|
|
1298
|
-
'e:AA.4_1_2.H91.Img.Name': {
|
|
1299
|
-
quality: 1,
|
|
1300
|
-
what: 'img element with button role has no accessible name'
|
|
1301
|
-
},
|
|
1302
|
-
'e:AA.4_1_2.H91.InputButton.Name': {
|
|
1303
|
-
quality: 1,
|
|
1304
|
-
what: 'Button input element has no accessible name'
|
|
1305
|
-
},
|
|
1306
|
-
'e:AA.4_1_2.H91.Span.Name': {
|
|
1307
|
-
quality: 1,
|
|
1308
|
-
what: 'Element with button role has no accessible name'
|
|
1309
|
-
}
|
|
1310
|
-
},
|
|
1311
|
-
wave: {
|
|
1312
|
-
'e:button_empty': {
|
|
1313
|
-
quality: 1,
|
|
1314
|
-
what: 'Button is empty or has no value text'
|
|
1315
|
-
}
|
|
1316
|
-
}
|
|
1317
|
-
}
|
|
1318
|
-
},
|
|
1319
|
-
parentMissing: {
|
|
1320
|
-
weight: 4,
|
|
1321
|
-
packages: {
|
|
1322
|
-
alfa: {
|
|
1323
|
-
r42: {
|
|
1324
|
-
quality: 1,
|
|
1325
|
-
what: 'Element is not owned by an element of its required context role'
|
|
1326
|
-
}
|
|
1327
|
-
},
|
|
1328
|
-
axe: {
|
|
1329
|
-
'aria-required-parent': {
|
|
1330
|
-
quality: 1,
|
|
1331
|
-
what: 'ARIA role is not contained by a required parent'
|
|
1332
|
-
}
|
|
1333
|
-
},
|
|
1334
|
-
ibm: {
|
|
1335
|
-
Rpt_Aria_RequiredParent_Native_Host_Sematics: {
|
|
1336
|
-
quality: 1,
|
|
1337
|
-
what: 'Element is not contained within a role-valid element'
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
},
|
|
1342
|
-
svgImageNoText: {
|
|
1343
|
-
weight: 4,
|
|
1344
|
-
packages: {
|
|
1345
|
-
alfa: {
|
|
1346
|
-
r43: {
|
|
1347
|
-
quality: 1,
|
|
1348
|
-
what: 'SVG image element has no accessible name'
|
|
1349
|
-
}
|
|
1350
|
-
},
|
|
1351
|
-
axe: {
|
|
1352
|
-
'svg-img-alt': {
|
|
1353
|
-
quality: 1,
|
|
1354
|
-
what: 'svg element with an img role has no text alternative'
|
|
1355
|
-
}
|
|
1356
|
-
},
|
|
1357
|
-
continuum: {
|
|
1358
|
-
123: {
|
|
1359
|
-
quality: 1,
|
|
1360
|
-
what: 'svg element has no mechanism that allows an accessible name to be calculated'
|
|
1361
|
-
}
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
},
|
|
1365
|
-
cssBansRotate: {
|
|
1366
|
-
weight: 4,
|
|
1367
|
-
packages: {
|
|
1368
|
-
axe: {
|
|
1369
|
-
'css-orientation-lock': {
|
|
1370
|
-
quality: 1,
|
|
1371
|
-
what: 'CSS media query locks display orientation'
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
},
|
|
1376
|
-
textRotated: {
|
|
1377
|
-
weight: 2,
|
|
1378
|
-
packages: {
|
|
1379
|
-
tenon: {
|
|
1380
|
-
271: {
|
|
1381
|
-
quality: 1,
|
|
1382
|
-
what: 'Text is needlessly rotated 60+ degrees or more, hurting comprehension'
|
|
1383
|
-
}
|
|
1384
|
-
}
|
|
1385
|
-
}
|
|
1386
|
-
},
|
|
1387
|
-
metaBansZoom: {
|
|
1388
|
-
weight: 4,
|
|
1389
|
-
packages: {
|
|
1390
|
-
alfa: {
|
|
1391
|
-
r47: {
|
|
1392
|
-
quality: 1,
|
|
1393
|
-
what: 'Meta element restricts zooming'
|
|
1394
|
-
}
|
|
1395
|
-
},
|
|
1396
|
-
axe: {
|
|
1397
|
-
'meta-viewport': {
|
|
1398
|
-
quality: 1,
|
|
1399
|
-
what: 'Zooming and scaling are disabled'
|
|
1400
|
-
},
|
|
1401
|
-
'meta-viewport-large': {
|
|
1402
|
-
quality: 1,
|
|
1403
|
-
what: 'User cannot zoom and scale the text up to 500%'
|
|
1404
|
-
}
|
|
1405
|
-
},
|
|
1406
|
-
continuum: {
|
|
1407
|
-
55: {
|
|
1408
|
-
quality: 1,
|
|
1409
|
-
what: 'meta element in the head stops a user from scaling the viewport size'
|
|
1410
|
-
},
|
|
1411
|
-
59: {
|
|
1412
|
-
quality: 1,
|
|
1413
|
-
what: 'meta element in the head sets the viewport maximum-scale to less than 2'
|
|
1414
|
-
}
|
|
1415
|
-
},
|
|
1416
|
-
nuVal: {
|
|
1417
|
-
'Consider avoiding viewport values that prevent users from resizing documents.': {
|
|
1418
|
-
quality: 1,
|
|
1419
|
-
what: 'viewport value prevents users from resizing the document'
|
|
1420
|
-
}
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
},
|
|
1424
|
-
childMissing: {
|
|
1425
|
-
weight: 4,
|
|
1426
|
-
packages: {
|
|
1427
|
-
alfa: {
|
|
1428
|
-
r68: {
|
|
1429
|
-
quality: 1,
|
|
1430
|
-
what: 'Element does not own an element required by its semantic role'
|
|
1431
|
-
}
|
|
1432
|
-
},
|
|
1433
|
-
axe: {
|
|
1434
|
-
'aria-required-children': {
|
|
1435
|
-
quality: 1,
|
|
1436
|
-
what: 'ARIA role does not contain a required child'
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
},
|
|
1441
|
-
presentationChild: {
|
|
1442
|
-
weight: 4,
|
|
1443
|
-
packages: {
|
|
1444
|
-
htmlcs: {
|
|
1445
|
-
'e:AA.1_3_1.F92,ARIA4': {
|
|
1446
|
-
quality: 1,
|
|
1447
|
-
what: 'Element has presentation role but semantic child'
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
},
|
|
1452
|
-
fontSizeAbsolute: {
|
|
1453
|
-
weight: 2,
|
|
1454
|
-
packages: {
|
|
1455
|
-
alfa: {
|
|
1456
|
-
r74: {
|
|
1457
|
-
quality: 1,
|
|
1458
|
-
what: 'Paragraph text has an absolute font size'
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
},
|
|
1463
|
-
fontSmall: {
|
|
1464
|
-
weight: 3,
|
|
1465
|
-
packages: {
|
|
1466
|
-
alfa: {
|
|
1467
|
-
r75: {
|
|
1468
|
-
quality: 1,
|
|
1469
|
-
what: 'Font size is smaller than 9 pixels'
|
|
1470
|
-
}
|
|
1471
|
-
},
|
|
1472
|
-
tenon: {
|
|
1473
|
-
134: {
|
|
1474
|
-
quality: 1,
|
|
1475
|
-
what: 'Text is very small'
|
|
1476
|
-
}
|
|
1477
|
-
},
|
|
1478
|
-
testaro: {
|
|
1479
|
-
miniText: {
|
|
1480
|
-
quality: 1,
|
|
1481
|
-
what: 'Text node has a font smaller than 11 pixels'
|
|
1482
|
-
}
|
|
1483
|
-
},
|
|
1484
|
-
wave: {
|
|
1485
|
-
'a:text_small': {
|
|
1486
|
-
quality: 1,
|
|
1487
|
-
what: 'Text is very small'
|
|
1488
|
-
}
|
|
1489
|
-
}
|
|
1490
|
-
}
|
|
1491
|
-
},
|
|
1492
|
-
leadingFrozen: {
|
|
1493
|
-
weight: 4,
|
|
1494
|
-
packages: {
|
|
1495
|
-
alfa: {
|
|
1496
|
-
r93: {
|
|
1497
|
-
quality: 1,
|
|
1498
|
-
what: 'Style attribute with !important prevents adjusting line height'
|
|
1499
|
-
}
|
|
1500
|
-
},
|
|
1501
|
-
axe: {
|
|
1502
|
-
'avoid-inline-spacing': {
|
|
1503
|
-
quality: 1,
|
|
1504
|
-
what: 'Inline text spacing is not adjustable with a custom stylesheet'
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
|
-
}
|
|
1508
|
-
},
|
|
1509
|
-
leadingAbsolute: {
|
|
1510
|
-
weight: 2,
|
|
1511
|
-
packages: {
|
|
1512
|
-
alfa: {
|
|
1513
|
-
r80: {
|
|
1514
|
-
quality: 1,
|
|
1515
|
-
what: 'Paragraph text has an absolute line height'
|
|
1516
|
-
}
|
|
1517
|
-
}
|
|
1518
|
-
}
|
|
1519
|
-
},
|
|
1520
|
-
noLeading: {
|
|
1521
|
-
weight: 3,
|
|
1522
|
-
packages: {
|
|
1523
|
-
alfa: {
|
|
1524
|
-
r73: {
|
|
1525
|
-
quality: 1,
|
|
1526
|
-
what: 'Paragraph of text has insufficient line height'
|
|
1527
|
-
}
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
},
|
|
1531
|
-
leadingClipsText: {
|
|
1532
|
-
weight: 4,
|
|
1533
|
-
packages: {
|
|
1534
|
-
tenon: {
|
|
1535
|
-
144: {
|
|
1536
|
-
quality: 1,
|
|
1537
|
-
what: 'Line height is insufficent to properly display the computed font size'
|
|
1538
|
-
}
|
|
1539
|
-
}
|
|
1540
|
-
}
|
|
1541
|
-
},
|
|
1542
|
-
overflowHidden: {
|
|
1543
|
-
weight: 4,
|
|
1544
|
-
packages: {
|
|
1545
|
-
alfa: {
|
|
1546
|
-
r83: {
|
|
1547
|
-
quality: 1,
|
|
1548
|
-
what: 'Overflow is hidden or clipped if the text is enlarged'
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
1552
|
-
},
|
|
1553
|
-
titleBad: {
|
|
1554
|
-
weight: 4,
|
|
1555
|
-
packages: {
|
|
1556
|
-
nuVal: {
|
|
1557
|
-
'Element title not allowed as child of element body in this context. (Suppressing further errors from this subtree.)': {
|
|
1558
|
-
quality: 1,
|
|
1559
|
-
what: 'title element is a child of the body element'
|
|
1560
|
-
}
|
|
1561
|
-
},
|
|
1562
|
-
testaro: {
|
|
1563
|
-
titleEl: {
|
|
1564
|
-
quality: 1,
|
|
1565
|
-
what: 'title attribute belongs to an inappropriate element'
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1569
|
-
},
|
|
1570
|
-
linkElementBad: {
|
|
1571
|
-
weight: 4,
|
|
1572
|
-
packages: {
|
|
1573
|
-
nuVal: {
|
|
1574
|
-
'A link element must not appear as a descendant of a body element unless the link element has an itemprop attribute or has a rel attribute whose value contains dns-prefetch, modulepreload, pingback, preconnect, prefetch, preload, prerender, or stylesheet.': {
|
|
1575
|
-
quality: 1,
|
|
1576
|
-
what: 'link element with a body ancestor has no itemprop or valid rel attribute'
|
|
1577
|
-
},
|
|
1578
|
-
'A link element with an as attribute must have a rel attribute that contains the value preload or the value modulepreload or the value prefetch.': {
|
|
1579
|
-
quality: 1,
|
|
1580
|
-
what: 'link element with an as attribute has no rel attribute with preload, modulepreload, or prefetch as its value'
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
}
|
|
1584
|
-
},
|
|
1585
|
-
metaBad: {
|
|
1586
|
-
weight: 3,
|
|
1587
|
-
packages: {
|
|
1588
|
-
nuVal: {
|
|
1589
|
-
'^Attribute .+ not allowed on element meta at this point.*$': {
|
|
1590
|
-
quality: 1,
|
|
1591
|
-
what: 'Attribute is not allowed on a meta element here'
|
|
1592
|
-
},
|
|
1593
|
-
'^Element meta is missing one or more of the following attributes: .+$': {
|
|
1594
|
-
quality: 1,
|
|
1595
|
-
what: 'meta element is missing a required attribute'
|
|
1596
|
-
},
|
|
1597
|
-
'A document must not include more than one meta element with its name attribute set to the value description.': {
|
|
1598
|
-
quality: 1,
|
|
1599
|
-
what: 'meta element with name="description" is not the only one'
|
|
1600
|
-
},
|
|
1601
|
-
'A document must not include both a meta element with an http-equiv attribute whose value is content-type, and a meta element with a charset attribute.': {
|
|
1602
|
-
quality: 1,
|
|
1603
|
-
what: 'meta element with http-equiv="content-type" is incompatible with the meta element with a charset attribute'
|
|
1604
|
-
},
|
|
1605
|
-
'A document must not include more than one meta element with a http-equiv attribute whose value is content-type.': {
|
|
1606
|
-
quality: 1,
|
|
1607
|
-
what: 'Page has more than 1 meta element with http-equiv="content-type"'
|
|
1608
|
-
},
|
|
1609
|
-
'A meta element with an http-equiv attribute whose value is X-UA-Compatible must have a content attribute with the value IE=edge.': {
|
|
1610
|
-
quality: 1,
|
|
1611
|
-
what: 'meta element with http-equiv="X-UA-Compatible" has no content="IE=edge"'
|
|
1612
|
-
},
|
|
1613
|
-
'A document must not include more than one meta element with a charset attribute.': {
|
|
1614
|
-
quality: 1,
|
|
1615
|
-
what: 'More than 1 meta element has a charset attribute'
|
|
1616
|
-
},
|
|
1617
|
-
'A charset attribute on a meta element found after the first 1024 bytes.': {
|
|
1618
|
-
quality: 1,
|
|
1619
|
-
what: 'charset attribute on a meta element appears after 1024 bytes'
|
|
1620
|
-
},
|
|
1621
|
-
'^Bad value .+ for attribute .+ on element meta.*$': {
|
|
1622
|
-
quality: 1,
|
|
1623
|
-
what: 'attribute of a meta element has an invalid value'
|
|
1624
|
-
}
|
|
1625
|
-
}
|
|
1626
|
-
}
|
|
1627
|
-
},
|
|
1628
|
-
scriptElementBad: {
|
|
1629
|
-
weight: 4,
|
|
1630
|
-
packages: {
|
|
1631
|
-
nuVal: {
|
|
1632
|
-
'Element script must not have attribute defer unless attribute src is also specified.': {
|
|
1633
|
-
quality: 1,
|
|
1634
|
-
what: 'script element has a defer attribute without a src attribute'
|
|
1635
|
-
},
|
|
1636
|
-
'A script element with a src attribute must not have a type attribute whose value is anything other than the empty string, a JavaScript MIME type, or module.': {
|
|
1637
|
-
quality: 1,
|
|
1638
|
-
what: 'script element has a src attribute but its type is not empty, a JS MIME type, or module'
|
|
1639
|
-
}
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
},
|
|
1643
|
-
itemTypeBad: {
|
|
1644
|
-
weight: 4,
|
|
1645
|
-
packages: {
|
|
1646
|
-
nuVal: {
|
|
1647
|
-
'The itemtype attribute must not be specified on elements that do not have an itemscope attribute specified.': {
|
|
1648
|
-
quality: 1,
|
|
1649
|
-
what: 'Element has an itemtype attribute without an itemscope attribute'
|
|
1650
|
-
}
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
},
|
|
1654
|
-
iframeTitleBad: {
|
|
1655
|
-
weight: 4,
|
|
1656
|
-
packages: {
|
|
1657
|
-
alfa: {
|
|
1658
|
-
r13: {
|
|
1659
|
-
quality: 1,
|
|
1660
|
-
what: 'iframe has no accessible name'
|
|
1661
|
-
}
|
|
1662
|
-
},
|
|
1663
|
-
axe: {
|
|
1664
|
-
'frame-title': {
|
|
1665
|
-
quality: 1,
|
|
1666
|
-
what: 'Frame has no accessible name'
|
|
1667
|
-
},
|
|
1668
|
-
'frame-title-unique': {
|
|
1669
|
-
quality: 1,
|
|
1670
|
-
what: 'Frame title attribute is not unique'
|
|
1671
|
-
}
|
|
1672
|
-
},
|
|
1673
|
-
continuum: {
|
|
1674
|
-
228: {
|
|
1675
|
-
quality: 1,
|
|
1676
|
-
what: 'iframe has no mechanism that allows an accessible name to be calculated'
|
|
1677
|
-
}
|
|
1678
|
-
},
|
|
1679
|
-
htmlcs: {
|
|
1680
|
-
'e:AA.2_4_1.H64.1': {
|
|
1681
|
-
quality: 1,
|
|
1682
|
-
what: 'iframe element has no non-empty title attribute'
|
|
1683
|
-
}
|
|
1684
|
-
},
|
|
1685
|
-
ibm: {
|
|
1686
|
-
WCAG20_Frame_HasTitle: {
|
|
1687
|
-
quality: 1,
|
|
1688
|
-
what: 'Inline frame has an empty or nonunique title attribute'
|
|
1689
|
-
}
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
},
|
|
1693
|
-
roleBad: {
|
|
1694
|
-
weight: 3,
|
|
1695
|
-
packages: {
|
|
1696
|
-
alfa: {
|
|
1697
|
-
r21: {
|
|
1698
|
-
quality: 1,
|
|
1699
|
-
what: 'Element does not have a valid role'
|
|
1700
|
-
}
|
|
1701
|
-
},
|
|
1702
|
-
axe: {
|
|
1703
|
-
'aria-roles': {
|
|
1704
|
-
quality: 1,
|
|
1705
|
-
what: 'ARIA role has an invalid value'
|
|
1706
|
-
},
|
|
1707
|
-
'aria-allowed-role': {
|
|
1708
|
-
quality: 1,
|
|
1709
|
-
what: 'ARIA role is not appropriate for the element'
|
|
1710
|
-
}
|
|
1711
|
-
},
|
|
1712
|
-
continuum: {
|
|
1713
|
-
37: {
|
|
1714
|
-
quality: 1,
|
|
1715
|
-
what: 'a element has a role attribute that is not allowed'
|
|
1716
|
-
},
|
|
1717
|
-
44: {
|
|
1718
|
-
quality: 1,
|
|
1719
|
-
what: 'hr element has a role attribute'
|
|
1720
|
-
},
|
|
1721
|
-
176: {
|
|
1722
|
-
quality: 1,
|
|
1723
|
-
what: 'label element has a role attribute'
|
|
1724
|
-
},
|
|
1725
|
-
319: {
|
|
1726
|
-
quality: 1,
|
|
1727
|
-
what: 'ol element has a role attribute that is not allowed'
|
|
1728
|
-
},
|
|
1729
|
-
325: {
|
|
1730
|
-
quality: 1,
|
|
1731
|
-
what: 'ul element has a role attribute that is not allowed'
|
|
1732
|
-
},
|
|
1733
|
-
412: {
|
|
1734
|
-
quality: 1,
|
|
1735
|
-
what: 'element has a role attribute set to an invalid ARIA role value'
|
|
1736
|
-
}
|
|
1737
|
-
},
|
|
1738
|
-
ibm: {
|
|
1739
|
-
aria_semantics_role: {
|
|
1740
|
-
quality: 1,
|
|
1741
|
-
what: 'ARIA role is not valid for the element to which it is assigned'
|
|
1742
|
-
},
|
|
1743
|
-
element_tabbable_role_valid: {
|
|
1744
|
-
quality: 1,
|
|
1745
|
-
what: 'Tabbable element has a non-widget role'
|
|
1746
|
-
},
|
|
1747
|
-
Rpt_Aria_ContentinfoWithNoMain_Implicit: {
|
|
1748
|
-
quality: 1,
|
|
1749
|
-
what: 'Element has a contentinfo role when no element has a main role'
|
|
1750
|
-
},
|
|
1751
|
-
Rpt_Aria_ValidRole: {
|
|
1752
|
-
quality: 1,
|
|
1753
|
-
what: 'Element has an invalid role'
|
|
1754
|
-
},
|
|
1755
|
-
Rpt_Aria_EventHandlerMissingRole_Native_Host_Sematics: {
|
|
1756
|
-
quality: 1,
|
|
1757
|
-
what: 'Element has an event handler but no valid ARIA role'
|
|
1758
|
-
},
|
|
1759
|
-
table_aria_descendants: {
|
|
1760
|
-
quality: 1,
|
|
1761
|
-
what: 'Table structure element specifies an explicit role within the table container'
|
|
1762
|
-
}
|
|
1763
|
-
},
|
|
1764
|
-
nuVal: {
|
|
1765
|
-
'Bad value dialog for attribute role on element li.': {
|
|
1766
|
-
quality: 1,
|
|
1767
|
-
what: 'dialog role is not valid for an li element'
|
|
1768
|
-
},
|
|
1769
|
-
'An img element with no alt attribute must not have a role attribute.': {
|
|
1770
|
-
quality: 1,
|
|
1771
|
-
what: 'img element has a role attribute but no alt attribute'
|
|
1772
|
-
},
|
|
1773
|
-
'^The role attribute must not be used on a .+ element which has a table ancestor with no role attribute, or with a role attribute whose value is table, grid, or treegrid.*$': {
|
|
1774
|
-
quality: 1,
|
|
1775
|
-
what: 'Table cell has a role attribute'
|
|
1776
|
-
}
|
|
1777
|
-
},
|
|
1778
|
-
testaro: {
|
|
1779
|
-
role: {
|
|
1780
|
-
quality: 1,
|
|
1781
|
-
what: 'Nonexistent or implicit-overriding role'
|
|
1782
|
-
}
|
|
1783
|
-
}
|
|
1784
|
-
}
|
|
1785
|
-
},
|
|
1786
|
-
roleRedundant: {
|
|
1787
|
-
weight: 1,
|
|
1788
|
-
packages: {
|
|
1789
|
-
ibm: {
|
|
1790
|
-
aria_role_redundant: {
|
|
1791
|
-
quality: 1,
|
|
1792
|
-
what: 'Explicitly assigned ARIA role is redundant with the implicit role of the element'
|
|
1793
|
-
}
|
|
1794
|
-
},
|
|
1795
|
-
nuVal: {
|
|
1796
|
-
'^The .+ role is unnecessary for element .+$': {
|
|
1797
|
-
quality: 1,
|
|
1798
|
-
what: 'explicit role is redundant for its element'
|
|
1799
|
-
},
|
|
1800
|
-
'The textbox role is unnecessary for an input element that has no list attribute and whose type is text.': {
|
|
1801
|
-
quality: 1,
|
|
1802
|
-
what: 'explicit role is redundant for a text-type input element without a list attribute'
|
|
1803
|
-
}
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1806
|
-
},
|
|
1807
|
-
roleMissingAttribute: {
|
|
1808
|
-
weight: 4,
|
|
1809
|
-
packages: {
|
|
1810
|
-
axe: {
|
|
1811
|
-
'aria-required-attr': {
|
|
1812
|
-
quality: 1,
|
|
1813
|
-
what: 'Required ARIA attribute is not provided'
|
|
1814
|
-
}
|
|
1815
|
-
},
|
|
1816
|
-
ibm: {
|
|
1817
|
-
Rpt_Aria_RequiredProperties: {
|
|
1818
|
-
quality: 1,
|
|
1819
|
-
what: 'ARIA role on an element does not have a required attribute'
|
|
1820
|
-
}
|
|
1821
|
-
},
|
|
1822
|
-
nuVal: {
|
|
1823
|
-
'Element a is missing required attribute aria-valuenow.': {
|
|
1824
|
-
quality: 1,
|
|
1825
|
-
what: 'a element has no aria-valuenow attribute'
|
|
1826
|
-
},
|
|
1827
|
-
'Element a is missing one or more of the following attributes: aria-checked, role.': {
|
|
1828
|
-
quality: 1,
|
|
1829
|
-
what: 'a element has no aria-checked attribute or has no role attribute'
|
|
1830
|
-
}
|
|
1831
|
-
}
|
|
1832
|
-
}
|
|
1833
|
-
},
|
|
1834
|
-
ariaMissing: {
|
|
1835
|
-
weight: 4,
|
|
1836
|
-
packages: {
|
|
1837
|
-
alfa: {
|
|
1838
|
-
r16: {
|
|
1839
|
-
quality: 1,
|
|
1840
|
-
what: 'Element does not have all required states and properties'
|
|
1841
|
-
}
|
|
1842
|
-
},
|
|
1843
|
-
continuum: {
|
|
1844
|
-
1040: {
|
|
1845
|
-
quality: 1,
|
|
1846
|
-
what: 'element with a combobox role has no aria-controls or no aria-expanded attribute'
|
|
1847
|
-
},
|
|
1848
|
-
1042: {
|
|
1849
|
-
quality: 1,
|
|
1850
|
-
what: 'element with an option role has no aria-selected attribute'
|
|
1851
|
-
},
|
|
1852
|
-
1043: {
|
|
1853
|
-
quality: 1,
|
|
1854
|
-
what: 'element with a radio role has no aria-checked attribute'
|
|
1855
|
-
}
|
|
1856
|
-
},
|
|
1857
|
-
wave: {
|
|
1858
|
-
'e:aria_reference_broken': {
|
|
1859
|
-
quality: 1,
|
|
1860
|
-
what: 'Broken ARIA reference'
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
1863
|
-
}
|
|
1864
|
-
},
|
|
1865
|
-
ariaBadAttribute: {
|
|
1866
|
-
weight: 4,
|
|
1867
|
-
packages: {
|
|
1868
|
-
alfa: {
|
|
1869
|
-
r18: {
|
|
1870
|
-
quality: 1,
|
|
1871
|
-
what: 'ARIA state or property is not allowed for the element on which it is specified'
|
|
1872
|
-
},
|
|
1873
|
-
r19: {
|
|
1874
|
-
quality: 1,
|
|
1875
|
-
what: 'ARIA state or property has an invalid value'
|
|
1876
|
-
},
|
|
1877
|
-
r20: {
|
|
1878
|
-
quality: 1,
|
|
1879
|
-
what: 'ARIA attribute is not defined'
|
|
1880
|
-
}
|
|
1881
|
-
},
|
|
1882
|
-
axe: {
|
|
1883
|
-
'aria-valid-attr': {
|
|
1884
|
-
quality: 1,
|
|
1885
|
-
what: 'ARIA attribute has an invalid name'
|
|
1886
|
-
},
|
|
1887
|
-
'aria-valid-attr-value': {
|
|
1888
|
-
quality: 1,
|
|
1889
|
-
what: 'ARIA attribute has an invalid value'
|
|
1890
|
-
},
|
|
1891
|
-
'aria-allowed-attr': {
|
|
1892
|
-
quality: 1,
|
|
1893
|
-
what: 'ARIA attribute is invalid for the role of its element'
|
|
1894
|
-
},
|
|
1895
|
-
'aria-roledescription': {
|
|
1896
|
-
quality: 1,
|
|
1897
|
-
what: 'aria-roledescription is on an element with no semantic role'
|
|
1898
|
-
}
|
|
1899
|
-
},
|
|
1900
|
-
continuum: {
|
|
1901
|
-
16: {
|
|
1902
|
-
quality: 1,
|
|
1903
|
-
what: 'Element has an aria-multiline attribute, which is not allowed'
|
|
1904
|
-
},
|
|
1905
|
-
38: {
|
|
1906
|
-
quality: 1,
|
|
1907
|
-
what: 'Element has an aria-pressed attribute, which is not allowed'
|
|
1908
|
-
},
|
|
1909
|
-
64: {
|
|
1910
|
-
quality: 1,
|
|
1911
|
-
what: 'Element has an aria-valuemax attribute that is not set to an integer'
|
|
1912
|
-
},
|
|
1913
|
-
257: {
|
|
1914
|
-
quality: 1,
|
|
1915
|
-
what: 'Element has an aria-checked attribute, which is not allowed'
|
|
1916
|
-
},
|
|
1917
|
-
260: {
|
|
1918
|
-
quality: 1,
|
|
1919
|
-
what: 'Element has an aria-level attribute, which is not allowed'
|
|
1920
|
-
},
|
|
1921
|
-
264: {
|
|
1922
|
-
quality: 1,
|
|
1923
|
-
what: 'Element has an aria-selected attribute, which is not allowed'
|
|
1924
|
-
},
|
|
1925
|
-
270: {
|
|
1926
|
-
quality: 1,
|
|
1927
|
-
what: 'Element has an aria-required attribute, which is not allowed'
|
|
1928
|
-
},
|
|
1929
|
-
281: {
|
|
1930
|
-
quality: 1,
|
|
1931
|
-
what: 'Element has an aria-expanded attribute, which is not allowed'
|
|
1932
|
-
},
|
|
1933
|
-
282: {
|
|
1934
|
-
quality: 1,
|
|
1935
|
-
what: 'Element has an aria-autocomplete attribute, which is not allowed'
|
|
1936
|
-
},
|
|
1937
|
-
283: {
|
|
1938
|
-
quality: 1,
|
|
1939
|
-
what: 'Element has an aria-activedescendant attribute, which is not allowed'
|
|
1940
|
-
},
|
|
1941
|
-
331: {
|
|
1942
|
-
quality: 1,
|
|
1943
|
-
what: 'Element has an aria-owns attribute set to a non-null value'
|
|
1944
|
-
},
|
|
1945
|
-
333: {
|
|
1946
|
-
quality: 1,
|
|
1947
|
-
what: 'Element with a textbox role has an aria-owns attribute, which is not allowed'
|
|
1948
|
-
},
|
|
1949
|
-
1066: {
|
|
1950
|
-
quality: 1,
|
|
1951
|
-
what: 'Element has an ARIA attribute which is not valid'
|
|
1952
|
-
}
|
|
1953
|
-
},
|
|
1954
|
-
ibm: {
|
|
1955
|
-
aria_semantics_attribute: {
|
|
1956
|
-
quality: 1,
|
|
1957
|
-
what: 'ARIA attributes is invalid for the element or ARIA role to which it is assigned'
|
|
1958
|
-
},
|
|
1959
|
-
Rpt_Aria_ValidProperty: {
|
|
1960
|
-
quality: 1,
|
|
1961
|
-
what: 'ARIA attribute is invalid for the role'
|
|
1962
|
-
},
|
|
1963
|
-
Rpt_Aria_ValidPropertyValue: {
|
|
1964
|
-
quality: 1,
|
|
1965
|
-
what: 'ARIA property value is invalid'
|
|
1966
|
-
}
|
|
1967
|
-
},
|
|
1968
|
-
nuVal: {
|
|
1969
|
-
'The aria-hidden attribute must not be specified on the noscript element.': {
|
|
1970
|
-
quality: 1,
|
|
1971
|
-
what: 'noscript element has an aria-hidden attribute'
|
|
1972
|
-
},
|
|
1973
|
-
'Attribute aria-activedescendant value should either refer to a descendant element, or should be accompanied by attribute aria-owns.': {
|
|
1974
|
-
quality: 1,
|
|
1975
|
-
what: 'element has no aria-owns attribute but its aria-activedescendant attribute references a non-descendant'
|
|
1976
|
-
},
|
|
1977
|
-
'The aria-checked attribute should not be used on an input element which has a type attribute whose value is checkbox.': {
|
|
1978
|
-
quality: 1,
|
|
1979
|
-
what: 'input element with type="checkbox" has an aria-checked attribute'
|
|
1980
|
-
}
|
|
1981
|
-
}
|
|
1982
|
-
}
|
|
1983
|
-
},
|
|
1984
|
-
ariaRedundant: {
|
|
1985
|
-
weight: 1,
|
|
1986
|
-
packages: {
|
|
1987
|
-
ibm: {
|
|
1988
|
-
aria_attribute_redundant: {
|
|
1989
|
-
quality: 1,
|
|
1990
|
-
what: 'ARIA attribute is used when there is a corresponding HTML attribute'
|
|
1991
|
-
}
|
|
1992
|
-
},
|
|
1993
|
-
nuVal: {
|
|
1994
|
-
'Attribute aria-required is unnecessary for elements that have attribute required.': {
|
|
1995
|
-
quality: 1,
|
|
1996
|
-
what: 'aria-required attribute is redundant with required attribute'
|
|
1997
|
-
}
|
|
1998
|
-
}
|
|
1999
|
-
}
|
|
2000
|
-
},
|
|
2001
|
-
ariaReferenceBad: {
|
|
2002
|
-
weight: 4,
|
|
2003
|
-
packages: {
|
|
2004
|
-
ibm: {
|
|
2005
|
-
Rpt_Aria_ValidIdRef: {
|
|
2006
|
-
quality: 1,
|
|
2007
|
-
what: 'ARIA property does not reference the non-empty unique id of a visible element'
|
|
2008
|
-
}
|
|
2009
|
-
},
|
|
2010
|
-
wave: {
|
|
2011
|
-
'e:aria_reference_broken': {
|
|
2012
|
-
quality: 1,
|
|
2013
|
-
what: 'Broken ARIA reference'
|
|
2014
|
-
}
|
|
2015
|
-
}
|
|
2016
|
-
}
|
|
2017
|
-
},
|
|
2018
|
-
autocompleteBad: {
|
|
2019
|
-
weight: 3,
|
|
2020
|
-
packages: {
|
|
2021
|
-
alfa: {
|
|
2022
|
-
r10: {
|
|
2023
|
-
quality: 1,
|
|
2024
|
-
what: 'Autocomplete attribute has no valid value'
|
|
2025
|
-
}
|
|
2026
|
-
},
|
|
2027
|
-
axe: {
|
|
2028
|
-
'autocomplete-valid': {
|
|
2029
|
-
quality: 1,
|
|
2030
|
-
what: 'autocomplete attribute is used incorrectly'
|
|
2031
|
-
}
|
|
2032
|
-
},
|
|
2033
|
-
htmlcs: {
|
|
2034
|
-
'e:AA.1_3_5.H98': {
|
|
2035
|
-
quality: 1,
|
|
2036
|
-
what: 'autocomplete attribute and the input type are mismatched'
|
|
2037
|
-
}
|
|
2038
|
-
},
|
|
2039
|
-
ibm: {
|
|
2040
|
-
WCAG21_Input_Autocomplete: {
|
|
2041
|
-
quality: 1,
|
|
2042
|
-
what: 'autocomplete attribute token is not appropriate for the input form field'
|
|
2043
|
-
}
|
|
2044
|
-
},
|
|
2045
|
-
nuVal: {
|
|
2046
|
-
'Bad value for attribute autocomplete on element input: Must not be empty.': {
|
|
2047
|
-
quality: 1,
|
|
2048
|
-
what: 'autocomplete attribute has an empty value'
|
|
2049
|
-
}
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
},
|
|
2053
|
-
autocompleteRisk: {
|
|
2054
|
-
weight: 1,
|
|
2055
|
-
packages: {
|
|
2056
|
-
htmlcs: {
|
|
2057
|
-
'w:AA.1_3_5.H98': {
|
|
2058
|
-
quality: 1,
|
|
2059
|
-
what: 'Element contains a potentially faulty value in its autocomplete attribute'
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
}
|
|
2063
|
-
},
|
|
2064
|
-
contrastAA: {
|
|
2065
|
-
weight: 4,
|
|
2066
|
-
packages: {
|
|
2067
|
-
alfa: {
|
|
2068
|
-
r69: {
|
|
2069
|
-
quality: 1,
|
|
2070
|
-
what: 'Text outside widget has subminimum contrast'
|
|
2071
|
-
}
|
|
2072
|
-
},
|
|
2073
|
-
axe: {
|
|
2074
|
-
'color-contrast': {
|
|
2075
|
-
quality: 1,
|
|
2076
|
-
what: 'Element has insufficient color contrast'
|
|
2077
|
-
}
|
|
2078
|
-
},
|
|
2079
|
-
htmlcs: {
|
|
2080
|
-
'e:AA.1_4_3.G145.Fail': {
|
|
2081
|
-
quality: 1,
|
|
2082
|
-
what: 'Contrast between the text and its background is less than 3:1.'
|
|
2083
|
-
},
|
|
2084
|
-
'e:AA.1_4_3.G18.Fail': {
|
|
2085
|
-
quality: 1,
|
|
2086
|
-
what: 'Contrast between the text and its background is less than 4.5:1'
|
|
2087
|
-
}
|
|
2088
|
-
},
|
|
2089
|
-
ibm: {
|
|
2090
|
-
IBMA_Color_Contrast_WCAG2AA: {
|
|
2091
|
-
quality: 1,
|
|
2092
|
-
what: 'Contrast ratio of text with background does not meet WCAG 2.1 AA'
|
|
2093
|
-
}
|
|
2094
|
-
},
|
|
2095
|
-
wave: {
|
|
2096
|
-
'c:contrast': {
|
|
2097
|
-
quality: 1,
|
|
2098
|
-
what: 'Very low contrast'
|
|
2099
|
-
}
|
|
2100
|
-
}
|
|
2101
|
-
}
|
|
2102
|
-
},
|
|
2103
|
-
contrastAAA: {
|
|
2104
|
-
weight: 1,
|
|
2105
|
-
packages: {
|
|
2106
|
-
alfa: {
|
|
2107
|
-
r66: {
|
|
2108
|
-
quality: 1,
|
|
2109
|
-
what: 'Text contrast less than AAA requires'
|
|
2110
|
-
}
|
|
2111
|
-
},
|
|
2112
|
-
axe: {
|
|
2113
|
-
'color-contrast-enhanced': {
|
|
2114
|
-
quality: 1,
|
|
2115
|
-
what: 'Element has insufficient color contrast (Level AAA)'
|
|
2116
|
-
}
|
|
2117
|
-
},
|
|
2118
|
-
htmlcs: {
|
|
2119
|
-
'e:WCAG2AAA.Principle1.Guideline1_4.1_4_3.G18': {
|
|
2120
|
-
quality: 1,
|
|
2121
|
-
what: 'Insufficient contrast'
|
|
2122
|
-
}
|
|
2123
|
-
},
|
|
2124
|
-
tenon: {
|
|
2125
|
-
95: {
|
|
2126
|
-
quality: 1,
|
|
2127
|
-
what: 'Element has insufficient color contrast (Level AAA)'
|
|
2128
|
-
}
|
|
2129
|
-
}
|
|
2130
|
-
}
|
|
2131
|
-
},
|
|
2132
|
-
contrastRisk: {
|
|
2133
|
-
weight: 1,
|
|
2134
|
-
packages: {
|
|
2135
|
-
htmlcs: {
|
|
2136
|
-
'w:AA.1_4_3_F24.F24.BGColour': {
|
|
2137
|
-
quality: 1,
|
|
2138
|
-
what: 'Inline background color may lack a complementary foreground color'
|
|
2139
|
-
},
|
|
2140
|
-
'w:AA.1_4_3_F24.F24.FGColour': {
|
|
2141
|
-
quality: 1,
|
|
2142
|
-
what: 'Inline foreground color may lack a complementary background color'
|
|
2143
|
-
},
|
|
2144
|
-
'w:AA.1_4_3.G18.Abs': {
|
|
2145
|
-
quality: 1,
|
|
2146
|
-
what: 'Contrast between the absolutely positioned text and its background may be inadequate'
|
|
2147
|
-
},
|
|
2148
|
-
'w:AA.1_4_3.G18.Alpha': {
|
|
2149
|
-
quality: 1,
|
|
2150
|
-
what: 'Contrast between the text and its background may be less than 4.5:1, given the transparency'
|
|
2151
|
-
},
|
|
2152
|
-
'w:AA.1_4_3.G145.Abs': {
|
|
2153
|
-
quality: 1,
|
|
2154
|
-
what: 'Contrast between the absolutely positioned large text and its background may be less than 3:1'
|
|
2155
|
-
},
|
|
2156
|
-
'w:AA.1_4_3.G145.Alpha': {
|
|
2157
|
-
quality: 1,
|
|
2158
|
-
what: 'Contrast between the text and its background may be less than 3:1, given the transparency'
|
|
2159
|
-
},
|
|
2160
|
-
'w:AA.1_4_3.G145.BgImage': {
|
|
2161
|
-
quality: 1,
|
|
2162
|
-
what: 'Contrast between the text and its background image may be less than 3:1'
|
|
2163
|
-
},
|
|
2164
|
-
'w:AA.1_4_3.G18.BgImage': {
|
|
2165
|
-
quality: 1,
|
|
2166
|
-
what: 'Contrast between the text and its background image may be less than 4.5:1'
|
|
2167
|
-
}
|
|
2168
|
-
}
|
|
2169
|
-
}
|
|
2170
|
-
},
|
|
2171
|
-
idEmpty: {
|
|
2172
|
-
weight: 4,
|
|
2173
|
-
packages: {
|
|
2174
|
-
nuVal: {
|
|
2175
|
-
'^Bad value for attribute .+ on element .+: An ID must not be the empty string.+$': {
|
|
2176
|
-
quality: 1,
|
|
2177
|
-
what: 'id attribute has an empty value'
|
|
2178
|
-
},
|
|
2179
|
-
'^Bad value for attribute aria-owns on element .+: An IDREFS value must contain at least one non-whitespace character.*$': {
|
|
2180
|
-
quality: 1,
|
|
2181
|
-
what: 'aria-owns attribute has an empty value'
|
|
2182
|
-
}
|
|
2183
|
-
}
|
|
2184
|
-
}
|
|
2185
|
-
},
|
|
2186
|
-
targetEmpty: {
|
|
2187
|
-
weight: 4,
|
|
2188
|
-
packages: {
|
|
2189
|
-
nuVal: {
|
|
2190
|
-
'Bad value for attribute target on element a: Browsing context name must be at least one character long.': {
|
|
2191
|
-
quality: 1,
|
|
2192
|
-
what: 'target attribute on an a element is empty'
|
|
2193
|
-
}
|
|
2194
|
-
}
|
|
2195
|
-
}
|
|
2196
|
-
},
|
|
2197
|
-
headingEmpty: {
|
|
2198
|
-
weight: 3,
|
|
2199
|
-
packages: {
|
|
2200
|
-
alfa: {
|
|
2201
|
-
r64: {
|
|
2202
|
-
quality: 1,
|
|
2203
|
-
what: 'Heading has no non-empty accessible name'
|
|
2204
|
-
}
|
|
2205
|
-
},
|
|
2206
|
-
axe: {
|
|
2207
|
-
'empty-heading': {
|
|
2208
|
-
quality: 1,
|
|
2209
|
-
what: 'Heading empty'
|
|
2210
|
-
}
|
|
2211
|
-
},
|
|
2212
|
-
htmlcs: {
|
|
2213
|
-
'e:AA.1_3_1.H42.2': {
|
|
2214
|
-
quality: 1,
|
|
2215
|
-
what: 'Heading empty'
|
|
2216
|
-
}
|
|
2217
|
-
},
|
|
2218
|
-
ibm: {
|
|
2219
|
-
RPT_Header_HasContent: {
|
|
2220
|
-
quality: 1,
|
|
2221
|
-
what: 'Heading element provides no descriptive text'
|
|
2222
|
-
}
|
|
2223
|
-
},
|
|
2224
|
-
nuVal: {
|
|
2225
|
-
'Empty heading.': {
|
|
2226
|
-
quality: 1,
|
|
2227
|
-
what: 'Empty heading'
|
|
2228
|
-
}
|
|
2229
|
-
},
|
|
2230
|
-
wave: {
|
|
2231
|
-
'e:heading_empty': {
|
|
2232
|
-
quality: 1,
|
|
2233
|
-
what: 'Empty heading'
|
|
2234
|
-
}
|
|
2235
|
-
}
|
|
2236
|
-
}
|
|
2237
|
-
},
|
|
2238
|
-
headingOfNothing: {
|
|
2239
|
-
weight: 2,
|
|
2240
|
-
packages: {
|
|
2241
|
-
alfa: {
|
|
2242
|
-
r78: {
|
|
2243
|
-
quality: 1,
|
|
2244
|
-
what: 'No content between two headings of the same level'
|
|
2245
|
-
}
|
|
2246
|
-
}
|
|
2247
|
-
}
|
|
2248
|
-
},
|
|
2249
|
-
typeRedundant: {
|
|
2250
|
-
weight: 1,
|
|
2251
|
-
packages: {
|
|
2252
|
-
nuVal: {
|
|
2253
|
-
'The type attribute is unnecessary for JavaScript resources.': {
|
|
2254
|
-
quality: 1,
|
|
2255
|
-
what: 'type attribute is unnecessary for a JavaScript resource'
|
|
2256
|
-
},
|
|
2257
|
-
'The type attribute for the style element is not needed and should be omitted.': {
|
|
2258
|
-
quality: 1,
|
|
2259
|
-
what: 'type attribute is unnecessary for a style element'
|
|
2260
|
-
}
|
|
2261
|
-
}
|
|
2262
|
-
}
|
|
2263
|
-
},
|
|
2264
|
-
imageTextRedundant: {
|
|
2265
|
-
weight: 1,
|
|
2266
|
-
packages: {
|
|
2267
|
-
axe: {
|
|
2268
|
-
'image-redundant-alt': {
|
|
2269
|
-
quality: 1,
|
|
2270
|
-
what: 'Text of a button or link is repeated in the image alternative'
|
|
2271
|
-
}
|
|
2272
|
-
},
|
|
2273
|
-
ibm: {
|
|
2274
|
-
WCAG20_Img_LinkTextNotRedundant: {
|
|
2275
|
-
quality: 1,
|
|
2276
|
-
what: 'Text alternative for the image in a link repeats text of the same or an adjacent link'
|
|
2277
|
-
}
|
|
2278
|
-
},
|
|
2279
|
-
tenon: {
|
|
2280
|
-
138: {
|
|
2281
|
-
quality: 1,
|
|
2282
|
-
what: 'Image link alternative text repeats text in the link'
|
|
2283
|
-
}
|
|
2284
|
-
},
|
|
2285
|
-
wave: {
|
|
2286
|
-
'a:alt_redundant': {
|
|
2287
|
-
quality: 1,
|
|
2288
|
-
what: 'Redundant text alternative'
|
|
2289
|
-
}
|
|
2290
|
-
}
|
|
2291
|
-
}
|
|
2292
|
-
},
|
|
2293
|
-
decorativeTitle: {
|
|
2294
|
-
weight: 1,
|
|
2295
|
-
packages: {
|
|
2296
|
-
htmlcs: {
|
|
2297
|
-
'e:AA.1_1_1.H67.1': {
|
|
2298
|
-
quality: 1,
|
|
2299
|
-
what: 'img element has an empty alt attribute but has a nonempty title attribute'
|
|
2300
|
-
}
|
|
2301
|
-
},
|
|
2302
|
-
ibm: {
|
|
2303
|
-
WCAG20_Img_TitleEmptyWhenAltNull: {
|
|
2304
|
-
quality: 1,
|
|
2305
|
-
what: 'Image alt attribute is empty, but its title attribute is not'
|
|
2306
|
-
}
|
|
2307
|
-
},
|
|
2308
|
-
wave: {
|
|
2309
|
-
'a:image_title': {
|
|
2310
|
-
quality: 1,
|
|
2311
|
-
what: 'Image has a title attribute value but no alt value'
|
|
2312
|
-
}
|
|
2313
|
-
}
|
|
2314
|
-
}
|
|
2315
|
-
},
|
|
2316
|
-
titleRedundant: {
|
|
2317
|
-
weight: 1,
|
|
2318
|
-
packages: {
|
|
2319
|
-
tenon: {
|
|
2320
|
-
79: {
|
|
2321
|
-
quality: 1,
|
|
2322
|
-
what: 'Link has a title attribute that is the same as the text inside the link'
|
|
2323
|
-
}
|
|
2324
|
-
},
|
|
2325
|
-
wave: {
|
|
2326
|
-
'a:title_redundant': {
|
|
2327
|
-
quality: 1,
|
|
2328
|
-
what: 'Title attribute text is the same as text or alternative text'
|
|
2329
|
-
}
|
|
2330
|
-
}
|
|
2331
|
-
}
|
|
2332
|
-
},
|
|
2333
|
-
titleEmpty: {
|
|
2334
|
-
weight: 1,
|
|
2335
|
-
packages: {
|
|
2336
|
-
htmlcs: {
|
|
2337
|
-
'w:AA.1_3_1.H65': {
|
|
2338
|
-
quality: 0.5,
|
|
2339
|
-
what: 'Value of the title attribute of the form control is empty or only whitespace'
|
|
2340
|
-
},
|
|
2341
|
-
'w:AA.4_1_2.H65': {
|
|
2342
|
-
quality: 0.5,
|
|
2343
|
-
what: 'Value of the title attribute of the form control is empty or only whitespace'
|
|
2344
|
-
}
|
|
2345
|
-
}
|
|
2346
|
-
}
|
|
2347
|
-
},
|
|
2348
|
-
docType: {
|
|
2349
|
-
weight: 3,
|
|
2350
|
-
packages: {
|
|
2351
|
-
nuVal: {
|
|
2352
|
-
'Start tag seen without seeing a doctype first. Expected <!DOCTYPE html>.': {
|
|
2353
|
-
quality: 1,
|
|
2354
|
-
what: 'Page does not start with <!DOCTYPE html>'
|
|
2355
|
-
}
|
|
2356
|
-
},
|
|
2357
|
-
testaro: {
|
|
2358
|
-
docType: {
|
|
2359
|
-
quality: 1,
|
|
2360
|
-
what: 'document has no doctype property'
|
|
2361
|
-
}
|
|
2362
|
-
}
|
|
2363
|
-
}
|
|
2364
|
-
},
|
|
2365
|
-
pageTitle: {
|
|
2366
|
-
weight: 3,
|
|
2367
|
-
packages: {
|
|
2368
|
-
alfa: {
|
|
2369
|
-
r1: {
|
|
2370
|
-
quality: 1,
|
|
2371
|
-
what: 'Document has no valid title element'
|
|
2372
|
-
}
|
|
2373
|
-
},
|
|
2374
|
-
axe: {
|
|
2375
|
-
'document-title': {
|
|
2376
|
-
quality: 1,
|
|
2377
|
-
what: 'Document contains no title element'
|
|
2378
|
-
}
|
|
2379
|
-
},
|
|
2380
|
-
continuum: {
|
|
2381
|
-
884: {
|
|
2382
|
-
quality: 1,
|
|
2383
|
-
what: 'DOM contains no document title element'
|
|
2384
|
-
}
|
|
2385
|
-
},
|
|
2386
|
-
htmlcs: {
|
|
2387
|
-
'e:AA.2_4_2.H25.1.NoTitleEl': {
|
|
2388
|
-
quality: 1,
|
|
2389
|
-
what: 'Document head element contains no non-empty title element'
|
|
2390
|
-
}
|
|
2391
|
-
},
|
|
2392
|
-
ibm: {
|
|
2393
|
-
WCAG20_Doc_HasTitle: {
|
|
2394
|
-
quality: 1,
|
|
2395
|
-
what: 'Page has no subject-identifying title'
|
|
2396
|
-
}
|
|
2397
|
-
},
|
|
2398
|
-
nuVal: {
|
|
2399
|
-
'Element head is missing a required instance of child element title.': {
|
|
2400
|
-
quality: 1,
|
|
2401
|
-
what: 'head element has no child title element'
|
|
2402
|
-
}
|
|
2403
|
-
},
|
|
2404
|
-
wave: {
|
|
2405
|
-
'e:title_invalid': {
|
|
2406
|
-
quality: 1,
|
|
2407
|
-
what: 'Missing or uninformative page title'
|
|
2408
|
-
}
|
|
2409
|
-
}
|
|
2410
|
-
}
|
|
2411
|
-
},
|
|
2412
|
-
headingStructure: {
|
|
2413
|
-
weight: 2,
|
|
2414
|
-
packages: {
|
|
2415
|
-
alfa: {
|
|
2416
|
-
r53: {
|
|
2417
|
-
quality: 1,
|
|
2418
|
-
what: 'Heading skips one or more levels'
|
|
2419
|
-
}
|
|
2420
|
-
},
|
|
2421
|
-
axe: {
|
|
2422
|
-
'heading-order': {
|
|
2423
|
-
quality: 1,
|
|
2424
|
-
what: 'Heading levels do not increase by only one'
|
|
2425
|
-
}
|
|
2426
|
-
},
|
|
2427
|
-
htmlcs: {
|
|
2428
|
-
'w:AA.1_3_1_A.G141': {
|
|
2429
|
-
quality: 1,
|
|
2430
|
-
what: 'Heading level is incorrect'
|
|
2431
|
-
}
|
|
2432
|
-
},
|
|
2433
|
-
nuVal: {
|
|
2434
|
-
'Consider using the h1 element as a top-level heading only (all h1 elements are treated as top-level headings by many screen readers and other tools).': {
|
|
2435
|
-
quality: 1,
|
|
2436
|
-
what: 'Page contains more than 1 h1 element'
|
|
2437
|
-
}
|
|
2438
|
-
},
|
|
2439
|
-
tenon: {
|
|
2440
|
-
155: {
|
|
2441
|
-
quality: 1,
|
|
2442
|
-
what: 'Headings are not structured in a hierarchical manner'
|
|
2443
|
-
}
|
|
2444
|
-
},
|
|
2445
|
-
wave: {
|
|
2446
|
-
'a:heading_skipped': {
|
|
2447
|
-
quality: 1,
|
|
2448
|
-
what: 'Skipped heading level'
|
|
2449
|
-
}
|
|
2450
|
-
}
|
|
2451
|
-
}
|
|
2452
|
-
},
|
|
2453
|
-
headingLevelless: {
|
|
2454
|
-
weight: 1,
|
|
2455
|
-
packages: {
|
|
2456
|
-
continuum: {
|
|
2457
|
-
71: {
|
|
2458
|
-
quality: 1,
|
|
2459
|
-
what: 'element with a heading role has no aria-level attribute'
|
|
2460
|
-
}
|
|
2461
|
-
}
|
|
2462
|
-
}
|
|
2463
|
-
},
|
|
2464
|
-
noHeading: {
|
|
2465
|
-
weight: 3,
|
|
2466
|
-
packages: {
|
|
2467
|
-
alfa: {
|
|
2468
|
-
r59: {
|
|
2469
|
-
quality: 1,
|
|
2470
|
-
what: 'Document has no headings'
|
|
2471
|
-
}
|
|
2472
|
-
},
|
|
2473
|
-
wave: {
|
|
2474
|
-
'a:heading_missing': {
|
|
2475
|
-
quality: 1,
|
|
2476
|
-
what: 'Page has no headings'
|
|
2477
|
-
}
|
|
2478
|
-
}
|
|
2479
|
-
}
|
|
2480
|
-
},
|
|
2481
|
-
h1Missing: {
|
|
2482
|
-
weight: 2,
|
|
2483
|
-
packages: {
|
|
2484
|
-
alfa: {
|
|
2485
|
-
r61: {
|
|
2486
|
-
quality: 1,
|
|
2487
|
-
what: 'First heading is not h1'
|
|
2488
|
-
}
|
|
2489
|
-
},
|
|
2490
|
-
axe: {
|
|
2491
|
-
'page-has-heading-one': {
|
|
2492
|
-
quality: 1,
|
|
2493
|
-
what: 'Page contains no level-one heading'
|
|
2494
|
-
}
|
|
2495
|
-
},
|
|
2496
|
-
wave: {
|
|
2497
|
-
'a:h1_missing': {
|
|
2498
|
-
quality: 1,
|
|
2499
|
-
what: 'Missing first level heading'
|
|
2500
|
-
}
|
|
2501
|
-
}
|
|
2502
|
-
}
|
|
2503
|
-
},
|
|
2504
|
-
articleHeadingless: {
|
|
2505
|
-
weight: 1,
|
|
2506
|
-
packages: {
|
|
2507
|
-
nuVal: {
|
|
2508
|
-
'Article lacks heading. Consider using h2-h6 elements to add identifying headings to all articles.': {
|
|
2509
|
-
quality: 1,
|
|
2510
|
-
what: 'article has no heading'
|
|
2511
|
-
}
|
|
2512
|
-
}
|
|
2513
|
-
}
|
|
2514
|
-
},
|
|
2515
|
-
sectionHeadingless: {
|
|
2516
|
-
weight: 1,
|
|
2517
|
-
packages: {
|
|
2518
|
-
nuVal: {
|
|
2519
|
-
'Section lacks heading. Consider using h2-h6 elements to add identifying headings to all sections.': {
|
|
2520
|
-
quality: 1,
|
|
2521
|
-
what: 'section has no heading'
|
|
2522
|
-
},
|
|
2523
|
-
'Section lacks heading. Consider using h2-h6 elements to add identifying headings to all sections, or else use a div element instead for any cases where no heading is needed.': {
|
|
2524
|
-
quality: 1,
|
|
2525
|
-
what: 'section has no heading'
|
|
2526
|
-
}
|
|
2527
|
-
}
|
|
2528
|
-
}
|
|
2529
|
-
},
|
|
2530
|
-
justification: {
|
|
2531
|
-
weight: 1,
|
|
2532
|
-
packages: {
|
|
2533
|
-
alfa: {
|
|
2534
|
-
r71: {
|
|
2535
|
-
quality: 1,
|
|
2536
|
-
what: 'Paragraph text is fully justified'
|
|
2537
|
-
}
|
|
2538
|
-
},
|
|
2539
|
-
tenon: {
|
|
2540
|
-
36: {
|
|
2541
|
-
quality: 1,
|
|
2542
|
-
what: 'Text is fully justified'
|
|
2543
|
-
}
|
|
2544
|
-
},
|
|
2545
|
-
wave: {
|
|
2546
|
-
'a:text_justified': {
|
|
2547
|
-
quality: 1,
|
|
2548
|
-
what: 'Text is justified'
|
|
2549
|
-
}
|
|
2550
|
-
}
|
|
2551
|
-
}
|
|
2552
|
-
},
|
|
2553
|
-
nonSemanticText: {
|
|
2554
|
-
weight: 2,
|
|
2555
|
-
packages: {
|
|
2556
|
-
htmlcs: {
|
|
2557
|
-
'w:AA.1_3_1.H49.AlignAttr': {
|
|
2558
|
-
quality: 1,
|
|
2559
|
-
what: 'Special text is aligned nonsemantically'
|
|
2560
|
-
},
|
|
2561
|
-
'w:AA.1_3_1.H49.B': {
|
|
2562
|
-
quality: 1,
|
|
2563
|
-
what: 'Special text is bolded nonsemantically'
|
|
2564
|
-
},
|
|
2565
|
-
'w:AA.1_3_1.H49.I': {
|
|
2566
|
-
quality: 1,
|
|
2567
|
-
what: 'Special text is italicized nonsemantically'
|
|
2568
|
-
},
|
|
2569
|
-
'w:AA.1_3_1.H49.Big': {
|
|
2570
|
-
quality: 1,
|
|
2571
|
-
what: 'Special text is enlarged nonsemantically'
|
|
2572
|
-
},
|
|
2573
|
-
'w:AA.1_3_1.H49.Small': {
|
|
2574
|
-
quality: 1,
|
|
2575
|
-
what: 'Special text is made small nonsemantically'
|
|
2576
|
-
},
|
|
2577
|
-
'w:AA.1_3_1.H49.U': {
|
|
2578
|
-
quality: 1,
|
|
2579
|
-
what: 'Special text is underlined nonsemantically'
|
|
2580
|
-
},
|
|
2581
|
-
'w:AA.1_3_1.H49.Center': {
|
|
2582
|
-
quality: 1,
|
|
2583
|
-
what: 'Special text is centered nonsemantically'
|
|
2584
|
-
},
|
|
2585
|
-
'w:AA.1_3_1.H49.Font': {
|
|
2586
|
-
quality: 1,
|
|
2587
|
-
what: 'Special text is designated nonsemantically with a (deprecated) font element'
|
|
2588
|
-
}
|
|
2589
|
-
}
|
|
2590
|
-
}
|
|
2591
|
-
},
|
|
2592
|
-
pseudoParagraphRisk: {
|
|
2593
|
-
weight: 1,
|
|
2594
|
-
packages: {
|
|
2595
|
-
tenon: {
|
|
2596
|
-
242: {
|
|
2597
|
-
quality: 1,
|
|
2598
|
-
what: 'Multiple consecutive br elements may simulate paragraphs'
|
|
2599
|
-
}
|
|
2600
|
-
}
|
|
2601
|
-
}
|
|
2602
|
-
},
|
|
2603
|
-
pseudoHeadingRisk: {
|
|
2604
|
-
weight: 1,
|
|
2605
|
-
packages: {
|
|
2606
|
-
axe: {
|
|
2607
|
-
'p-as-heading': {
|
|
2608
|
-
quality: 1,
|
|
2609
|
-
what: 'Styled p element may be misused as a heading'
|
|
2610
|
-
}
|
|
2611
|
-
},
|
|
2612
|
-
htmlcs: {
|
|
2613
|
-
'w:AA.1_3_1.H42': {
|
|
2614
|
-
quality: 1,
|
|
2615
|
-
what: 'Heading coding is not used but the element may be intended as a heading'
|
|
2616
|
-
}
|
|
2617
|
-
},
|
|
2618
|
-
wave: {
|
|
2619
|
-
'a:heading_possible': {
|
|
2620
|
-
quality: 1,
|
|
2621
|
-
what: 'Possible heading'
|
|
2622
|
-
}
|
|
2623
|
-
}
|
|
2624
|
-
}
|
|
2625
|
-
},
|
|
2626
|
-
pseudoLinkRisk: {
|
|
2627
|
-
weight: 1,
|
|
2628
|
-
packages: {
|
|
2629
|
-
tenon: {
|
|
2630
|
-
129: {
|
|
2631
|
-
quality: 1,
|
|
2632
|
-
what: 'CSS underline on text that is not a link'
|
|
2633
|
-
}
|
|
2634
|
-
},
|
|
2635
|
-
wave: {
|
|
2636
|
-
'a:underline': {
|
|
2637
|
-
quality: 1,
|
|
2638
|
-
what: 'CSS underline on text that is not a link'
|
|
2639
|
-
}
|
|
2640
|
-
}
|
|
2641
|
-
}
|
|
2642
|
-
},
|
|
2643
|
-
listChild: {
|
|
2644
|
-
weight: 4,
|
|
2645
|
-
packages: {
|
|
2646
|
-
axe: {
|
|
2647
|
-
list: {
|
|
2648
|
-
quality: 1,
|
|
2649
|
-
what: 'List element ul or ol has a child element other than li, script, and template'
|
|
2650
|
-
},
|
|
2651
|
-
'definition-list': {
|
|
2652
|
-
quality: 1,
|
|
2653
|
-
what: 'List element dl has a child element other than properly ordered dt and dt group, script, template, and div'
|
|
2654
|
-
}
|
|
2655
|
-
},
|
|
2656
|
-
continuum: {
|
|
2657
|
-
246: {
|
|
2658
|
-
quality: 1,
|
|
2659
|
-
what: 'ul element does not contain only li, script, template, or listitem-role elements as direct child elements'
|
|
2660
|
-
}
|
|
2661
|
-
},
|
|
2662
|
-
ibm: {
|
|
2663
|
-
HAAC_List_Group_ListItem: {
|
|
2664
|
-
quality: 1,
|
|
2665
|
-
what: 'List component with a group role has a non-listitem child'
|
|
2666
|
-
}
|
|
2667
|
-
},
|
|
2668
|
-
nuVal: {
|
|
2669
|
-
'Element dl is missing a required child element.': {
|
|
2670
|
-
quality: 1,
|
|
2671
|
-
what: 'dl element has no child element.'
|
|
2672
|
-
}
|
|
2673
|
-
}
|
|
2674
|
-
}
|
|
2675
|
-
},
|
|
2676
|
-
listItemOrphan: {
|
|
2677
|
-
weight: 4,
|
|
2678
|
-
packages: {
|
|
2679
|
-
axe: {
|
|
2680
|
-
listitem: {
|
|
2681
|
-
quality: 1,
|
|
2682
|
-
what: 'li element is not contained by a ul or ol element'
|
|
2683
|
-
}
|
|
2684
|
-
},
|
|
2685
|
-
continuum: {
|
|
2686
|
-
99: {
|
|
2687
|
-
quality: 1,
|
|
2688
|
-
what: 'li element has no ul, ol, or list-role parent'
|
|
2689
|
-
},
|
|
2690
|
-
385: {
|
|
2691
|
-
quality: 1,
|
|
2692
|
-
what: 'list item has no ul, ol, or list-role parent or owner'
|
|
2693
|
-
}
|
|
2694
|
-
},
|
|
2695
|
-
nuVal: {
|
|
2696
|
-
'Element li not allowed as child of element div in this context. (Suppressing further errors from this subtree.)': {
|
|
2697
|
-
quality: 1,
|
|
2698
|
-
what: 'li element is a child of a div element'
|
|
2699
|
-
}
|
|
2700
|
-
}
|
|
2701
|
-
}
|
|
2702
|
-
},
|
|
2703
|
-
pseudoOrderedListRisk: {
|
|
2704
|
-
weight: 1,
|
|
2705
|
-
packages: {
|
|
2706
|
-
htmlcs: {
|
|
2707
|
-
'w:AA.1_3_1.H48.2': {
|
|
2708
|
-
quality: 1,
|
|
2709
|
-
what: 'Ordered list may fail to be coded as such'
|
|
2710
|
-
}
|
|
2711
|
-
}
|
|
2712
|
-
}
|
|
2713
|
-
},
|
|
2714
|
-
pseudoNavListRisk: {
|
|
2715
|
-
weight: 1,
|
|
2716
|
-
packages: {
|
|
2717
|
-
htmlcs: {
|
|
2718
|
-
'w:AA.1_3_1.H48': {
|
|
2719
|
-
quality: 1,
|
|
2720
|
-
what: 'Navigation links are not coded as a list'
|
|
2721
|
-
}
|
|
2722
|
-
}
|
|
2723
|
-
}
|
|
2724
|
-
},
|
|
2725
|
-
selectNoText: {
|
|
2726
|
-
weight: 3,
|
|
2727
|
-
packages: {
|
|
2728
|
-
axe: {
|
|
2729
|
-
'select-name': {
|
|
2730
|
-
quality: 1,
|
|
2731
|
-
what: 'select element has no accessible name'
|
|
2732
|
-
}
|
|
2733
|
-
},
|
|
2734
|
-
continuum: {
|
|
2735
|
-
114: {
|
|
2736
|
-
quality: 1,
|
|
2737
|
-
what: 'select element has no mechanism that allows an accessible name to be calculated'
|
|
2738
|
-
}
|
|
2739
|
-
},
|
|
2740
|
-
htmlcs: {
|
|
2741
|
-
'e:AA.4_1_2.H91.Select.Name': {
|
|
2742
|
-
quality: 1,
|
|
2743
|
-
what: 'Select element has no accessible name'
|
|
2744
|
-
},
|
|
2745
|
-
'w:AA.4_1_2.H91.Select.Value': {
|
|
2746
|
-
quality: 1,
|
|
2747
|
-
what: 'Select element value has no accessible name'
|
|
2748
|
-
}
|
|
2749
|
-
},
|
|
2750
|
-
wave: {
|
|
2751
|
-
'a:select_missing_label': {
|
|
2752
|
-
quality: 1,
|
|
2753
|
-
what: 'Select element has no label'
|
|
2754
|
-
}
|
|
2755
|
-
}
|
|
2756
|
-
}
|
|
2757
|
-
},
|
|
2758
|
-
optionOrphan: {
|
|
2759
|
-
weight: 4,
|
|
2760
|
-
packages: {
|
|
2761
|
-
nuVal: {
|
|
2762
|
-
'An element with role=option must be contained in, or owned by, an element with role=listbox.': {
|
|
2763
|
-
quality: 1,
|
|
2764
|
-
what: 'element with an option role is not contained by an element with a listbox role'
|
|
2765
|
-
}
|
|
2766
|
-
}
|
|
2767
|
-
}
|
|
2768
|
-
},
|
|
2769
|
-
optionNoText: {
|
|
2770
|
-
weight: 4,
|
|
2771
|
-
packages: {
|
|
2772
|
-
nuVal: {
|
|
2773
|
-
'Element option without attribute label must not be empty.': {
|
|
2774
|
-
quality: 1,
|
|
2775
|
-
what: 'option element is empty but has no label attribute'
|
|
2776
|
-
}
|
|
2777
|
-
}
|
|
2778
|
-
}
|
|
2779
|
-
},
|
|
2780
|
-
selectFlatRisk: {
|
|
2781
|
-
weight: 1,
|
|
2782
|
-
packages: {
|
|
2783
|
-
htmlcs: {
|
|
2784
|
-
'w:AA.1_3_1.H85.2': {
|
|
2785
|
-
quality: 1,
|
|
2786
|
-
what: 'Selection list may contain groups of related options that are not grouped with optgroup'
|
|
2787
|
-
}
|
|
2788
|
-
}
|
|
2789
|
-
}
|
|
2790
|
-
},
|
|
2791
|
-
accessKeyDuplicate: {
|
|
2792
|
-
weight: 3,
|
|
2793
|
-
packages: {
|
|
2794
|
-
axe: {
|
|
2795
|
-
accesskeys: {
|
|
2796
|
-
quality: 1,
|
|
2797
|
-
what: 'accesskey attribute value is not unique'
|
|
2798
|
-
}
|
|
2799
|
-
},
|
|
2800
|
-
ibm: {
|
|
2801
|
-
WCAG20_Elem_UniqueAccessKey: {
|
|
2802
|
-
quality: 1,
|
|
2803
|
-
what: 'Accesskey attribute value on an element is not unique for the page'
|
|
2804
|
-
}
|
|
2805
|
-
},
|
|
2806
|
-
tenon: {
|
|
2807
|
-
101: {
|
|
2808
|
-
quality: 1,
|
|
2809
|
-
what: 'Duplicate accesskey value'
|
|
2810
|
-
}
|
|
2811
|
-
},
|
|
2812
|
-
wave: {
|
|
2813
|
-
'a:accesskey': {
|
|
2814
|
-
quality: 1,
|
|
2815
|
-
what: 'Accesskey'
|
|
2816
|
-
}
|
|
2817
|
-
}
|
|
2818
|
-
}
|
|
2819
|
-
},
|
|
2820
|
-
fieldSetMissing: {
|
|
2821
|
-
weight: 2,
|
|
2822
|
-
packages: {
|
|
2823
|
-
ibm: {
|
|
2824
|
-
WCAG20_Input_RadioChkInFieldSet: {
|
|
2825
|
-
quality: 1,
|
|
2826
|
-
what: 'Input is in a different group than another with the name'
|
|
2827
|
-
}
|
|
2828
|
-
},
|
|
2829
|
-
testaro: {
|
|
2830
|
-
radioSet: {
|
|
2831
|
-
quality: 1,
|
|
2832
|
-
what: 'No or invalid grouping of radio buttons in fieldsets'
|
|
2833
|
-
}
|
|
2834
|
-
},
|
|
2835
|
-
wave: {
|
|
2836
|
-
'a:fieldset_missing': {
|
|
2837
|
-
quality: 1,
|
|
2838
|
-
what: 'fieldset element is missing'
|
|
2839
|
-
}
|
|
2840
|
-
}
|
|
2841
|
-
}
|
|
2842
|
-
},
|
|
2843
|
-
fieldSetRisk: {
|
|
2844
|
-
weight: 1,
|
|
2845
|
-
packages: {
|
|
2846
|
-
htmlcs: {
|
|
2847
|
-
'w:AA.1_3_1.H71.SameName': {
|
|
2848
|
-
quality: 1,
|
|
2849
|
-
what: 'Radio buttons or check boxes may require a group description via a fieldset element'
|
|
2850
|
-
}
|
|
2851
|
-
}
|
|
2852
|
-
}
|
|
2853
|
-
},
|
|
2854
|
-
legendMissing: {
|
|
2855
|
-
weight: 2,
|
|
2856
|
-
packages: {
|
|
2857
|
-
htmlcs: {
|
|
2858
|
-
'e:AA.1_3_1.H71.NoLegend': {
|
|
2859
|
-
quality: 1,
|
|
2860
|
-
what: 'Fieldset has no legend element'
|
|
2861
|
-
}
|
|
2862
|
-
},
|
|
2863
|
-
ibm: {
|
|
2864
|
-
WCAG20_Fieldset_HasLegend: {
|
|
2865
|
-
quality: 1,
|
|
2866
|
-
what: 'fieldset element has no single, non-empty legend as a label'
|
|
2867
|
-
}
|
|
2868
|
-
},
|
|
2869
|
-
wave: {
|
|
2870
|
-
'a:legend_missing': {
|
|
2871
|
-
quality: 1,
|
|
2872
|
-
what: 'Fieldset has no legend element'
|
|
2873
|
-
}
|
|
2874
|
-
}
|
|
2875
|
-
}
|
|
2876
|
-
},
|
|
2877
|
-
groupName: {
|
|
2878
|
-
weight: 3,
|
|
2879
|
-
packages: {
|
|
2880
|
-
alfa: {
|
|
2881
|
-
r60: {
|
|
2882
|
-
quality: 1,
|
|
2883
|
-
what: 'Form-control group has no accessible name'
|
|
2884
|
-
}
|
|
2885
|
-
},
|
|
2886
|
-
htmlcs: {
|
|
2887
|
-
'e:AA.4_1_2.H91.Fieldset.Name': {
|
|
2888
|
-
quality: 1,
|
|
2889
|
-
what: 'Fieldset has no accessible name'
|
|
2890
|
-
}
|
|
2891
|
-
}
|
|
2892
|
-
}
|
|
2893
|
-
},
|
|
2894
|
-
layoutTable: {
|
|
2895
|
-
weight: 2,
|
|
2896
|
-
packages: {
|
|
2897
|
-
testaro: {
|
|
2898
|
-
nonTable: {
|
|
2899
|
-
quality: 1,
|
|
2900
|
-
what: 'table element fails the structural requirements for tabular data'
|
|
2901
|
-
}
|
|
2902
|
-
},
|
|
2903
|
-
wave: {
|
|
2904
|
-
'a:table_layout': {
|
|
2905
|
-
quality: 1,
|
|
2906
|
-
what: 'table element is misused to arrange content'
|
|
2907
|
-
}
|
|
2908
|
-
}
|
|
2909
|
-
}
|
|
2910
|
-
},
|
|
2911
|
-
tableCaption: {
|
|
2912
|
-
weight: 1,
|
|
2913
|
-
packages: {
|
|
2914
|
-
axe: {
|
|
2915
|
-
'table-fake-caption': {
|
|
2916
|
-
quality: 1,
|
|
2917
|
-
what: 'Data or header cells are used for a table caption instead of a caption element'
|
|
2918
|
-
}
|
|
2919
|
-
},
|
|
2920
|
-
htmlcs: {
|
|
2921
|
-
'w:AA.1_3_1.H39.3.NoCaption': {
|
|
2922
|
-
quality: 1,
|
|
2923
|
-
what: 'Table has no caption element'
|
|
2924
|
-
}
|
|
2925
|
-
}
|
|
2926
|
-
}
|
|
2927
|
-
},
|
|
2928
|
-
cellHeadersNotInferrable: {
|
|
2929
|
-
weight: 4,
|
|
2930
|
-
packages: {
|
|
2931
|
-
htmlcs: {
|
|
2932
|
-
'e:AA.1_3_1.H43.HeadersRequired': {
|
|
2933
|
-
quality: 1,
|
|
2934
|
-
what: 'Complex table requires headers attributes of cells'
|
|
2935
|
-
}
|
|
2936
|
-
},
|
|
2937
|
-
ibm: {
|
|
2938
|
-
Valerie_Table_DataCellRelationships: {
|
|
2939
|
-
quality: 1,
|
|
2940
|
-
what: 'Not all th and td elements in the complex table have header or scope attributes'
|
|
2941
|
-
}
|
|
2942
|
-
}
|
|
2943
|
-
}
|
|
2944
|
-
},
|
|
2945
|
-
cellHeadersAmbiguityRisk: {
|
|
2946
|
-
weight: 2,
|
|
2947
|
-
packages: {
|
|
2948
|
-
htmlcs: {
|
|
2949
|
-
'w:AA.1_3_1.H43.ScopeAmbiguous': {
|
|
2950
|
-
quality: 1,
|
|
2951
|
-
what: 'Complex table requires headers attributes of cells instead of header scopes'
|
|
2952
|
-
}
|
|
2953
|
-
}
|
|
2954
|
-
}
|
|
2955
|
-
},
|
|
2956
|
-
tableHeaderless: {
|
|
2957
|
-
weight: 3,
|
|
2958
|
-
packages: {
|
|
2959
|
-
continuum: {
|
|
2960
|
-
387: {
|
|
2961
|
-
quality: 1,
|
|
2962
|
-
what: 'table element contains no th element or element with a rowheader or columnheader role'
|
|
2963
|
-
}
|
|
2964
|
-
},
|
|
2965
|
-
ibm: {
|
|
2966
|
-
RPT_Table_DataHeadingsAria: {
|
|
2967
|
-
quality: 1,
|
|
2968
|
-
what: 'Data table does not identify headers'
|
|
2969
|
-
}
|
|
2970
|
-
}
|
|
2971
|
-
}
|
|
2972
|
-
},
|
|
2973
|
-
tableCellHeaderless: {
|
|
2974
|
-
weight: 3,
|
|
2975
|
-
packages: {
|
|
2976
|
-
alfa: {
|
|
2977
|
-
r77: {
|
|
2978
|
-
quality: 1,
|
|
2979
|
-
what: 'Table cell has no header'
|
|
2980
|
-
}
|
|
2981
|
-
},
|
|
2982
|
-
axe: {
|
|
2983
|
-
'td-has-header': {
|
|
2984
|
-
quality: 1,
|
|
2985
|
-
what: 'Cell in table larger than 3 by 3 has no header'
|
|
2986
|
-
}
|
|
2987
|
-
}
|
|
2988
|
-
}
|
|
2989
|
-
},
|
|
2990
|
-
tableHeaderCelless: {
|
|
2991
|
-
weight: 4,
|
|
2992
|
-
packages: {
|
|
2993
|
-
alfa: {
|
|
2994
|
-
r46: {
|
|
2995
|
-
quality: 1,
|
|
2996
|
-
what: 'Header cell is not assigned to any cell'
|
|
2997
|
-
}
|
|
2998
|
-
},
|
|
2999
|
-
axe: {
|
|
3000
|
-
'th-has-data-cells': {
|
|
3001
|
-
quality: 1,
|
|
3002
|
-
what: 'Table header refers to no cell'
|
|
3003
|
-
}
|
|
3004
|
-
}
|
|
3005
|
-
}
|
|
3006
|
-
},
|
|
3007
|
-
TableHeaderScopeRisk: {
|
|
3008
|
-
weight: 1,
|
|
3009
|
-
packages: {
|
|
3010
|
-
htmlcs: {
|
|
3011
|
-
'e:AA.1_3_1.H63.1': {
|
|
3012
|
-
quality: 1,
|
|
3013
|
-
what: 'Not all th elements in the table have a scope attribute, so an inferred scope may be incorrect'
|
|
3014
|
-
}
|
|
3015
|
-
}
|
|
3016
|
-
}
|
|
3017
|
-
},
|
|
3018
|
-
tableHeaderEmpty: {
|
|
3019
|
-
weight: 2,
|
|
3020
|
-
packages: {
|
|
3021
|
-
wave: {
|
|
3022
|
-
'e:th_empty': {
|
|
3023
|
-
quality: 1,
|
|
3024
|
-
what: 'th (table header) contains no text'
|
|
3025
|
-
}
|
|
3026
|
-
}
|
|
3027
|
-
}
|
|
3028
|
-
},
|
|
3029
|
-
controlNoText: {
|
|
3030
|
-
weight: 4,
|
|
3031
|
-
packages: {
|
|
3032
|
-
axe: {
|
|
3033
|
-
label: {
|
|
3034
|
-
quality: 1,
|
|
3035
|
-
what: 'Form element has no label'
|
|
3036
|
-
}
|
|
3037
|
-
},
|
|
3038
|
-
htmlcs: {
|
|
3039
|
-
'e:AA.1_3_1.F68': {
|
|
3040
|
-
quality: 1,
|
|
3041
|
-
what: 'Form control has no label'
|
|
3042
|
-
}
|
|
3043
|
-
},
|
|
3044
|
-
ibm: {
|
|
3045
|
-
WCAG20_Input_ExplicitLabel: {
|
|
3046
|
-
quality: 1,
|
|
3047
|
-
what: 'Form control has no associated label'
|
|
3048
|
-
}
|
|
3049
|
-
},
|
|
3050
|
-
wave: {
|
|
3051
|
-
'e:label_missing': {
|
|
3052
|
-
quality: 1,
|
|
3053
|
-
what: 'form element has no label'
|
|
3054
|
-
}
|
|
3055
|
-
}
|
|
3056
|
-
}
|
|
3057
|
-
},
|
|
3058
|
-
controlLabelInvisible: {
|
|
3059
|
-
weight: 4,
|
|
3060
|
-
packages: {
|
|
3061
|
-
axe: {
|
|
3062
|
-
'label-title-only': {
|
|
3063
|
-
quality: 1,
|
|
3064
|
-
what: 'Form element has no visible label'
|
|
3065
|
-
}
|
|
3066
|
-
}
|
|
3067
|
-
}
|
|
3068
|
-
},
|
|
3069
|
-
titleAsLabel: {
|
|
3070
|
-
weight: 3,
|
|
3071
|
-
packages: {
|
|
3072
|
-
wave: {
|
|
3073
|
-
'a:label_title': {
|
|
3074
|
-
quality: 1,
|
|
3075
|
-
what: 'Form control has a title but no label'
|
|
3076
|
-
}
|
|
3077
|
-
}
|
|
3078
|
-
}
|
|
3079
|
-
},
|
|
3080
|
-
visibleLabelNotName: {
|
|
3081
|
-
weight: 3,
|
|
3082
|
-
packages: {
|
|
3083
|
-
alfa: {
|
|
3084
|
-
r14: {
|
|
3085
|
-
quality: 1,
|
|
3086
|
-
what: 'Visible label is not in the accessible name'
|
|
3087
|
-
}
|
|
3088
|
-
},
|
|
3089
|
-
axe: {
|
|
3090
|
-
'label-content-name-mismatch': {
|
|
3091
|
-
quality: 1,
|
|
3092
|
-
what: 'Element visible text is not part of its accessible name'
|
|
3093
|
-
}
|
|
3094
|
-
},
|
|
3095
|
-
htmlcs: {
|
|
3096
|
-
'w:AA.2_5_3.F96': {
|
|
3097
|
-
quality: 1,
|
|
3098
|
-
what: 'Visible label is not in the accessible name'
|
|
3099
|
-
}
|
|
3100
|
-
},
|
|
3101
|
-
ibm: {
|
|
3102
|
-
WCAG21_Label_Accessible: {
|
|
3103
|
-
quality: 1,
|
|
3104
|
-
what: 'Accessible name does not match or contain the visible label text'
|
|
3105
|
-
}
|
|
3106
|
-
}
|
|
3107
|
-
}
|
|
3108
|
-
},
|
|
3109
|
-
targetSize: {
|
|
3110
|
-
weight: 3,
|
|
3111
|
-
packages: {
|
|
3112
|
-
tenon: {
|
|
3113
|
-
152: {
|
|
3114
|
-
quality: 1,
|
|
3115
|
-
what: 'Actionable element is smaller than the minimum required size'
|
|
3116
|
-
}
|
|
3117
|
-
}
|
|
3118
|
-
}
|
|
3119
|
-
},
|
|
3120
|
-
visibleBulk: {
|
|
3121
|
-
weight: 1,
|
|
3122
|
-
packages: {
|
|
3123
|
-
testaro: {
|
|
3124
|
-
bulk: {
|
|
3125
|
-
quality: 1,
|
|
3126
|
-
what: 'Page contains many visible elements'
|
|
3127
|
-
}
|
|
3128
|
-
}
|
|
3129
|
-
}
|
|
3130
|
-
},
|
|
3131
|
-
activeEmbedding: {
|
|
3132
|
-
weight: 3,
|
|
3133
|
-
packages: {
|
|
3134
|
-
axe: {
|
|
3135
|
-
'nested-interactive': {
|
|
3136
|
-
quality: 1,
|
|
3137
|
-
what: 'Interactive controls are nested'
|
|
3138
|
-
}
|
|
3139
|
-
},
|
|
3140
|
-
continuum: {
|
|
3141
|
-
22: {
|
|
3142
|
-
quality: 1,
|
|
3143
|
-
what: 'Link contains an input, keygen, select, textarea, or button'
|
|
3144
|
-
}
|
|
3145
|
-
},
|
|
3146
|
-
nuVal: {
|
|
3147
|
-
'The element a must not appear as a descendant of an element with the attribute role=link.': {
|
|
3148
|
-
quality: 1,
|
|
3149
|
-
what: 'a element is a descendant of an element with a link role'
|
|
3150
|
-
},
|
|
3151
|
-
'An element with the attribute tabindex must not appear as a descendant of the a element.': {
|
|
3152
|
-
quality: 1,
|
|
3153
|
-
what: 'descendant of an a element has a tabindex attribute'
|
|
3154
|
-
},
|
|
3155
|
-
'An element with the attribute tabindex must not appear as a descendant of an element with the attribute role=link.': {
|
|
3156
|
-
quality: 1,
|
|
3157
|
-
what: 'descendant of an element with a link role has a tabindex attribute'
|
|
3158
|
-
}
|
|
3159
|
-
},
|
|
3160
|
-
testaro: {
|
|
3161
|
-
embAc: {
|
|
3162
|
-
quality: 1,
|
|
3163
|
-
what: 'Active element is embedded in a link or button'
|
|
3164
|
-
}
|
|
3165
|
-
}
|
|
3166
|
-
}
|
|
3167
|
-
},
|
|
3168
|
-
tabFocusability: {
|
|
3169
|
-
weight: 4,
|
|
3170
|
-
packages: {
|
|
3171
|
-
ibm: {
|
|
3172
|
-
Rpt_Aria_MissingFocusableChild: {
|
|
3173
|
-
quality: 1,
|
|
3174
|
-
what: 'UI component has no focusable child element for keyboard access'
|
|
3175
|
-
}
|
|
3176
|
-
},
|
|
3177
|
-
testaro: {
|
|
3178
|
-
focAll: {
|
|
3179
|
-
quality: 0.5,
|
|
3180
|
-
what: 'Discrepancy between elements that should be and that are Tab-focusable'
|
|
3181
|
-
}
|
|
3182
|
-
}
|
|
3183
|
-
}
|
|
3184
|
-
},
|
|
3185
|
-
focusIndication: {
|
|
3186
|
-
weight: 4,
|
|
3187
|
-
packages: {
|
|
3188
|
-
alfa: {
|
|
3189
|
-
r65: {
|
|
3190
|
-
quality: 1,
|
|
3191
|
-
what: 'Element in sequential focus order has no visible focus'
|
|
3192
|
-
}
|
|
3193
|
-
},
|
|
3194
|
-
testaro: {
|
|
3195
|
-
focInd: {
|
|
3196
|
-
quality: 1,
|
|
3197
|
-
what: 'Focused element displaying no or nostandard focus indicator'
|
|
3198
|
-
}
|
|
3199
|
-
}
|
|
3200
|
-
}
|
|
3201
|
-
},
|
|
3202
|
-
allCaps: {
|
|
3203
|
-
weight: 1,
|
|
3204
|
-
packages: {
|
|
3205
|
-
alfa: {
|
|
3206
|
-
r72: {
|
|
3207
|
-
quality: 1,
|
|
3208
|
-
what: 'Paragraph text is uppercased'
|
|
3209
|
-
}
|
|
3210
|
-
},
|
|
3211
|
-
tenon: {
|
|
3212
|
-
153: {
|
|
3213
|
-
quality: 1,
|
|
3214
|
-
what: 'Long string of text is in all caps'
|
|
3215
|
-
}
|
|
3216
|
-
}
|
|
3217
|
-
}
|
|
3218
|
-
},
|
|
3219
|
-
allItalics: {
|
|
3220
|
-
weight: 1,
|
|
3221
|
-
packages: {
|
|
3222
|
-
alfa: {
|
|
3223
|
-
r85: {
|
|
3224
|
-
quality: 1,
|
|
3225
|
-
what: 'Text of the paragraph is all italic'
|
|
3226
|
-
}
|
|
3227
|
-
},
|
|
3228
|
-
tenon: {
|
|
3229
|
-
154: {
|
|
3230
|
-
quality: 1,
|
|
3231
|
-
what: 'Long string of text is italic'
|
|
3232
|
-
}
|
|
3233
|
-
}
|
|
3234
|
-
}
|
|
3235
|
-
},
|
|
3236
|
-
noLandmarks: {
|
|
3237
|
-
weight: 2,
|
|
3238
|
-
packages: {
|
|
3239
|
-
wave: {
|
|
3240
|
-
'a:region_missing': {
|
|
3241
|
-
quality: 1,
|
|
3242
|
-
what: 'Page has no regions or ARIA landmarks'
|
|
3243
|
-
}
|
|
3244
|
-
}
|
|
3245
|
-
}
|
|
3246
|
-
},
|
|
3247
|
-
contentBeyondLandmarks: {
|
|
3248
|
-
weight: 2,
|
|
3249
|
-
packages: {
|
|
3250
|
-
alfa: {
|
|
3251
|
-
r57: {
|
|
3252
|
-
quality: 1,
|
|
3253
|
-
what: 'Perceivable text content is not included in any landmark'
|
|
3254
|
-
}
|
|
3255
|
-
},
|
|
3256
|
-
axe: {
|
|
3257
|
-
region: {
|
|
3258
|
-
quality: 1,
|
|
3259
|
-
what: 'Some page content is not contained by landmarks'
|
|
3260
|
-
}
|
|
3261
|
-
},
|
|
3262
|
-
ibm: {
|
|
3263
|
-
Rpt_Aria_OrphanedContent_Native_Host_Sematics: {
|
|
3264
|
-
quality: 1,
|
|
3265
|
-
what: 'Content does not reside within an element with a landmark role'
|
|
3266
|
-
}
|
|
3267
|
-
}
|
|
3268
|
-
}
|
|
3269
|
-
},
|
|
3270
|
-
footerTopLandmark: {
|
|
3271
|
-
weight: 1,
|
|
3272
|
-
packages: {
|
|
3273
|
-
axe: {
|
|
3274
|
-
'landmark-contentinfo-is-top-level': {
|
|
3275
|
-
quality: 1,
|
|
3276
|
-
what: 'contentinfo landmark (footer) is contained in another landmark'
|
|
3277
|
-
}
|
|
3278
|
-
}
|
|
3279
|
-
}
|
|
3280
|
-
},
|
|
3281
|
-
asideNotTop: {
|
|
3282
|
-
weight: 2,
|
|
3283
|
-
packages: {
|
|
3284
|
-
axe: {
|
|
3285
|
-
'landmark-complementary-is-top-level': {
|
|
3286
|
-
quality: 1,
|
|
3287
|
-
what: 'complementary landmark (aside) is contained in another landmark'
|
|
3288
|
-
}
|
|
3289
|
-
}
|
|
3290
|
-
}
|
|
3291
|
-
},
|
|
3292
|
-
mainNotTop: {
|
|
3293
|
-
weight: 2,
|
|
3294
|
-
packages: {
|
|
3295
|
-
axe: {
|
|
3296
|
-
'landmark-main-is-top-level': {
|
|
3297
|
-
quality: 1,
|
|
3298
|
-
what: 'main landmark is contained in another landmark'
|
|
3299
|
-
}
|
|
3300
|
-
}
|
|
3301
|
-
}
|
|
3302
|
-
},
|
|
3303
|
-
mainConfusion: {
|
|
3304
|
-
weight: 3,
|
|
3305
|
-
packages: {
|
|
3306
|
-
ibm: {
|
|
3307
|
-
Rpt_Aria_MultipleMainsRequireLabel_Implicit_2: {
|
|
3308
|
-
quality: 1,
|
|
3309
|
-
what: 'Element with main role has no unique label among the main-role elements'
|
|
3310
|
-
},
|
|
3311
|
-
Rpt_Aria_MultipleMainsVisibleLabel_Implicit: {
|
|
3312
|
-
quality: 1,
|
|
3313
|
-
what: 'Element with main role has no unique visible label among the main-role elements'
|
|
3314
|
-
}
|
|
3315
|
-
}
|
|
3316
|
-
}
|
|
3317
|
-
},
|
|
3318
|
-
mainNot1: {
|
|
3319
|
-
weight: 2,
|
|
3320
|
-
packages: {
|
|
3321
|
-
axe: {
|
|
3322
|
-
'landmark-one-main': {
|
|
3323
|
-
quality: 1,
|
|
3324
|
-
what: 'page has no main landmark'
|
|
3325
|
-
},
|
|
3326
|
-
'landmark-no-duplicate-main': {
|
|
3327
|
-
quality: 1,
|
|
3328
|
-
what: 'page has more than 1 main landmark'
|
|
3329
|
-
}
|
|
3330
|
-
},
|
|
3331
|
-
continuum: {
|
|
3332
|
-
809: {
|
|
3333
|
-
quality: 1,
|
|
3334
|
-
what: 'More than 1 main element is located in the body element'
|
|
3335
|
-
}
|
|
3336
|
-
}
|
|
3337
|
-
}
|
|
3338
|
-
},
|
|
3339
|
-
bannerNot1: {
|
|
3340
|
-
weight: 2,
|
|
3341
|
-
packages: {
|
|
3342
|
-
axe: {
|
|
3343
|
-
'landmark-no-duplicate-banner': {
|
|
3344
|
-
quality: 1,
|
|
3345
|
-
what: 'Page has more than 1 banner landmark'
|
|
3346
|
-
}
|
|
3347
|
-
},
|
|
3348
|
-
ibm: {
|
|
3349
|
-
Rpt_Aria_OneBannerInSiblingSet_Implicit: {
|
|
3350
|
-
quality: 1,
|
|
3351
|
-
what: 'Multiple elements with a banner role are on the page'
|
|
3352
|
-
}
|
|
3353
|
-
}
|
|
3354
|
-
}
|
|
3355
|
-
},
|
|
3356
|
-
bannerNotTop: {
|
|
3357
|
-
weight: 2,
|
|
3358
|
-
packages: {
|
|
3359
|
-
axe: {
|
|
3360
|
-
'landmark-banner-is-top-level': {
|
|
3361
|
-
quality: 1,
|
|
3362
|
-
what: 'banner landmark is contained in another landmark'
|
|
3363
|
-
}
|
|
3364
|
-
}
|
|
3365
|
-
}
|
|
3366
|
-
},
|
|
3367
|
-
footerConfusion: {
|
|
3368
|
-
weight: 3,
|
|
3369
|
-
packages: {
|
|
3370
|
-
ibm: {
|
|
3371
|
-
Rpt_Aria_MultipleContentinfoLandmarks_Implicit: {
|
|
3372
|
-
quality: 1,
|
|
3373
|
-
what: 'Element with a contentinfo role has no unique purpose label among the contentinfo-role elements'
|
|
3374
|
-
}
|
|
3375
|
-
}
|
|
3376
|
-
}
|
|
3377
|
-
},
|
|
3378
|
-
footerNot1: {
|
|
3379
|
-
weight: 2,
|
|
3380
|
-
packages: {
|
|
3381
|
-
axe: {
|
|
3382
|
-
'landmark-no-duplicate-contentinfo': {
|
|
3383
|
-
quality: 1,
|
|
3384
|
-
what: 'Page has more than 1 contentinfo landmark (footer)'
|
|
3385
|
-
}
|
|
3386
|
-
},
|
|
3387
|
-
ibm: {
|
|
3388
|
-
Rpt_Aria_MultipleContentinfoInSiblingSet_Implicit: {
|
|
3389
|
-
quality: 1,
|
|
3390
|
-
what: 'Page, document, or application has more than one element with a contentinfo role'
|
|
3391
|
-
}
|
|
3392
|
-
}
|
|
3393
|
-
}
|
|
3394
|
-
},
|
|
3395
|
-
landmarkConfusion: {
|
|
3396
|
-
weight: 3,
|
|
3397
|
-
packages: {
|
|
3398
|
-
axe: {
|
|
3399
|
-
'landmark-unique': {
|
|
3400
|
-
quality: 1,
|
|
3401
|
-
what: 'Landmark has a role and an accessible name that are identical to another'
|
|
3402
|
-
}
|
|
3403
|
-
},
|
|
3404
|
-
ibm: {
|
|
3405
|
-
landmark_name_unique: {
|
|
3406
|
-
quality: 1,
|
|
3407
|
-
what: 'Landmark has no unique aria-labelledby or aria-label among landmarks in the same parent region'
|
|
3408
|
-
}
|
|
3409
|
-
}
|
|
3410
|
-
}
|
|
3411
|
-
},
|
|
3412
|
-
articleConfusion: {
|
|
3413
|
-
weight: 3,
|
|
3414
|
-
packages: {
|
|
3415
|
-
ibm: {
|
|
3416
|
-
Rpt_Aria_MultipleArticleRoles_Implicit: {
|
|
3417
|
-
quality: 1,
|
|
3418
|
-
what: 'Element with an article role has no unique purpose label among the article-role elements'
|
|
3419
|
-
}
|
|
3420
|
-
}
|
|
3421
|
-
}
|
|
3422
|
-
},
|
|
3423
|
-
formConfusion: {
|
|
3424
|
-
weight: 3,
|
|
3425
|
-
packages: {
|
|
3426
|
-
ibm: {
|
|
3427
|
-
Rpt_Aria_MultipleFormLandmarks_Implicit: {
|
|
3428
|
-
quality: 1,
|
|
3429
|
-
what: 'Element with a form role has no unique purpose label among the form-role elements'
|
|
3430
|
-
}
|
|
3431
|
-
}
|
|
3432
|
-
}
|
|
3433
|
-
},
|
|
3434
|
-
applicationConfusion: {
|
|
3435
|
-
weight: 3,
|
|
3436
|
-
packages: {
|
|
3437
|
-
ibm: {
|
|
3438
|
-
Rpt_Aria_MultipleApplicationLandmarks: {
|
|
3439
|
-
quality: 1,
|
|
3440
|
-
what: 'Element with an application role has no unique purpose label among the application-role elements'
|
|
3441
|
-
}
|
|
3442
|
-
}
|
|
3443
|
-
}
|
|
3444
|
-
},
|
|
3445
|
-
asideConfusion: {
|
|
3446
|
-
weight: 3,
|
|
3447
|
-
packages: {
|
|
3448
|
-
continuum: {
|
|
3449
|
-
527: {
|
|
3450
|
-
quality: 1,
|
|
3451
|
-
what: 'aside element has an accessible name that is non-unique among the aside elements'
|
|
3452
|
-
}
|
|
3453
|
-
},
|
|
3454
|
-
ibm: {
|
|
3455
|
-
Rpt_Aria_MultipleComplementaryLandmarks_Implicit: {
|
|
3456
|
-
quality: 1,
|
|
3457
|
-
what: 'Element with a complementary role has no unique purpose label among the complementary-role elements'
|
|
3458
|
-
}
|
|
3459
|
-
}
|
|
3460
|
-
}
|
|
3461
|
-
},
|
|
3462
|
-
bannerConfusion: {
|
|
3463
|
-
weight: 3,
|
|
3464
|
-
packages: {
|
|
3465
|
-
ibm: {
|
|
3466
|
-
Rpt_Aria_MultipleBannerLandmarks_Implicit: {
|
|
3467
|
-
quality: 1,
|
|
3468
|
-
what: 'Element with a banner role has no unique purpose label among the banner-role elements'
|
|
3469
|
-
}
|
|
3470
|
-
}
|
|
3471
|
-
}
|
|
3472
|
-
},
|
|
3473
|
-
navConfusion: {
|
|
3474
|
-
weight: 3,
|
|
3475
|
-
packages: {
|
|
3476
|
-
continuum: {
|
|
3477
|
-
531: {
|
|
3478
|
-
quality: 1,
|
|
3479
|
-
what: 'nav element has an accessible name that is non-unique among the nav elements'
|
|
3480
|
-
}
|
|
3481
|
-
},
|
|
3482
|
-
ibm: {
|
|
3483
|
-
Rpt_Aria_MultipleNavigationLandmarks_Implicit: {
|
|
3484
|
-
quality: 1,
|
|
3485
|
-
what: 'Element with a navigation role has no unique purpose label among the navigation-role elements'
|
|
3486
|
-
}
|
|
3487
|
-
}
|
|
3488
|
-
}
|
|
3489
|
-
},
|
|
3490
|
-
regionConfusion: {
|
|
3491
|
-
weight: 3,
|
|
3492
|
-
packages: {
|
|
3493
|
-
ibm: {
|
|
3494
|
-
Rpt_Aria_MultipleRegionsUniqueLabel_Implicit: {
|
|
3495
|
-
quality: 1,
|
|
3496
|
-
what: 'Element with a region role has no unique label among the region-role elements'
|
|
3497
|
-
}
|
|
3498
|
-
}
|
|
3499
|
-
}
|
|
3500
|
-
},
|
|
3501
|
-
searchConfusion: {
|
|
3502
|
-
weight: 3,
|
|
3503
|
-
packages: {
|
|
3504
|
-
ibm: {
|
|
3505
|
-
Rpt_Aria_MultipleSearchLandmarks: {
|
|
3506
|
-
quality: 1,
|
|
3507
|
-
what: 'Element with a search role has no unique purpose label among the search-role elements'
|
|
3508
|
-
}
|
|
3509
|
-
}
|
|
3510
|
-
}
|
|
3511
|
-
},
|
|
3512
|
-
asideNoText: {
|
|
3513
|
-
weight: 3,
|
|
3514
|
-
packages: {
|
|
3515
|
-
continuum: {
|
|
3516
|
-
532: {
|
|
3517
|
-
quality: 1,
|
|
3518
|
-
what: 'aside element is not the only aside element but has no accessible name'
|
|
3519
|
-
}
|
|
3520
|
-
}
|
|
3521
|
-
}
|
|
3522
|
-
},
|
|
3523
|
-
complementaryNoText: {
|
|
3524
|
-
weight: 1,
|
|
3525
|
-
packages: {
|
|
3526
|
-
ibm: {
|
|
3527
|
-
Rpt_Aria_ComplementaryRequiredLabel_Implicit: {
|
|
3528
|
-
quality: 1,
|
|
3529
|
-
what: 'Element has a complementary role but has no label'
|
|
3530
|
-
},
|
|
3531
|
-
Rpt_Aria_ComplementaryLandmarkLabel_Implicit: {
|
|
3532
|
-
quality: 1,
|
|
3533
|
-
what: 'Element with a complementary role has no visible purpose label'
|
|
3534
|
-
}
|
|
3535
|
-
}
|
|
3536
|
-
}
|
|
3537
|
-
},
|
|
3538
|
-
navNoText: {
|
|
3539
|
-
weight: 3,
|
|
3540
|
-
packages: {
|
|
3541
|
-
continuum: {
|
|
3542
|
-
533: {
|
|
3543
|
-
quality: 1,
|
|
3544
|
-
what: 'nav element is not the only nav element but has no accessible name'
|
|
3545
|
-
}
|
|
3546
|
-
}
|
|
3547
|
-
}
|
|
3548
|
-
},
|
|
3549
|
-
labelNoText: {
|
|
3550
|
-
weight: 4,
|
|
3551
|
-
packages: {
|
|
3552
|
-
ibm: {
|
|
3553
|
-
Valerie_Label_HasContent: {
|
|
3554
|
-
quality: 1,
|
|
3555
|
-
what: 'label element has no non-empty purpose-descriptive text'
|
|
3556
|
-
}
|
|
3557
|
-
}
|
|
3558
|
-
}
|
|
3559
|
-
},
|
|
3560
|
-
focusableOperable: {
|
|
3561
|
-
weight: 3,
|
|
3562
|
-
packages: {
|
|
3563
|
-
testaro: {
|
|
3564
|
-
focOp: {
|
|
3565
|
-
quality: 1,
|
|
3566
|
-
what: 'Operable elements that cannot be Tab-focused and vice versa'
|
|
3567
|
-
}
|
|
3568
|
-
}
|
|
3569
|
-
}
|
|
3570
|
-
},
|
|
3571
|
-
focusableRole: {
|
|
3572
|
-
weight: 3,
|
|
3573
|
-
packages: {
|
|
3574
|
-
axe: {
|
|
3575
|
-
'focus-order-semantics': {
|
|
3576
|
-
quality: 1,
|
|
3577
|
-
what: 'Focusable element has no active role'
|
|
3578
|
-
}
|
|
3579
|
-
}
|
|
3580
|
-
}
|
|
3581
|
-
},
|
|
3582
|
-
focusableHidden: {
|
|
3583
|
-
weight: 4,
|
|
3584
|
-
packages: {
|
|
3585
|
-
alfa: {
|
|
3586
|
-
r17: {
|
|
3587
|
-
quality: 1,
|
|
3588
|
-
what: 'Tab-focusable element is or has an ancestor that is aria-hidden'
|
|
3589
|
-
}
|
|
3590
|
-
},
|
|
3591
|
-
axe: {
|
|
3592
|
-
'aria-hidden-focus': {
|
|
3593
|
-
quality: 1,
|
|
3594
|
-
what: 'ARIA hidden element is focusable or contains a focusable element'
|
|
3595
|
-
},
|
|
3596
|
-
'presentation-role-conflict': {
|
|
3597
|
-
quality: 1,
|
|
3598
|
-
what: 'Element has a none/presentation role but is focusable or has a global ARIA state or property'
|
|
3599
|
-
}
|
|
3600
|
-
},
|
|
3601
|
-
continuum: {
|
|
3602
|
-
790: {
|
|
3603
|
-
quality: 1,
|
|
3604
|
-
what: 'Element with an explicit or implicit nonnegative tabindex attribute is directly aria-hidden'
|
|
3605
|
-
}
|
|
3606
|
-
},
|
|
3607
|
-
ibm: {
|
|
3608
|
-
aria_hidden_focus_misuse: {
|
|
3609
|
-
quality: 1,
|
|
3610
|
-
what: 'Focusable element is within the subtree of an element with aria-hidden set to true'
|
|
3611
|
-
}
|
|
3612
|
-
},
|
|
3613
|
-
tenon: {
|
|
3614
|
-
189: {
|
|
3615
|
-
quality: 1,
|
|
3616
|
-
what: 'Element is typically used for interaction but has a presentation role'
|
|
3617
|
-
},
|
|
3618
|
-
194: {
|
|
3619
|
-
quality: 1,
|
|
3620
|
-
what: 'Visible element is focusable but has a presentation role or aria-hidden=true attribute'
|
|
3621
|
-
}
|
|
3622
|
-
}
|
|
3623
|
-
}
|
|
3624
|
-
},
|
|
3625
|
-
focusedAway: {
|
|
3626
|
-
weight: 3,
|
|
3627
|
-
packages: {
|
|
3628
|
-
testaro: {
|
|
3629
|
-
focVis: {
|
|
3630
|
-
quality: 1,
|
|
3631
|
-
what: 'Element when focused is off the display'
|
|
3632
|
-
}
|
|
3633
|
-
}
|
|
3634
|
-
}
|
|
3635
|
-
},
|
|
3636
|
-
focusableDescendants: {
|
|
3637
|
-
weight: 4,
|
|
3638
|
-
packages: {
|
|
3639
|
-
alfa: {
|
|
3640
|
-
r90: {
|
|
3641
|
-
quality: 1,
|
|
3642
|
-
what: 'Element has a role making its children presentational but contains a focusable element'
|
|
3643
|
-
}
|
|
3644
|
-
}
|
|
3645
|
-
}
|
|
3646
|
-
},
|
|
3647
|
-
labeledHidden: {
|
|
3648
|
-
weight: 2,
|
|
3649
|
-
packages: {
|
|
3650
|
-
htmlcs: {
|
|
3651
|
-
'w:AA.1_3_1.F68.Hidden': {
|
|
3652
|
-
quality: 1,
|
|
3653
|
-
what: 'Hidden form field is needlessly labeled.'
|
|
3654
|
-
},
|
|
3655
|
-
'w:AA.1_3_1.F68.HiddenAttr': {
|
|
3656
|
-
quality: 1,
|
|
3657
|
-
what: 'Form field with a hidden attribute is needlessly labeled.'
|
|
3658
|
-
}
|
|
3659
|
-
}
|
|
3660
|
-
}
|
|
3661
|
-
},
|
|
3662
|
-
hiddenContentRisk: {
|
|
3663
|
-
weight: 1,
|
|
3664
|
-
packages: {
|
|
3665
|
-
axe: {
|
|
3666
|
-
'hidden-content': {
|
|
3667
|
-
quality: 1,
|
|
3668
|
-
what: 'Some content is hidden and therefore may not be testable for accessibility'
|
|
3669
|
-
}
|
|
3670
|
-
}
|
|
3671
|
-
}
|
|
3672
|
-
},
|
|
3673
|
-
frameContentRisk: {
|
|
3674
|
-
weight: 1,
|
|
3675
|
-
packages: {
|
|
3676
|
-
axe: {
|
|
3677
|
-
'frame-tested': {
|
|
3678
|
-
quality: 0.2,
|
|
3679
|
-
what: 'Some content is in an iframe and therefore may not be testable for accessibility'
|
|
3680
|
-
}
|
|
3681
|
-
}
|
|
3682
|
-
}
|
|
3683
|
-
},
|
|
3684
|
-
frameSandboxRisk: {
|
|
3685
|
-
weight: 2,
|
|
3686
|
-
packages: {
|
|
3687
|
-
nuVal: {
|
|
3688
|
-
'^Potentially bad value .+ for attribute sandbox on element iframe: Setting both allow-scripts and allow-same-origin is not recommended, because it effectively enables an embedded page to break out of all sandboxing.*$': {
|
|
3689
|
-
quality: 1,
|
|
3690
|
-
what: 'iframe element has a vulnerable sandbox value containing both allow-scripts and allow-same-origin'
|
|
3691
|
-
}
|
|
3692
|
-
}
|
|
3693
|
-
}
|
|
3694
|
-
},
|
|
3695
|
-
hoverSurprise: {
|
|
3696
|
-
weight: 1,
|
|
3697
|
-
packages: {
|
|
3698
|
-
testaro: {
|
|
3699
|
-
hover: {
|
|
3700
|
-
quality: 1,
|
|
3701
|
-
what: 'Content changes caused by hovering'
|
|
3702
|
-
}
|
|
3703
|
-
}
|
|
3704
|
-
}
|
|
3705
|
-
},
|
|
3706
|
-
labelClash: {
|
|
3707
|
-
weight: 2,
|
|
3708
|
-
packages: {
|
|
3709
|
-
testaro: {
|
|
3710
|
-
labClash: {
|
|
3711
|
-
quality: 1,
|
|
3712
|
-
what: 'Incompatible label types'
|
|
3713
|
-
}
|
|
3714
|
-
},
|
|
3715
|
-
ibm: {
|
|
3716
|
-
RPT_Label_UniqueFor: {
|
|
3717
|
-
quality: 1,
|
|
3718
|
-
what: 'Form control does not have exactly one label'
|
|
3719
|
-
}
|
|
3720
|
-
},
|
|
3721
|
-
wave: {
|
|
3722
|
-
'e:label_multiple': {
|
|
3723
|
-
quality: 1,
|
|
3724
|
-
what: 'Form control has more than one label associated with it'
|
|
3725
|
-
}
|
|
3726
|
-
}
|
|
3727
|
-
}
|
|
3728
|
-
},
|
|
3729
|
-
labelEmpty: {
|
|
3730
|
-
weight: 3,
|
|
3731
|
-
packages: {
|
|
3732
|
-
htmlcs: {
|
|
3733
|
-
'w:AA.1_3_1.ARIA6': {
|
|
3734
|
-
quality: 1,
|
|
3735
|
-
what: 'Value of the aria-label attribute of the form control is empty or only whitespace'
|
|
3736
|
-
},
|
|
3737
|
-
'w:AA.4_1_2.ARIA6': {
|
|
3738
|
-
quality: 1,
|
|
3739
|
-
what: 'Value of the aria-label attribute of the form control is empty or only whitespace'
|
|
3740
|
-
}
|
|
3741
|
-
},
|
|
3742
|
-
wave: {
|
|
3743
|
-
'e:label_empty': {
|
|
3744
|
-
quality: 1,
|
|
3745
|
-
what: 'Empty form label'
|
|
3746
|
-
}
|
|
3747
|
-
}
|
|
3748
|
-
}
|
|
3749
|
-
},
|
|
3750
|
-
linkComprehensionRisk: {
|
|
3751
|
-
weight: 1,
|
|
3752
|
-
packages: {
|
|
3753
|
-
wave: {
|
|
3754
|
-
'a:link_suspicious': {
|
|
3755
|
-
quality: 1,
|
|
3756
|
-
what: 'Suspicious link text'
|
|
3757
|
-
}
|
|
3758
|
-
}
|
|
3759
|
-
}
|
|
3760
|
-
},
|
|
3761
|
-
attributeBad: {
|
|
3762
|
-
weight: 4,
|
|
3763
|
-
packages: {
|
|
3764
|
-
nuVal: {
|
|
3765
|
-
'^Attribute .+ not allowed on element .+ at this point.*$': {
|
|
3766
|
-
quality: 1,
|
|
3767
|
-
what: 'attribute not allowed on this element'
|
|
3768
|
-
},
|
|
3769
|
-
'^Bad value .+ for attribute .+ on element .+$': {
|
|
3770
|
-
quality: 1,
|
|
3771
|
-
what: 'attribute on this element has an invalid value'
|
|
3772
|
-
},
|
|
3773
|
-
'^Bad value .+ for the attribute .+$': {
|
|
3774
|
-
quality: 1,
|
|
3775
|
-
what: 'attribute has an invalid value'
|
|
3776
|
-
},
|
|
3777
|
-
'^Attribute .+ not allowed here.*$': {
|
|
3778
|
-
quality: 1,
|
|
3779
|
-
what: 'Attribute not allowed here'
|
|
3780
|
-
},
|
|
3781
|
-
'^Attribute .+ is not serializable as XML 1\\.0.*$': {
|
|
3782
|
-
quality: 1,
|
|
3783
|
-
what: 'Attribute is invalidly nonserializable'
|
|
3784
|
-
},
|
|
3785
|
-
'^Attribute .+ is only allowed when .+$': {
|
|
3786
|
-
quality: 1,
|
|
3787
|
-
what: 'Attribute is invalid here'
|
|
3788
|
-
}
|
|
3789
|
-
}
|
|
3790
|
-
}
|
|
3791
|
-
},
|
|
3792
|
-
nonWebLink: {
|
|
3793
|
-
weight: 1,
|
|
3794
|
-
packages: {
|
|
3795
|
-
continuum: {
|
|
3796
|
-
141: {
|
|
3797
|
-
quality: 1,
|
|
3798
|
-
what: 'a element has an href attribute set to an image file reference'
|
|
3799
|
-
}
|
|
3800
|
-
},
|
|
3801
|
-
wave: {
|
|
3802
|
-
'a:link_excel': {
|
|
3803
|
-
quality: 1,
|
|
3804
|
-
what: 'Link to Microsoft Excel workbook'
|
|
3805
|
-
},
|
|
3806
|
-
'a:link_word': {
|
|
3807
|
-
quality: 1,
|
|
3808
|
-
what: 'Link to Microsoft Word document'
|
|
3809
|
-
}
|
|
3810
|
-
}
|
|
3811
|
-
}
|
|
3812
|
-
},
|
|
3813
|
-
linkVague: {
|
|
3814
|
-
weight: 3,
|
|
3815
|
-
packages: {
|
|
3816
|
-
tenon: {
|
|
3817
|
-
73: {
|
|
3818
|
-
quality: 1,
|
|
3819
|
-
what: 'Link text is too generic to communicate the purpose or destination'
|
|
3820
|
-
}
|
|
3821
|
-
}
|
|
3822
|
-
}
|
|
3823
|
-
},
|
|
3824
|
-
linkIndication: {
|
|
3825
|
-
weight: 2,
|
|
3826
|
-
packages: {
|
|
3827
|
-
alfa: {
|
|
3828
|
-
r62: {
|
|
3829
|
-
quality: 1,
|
|
3830
|
-
what: 'Inline link is not distinct from the surrounding text except by color'
|
|
3831
|
-
}
|
|
3832
|
-
},
|
|
3833
|
-
axe: {
|
|
3834
|
-
'link-in-text-block': {
|
|
3835
|
-
quality: 1,
|
|
3836
|
-
what: 'Link is not distinct from surrounding text without reliance on color'
|
|
3837
|
-
}
|
|
3838
|
-
},
|
|
3839
|
-
testaro: {
|
|
3840
|
-
linkUl: {
|
|
3841
|
-
quality: 1,
|
|
3842
|
-
what: 'Non-underlined adjacent links'
|
|
3843
|
-
}
|
|
3844
|
-
}
|
|
3845
|
-
}
|
|
3846
|
-
},
|
|
3847
|
-
menuNavigation: {
|
|
3848
|
-
weight: 2,
|
|
3849
|
-
packages: {
|
|
3850
|
-
testaro: {
|
|
3851
|
-
menuNav: {
|
|
3852
|
-
quality: 1,
|
|
3853
|
-
what: 'Nonstandard keyboard navigation among focusable menu items'
|
|
3854
|
-
}
|
|
3855
|
-
}
|
|
3856
|
-
}
|
|
3857
|
-
},
|
|
3858
|
-
menuItemless: {
|
|
3859
|
-
weight: 4,
|
|
3860
|
-
packages: {
|
|
3861
|
-
wave: {
|
|
3862
|
-
'e:aria_menu_broken': {
|
|
3863
|
-
quality: 1,
|
|
3864
|
-
what: 'ARIA menu does not contain required menu items'
|
|
3865
|
-
}
|
|
3866
|
-
}
|
|
3867
|
-
}
|
|
3868
|
-
},
|
|
3869
|
-
tabNavigation: {
|
|
3870
|
-
weight: 2,
|
|
3871
|
-
packages: {
|
|
3872
|
-
testaro: {
|
|
3873
|
-
tabNav: {
|
|
3874
|
-
quality: 1,
|
|
3875
|
-
what: 'Nonstandard keyboard navigation among tabs'
|
|
3876
|
-
}
|
|
3877
|
-
}
|
|
3878
|
-
}
|
|
3879
|
-
},
|
|
3880
|
-
spontaneousMotion: {
|
|
3881
|
-
weight: 2,
|
|
3882
|
-
packages: {
|
|
3883
|
-
testaro: {
|
|
3884
|
-
motion: {
|
|
3885
|
-
quality: 1,
|
|
3886
|
-
what: 'Change of visible content not requested by user'
|
|
3887
|
-
}
|
|
3888
|
-
}
|
|
3889
|
-
}
|
|
3890
|
-
},
|
|
3891
|
-
autoplay: {
|
|
3892
|
-
weight: 2,
|
|
3893
|
-
packages: {
|
|
3894
|
-
axe: {
|
|
3895
|
-
'no-autoplay-audio': {
|
|
3896
|
-
quality: 1,
|
|
3897
|
-
what: 'video or audio element plays automatically'
|
|
3898
|
-
}
|
|
3899
|
-
}
|
|
3900
|
-
}
|
|
3901
|
-
},
|
|
3902
|
-
divParentBad: {
|
|
3903
|
-
weight: 4,
|
|
3904
|
-
packages: {
|
|
3905
|
-
nuVal: {
|
|
3906
|
-
'Element div not allowed as child of element button in this context. (Suppressing further errors from this subtree.)': {
|
|
3907
|
-
quality: 1,
|
|
3908
|
-
what: 'div element has a button element as its parent'
|
|
3909
|
-
}
|
|
3910
|
-
}
|
|
3911
|
-
}
|
|
3912
|
-
},
|
|
3913
|
-
pParentBad: {
|
|
3914
|
-
weight: 4,
|
|
3915
|
-
packages: {
|
|
3916
|
-
nuVal: {
|
|
3917
|
-
'Element p not allowed as child of element strong in this context. (Suppressing further errors from this subtree.)': {
|
|
3918
|
-
quality: 1,
|
|
3919
|
-
what: 'p element has a strong element as its parent'
|
|
3920
|
-
}
|
|
3921
|
-
}
|
|
3922
|
-
}
|
|
3923
|
-
},
|
|
3924
|
-
styleParentBad: {
|
|
3925
|
-
weight: 4,
|
|
3926
|
-
packages: {
|
|
3927
|
-
nuVal: {
|
|
3928
|
-
'Element style not allowed as child of element body in this context. (Suppressing further errors from this subtree.)': {
|
|
3929
|
-
quality: 1,
|
|
3930
|
-
what: 'style element not allowed as a child of the body element'
|
|
3931
|
-
},
|
|
3932
|
-
'Element style not allowed as child of element div in this context. (Suppressing further errors from this subtree.)': {
|
|
3933
|
-
quality: 1,
|
|
3934
|
-
what: 'style element not allowed as a child of this div element'
|
|
3935
|
-
},
|
|
3936
|
-
'Element style not allowed as child of element main in this context. (Suppressing further errors from this subtree.)': {
|
|
3937
|
-
quality: 1,
|
|
3938
|
-
what: 'style element not allowed as a child of this main element'
|
|
3939
|
-
},
|
|
3940
|
-
'Element style not allowed as child of element footer in this context. (Suppressing further errors from this subtree.)': {
|
|
3941
|
-
quality: 1,
|
|
3942
|
-
what: 'style element not allowed as a child of this footer element'
|
|
3943
|
-
}
|
|
3944
|
-
}
|
|
3945
|
-
}
|
|
3946
|
-
},
|
|
3947
|
-
inconsistentStyles: {
|
|
3948
|
-
weight: 1,
|
|
3949
|
-
packages: {
|
|
3950
|
-
testaro: {
|
|
3951
|
-
styleDiff: {
|
|
3952
|
-
quality: 1,
|
|
3953
|
-
what: 'Heading, link, and button style inconsistencies'
|
|
3954
|
-
}
|
|
3955
|
-
}
|
|
3956
|
-
}
|
|
3957
|
-
},
|
|
3958
|
-
zIndexNotZero: {
|
|
3959
|
-
weight: 1,
|
|
3960
|
-
packages: {
|
|
3961
|
-
testaro: {
|
|
3962
|
-
zIndex: {
|
|
3963
|
-
quality: 1,
|
|
3964
|
-
what: 'Layering with nondefault z-index values'
|
|
3965
|
-
}
|
|
3966
|
-
}
|
|
3967
|
-
}
|
|
3968
|
-
},
|
|
3969
|
-
tabIndexPositive: {
|
|
3970
|
-
weight: 1,
|
|
3971
|
-
packages: {
|
|
3972
|
-
axe: {
|
|
3973
|
-
tabindex: {
|
|
3974
|
-
quality: 1,
|
|
3975
|
-
what: 'Positive tabIndex risks creating a confusing focus order'
|
|
3976
|
-
}
|
|
3977
|
-
},
|
|
3978
|
-
wave: {
|
|
3979
|
-
'a:tabindex': {
|
|
3980
|
-
quality: 1,
|
|
3981
|
-
what: 'tabIndex value positive'
|
|
3982
|
-
}
|
|
3983
|
-
}
|
|
3984
|
-
}
|
|
3985
|
-
},
|
|
3986
|
-
tabIndexBad: {
|
|
3987
|
-
weight: 4,
|
|
3988
|
-
packages: {
|
|
3989
|
-
nuVal: {
|
|
3990
|
-
'^Bad value for attribute tabindex on element .+: The empty string is not a valid integer.*$': {
|
|
3991
|
-
quality: 1,
|
|
3992
|
-
what: 'tabindex attribute has an empty value instead of an integer'
|
|
3993
|
-
}
|
|
3994
|
-
}
|
|
3995
|
-
}
|
|
3996
|
-
},
|
|
3997
|
-
tabIndexMissing: {
|
|
3998
|
-
weight: 4,
|
|
3999
|
-
packages: {
|
|
4000
|
-
continuum: {
|
|
4001
|
-
337: {
|
|
4002
|
-
quality: 1,
|
|
4003
|
-
what: 'Enabled element with a button role has no nonpositive tabindex attribute'
|
|
4004
|
-
},
|
|
4005
|
-
356: {
|
|
4006
|
-
quality: 1,
|
|
4007
|
-
what: 'Enabled element with a textbox role has no nonpositive tabindex attribute'
|
|
4008
|
-
}
|
|
4009
|
-
},
|
|
4010
|
-
tenon: {
|
|
4011
|
-
190: {
|
|
4012
|
-
quality: 1,
|
|
4013
|
-
what: 'Interactive item is not natively actionable, but has no tabindex=0 attribute'
|
|
4014
|
-
}
|
|
4015
|
-
}
|
|
4016
|
-
}
|
|
4017
|
-
},
|
|
4018
|
-
trackNoLabel: {
|
|
4019
|
-
weight: 4,
|
|
4020
|
-
packages: {
|
|
4021
|
-
continuum: {
|
|
4022
|
-
40: {
|
|
4023
|
-
quality: 1,
|
|
4024
|
-
what: 'captions track element has no label attribute set to a text value'
|
|
4025
|
-
},
|
|
4026
|
-
368: {
|
|
4027
|
-
quality: 1,
|
|
4028
|
-
what: 'subtitle track element has no label attribute set to a text value'
|
|
4029
|
-
}
|
|
4030
|
-
}
|
|
4031
|
-
}
|
|
4032
|
-
},
|
|
4033
|
-
audioCaptionMissing: {
|
|
4034
|
-
weight: 4,
|
|
4035
|
-
packages: {
|
|
4036
|
-
axe: {
|
|
4037
|
-
'audio-caption': {
|
|
4038
|
-
quality: 1,
|
|
4039
|
-
what: 'audio element has no captions track'
|
|
4040
|
-
}
|
|
4041
|
-
}
|
|
4042
|
-
}
|
|
4043
|
-
},
|
|
4044
|
-
videoCaptionMissing: {
|
|
4045
|
-
weight: 4,
|
|
4046
|
-
packages: {
|
|
4047
|
-
axe: {
|
|
4048
|
-
'video-caption': {
|
|
4049
|
-
quality: 1,
|
|
4050
|
-
what: 'video element has no captions'
|
|
4051
|
-
}
|
|
4052
|
-
}
|
|
4053
|
-
}
|
|
4054
|
-
},
|
|
4055
|
-
videoCaptionRisk: {
|
|
4056
|
-
weight: 1,
|
|
4057
|
-
packages: {
|
|
4058
|
-
wave: {
|
|
4059
|
-
'a:html5_video_audio': {
|
|
4060
|
-
quality: 1,
|
|
4061
|
-
what: 'video or audio element may have no or incorrect captions, transcript, or audio description'
|
|
4062
|
-
},
|
|
4063
|
-
'a:audio_video': {
|
|
4064
|
-
quality: 1,
|
|
4065
|
-
what: 'audio or video file or link may have no or incorrect captions, transcript, or audio description'
|
|
4066
|
-
},
|
|
4067
|
-
'a:youtube_video': {
|
|
4068
|
-
quality: 1,
|
|
4069
|
-
what: 'YouTube video may have no or incorrect captions'
|
|
4070
|
-
}
|
|
4071
|
-
}
|
|
4072
|
-
}
|
|
4073
|
-
},
|
|
4074
|
-
notKeyboardScrollable: {
|
|
4075
|
-
weight: 4,
|
|
4076
|
-
packages: {
|
|
4077
|
-
alfa: {
|
|
4078
|
-
r84: {
|
|
4079
|
-
quality: 1,
|
|
4080
|
-
what: 'Element is scrollable but not by keyboard'
|
|
4081
|
-
}
|
|
4082
|
-
},
|
|
4083
|
-
axe: {
|
|
4084
|
-
'scrollable-region-focusable': {
|
|
4085
|
-
quality: 1,
|
|
4086
|
-
what: 'Element is scrollable but has no keyboard access'
|
|
4087
|
-
}
|
|
4088
|
-
}
|
|
4089
|
-
}
|
|
4090
|
-
},
|
|
4091
|
-
horizontalScrolling: {
|
|
4092
|
-
weight: 3,
|
|
4093
|
-
packages: {
|
|
4094
|
-
tenon: {
|
|
4095
|
-
28: {
|
|
4096
|
-
quality: 1,
|
|
4097
|
-
what: 'Layout or sizing of the page causes horizontal scrolling'
|
|
4098
|
-
}
|
|
4099
|
-
}
|
|
4100
|
-
}
|
|
4101
|
-
},
|
|
4102
|
-
scrollRisk: {
|
|
4103
|
-
weight: 1,
|
|
4104
|
-
packages: {
|
|
4105
|
-
htmlcs: {
|
|
4106
|
-
'w:AA.1_4_10.C32,C31,C33,C38,SCR34,G206': {
|
|
4107
|
-
quality: 1,
|
|
4108
|
-
what: 'Fixed-position element may force bidirectional scrolling'
|
|
4109
|
-
}
|
|
4110
|
-
}
|
|
4111
|
-
}
|
|
4112
|
-
},
|
|
4113
|
-
skipRepeatedContent: {
|
|
4114
|
-
weight: 3,
|
|
4115
|
-
packages: {
|
|
4116
|
-
alfa: {
|
|
4117
|
-
'r87': {
|
|
4118
|
-
quality: 0.5,
|
|
4119
|
-
what: 'First focusable element is not a link to the main content'
|
|
4120
|
-
}
|
|
4121
|
-
},
|
|
4122
|
-
axe: {
|
|
4123
|
-
'bypass': {
|
|
4124
|
-
quality: 1,
|
|
4125
|
-
what: 'Page has no means to bypass repeated blocks'
|
|
4126
|
-
},
|
|
4127
|
-
'skip-link': {
|
|
4128
|
-
quality: 1,
|
|
4129
|
-
what: 'Skip-link target is not focusable or does not exist'
|
|
4130
|
-
}
|
|
4131
|
-
},
|
|
4132
|
-
ibm: {
|
|
4133
|
-
WCAG20_Body_FirstASkips_Native_Host_Sematics: {
|
|
4134
|
-
quality: 0.5,
|
|
4135
|
-
what: 'Page provides no way to skip directly to the main content'
|
|
4136
|
-
}
|
|
4137
|
-
},
|
|
4138
|
-
wave: {
|
|
4139
|
-
'e:link_skip_broken': {
|
|
4140
|
-
quality: 1,
|
|
4141
|
-
what: 'Skip-navigation link has no target or is not keyboard accessible'
|
|
4142
|
-
}
|
|
4143
|
-
}
|
|
4144
|
-
}
|
|
4145
|
-
},
|
|
4146
|
-
submitButton: {
|
|
4147
|
-
weight: 3,
|
|
4148
|
-
packages: {
|
|
4149
|
-
htmlcs: {
|
|
4150
|
-
'e:AA.3_2_2.H32.2': {
|
|
4151
|
-
quality: 1,
|
|
4152
|
-
what: 'Form has no submit button'
|
|
4153
|
-
}
|
|
4154
|
-
}
|
|
4155
|
-
}
|
|
4156
|
-
},
|
|
4157
|
-
fragmentaryNoticeRisk: {
|
|
4158
|
-
weight: 2,
|
|
4159
|
-
packages: {
|
|
4160
|
-
alfa: {
|
|
4161
|
-
r54: {
|
|
4162
|
-
quality: 1,
|
|
4163
|
-
what: 'Assertive region is not atomic'
|
|
4164
|
-
}
|
|
4165
|
-
}
|
|
4166
|
-
}
|
|
4167
|
-
},
|
|
4168
|
-
noScriptRisk: {
|
|
4169
|
-
weight: 1,
|
|
4170
|
-
packages: {
|
|
4171
|
-
wave: {
|
|
4172
|
-
'a:noscript': {
|
|
4173
|
-
quality: 1,
|
|
4174
|
-
what: 'noscript element may fail to contain an accessible equivalent or alternative'
|
|
4175
|
-
}
|
|
4176
|
-
}
|
|
4177
|
-
}
|
|
4178
|
-
},
|
|
4179
|
-
obsolete: {
|
|
4180
|
-
weight: 3,
|
|
4181
|
-
packages: {
|
|
4182
|
-
alfa: {
|
|
4183
|
-
r70: {
|
|
4184
|
-
quality: 1,
|
|
4185
|
-
what: 'Element is obsolete or deprecated'
|
|
4186
|
-
}
|
|
4187
|
-
},
|
|
4188
|
-
htmlcs: {
|
|
4189
|
-
'e:AA.1_3_1.H49.AlignAttr': {
|
|
4190
|
-
quality: 1,
|
|
4191
|
-
what: 'align attribute is obsolete'
|
|
4192
|
-
},
|
|
4193
|
-
'e:AA.1_3_1.H49.Center': {
|
|
4194
|
-
quality: 1,
|
|
4195
|
-
what: 'center element is obsolete'
|
|
4196
|
-
},
|
|
4197
|
-
'e:AA.1_3_1.H49.Font': {
|
|
4198
|
-
quality: 1,
|
|
4199
|
-
what: 'font element is obsolete'
|
|
4200
|
-
}
|
|
4201
|
-
},
|
|
4202
|
-
ibm: {
|
|
4203
|
-
aria_attribute_deprecated: {
|
|
4204
|
-
quality: 1,
|
|
4205
|
-
what: 'ARIA role or attribute is deprecated'
|
|
4206
|
-
},
|
|
4207
|
-
combobox_version: {
|
|
4208
|
-
quality: 1,
|
|
4209
|
-
what: 'combobox design pattern is invalid for ARIA 1.2'
|
|
4210
|
-
},
|
|
4211
|
-
element_attribute_deprecated: {
|
|
4212
|
-
quality: 1,
|
|
4213
|
-
what: 'Element or attribute is obsolete'
|
|
4214
|
-
}
|
|
4215
|
-
},
|
|
4216
|
-
nuVal: {
|
|
4217
|
-
'The center element is obsolete. Use CSS instead.': {
|
|
4218
|
-
quality: 1,
|
|
4219
|
-
what: 'center element is obsolete'
|
|
4220
|
-
},
|
|
4221
|
-
'The font element is obsolete. Use CSS instead.': {
|
|
4222
|
-
quality: 1,
|
|
4223
|
-
what: 'font element is obsolete'
|
|
4224
|
-
},
|
|
4225
|
-
'^The .+ attribute on the .+ element is obsolete.+$': {
|
|
4226
|
-
quality: 1,
|
|
4227
|
-
what: 'attribute is obsolete on its element'
|
|
4228
|
-
},
|
|
4229
|
-
'The only allowed value for the charset attribute for the script element is utf-8. (But the attribute is not needed and should be omitted altogether.)': {
|
|
4230
|
-
quality: 1,
|
|
4231
|
-
what: 'charset attribute has a value other than utf-8 and is unnecessary'
|
|
4232
|
-
},
|
|
4233
|
-
'Using the meta element to specify the document-wide default language is obsolete. Consider specifying the language on the root element instead.': {
|
|
4234
|
-
quality: 1,
|
|
4235
|
-
what: 'language declaration in a meta element is obsolete'
|
|
4236
|
-
},
|
|
4237
|
-
'The name attribute is obsolete. Consider putting an id attribute on the nearest container instead.': {
|
|
4238
|
-
quality: 1,
|
|
4239
|
-
what: 'name attribute is obsolete'
|
|
4240
|
-
}
|
|
4241
|
-
},
|
|
4242
|
-
wave: {
|
|
4243
|
-
'a:longdesc': {
|
|
4244
|
-
quality: 1,
|
|
4245
|
-
what: 'longdesc attribute is obsolete'
|
|
4246
|
-
}
|
|
4247
|
-
}
|
|
4248
|
-
}
|
|
4249
|
-
},
|
|
4250
|
-
parseError: {
|
|
4251
|
-
weight: 3,
|
|
4252
|
-
packages: {
|
|
4253
|
-
nuVal: {
|
|
4254
|
-
'CSS: font-size: One operand must be a number.': {
|
|
4255
|
-
quality: 1,
|
|
4256
|
-
what: 'CSS font-size property has no numeric operand'
|
|
4257
|
-
},
|
|
4258
|
-
'^CSS: .+: Parse Error.*$': {
|
|
4259
|
-
quality: 1,
|
|
4260
|
-
what: 'Invalid CSS'
|
|
4261
|
-
},
|
|
4262
|
-
'^CSS: .+: .+ is not a .+ value.*$': {
|
|
4263
|
-
quality: 1,
|
|
4264
|
-
what: 'Invalid value in CSS'
|
|
4265
|
-
},
|
|
4266
|
-
'^CSS: .+: Property .+ doesn\'t exist.*$': {
|
|
4267
|
-
quality: 1,
|
|
4268
|
-
what: 'Invalid property in CSS'
|
|
4269
|
-
},
|
|
4270
|
-
'^CSS: .+: only 0 can be a length. You must put a unit after your number.*$': {
|
|
4271
|
-
quality: 1,
|
|
4272
|
-
what: 'Length in CSS is nonzero but has no unit'
|
|
4273
|
-
},
|
|
4274
|
-
'^CSS: .+: only 0 can be a unit. You must put a unit after your number.*$': {
|
|
4275
|
-
quality: 1,
|
|
4276
|
-
what: 'Number in CSS is nonzero but has no unit'
|
|
4277
|
-
},
|
|
4278
|
-
'CSS: Parse Error.': {
|
|
4279
|
-
quality: 1,
|
|
4280
|
-
what: 'Invalid CSS'
|
|
4281
|
-
},
|
|
4282
|
-
'^CSS: .+: Too many values or values are not recognized.+$': {
|
|
4283
|
-
quality: 1,
|
|
4284
|
-
what: 'Invalid CSS value or too many values'
|
|
4285
|
-
},
|
|
4286
|
-
'^CSS: .+: Invalid type: .+$': {
|
|
4287
|
-
quality: 1,
|
|
4288
|
-
what: 'Invalid type of CSS value'
|
|
4289
|
-
},
|
|
4290
|
-
'^CSS: .+: The types are incompatible.*$': {
|
|
4291
|
-
quality: 1,
|
|
4292
|
-
what: 'Incompatible types of CSS values'
|
|
4293
|
-
},
|
|
4294
|
-
'^CSS: .+: Unknown dimension.*$': {
|
|
4295
|
-
quality: 1,
|
|
4296
|
-
what: 'Unknown CSS dimension'
|
|
4297
|
-
},
|
|
4298
|
-
'^The aria-hidden attribute must not be specified on the .+ element.*$': {
|
|
4299
|
-
quality: 1,
|
|
4300
|
-
what: 'aria-hidden attribute is invalid for its element'
|
|
4301
|
-
},
|
|
4302
|
-
'The aria-hidden attribute must not be specified on an input element whose type attribute has the value hidden.': {
|
|
4303
|
-
quality: 1,
|
|
4304
|
-
what: 'aria-hidden attribute is invalid for an input element with type="hidden"'
|
|
4305
|
-
},
|
|
4306
|
-
'^Stray end tag .+$': {
|
|
4307
|
-
quality: 1,
|
|
4308
|
-
what: 'Invalid closing tag'
|
|
4309
|
-
},
|
|
4310
|
-
'^Start tag .+ seen but an element of the same type was already open.*$': {
|
|
4311
|
-
quality: 1,
|
|
4312
|
-
what: 'Element is invalidly a descendant of another such element'
|
|
4313
|
-
},
|
|
4314
|
-
'^Bad start tag in .+$': {
|
|
4315
|
-
quality: 1,
|
|
4316
|
-
what: 'Invalid start tag'
|
|
4317
|
-
},
|
|
4318
|
-
'^End tag .+ violates nesting rules.*$': {
|
|
4319
|
-
quality: 1,
|
|
4320
|
-
what: 'End tag violates nesting rules'
|
|
4321
|
-
},
|
|
4322
|
-
'^Element .+ not allowed as child of element .+ in this context.*$': {
|
|
4323
|
-
quality: 1,
|
|
4324
|
-
what: 'Element not allowed as a child of its parent here'
|
|
4325
|
-
},
|
|
4326
|
-
'Saw <!-- within a comment. Probable cause: Nested comment (not allowed).': {
|
|
4327
|
-
quality: 1,
|
|
4328
|
-
what: 'Comment is nested within a comment'
|
|
4329
|
-
},
|
|
4330
|
-
'The document is not mappable to XML 1.0 due to two consecutive hyphens in a comment.': {
|
|
4331
|
-
quality: 1,
|
|
4332
|
-
what: 'Comment contains --'
|
|
4333
|
-
},
|
|
4334
|
-
'^Element name .+ cannot be represented as XML 1\\.0.*$': {
|
|
4335
|
-
quality: 1,
|
|
4336
|
-
what: 'Invalid element name'
|
|
4337
|
-
},
|
|
4338
|
-
'^Forbidden code point U+.+$': {
|
|
4339
|
-
quality: 1,
|
|
4340
|
-
what: 'Invalid Unicode code point'
|
|
4341
|
-
},
|
|
4342
|
-
'^Internal encoding declaration .+ disagrees with the actual encoding of the document.*$': {
|
|
4343
|
-
quality: 1,
|
|
4344
|
-
what: 'Encoding declaration disagrees with the actual encoding of the page'
|
|
4345
|
-
}
|
|
4346
|
-
}
|
|
4347
|
-
}
|
|
4348
|
-
},
|
|
4349
|
-
encodingBad: {
|
|
4350
|
-
weight: 4,
|
|
4351
|
-
packages: {
|
|
4352
|
-
nuVal: {
|
|
4353
|
-
'Document uses the Unicode Private Use Area(s), which should not be used in publicly exchanged documents. (Charmod C073)': {
|
|
4354
|
-
quality: 1,
|
|
4355
|
-
what: 'Page includes a Unicode PUA character'
|
|
4356
|
-
}
|
|
4357
|
-
}
|
|
4358
|
-
}
|
|
4359
|
-
},
|
|
4360
|
-
fatalError: {
|
|
4361
|
-
weight: 50,
|
|
4362
|
-
packages: {
|
|
4363
|
-
nuVal: {
|
|
4364
|
-
'Cannot recover after last error. Any further errors will be ignored.': {
|
|
4365
|
-
quality: 1,
|
|
4366
|
-
what: 'Testing was interrupted by a fatal error'
|
|
4367
|
-
}
|
|
4368
|
-
}
|
|
4369
|
-
}
|
|
4370
|
-
}
|
|
4371
|
-
};
|
|
4372
|
-
|
|
4373
|
-
// VARIABLES
|
|
4374
|
-
|
|
4375
|
-
let packageDetails = {};
|
|
4376
|
-
let groupDetails = {};
|
|
4377
|
-
let summary = {};
|
|
4378
|
-
let preventionScores = {};
|
|
4379
|
-
|
|
4380
|
-
// FUNCTIONS
|
|
4381
|
-
|
|
4382
|
-
// Initialize the variables.
|
|
4383
|
-
const init = () => {
|
|
4384
|
-
packageDetails = {};
|
|
4385
|
-
groupDetails = {
|
|
4386
|
-
groups: {},
|
|
4387
|
-
solos: {}
|
|
4388
|
-
};
|
|
4389
|
-
summary = {
|
|
4390
|
-
total: 0,
|
|
4391
|
-
log: 0,
|
|
4392
|
-
preventions: 0,
|
|
4393
|
-
solos: 0,
|
|
4394
|
-
groups: []
|
|
4395
|
-
};
|
|
4396
|
-
preventionScores = {};
|
|
4397
|
-
};
|
|
4398
|
-
|
|
4399
|
-
// Adds a score to the package details.
|
|
4400
|
-
const addDetail = (actWhich, testID, addition = 1) => {
|
|
4401
|
-
if (addition) {
|
|
4402
|
-
if (!packageDetails[actWhich]) {
|
|
4403
|
-
packageDetails[actWhich] = {};
|
|
4404
|
-
}
|
|
4405
|
-
if (!packageDetails[actWhich][testID]) {
|
|
4406
|
-
packageDetails[actWhich][testID] = 0;
|
|
4407
|
-
}
|
|
4408
|
-
packageDetails[actWhich][testID] += Math.round(addition);
|
|
4409
|
-
}
|
|
4410
|
-
};
|
|
4411
|
-
// Scores a report.
|
|
4412
|
-
exports.scorer = async report => {
|
|
4413
|
-
// Initialize the variables.
|
|
4414
|
-
init();
|
|
4415
|
-
// If there are any acts in the report:
|
|
4416
|
-
const {acts} = report;
|
|
4417
|
-
if (Array.isArray(acts)) {
|
|
4418
|
-
// If any of them are test acts:
|
|
4419
|
-
const testActs = acts.filter(act => act.type === 'test');
|
|
4420
|
-
if (testActs.length) {
|
|
4421
|
-
// For each test act:
|
|
4422
|
-
testActs.forEach(test => {
|
|
4423
|
-
const {which} = test;
|
|
4424
|
-
// Add scores to the package details.
|
|
4425
|
-
if (which === 'alfa') {
|
|
4426
|
-
const issues = test.result && test.result.items;
|
|
4427
|
-
if (issues && Array.isArray(issues)) {
|
|
4428
|
-
issues.forEach(issue => {
|
|
4429
|
-
const {verdict, rule} = issue;
|
|
4430
|
-
if (verdict && rule) {
|
|
4431
|
-
const {ruleID} = rule;
|
|
4432
|
-
if (ruleID) {
|
|
4433
|
-
// Add 4 per failure, 1 per warning (cantTell).
|
|
4434
|
-
addDetail(which, ruleID, verdict === 'failed' ? 4 : 1);
|
|
4435
|
-
}
|
|
4436
|
-
}
|
|
4437
|
-
});
|
|
4438
|
-
}
|
|
4439
|
-
}
|
|
4440
|
-
else if (which === 'axe') {
|
|
4441
|
-
const impactScores = {
|
|
4442
|
-
minor: 1,
|
|
4443
|
-
moderate: 2,
|
|
4444
|
-
serious: 3,
|
|
4445
|
-
critical: 4
|
|
4446
|
-
};
|
|
4447
|
-
const tests = test.result && test.result.details;
|
|
4448
|
-
if (tests) {
|
|
4449
|
-
const warnings = tests.incomplete;
|
|
4450
|
-
const {violations} = tests;
|
|
4451
|
-
[[warnings, 0.25], [violations, 1]].forEach(issueClass => {
|
|
4452
|
-
if (issueClass[0] && Array.isArray(issueClass[0])) {
|
|
4453
|
-
issueClass[0].forEach(issueType => {
|
|
4454
|
-
const {id, nodes} = issueType;
|
|
4455
|
-
if (id && nodes && Array.isArray(nodes)) {
|
|
4456
|
-
nodes.forEach(node => {
|
|
4457
|
-
const {impact} = node;
|
|
4458
|
-
if (impact) {
|
|
4459
|
-
// Add the impact score for a violation or 25% of it for a warning.
|
|
4460
|
-
addDetail(which, id, issueClass[1] * impactScores[impact]);
|
|
4461
|
-
}
|
|
4462
|
-
});
|
|
4463
|
-
}
|
|
4464
|
-
});
|
|
4465
|
-
}
|
|
4466
|
-
});
|
|
4467
|
-
}
|
|
4468
|
-
}
|
|
4469
|
-
else if (which === 'continuum') {
|
|
4470
|
-
const issues = test.result;
|
|
4471
|
-
if (issues && Array.isArray(issues)) {
|
|
4472
|
-
issues.forEach(issue => {
|
|
4473
|
-
// Add 4 per violation.
|
|
4474
|
-
addDetail(which, issue.engineTestId, 4);
|
|
4475
|
-
});
|
|
4476
|
-
}
|
|
4477
|
-
}
|
|
4478
|
-
else if (which === 'htmlcs') {
|
|
4479
|
-
const issues = test.result;
|
|
4480
|
-
if (issues) {
|
|
4481
|
-
['Error', 'Warning'].forEach(issueClassName => {
|
|
4482
|
-
const classData = issues[issueClassName];
|
|
4483
|
-
if (classData) {
|
|
4484
|
-
const issueTypes = Object.keys(classData);
|
|
4485
|
-
issueTypes.forEach(issueTypeName => {
|
|
4486
|
-
const issueArrays = Object.values(classData[issueTypeName]);
|
|
4487
|
-
const issueCount = issueArrays.reduce((count, array) => count + array.length, 0);
|
|
4488
|
-
const classCode = issueClassName[0].toLowerCase();
|
|
4489
|
-
const code = `${classCode}:${issueTypeName}`;
|
|
4490
|
-
// Add 4 per error, 1 per warning.
|
|
4491
|
-
const weight = classCode === 'e' ? 4 : 1;
|
|
4492
|
-
addDetail(which, code, weight * issueCount);
|
|
4493
|
-
});
|
|
4494
|
-
}
|
|
4495
|
-
});
|
|
4496
|
-
}
|
|
4497
|
-
}
|
|
4498
|
-
else if (which === 'ibm') {
|
|
4499
|
-
const {result} = test;
|
|
4500
|
-
const {content, url} = result;
|
|
4501
|
-
if (content && url) {
|
|
4502
|
-
let preferredMode = 'content';
|
|
4503
|
-
if (
|
|
4504
|
-
content.error ||
|
|
4505
|
-
(content.totals &&
|
|
4506
|
-
content.totals.violation &&
|
|
4507
|
-
url.totals &&
|
|
4508
|
-
url.totals.violation &&
|
|
4509
|
-
url.totals.violation > content.totals.violation)
|
|
4510
|
-
) {
|
|
4511
|
-
preferredMode = 'url';
|
|
4512
|
-
}
|
|
4513
|
-
const {items} = result[preferredMode];
|
|
4514
|
-
if (items && Array.isArray(items)) {
|
|
4515
|
-
items.forEach(issue => {
|
|
4516
|
-
const {ruleId, level} = issue;
|
|
4517
|
-
if (ruleId && level) {
|
|
4518
|
-
// Add 4 per violation, 1 per warning (recommendation).
|
|
4519
|
-
addDetail(which, ruleId, level === 'violation' ? 4 : 1);
|
|
4520
|
-
}
|
|
4521
|
-
});
|
|
4522
|
-
}
|
|
4523
|
-
}
|
|
4524
|
-
}
|
|
4525
|
-
else if (which === 'nuVal') {
|
|
4526
|
-
const issues = test.result && test.result.messages;
|
|
4527
|
-
if (issues) {
|
|
4528
|
-
issues.forEach(issue => {
|
|
4529
|
-
// Add 4 per error, 1 per warning.
|
|
4530
|
-
const weight = issue.type === 'error' ? 4 : 1;
|
|
4531
|
-
addDetail(which, issue.message, weight);
|
|
4532
|
-
});
|
|
4533
|
-
}
|
|
4534
|
-
}
|
|
4535
|
-
else if (which === 'tenon') {
|
|
4536
|
-
const issues =
|
|
4537
|
-
test.result && test.result.data && test.result.data.resultSet;
|
|
4538
|
-
if (issues && Array.isArray(issues)) {
|
|
4539
|
-
issues.forEach(issue => {
|
|
4540
|
-
const {tID, priority, certainty} = issue;
|
|
4541
|
-
if (tID && priority && certainty) {
|
|
4542
|
-
// Add 4 per issue if certainty and priority 100, less if less.
|
|
4543
|
-
addDetail(which, tID, certainty * priority / 2500);
|
|
4544
|
-
}
|
|
4545
|
-
});
|
|
4546
|
-
}
|
|
4547
|
-
}
|
|
4548
|
-
else if (which === 'wave') {
|
|
4549
|
-
const classScores = {
|
|
4550
|
-
error: 4,
|
|
4551
|
-
contrast: 3,
|
|
4552
|
-
alert: 1
|
|
4553
|
-
};
|
|
4554
|
-
const issueClasses = test.result && test.result.categories;
|
|
4555
|
-
if (issueClasses) {
|
|
4556
|
-
['error', 'contrast', 'alert'].forEach(issueClass => {
|
|
4557
|
-
const {items} = issueClasses[issueClass];
|
|
4558
|
-
if (items) {
|
|
4559
|
-
const testIDs = Object.keys(items);
|
|
4560
|
-
if (testIDs.length) {
|
|
4561
|
-
testIDs.forEach(testID => {
|
|
4562
|
-
const {count} = items[testID];
|
|
4563
|
-
if (count) {
|
|
4564
|
-
// Add 4 per error, 3 per contrast error, 1 per warning (alert).
|
|
4565
|
-
addDetail(
|
|
4566
|
-
which, `${issueClass[0]}:${testID}`, count * classScores[issueClass]
|
|
4567
|
-
);
|
|
4568
|
-
}
|
|
4569
|
-
});
|
|
4570
|
-
}
|
|
4571
|
-
}
|
|
4572
|
-
});
|
|
4573
|
-
}
|
|
4574
|
-
}
|
|
4575
|
-
else if (which === 'bulk') {
|
|
4576
|
-
const count = test.result && test.result.visibleElements;
|
|
4577
|
-
if (typeof count === 'number') {
|
|
4578
|
-
// Add 1 per 300 visible elements beyond 300.
|
|
4579
|
-
addDetail('testaro', which, Math.max(0, count / 300 - 1));
|
|
4580
|
-
}
|
|
4581
|
-
}
|
|
4582
|
-
else if (which === 'embAc') {
|
|
4583
|
-
const issueCounts = test.result && test.result.totals;
|
|
4584
|
-
if (issueCounts) {
|
|
4585
|
-
const counts = Object.values(issueCounts);
|
|
4586
|
-
const total = counts.reduce((sum, current) => sum + current);
|
|
4587
|
-
// Add 3 per embedded element.
|
|
4588
|
-
addDetail('testaro', which, 3 * total);
|
|
4589
|
-
}
|
|
4590
|
-
}
|
|
4591
|
-
else if (which === 'focAll') {
|
|
4592
|
-
const discrepancy = test.result && test.result.discrepancy;
|
|
4593
|
-
if (discrepancy) {
|
|
4594
|
-
addDetail('testaro', which, 2 * Math.abs(discrepancy));
|
|
4595
|
-
}
|
|
4596
|
-
}
|
|
4597
|
-
else if (which === 'focInd') {
|
|
4598
|
-
const issueTypes =
|
|
4599
|
-
test.result && test.result.totals && test.result.totals.types;
|
|
4600
|
-
if (issueTypes) {
|
|
4601
|
-
const missingCount = issueTypes.indicatorMissing
|
|
4602
|
-
&& issueTypes.indicatorMissing.total
|
|
4603
|
-
|| 0;
|
|
4604
|
-
const badCount = issueTypes.nonOutlinePresent
|
|
4605
|
-
&& issueTypes.nonOutlinePresent.total
|
|
4606
|
-
|| 0;
|
|
4607
|
-
// Add 3 per missing, 1 per non-outline focus indicator.
|
|
4608
|
-
addDetail('testaro', which, badCount + 3 * missingCount);
|
|
4609
|
-
}
|
|
4610
|
-
}
|
|
4611
|
-
else if (which === 'focOp') {
|
|
4612
|
-
const issueTypes =
|
|
4613
|
-
test.result && test.result.totals && test.result.totals.types;
|
|
4614
|
-
if (issueTypes) {
|
|
4615
|
-
const noOpCount = issueTypes.onlyFocusable && issueTypes.onlyFocusable.total || 0;
|
|
4616
|
-
const noFocCount = issueTypes.onlyOperable && issueTypes.onlyOperable.total || 0;
|
|
4617
|
-
// Add 2 per unfocusable, 0.5 per inoperable element.
|
|
4618
|
-
addDetail('testaro', which, 2 * noFocCount + 0.5 * noOpCount);
|
|
4619
|
-
}
|
|
4620
|
-
}
|
|
4621
|
-
else if (which === 'hover') {
|
|
4622
|
-
const issues = test.result && test.result.totals;
|
|
4623
|
-
if (issues) {
|
|
4624
|
-
const {
|
|
4625
|
-
impactTriggers,
|
|
4626
|
-
additions,
|
|
4627
|
-
removals,
|
|
4628
|
-
opacityChanges,
|
|
4629
|
-
opacityImpact,
|
|
4630
|
-
unhoverables
|
|
4631
|
-
} = issues;
|
|
4632
|
-
// Add score with weights on hover-impact types.
|
|
4633
|
-
const score = 2 * impactTriggers
|
|
4634
|
-
+ 0.3 * additions
|
|
4635
|
-
+ removals
|
|
4636
|
-
+ 0.2 * opacityChanges
|
|
4637
|
-
+ 0.1 * opacityImpact
|
|
4638
|
-
+ unhoverables;
|
|
4639
|
-
if (score) {
|
|
4640
|
-
addDetail('testaro', which, score);
|
|
4641
|
-
}
|
|
4642
|
-
}
|
|
4643
|
-
}
|
|
4644
|
-
else if (which === 'labClash') {
|
|
4645
|
-
const mislabeledCount = test.result
|
|
4646
|
-
&& test.result.totals
|
|
4647
|
-
&& test.result.totals.mislabeled
|
|
4648
|
-
|| 0;
|
|
4649
|
-
// Add 1 per element with conflicting labels (ignoring unlabeled elements).
|
|
4650
|
-
addDetail('testaro', which, mislabeledCount);
|
|
4651
|
-
}
|
|
4652
|
-
else if (which === 'linkUl') {
|
|
4653
|
-
const totals = test.result && test.result.totals && test.result.totals.adjacent;
|
|
4654
|
-
if (totals) {
|
|
4655
|
-
const nonUl = totals.total - totals.underlined || 0;
|
|
4656
|
-
// Add 2 per non-underlined adjacent link.
|
|
4657
|
-
addDetail('testaro', which, 2 * nonUl);
|
|
4658
|
-
}
|
|
4659
|
-
}
|
|
4660
|
-
else if (which === 'menuNav') {
|
|
4661
|
-
const issueCount = test.result
|
|
4662
|
-
&& test.result.totals
|
|
4663
|
-
&& test.result.totals.navigations
|
|
4664
|
-
&& test.result.totals.navigations.all
|
|
4665
|
-
&& test.result.totals.navigations.all.incorrect
|
|
4666
|
-
|| 0;
|
|
4667
|
-
// Add 2 per defect.
|
|
4668
|
-
addDetail('testaro', which, 2 * issueCount);
|
|
4669
|
-
}
|
|
4670
|
-
else if (which === 'motion') {
|
|
4671
|
-
const data = test.result;
|
|
4672
|
-
if (data) {
|
|
4673
|
-
const {
|
|
4674
|
-
meanLocalRatio,
|
|
4675
|
-
maxLocalRatio,
|
|
4676
|
-
globalRatio,
|
|
4677
|
-
meanPixelChange,
|
|
4678
|
-
maxPixelChange,
|
|
4679
|
-
changeFrequency
|
|
4680
|
-
} = data;
|
|
4681
|
-
const score = 2 * (meanLocalRatio - 1)
|
|
4682
|
-
+ (maxLocalRatio - 1)
|
|
4683
|
-
+ globalRatio - 1
|
|
4684
|
-
+ meanPixelChange / 10000
|
|
4685
|
-
+ maxPixelChange / 25000
|
|
4686
|
-
+ 3 * changeFrequency
|
|
4687
|
-
|| 0;
|
|
4688
|
-
addDetail('testaro', which, score);
|
|
4689
|
-
}
|
|
4690
|
-
}
|
|
4691
|
-
else if (which === 'radioSet') {
|
|
4692
|
-
const totals = test.result && test.result.totals;
|
|
4693
|
-
if (totals) {
|
|
4694
|
-
const {total, inSet} = totals;
|
|
4695
|
-
const score = total - inSet || 0;
|
|
4696
|
-
// Add 1 per misgrouped radio button.
|
|
4697
|
-
addDetail('testaro', which, score);
|
|
4698
|
-
}
|
|
4699
|
-
}
|
|
4700
|
-
else if (which === 'role') {
|
|
4701
|
-
const badCount = test.result && test.result.badRoleElements || 0;
|
|
4702
|
-
const redundantCount = test.result && test.result.redundantRoleElements || 0;
|
|
4703
|
-
// Add 2 per bad role and 1 per redundant role.
|
|
4704
|
-
addDetail('testaro', which, 2 * badCount + redundantCount);
|
|
4705
|
-
}
|
|
4706
|
-
else if (which === 'styleDiff') {
|
|
4707
|
-
const totals = test.result && test.result.totals;
|
|
4708
|
-
if (totals) {
|
|
4709
|
-
let score = 0;
|
|
4710
|
-
// For each element type that has any style diversity:
|
|
4711
|
-
Object.values(totals).forEach(typeData => {
|
|
4712
|
-
const {total, subtotals} = typeData;
|
|
4713
|
-
if (subtotals) {
|
|
4714
|
-
const styleCount = subtotals.length;
|
|
4715
|
-
const plurality = subtotals[0];
|
|
4716
|
-
const minorities = total - plurality;
|
|
4717
|
-
// Add 1 per style, 0.2 per element with any nonplurality style.
|
|
4718
|
-
score += styleCount + 0.2 * minorities;
|
|
4719
|
-
}
|
|
4720
|
-
});
|
|
4721
|
-
addDetail('testaro', which, score);
|
|
4722
|
-
}
|
|
4723
|
-
}
|
|
4724
|
-
else if (which === 'tabNav') {
|
|
4725
|
-
const issueCount = test.result
|
|
4726
|
-
&& test.result.totals
|
|
4727
|
-
&& test.result.totals.navigations
|
|
4728
|
-
&& test.result.totals.navigations.all
|
|
4729
|
-
&& test.result.totals.navigations.all.incorrect
|
|
4730
|
-
|| 0;
|
|
4731
|
-
// Add 2 per defect.
|
|
4732
|
-
addDetail('testaro', which, 2 * issueCount);
|
|
4733
|
-
}
|
|
4734
|
-
else if (which === 'zIndex') {
|
|
4735
|
-
const issueCount = test.result && test.result.totals && test.result.totals.total || 0;
|
|
4736
|
-
// Add 1 per non-auto zIndex.
|
|
4737
|
-
addDetail('testaro', which, issueCount);
|
|
4738
|
-
}
|
|
4739
|
-
});
|
|
4740
|
-
// Get the prevention scores and add them to the summary.
|
|
4741
|
-
const actsPrevented = testActs.filter(test => test.result.prevented);
|
|
4742
|
-
actsPrevented.forEach(act => {
|
|
4743
|
-
if (otherPackages.includes(act.which)) {
|
|
4744
|
-
preventionScores[act.which] = preventionWeights.other;
|
|
4745
|
-
}
|
|
4746
|
-
else {
|
|
4747
|
-
preventionScores[`testaro-${act.which}`] = preventionWeights.testaro;
|
|
4748
|
-
}
|
|
4749
|
-
});
|
|
4750
|
-
const preventionScore = Object.values(preventionScores).reduce(
|
|
4751
|
-
(sum, current) => sum + current,
|
|
4752
|
-
0
|
|
4753
|
-
);
|
|
4754
|
-
const roundedScore = Math.round(preventionScore);
|
|
4755
|
-
summary.preventions = roundedScore;
|
|
4756
|
-
summary.total += roundedScore;
|
|
4757
|
-
// Reorganize the group data.
|
|
4758
|
-
const testGroups = {
|
|
4759
|
-
testaro: {},
|
|
4760
|
-
alfa: {},
|
|
4761
|
-
axe: {},
|
|
4762
|
-
continuum: {},
|
|
4763
|
-
htmlcs: {},
|
|
4764
|
-
ibm: {},
|
|
4765
|
-
nuVal: {},
|
|
4766
|
-
tenon: {},
|
|
4767
|
-
wave: {}
|
|
4768
|
-
};
|
|
4769
|
-
Object.keys(groups).forEach(groupName => {
|
|
4770
|
-
Object.keys(groups[groupName].packages).forEach(packageName => {
|
|
4771
|
-
Object.keys(groups[groupName].packages[packageName]).forEach(testID => {
|
|
4772
|
-
testGroups[packageName][testID] = groupName;
|
|
4773
|
-
});
|
|
4774
|
-
});
|
|
4775
|
-
});
|
|
4776
|
-
// Populate the group details with group and solo test scores.
|
|
4777
|
-
// For each package with any scores:
|
|
4778
|
-
Object.keys(packageDetails).forEach(packageName => {
|
|
4779
|
-
const matchers = testMatchers[packageName];
|
|
4780
|
-
let testClass = '';
|
|
4781
|
-
// For each test with any scores in the package:
|
|
4782
|
-
Object.keys(packageDetails[packageName]).forEach(testID => {
|
|
4783
|
-
// Determine whether the test is in a group.
|
|
4784
|
-
let groupName = testGroups[packageName][testID];
|
|
4785
|
-
// If not:
|
|
4786
|
-
if (! groupName) {
|
|
4787
|
-
// Determine whether the package has test classes and the class is in a group.
|
|
4788
|
-
testClass = matchers && matchers.find(matcher => matcher.test(testID));
|
|
4789
|
-
if (testClass) {
|
|
4790
|
-
testID = testClass.source;
|
|
4791
|
-
groupName = testGroups[packageName][testID];
|
|
4792
|
-
}
|
|
4793
|
-
}
|
|
4794
|
-
// If the test or its class is in a group:
|
|
4795
|
-
if (groupName) {
|
|
4796
|
-
// Determine the preweighted or group-weighted score.
|
|
4797
|
-
if (! groupDetails.groups[groupName]) {
|
|
4798
|
-
groupDetails.groups[groupName] = {};
|
|
4799
|
-
}
|
|
4800
|
-
if (! groupDetails.groups[groupName][packageName]) {
|
|
4801
|
-
groupDetails.groups[groupName][packageName] = {};
|
|
4802
|
-
}
|
|
4803
|
-
let weightedScore = packageDetails[packageName][testID];
|
|
4804
|
-
if (!preWeightedPackages.includes(groupName)) {
|
|
4805
|
-
weightedScore *= groups[groupName].weight / 4;
|
|
4806
|
-
}
|
|
4807
|
-
// Adjust the score for the quality of the test.
|
|
4808
|
-
weightedScore *= groups[groupName].packages[packageName][testID].quality;
|
|
4809
|
-
// Round the score, but not to less than 1.
|
|
4810
|
-
const roundedScore = Math.max(Math.round(weightedScore), 1);
|
|
4811
|
-
// Add the rounded score and the test description to the group details.
|
|
4812
|
-
groupDetails.groups[groupName][packageName][testID] = {
|
|
4813
|
-
score: roundedScore,
|
|
4814
|
-
what: groups[groupName].packages[packageName][testID].what
|
|
4815
|
-
};
|
|
4816
|
-
}
|
|
4817
|
-
// Otherwise, if the package has varying test names and the test belongs to a class:
|
|
4818
|
-
else if (matchers && (testCode = matchers.find(matcher => matcher.test(testID)))) {
|
|
4819
|
-
|
|
4820
|
-
}
|
|
4821
|
-
// Otherwise, i.e. if the test is solo:
|
|
4822
|
-
else {
|
|
4823
|
-
if (! groupDetails.solos[packageName]) {
|
|
4824
|
-
groupDetails.solos[packageName] = {};
|
|
4825
|
-
}
|
|
4826
|
-
const roundedScore = Math.round(packageDetails[packageName][testID]);
|
|
4827
|
-
groupDetails.solos[packageName][testID] = roundedScore;
|
|
4828
|
-
}
|
|
4829
|
-
});
|
|
4830
|
-
});
|
|
4831
|
-
// Determine the group scores and add them to the summary.
|
|
4832
|
-
const groupNames = Object.keys(groupDetails.groups);
|
|
4833
|
-
const {absolute, largest, smaller} = groupWeights;
|
|
4834
|
-
// For each group with any scores:
|
|
4835
|
-
groupNames.forEach(groupName => {
|
|
4836
|
-
const scores = [];
|
|
4837
|
-
// For each package with any scores in the group:
|
|
4838
|
-
const groupPackageData = Object.values(groupDetails.groups[groupName]);
|
|
4839
|
-
groupPackageData.forEach(packageObj => {
|
|
4840
|
-
// Get the sum of the scores of the tests of the package in the group.
|
|
4841
|
-
const scoreSum = Object.values(packageObj).reduce(
|
|
4842
|
-
(sum, current) => sum + current.score,
|
|
4843
|
-
0
|
|
4844
|
-
);
|
|
4845
|
-
// Add the sum to the list of package scores in the group.
|
|
4846
|
-
scores.push(scoreSum);
|
|
4847
|
-
});
|
|
4848
|
-
// Sort the scores in descending order.
|
|
4849
|
-
scores.sort((a, b) => b - a);
|
|
4850
|
-
// Compute the sum of the absolute score and the weighted largest and other scores.
|
|
4851
|
-
const groupScore = absolute
|
|
4852
|
-
+ largest * scores[0]
|
|
4853
|
-
+ smaller * scores.slice(1).reduce((sum, current) => sum + current, 0);
|
|
4854
|
-
const roundedGroupScore = Math.round(groupScore);
|
|
4855
|
-
summary.groups.push({
|
|
4856
|
-
groupName,
|
|
4857
|
-
score: roundedGroupScore
|
|
4858
|
-
});
|
|
4859
|
-
summary.total += roundedGroupScore;
|
|
4860
|
-
});
|
|
4861
|
-
summary.groups.sort((a, b) => b.score - a.score);
|
|
4862
|
-
// Determine the solo score and add it to the summary.
|
|
4863
|
-
const soloPackageNames = Object.keys(groupDetails.solos);
|
|
4864
|
-
soloPackageNames.forEach(packageName => {
|
|
4865
|
-
const testIDs = Object.keys(groupDetails.solos[packageName]);
|
|
4866
|
-
testIDs.forEach(testID => {
|
|
4867
|
-
const score = soloWeight * groupDetails.solos[packageName][testID];
|
|
4868
|
-
summary.solos += score;
|
|
4869
|
-
summary.total += score;
|
|
4870
|
-
});
|
|
4871
|
-
});
|
|
4872
|
-
summary.solos = Math.round(summary.solos);
|
|
4873
|
-
summary.total = Math.round(summary.total);
|
|
4874
|
-
}
|
|
4875
|
-
}
|
|
4876
|
-
// Get the log score.
|
|
4877
|
-
const logScore = logWeights.logCount * report.logCount
|
|
4878
|
-
+ logWeights.logSize * report.logSize +
|
|
4879
|
-
+ logWeights.errorLogCount * report.errorLogCount
|
|
4880
|
-
+ logWeights.errorLogSize * report.errorLogSize
|
|
4881
|
-
+ logWeights.prohibitedCount * report.prohibitedCount +
|
|
4882
|
-
+ logWeights.visitTimeoutCount * report.visitTimeoutCount +
|
|
4883
|
-
+ logWeights.visitRejectionCount * report.visitRejectionCount;
|
|
4884
|
-
const roundedLogScore = Math.round(logScore);
|
|
4885
|
-
summary.log = roundedLogScore;
|
|
4886
|
-
summary.total += roundedLogScore;
|
|
4887
|
-
// Add the score facts to the report.
|
|
4888
|
-
report.score = {
|
|
4889
|
-
scoreProcID,
|
|
4890
|
-
logWeights,
|
|
4891
|
-
soloWeight,
|
|
4892
|
-
groupWeights,
|
|
4893
|
-
preventionWeights,
|
|
4894
|
-
packageDetails,
|
|
4895
|
-
groupDetails,
|
|
4896
|
-
preventionScores,
|
|
4897
|
-
summary
|
|
4898
|
-
};
|
|
4899
|
-
};
|