testaro 14.2.6 → 14.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -32
- package/package.json +1 -1
- package/testaro/allHidden.js +11 -3
- package/testaro/bulk.js +3 -1
- package/testaro/embAc.js +1 -0
- package/testaro/focAll.js +1 -0
- package/testaro/focInd.js +29 -12
- package/testaro/focOp.js +29 -12
- package/testaro/focVis.js +1 -0
- package/testaro/hover.js +2 -0
- package/testaro/labClash.js +29 -12
- package/testaro/linkTo.js +1 -0
- package/testaro/linkUl.js +1 -0
- package/testaro/menuNav.js +7 -4
- package/testaro/miniText.js +1 -0
- package/testaro/motion.js +11 -9
- package/testaro/nonTable.js +2 -1
- package/testaro/radioSet.js +5 -3
- package/testaro/role.js +12 -8
- package/testaro/styleDiff.js +3 -1
- package/testaro/tabNav.js +5 -2
- package/testaro/titledEl.js +1 -0
- package/testaro/zIndex.js +2 -1
- package/tests/ibm.js +1 -1
package/README.md
CHANGED
|
@@ -207,6 +207,7 @@ The standard format of each tool report has two properties:
|
|
|
207
207
|
- `instances`: an array of objects describing facts about issue instances reported by the tool. Insofar as each tool permits, this object has these properties:
|
|
208
208
|
- `issueID`: a code identifying the issue
|
|
209
209
|
- `what`: a description of the issue
|
|
210
|
+
- `count` (optional): the count of instances if this instance represents multiple instances
|
|
210
211
|
- `ordinalSeverity`: how the tool ranks the severity of the instance, on a 4-point ordinal scale
|
|
211
212
|
- `location`: an object with three properties:
|
|
212
213
|
- `doc`: whether the source (`source`) or the browser rendition (`dom`) was tested
|
|
@@ -218,11 +219,11 @@ The original result of a test act is recorded as the value of a `result` propert
|
|
|
218
219
|
|
|
219
220
|
``` javascript
|
|
220
221
|
standardResult: {
|
|
221
|
-
totals: [2, 0,
|
|
222
|
+
totals: [2, 0, 17, 0],
|
|
222
223
|
instances: [
|
|
223
224
|
{
|
|
224
225
|
issueID: 'rule01',
|
|
225
|
-
what: '
|
|
226
|
+
what: 'Button type invalid',
|
|
226
227
|
ordinalSeverity: 0,
|
|
227
228
|
location: {
|
|
228
229
|
doc: 'dom',
|
|
@@ -233,7 +234,7 @@ standardResult: {
|
|
|
233
234
|
},
|
|
234
235
|
{
|
|
235
236
|
issueID: 'rule01',
|
|
236
|
-
what: '
|
|
237
|
+
what: 'Button type invalid',
|
|
237
238
|
ordinalSeverity: 1,
|
|
238
239
|
location: {
|
|
239
240
|
doc: 'dom',
|
|
@@ -244,20 +245,21 @@ standardResult: {
|
|
|
244
245
|
},
|
|
245
246
|
{
|
|
246
247
|
issueID: 'rule02',
|
|
247
|
-
what: '
|
|
248
|
+
what: 'Links have empty href attributes',
|
|
249
|
+
count: 17,
|
|
248
250
|
ordinalSeverity: 3,
|
|
249
251
|
location: {
|
|
250
|
-
doc: '
|
|
251
|
-
type: '
|
|
252
|
-
spec: '
|
|
252
|
+
doc: '',
|
|
253
|
+
type: '',
|
|
254
|
+
spec: ''
|
|
253
255
|
},
|
|
254
|
-
excerpt: '
|
|
256
|
+
excerpt: ''
|
|
255
257
|
}
|
|
256
258
|
]
|
|
257
259
|
}
|
|
258
260
|
```
|
|
259
261
|
|
|
260
|
-
If a tool has the option to be used without itemization and is being so used, the `instances` array
|
|
262
|
+
If a tool has the option to be used without itemization and is being so used, the `instances` array may be empty.
|
|
261
263
|
|
|
262
264
|
### Acts
|
|
263
265
|
|
|
@@ -454,29 +456,6 @@ The `continuum` tests makes use of the files in the `continuum` directory. The t
|
|
|
454
456
|
|
|
455
457
|
Level Access on 22 August 2022 granted authorization for the copying of the `AccessEngine.community.js` file insofar as necessary for allowing Continuum community edition tests to be included in Testaro.
|
|
456
458
|
|
|
457
|
-
###### IBM Equal Access
|
|
458
|
-
|
|
459
|
-
The `ibm` tests require the `aceconfig.js` file.
|
|
460
|
-
|
|
461
|
-
As of 2 March 2023 (version 3.1.45 of `accessibility-checker`), the `ibm` tool threw errors when hosted under the Windows operating system. To prevent these errors, it was possible to edit two files in the `accessibility-checker` package as follows:
|
|
462
|
-
|
|
463
|
-
In `node_modules/accessibility-checker/lib/ACEngineManager.js`, remove or comment out these lines starting on line 169:
|
|
464
|
-
|
|
465
|
-
```javaScript
|
|
466
|
-
if (nodePath.charAt(0) !== '/') {
|
|
467
|
-
nodePath = "../../" + nodePath;
|
|
468
|
-
}
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
In `node_modules/accessibility-checker/lib/reporters/ACReporterJSON.js`, add these lines starting on line 106, immediately before the line `var resultsFileName = pathLib.join(resultDir, results.label + '.json');`:
|
|
472
|
-
|
|
473
|
-
```javaScript
|
|
474
|
-
// Replace the colons in the label with hyphen-minuses.
|
|
475
|
-
results.label = results.label.replace(/:/g, '-');
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
These changes were proposed as pull requests 1333 and 1334 (https://github.com/IBMa/equal-access/pulls).
|
|
479
|
-
|
|
480
459
|
###### HTML CodeSniffer
|
|
481
460
|
|
|
482
461
|
The `htmlcs` tool makes use of the `htmlcs/HTMLCS.js` file. That file was created, and can be recreated if necessary, as follows:
|
|
@@ -509,6 +488,31 @@ The changes in `htmlcs/HTMLCS.js` are:
|
|
|
509
488
|
> );
|
|
510
489
|
```
|
|
511
490
|
|
|
491
|
+
###### IBM Equal Access
|
|
492
|
+
|
|
493
|
+
The `ibm` tests require the `aceconfig.js` file.
|
|
494
|
+
|
|
495
|
+
As of 2 March 2023 (version 3.1.45 of `accessibility-checker`), the `ibm` tool threw errors when hosted under the Windows operating system. To prevent these errors, it was possible to edit two files in the `accessibility-checker` package as follows:
|
|
496
|
+
|
|
497
|
+
In `node_modules/accessibility-checker/lib/ACEngineManager.js`, remove or comment out these lines starting on line 169:
|
|
498
|
+
|
|
499
|
+
```javaScript
|
|
500
|
+
if (nodePath.charAt(0) !== '/') {
|
|
501
|
+
nodePath = "../../" + nodePath;
|
|
502
|
+
}
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
In `node_modules/accessibility-checker/lib/reporters/ACReporterJSON.js`, add these lines starting on line 106, immediately before the line `var resultsFileName = pathLib.join(resultDir, results.label + '.json');`:
|
|
506
|
+
|
|
507
|
+
```javaScript
|
|
508
|
+
// Replace the colons in the label with hyphen-minuses.
|
|
509
|
+
results.label = results.label.replace(/:/g, '-');
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
These changes were proposed as pull requests 1333 and 1334 (https://github.com/IBMa/equal-access/pulls).
|
|
513
|
+
|
|
514
|
+
The `ibm` tool is one of two tools (`testaro` is the other) with a `withItems` property. If you set `withItems` to `false`, the result includes the counts of “violations” and “recommendations”, but no information about the rules that gave rise to them.
|
|
515
|
+
|
|
512
516
|
###### QualWeb
|
|
513
517
|
|
|
514
518
|
The `qualWeb` tool performs the ACT rules, WCAG Techniques, and best-practices tests of QualWeb. Only failures and warnings are included in the report. The EARL report of QualWeb is not generated, because it is equivalent to the report of the ACT rules tests.
|
|
@@ -555,6 +559,14 @@ Tenon recommends giving it a public URL rather than giving it the content of a p
|
|
|
555
559
|
|
|
556
560
|
If a `tenon` test act is included in a job, environment variables named `TENON_USER` and `TENON_PASSWORD` must exist, with your Tenon username and password, respectively, as their values. These could be obtained from [Tenon](https://tenon.io/documentation/overview) until Tenon was closed to new subscribers in or about October 2022.
|
|
557
561
|
|
|
562
|
+
###### Testaro
|
|
563
|
+
|
|
564
|
+
If you do not specify rules when using the `testaro` tool, Testaro will test for the rules listed in the `evalRules` object of the `tests/testaro.js` file.
|
|
565
|
+
|
|
566
|
+
It has been found that the `motion` test of the `testaro` tool measures motion only when the `webkit` browser type is in use. If you want to use `testaro` with different browser types for different tests, you can include 2 or 3 `testaro` test acts in your job, specifying different browser types and different rules.
|
|
567
|
+
|
|
568
|
+
The `testaro` tool (like the `ibm` tool) has a `withItems` property. If you set it to `false`, the `standardResult` object of `testaro` will contain an `instances` property with summaries that identify issues and instance counts. If you set it to `true`, some of the instances will be itemized.
|
|
569
|
+
|
|
558
570
|
###### WAVE
|
|
559
571
|
|
|
560
572
|
If a `wave` test act is included in the job, an environment variable named `WAVE_KEY` must exist, with your WAVE API key as its value. You can get it from [WebAIM](https://wave.webaim.org/api/).
|
package/package.json
CHANGED
package/testaro/allHidden.js
CHANGED
|
@@ -3,14 +3,17 @@
|
|
|
3
3
|
This test reports a page that is entirely or mainly hidden.
|
|
4
4
|
*/
|
|
5
5
|
exports.reporter = async page => {
|
|
6
|
+
// Gets the hiddennesses of the document, body, and main region.
|
|
6
7
|
const data = await page.evaluate(() => {
|
|
8
|
+
// Identify the styles of the document, its body, and its main region.
|
|
7
9
|
const {body} = document;
|
|
8
|
-
const main = body && body.querySelector('main');
|
|
10
|
+
const main = body && body.querySelector('main, [role=main]');
|
|
9
11
|
const styles = {
|
|
10
12
|
doc: window.getComputedStyle(document.documentElement),
|
|
11
13
|
body: body && window.getComputedStyle(body),
|
|
12
14
|
main: main && window.getComputedStyle(main)
|
|
13
15
|
};
|
|
16
|
+
// Get the hiddennesses of the regions.
|
|
14
17
|
const data = {
|
|
15
18
|
hidden: {
|
|
16
19
|
document: document.documentElement.hidden,
|
|
@@ -38,6 +41,7 @@ exports.reporter = async page => {
|
|
|
38
41
|
main: main ? main.ariaHidden === 'true' : false
|
|
39
42
|
}
|
|
40
43
|
};
|
|
44
|
+
// Identify whether each region is really hidden.
|
|
41
45
|
['document', 'body', 'main'].forEach(element => {
|
|
42
46
|
if (data.hidden[element] && ! ['block', 'flex'].includes(data.display[element])) {
|
|
43
47
|
data.reallyHidden[element] = true;
|
|
@@ -45,10 +49,11 @@ exports.reporter = async page => {
|
|
|
45
49
|
});
|
|
46
50
|
return data;
|
|
47
51
|
});
|
|
52
|
+
// For each combination of region and hiddenness:
|
|
48
53
|
const standardInstances = [];
|
|
49
54
|
const reportables = {
|
|
50
|
-
hidden: [
|
|
51
|
-
reallyHidden: [
|
|
55
|
+
hidden: [1, 'hidden'],
|
|
56
|
+
reallyHidden: [2, 'effectively hidden'],
|
|
52
57
|
visHidden: [0, 'visually hidden'],
|
|
53
58
|
ariaHidden: [1, 'hidden by ARIA'],
|
|
54
59
|
document: [1, 'Document', 'document.documentElement'],
|
|
@@ -57,7 +62,9 @@ exports.reporter = async page => {
|
|
|
57
62
|
};
|
|
58
63
|
['document', 'body', 'main'].forEach(region => {
|
|
59
64
|
['hidden', 'reallyHidden', 'visHidden', 'ariaHidden'].forEach(hider => {
|
|
65
|
+
// If the region has that hiddenness:
|
|
60
66
|
if (data[hider][region]) {
|
|
67
|
+
// Add a standard instance for that combination.
|
|
61
68
|
standardInstances.push({
|
|
62
69
|
issueID: `allHidden-${hider}-${region}`,
|
|
63
70
|
what: `${reportables[region][1]} ${reportables[hider][1]}`,
|
|
@@ -72,6 +79,7 @@ exports.reporter = async page => {
|
|
|
72
79
|
}
|
|
73
80
|
});
|
|
74
81
|
});
|
|
82
|
+
// Get the severity totals.
|
|
75
83
|
const totals = [0, 0, 0, 0];
|
|
76
84
|
standardInstances.forEach(instance => {
|
|
77
85
|
totals[instance.ordinalSeverity]++;
|
package/testaro/bulk.js
CHANGED
|
@@ -18,12 +18,14 @@ exports.reporter = async page => {
|
|
|
18
18
|
});
|
|
19
19
|
const visibleElements = await page.$$('body :visible');
|
|
20
20
|
data.visibleElements = visibleElements.length;
|
|
21
|
+
const count = Math.round(data.visibleElements / 400);
|
|
21
22
|
return {
|
|
22
23
|
data,
|
|
23
|
-
totals: [
|
|
24
|
+
totals: [count, 0, 0, 0],
|
|
24
25
|
standardInstances: data.visibleElements < 200 ? [] : [{
|
|
25
26
|
issueID: 'bulk',
|
|
26
27
|
what: 'Page contains a large number of visible elements',
|
|
28
|
+
count,
|
|
27
29
|
ordinalSeverity: 0,
|
|
28
30
|
location: {
|
|
29
31
|
doc: '',
|
package/testaro/embAc.js
CHANGED
package/testaro/focAll.js
CHANGED
package/testaro/focInd.js
CHANGED
|
@@ -186,18 +186,35 @@ exports.reporter = async (page, withItems, revealAll = false, allowedDelay = 250
|
|
|
186
186
|
});
|
|
187
187
|
});
|
|
188
188
|
}
|
|
189
|
-
else
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
189
|
+
else {
|
|
190
|
+
if (types.indicatorMissing.total) {
|
|
191
|
+
standardInstances.push({
|
|
192
|
+
issueID: 'focInd-missing',
|
|
193
|
+
what: 'Elements have missing focus indicators',
|
|
194
|
+
count: types.indicatorMissing.total,
|
|
195
|
+
ordinalSeverity: 3,
|
|
196
|
+
location: {
|
|
197
|
+
doc: '',
|
|
198
|
+
type: '',
|
|
199
|
+
spec: ''
|
|
200
|
+
},
|
|
201
|
+
excerpt: ''
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
if (types.nonOutlinePresent.total) {
|
|
205
|
+
standardInstances.push({
|
|
206
|
+
issueID: 'focInd-nonoutline',
|
|
207
|
+
what: 'Elements have non-outline focus indicators',
|
|
208
|
+
count: types.nonOutlinePresent.total,
|
|
209
|
+
ordinalSeverity: 2,
|
|
210
|
+
location: {
|
|
211
|
+
doc: '',
|
|
212
|
+
type: '',
|
|
213
|
+
spec: ''
|
|
214
|
+
},
|
|
215
|
+
excerpt: ''
|
|
216
|
+
});
|
|
217
|
+
}
|
|
201
218
|
}
|
|
202
219
|
// Reload the page.
|
|
203
220
|
try {
|
package/testaro/focOp.js
CHANGED
|
@@ -174,18 +174,35 @@ exports.reporter = async (page, withItems) => {
|
|
|
174
174
|
});
|
|
175
175
|
});
|
|
176
176
|
}
|
|
177
|
-
else
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
177
|
+
else {
|
|
178
|
+
if (totals[2]) {
|
|
179
|
+
standardInstances.push({
|
|
180
|
+
issueID: 'focOp-onlyFocusable',
|
|
181
|
+
what: 'Focusable elements are inoperable',
|
|
182
|
+
count: totals[2],
|
|
183
|
+
ordinalSeverity: 2,
|
|
184
|
+
location: {
|
|
185
|
+
doc: '',
|
|
186
|
+
type: '',
|
|
187
|
+
spec: ''
|
|
188
|
+
},
|
|
189
|
+
excerpt: ''
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (totals[3]) {
|
|
193
|
+
standardInstances.push({
|
|
194
|
+
issueID: 'focOp-onlyOperable',
|
|
195
|
+
what: 'Operable elements are nonfocusable',
|
|
196
|
+
count: totals[3],
|
|
197
|
+
ordinalSeverity: 3,
|
|
198
|
+
location: {
|
|
199
|
+
doc: '',
|
|
200
|
+
type: '',
|
|
201
|
+
spec: ''
|
|
202
|
+
},
|
|
203
|
+
excerpt: ''
|
|
204
|
+
});
|
|
205
|
+
}
|
|
189
206
|
}
|
|
190
207
|
// Reload the page.
|
|
191
208
|
try {
|
package/testaro/focVis.js
CHANGED
package/testaro/hover.js
CHANGED
|
@@ -408,6 +408,7 @@ exports.reporter = async (page, withItems, sampleSize = -1) => {
|
|
|
408
408
|
standardInstances.push({
|
|
409
409
|
issueID: `hover-${issue}`,
|
|
410
410
|
what: what[issue],
|
|
411
|
+
count: data.totals[issue],
|
|
411
412
|
ordinalSeverity: severity[issue],
|
|
412
413
|
location: {
|
|
413
414
|
doc: '',
|
|
@@ -423,6 +424,7 @@ exports.reporter = async (page, withItems, sampleSize = -1) => {
|
|
|
423
424
|
standardInstances.push({
|
|
424
425
|
issueID: 'hover',
|
|
425
426
|
what: 'Hovering has unexpected impacts',
|
|
427
|
+
count: Object.values(data.totals).reduce((total, current) => total + current),
|
|
426
428
|
ordinalSeverity: totals.reduce((max, current, index) => current ? index : max, 0),
|
|
427
429
|
location: {
|
|
428
430
|
doc: '',
|
package/testaro/labClash.js
CHANGED
|
@@ -176,18 +176,35 @@ exports.reporter = async (page, withItems) => {
|
|
|
176
176
|
});
|
|
177
177
|
});
|
|
178
178
|
}
|
|
179
|
-
else
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
179
|
+
else {
|
|
180
|
+
if (data.totals.unlabeled) {
|
|
181
|
+
standardInstances.push({
|
|
182
|
+
issueID: 'labClash-unlabeled',
|
|
183
|
+
what: 'Element labels are missing',
|
|
184
|
+
count: data.totals.unlabeled,
|
|
185
|
+
ordinalSeverity: 3,
|
|
186
|
+
location: {
|
|
187
|
+
doc: '',
|
|
188
|
+
type: '',
|
|
189
|
+
spec: ''
|
|
190
|
+
},
|
|
191
|
+
excerpt: ''
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
if (data.totals.mislabeled) {
|
|
195
|
+
standardInstances.push({
|
|
196
|
+
issueID: 'labClash-mislabeled',
|
|
197
|
+
what: 'Element labels are conflicting',
|
|
198
|
+
count: data.totals.mislabeled,
|
|
199
|
+
ordinalSeverity: 2,
|
|
200
|
+
location: {
|
|
201
|
+
doc: '',
|
|
202
|
+
type: '',
|
|
203
|
+
spec: ''
|
|
204
|
+
},
|
|
205
|
+
excerpt: ''
|
|
206
|
+
});
|
|
207
|
+
}
|
|
191
208
|
}
|
|
192
209
|
return {
|
|
193
210
|
data,
|
package/testaro/linkTo.js
CHANGED
package/testaro/linkUl.js
CHANGED
package/testaro/menuNav.js
CHANGED
|
@@ -203,14 +203,14 @@ exports.reporter = async (page, withItems) => {
|
|
|
203
203
|
isCorrect = await testKey(
|
|
204
204
|
menu, menuItems, currentItem, 'End', 'end', itemCount - 1, isCorrect, itemData
|
|
205
205
|
);
|
|
206
|
-
// Update the menu
|
|
206
|
+
// Update the menu status (Node 14 does not support the ES 2021 &&= operator).
|
|
207
207
|
menuIsCorrect = menuIsCorrect && isCorrect;
|
|
208
208
|
// Increment the data.
|
|
209
209
|
data.totals.menuItems[isCorrect ? 'correct' : 'incorrect']++;
|
|
210
210
|
if (withItems) {
|
|
211
211
|
data.menuItems[isCorrect ? 'correct' : 'incorrect'].push(itemData);
|
|
212
212
|
}
|
|
213
|
-
// Process the next
|
|
213
|
+
// Process the next menu item.
|
|
214
214
|
return await testMenuItems(menu, menuItems, index + 1, orientation, menuIsCorrect);
|
|
215
215
|
}
|
|
216
216
|
// Otherwise, i.e. if all menu items have been tested:
|
|
@@ -271,7 +271,9 @@ exports.reporter = async (page, withItems) => {
|
|
|
271
271
|
data.menuItems.incorrect.forEach(item => {
|
|
272
272
|
standardInstances.push({
|
|
273
273
|
issueID: 'menuNav',
|
|
274
|
-
what:
|
|
274
|
+
what:
|
|
275
|
+
`Menu item ${item.tagName} responds nonstandardly to ${item.navigationErrors.join(', ')}`,
|
|
276
|
+
count: item.navigationErrors.length,
|
|
275
277
|
ordinalSeverity: 1,
|
|
276
278
|
location: {
|
|
277
279
|
doc: '',
|
|
@@ -286,7 +288,8 @@ exports.reporter = async (page, withItems) => {
|
|
|
286
288
|
standardInstances.push({
|
|
287
289
|
issueID: 'menuNav',
|
|
288
290
|
what: 'Menus and menu items have nonstandard navigation',
|
|
289
|
-
|
|
291
|
+
count: data.totals.navigations.all.incorrect,
|
|
292
|
+
ordinalSeverity: 1,
|
|
290
293
|
location: {
|
|
291
294
|
doc: '',
|
|
292
295
|
type: '',
|
package/testaro/miniText.js
CHANGED
package/testaro/motion.js
CHANGED
|
@@ -98,6 +98,13 @@ exports.reporter = async (page, withItems, delay = 2500, interval = 2500, count
|
|
|
98
98
|
pixelChanges.reduce((count, change) => count + (change ? 1 : 0), 0) / pixelChanges.length, 2
|
|
99
99
|
);
|
|
100
100
|
// Return the result.
|
|
101
|
+
const count = 2 * (meanLocalRatio - 1)
|
|
102
|
+
+ maxLocalRatio - 1
|
|
103
|
+
+ globalRatio - 1
|
|
104
|
+
+ meanPixelChange / 10000
|
|
105
|
+
+ maxPixelChange / 25000
|
|
106
|
+
+ 3 * changeFrequency
|
|
107
|
+
|| 0;
|
|
101
108
|
return {
|
|
102
109
|
data: {
|
|
103
110
|
bytes,
|
|
@@ -112,19 +119,14 @@ exports.reporter = async (page, withItems, delay = 2500, interval = 2500, count
|
|
|
112
119
|
},
|
|
113
120
|
totals: [
|
|
114
121
|
0,
|
|
115
|
-
0,
|
|
116
|
-
|
|
117
|
-
+ maxLocalRatio - 1
|
|
118
|
-
+ globalRatio - 1
|
|
119
|
-
+ meanPixelChange / 10000
|
|
120
|
-
+ maxPixelChange / 25000
|
|
121
|
-
+ 3 * changeFrequency
|
|
122
|
-
|| 0,
|
|
122
|
+
0,
|
|
123
|
+
count,
|
|
123
124
|
0
|
|
124
125
|
],
|
|
125
|
-
standardInstances:
|
|
126
|
+
standardInstances: count ? [{
|
|
126
127
|
issueID: 'motion',
|
|
127
128
|
what: 'Content moves or changes without user request',
|
|
129
|
+
count,
|
|
128
130
|
ordinalSeverity: 2,
|
|
129
131
|
location: {
|
|
130
132
|
doc: '',
|
package/testaro/nonTable.js
CHANGED
package/testaro/radioSet.js
CHANGED
|
@@ -74,6 +74,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
74
74
|
totals.total = allRadios.length;
|
|
75
75
|
totals.inSet = setRadios.length;
|
|
76
76
|
totals.percent = totals.total ? Math.floor(100 * totals.inSet / totals.total) : 'N.A.';
|
|
77
|
+
const loneRadios = totals.total - totals.inSet;
|
|
77
78
|
// If itemization is required:
|
|
78
79
|
const standardInstances = [];
|
|
79
80
|
if (withItems) {
|
|
@@ -85,7 +86,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
85
86
|
items.notInSet.forEach(text => {
|
|
86
87
|
standardInstances.push({
|
|
87
88
|
issueID: 'radioSet',
|
|
88
|
-
what: 'Radio button and
|
|
89
|
+
what: 'Radio button and its peers are not in a fieldset with a legend',
|
|
89
90
|
ordinalSeverity: 2,
|
|
90
91
|
location: {
|
|
91
92
|
doc: '',
|
|
@@ -96,10 +97,11 @@ exports.reporter = async (page, withItems) => {
|
|
|
96
97
|
});
|
|
97
98
|
});
|
|
98
99
|
}
|
|
99
|
-
else if (
|
|
100
|
+
else if (loneRadios > 0) {
|
|
100
101
|
standardInstances.push({
|
|
101
102
|
issueID: 'radioSet',
|
|
102
103
|
what: 'Radio buttons are not validly grouped in fieldsets with legends',
|
|
104
|
+
count: loneRadios,
|
|
103
105
|
ordinalSeverity: 2,
|
|
104
106
|
location: {
|
|
105
107
|
doc: '',
|
|
@@ -111,7 +113,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
111
113
|
}
|
|
112
114
|
return {
|
|
113
115
|
data,
|
|
114
|
-
totals: [0, 0,
|
|
116
|
+
totals: [0, 0, loneRadios, 0],
|
|
115
117
|
standardInstances
|
|
116
118
|
};
|
|
117
119
|
}
|
package/testaro/role.js
CHANGED
|
@@ -481,11 +481,13 @@ exports.reporter = async page => await page.$eval('body', body => {
|
|
|
481
481
|
const standardInstances = [];
|
|
482
482
|
Object.keys(data.tagNames).forEach(tagName => {
|
|
483
483
|
Object.keys(data.tagNames[tagName]).forEach(role => {
|
|
484
|
-
|
|
485
|
-
|
|
484
|
+
const pairTotals = data.tagNames[tagName][role];
|
|
485
|
+
const redCount = pairTotals.redundant;
|
|
486
|
+
if (redCount) {
|
|
486
487
|
standardInstances.push({
|
|
487
|
-
issueID: 'role',
|
|
488
|
-
what:
|
|
488
|
+
issueID: 'role-redundant',
|
|
489
|
+
what: `${tagName} elements have redundant explicit role ${role} (count: ${redCount})`,
|
|
490
|
+
count: redCount,
|
|
489
491
|
ordinalSeverity: 1,
|
|
490
492
|
location: {
|
|
491
493
|
doc: '',
|
|
@@ -495,11 +497,13 @@ exports.reporter = async page => await page.$eval('body', body => {
|
|
|
495
497
|
excerpt: ''
|
|
496
498
|
});
|
|
497
499
|
}
|
|
498
|
-
|
|
499
|
-
if (
|
|
500
|
+
const badCount = pairTotals.bad;
|
|
501
|
+
if (badCount) {
|
|
500
502
|
standardInstances.push({
|
|
501
|
-
issueID: 'role',
|
|
502
|
-
what:
|
|
503
|
+
issueID: 'role-bad',
|
|
504
|
+
what:
|
|
505
|
+
`Elements ${tagName} have invalid or native-replaceable explicit role ${role} (count: ${badCount})`,
|
|
506
|
+
count: badCount,
|
|
503
507
|
ordinalSeverity: 3,
|
|
504
508
|
location: {
|
|
505
509
|
doc: '',
|
package/testaro/styleDiff.js
CHANGED
|
@@ -171,10 +171,12 @@ exports.reporter = async (page, withItems) => {
|
|
|
171
171
|
const currentData = elementData[elementName];
|
|
172
172
|
const severity = currentData[0];
|
|
173
173
|
const elementSubtotals = elementTotal.subtotals;
|
|
174
|
-
|
|
174
|
+
const extraCount = elementSubtotals.length - 1;
|
|
175
|
+
totals[severity] += extraCount;
|
|
175
176
|
standardInstances.push({
|
|
176
177
|
issueID: 'styleDiff',
|
|
177
178
|
what: `${currentData[1]} have ${elementSubtotals.length} different styles`,
|
|
179
|
+
count: extraCount,
|
|
178
180
|
ordinalSeverity: severity,
|
|
179
181
|
location: {
|
|
180
182
|
doc: '',
|
package/testaro/tabNav.js
CHANGED
|
@@ -335,7 +335,9 @@ exports.reporter = async (page, withItems) => {
|
|
|
335
335
|
data.tabElements.incorrect.forEach(item => {
|
|
336
336
|
standardInstances.push({
|
|
337
337
|
issueID: 'tabNav',
|
|
338
|
-
what:
|
|
338
|
+
what:
|
|
339
|
+
`${item.tagName} element responds nonstandardly to ${item.navigationErrors.join(', ')}`,
|
|
340
|
+
count: item.navigationErrors.length,
|
|
339
341
|
ordinalSeverity: 1,
|
|
340
342
|
location: {
|
|
341
343
|
doc: '',
|
|
@@ -350,7 +352,8 @@ exports.reporter = async (page, withItems) => {
|
|
|
350
352
|
standardInstances.push({
|
|
351
353
|
issueID: 'tabNav',
|
|
352
354
|
what: 'Tablists have nonstandard navigation',
|
|
353
|
-
|
|
355
|
+
count: data.totals.navigations.all.incorrect,
|
|
356
|
+
ordinalSeverity: 1,
|
|
354
357
|
location: {
|
|
355
358
|
doc: '',
|
|
356
359
|
type: '',
|
package/testaro/titledEl.js
CHANGED
package/testaro/zIndex.js
CHANGED
|
@@ -55,7 +55,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
55
55
|
const which = `${item.tagName}${itemID}`;
|
|
56
56
|
standardInstances.push({
|
|
57
57
|
issueID: 'zIndex',
|
|
58
|
-
what:
|
|
58
|
+
what: `${item.tagName} element has a non-default Z index`,
|
|
59
59
|
ordinalSeverity: 0,
|
|
60
60
|
location: {
|
|
61
61
|
doc: '',
|
|
@@ -70,6 +70,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
70
70
|
standardInstances.push({
|
|
71
71
|
issueID: 'zIndex',
|
|
72
72
|
what: 'Elements have non-default Z indexes',
|
|
73
|
+
count: data.totals.total,
|
|
73
74
|
ordinalSeverity: 0,
|
|
74
75
|
location: {
|
|
75
76
|
doc: '',
|
package/tests/ibm.js
CHANGED
|
@@ -87,7 +87,7 @@ const trimReport = (report, withItems, rules) => {
|
|
|
87
87
|
}
|
|
88
88
|
return data;
|
|
89
89
|
};
|
|
90
|
-
// Performs
|
|
90
|
+
// Performs the IBM tests and returns the result.
|
|
91
91
|
const doTest = async (content, withItems, timeLimit, rules) => {
|
|
92
92
|
// Conduct the test and get the result.
|
|
93
93
|
let report;
|