testaro 45.0.10 → 45.0.12
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 +28 -20
- package/package.json +2 -1
- package/procs/job.js +9 -1
- package/procs/standardize.js +43 -0
- package/tests/wax.js +93 -0
package/README.md
CHANGED
|
@@ -44,35 +44,37 @@ Testaro uses:
|
|
|
44
44
|
- [pixelmatch](https://www.npmjs.com/package/pixelmatch) to measure motion
|
|
45
45
|
|
|
46
46
|
Testaro performs tests of these _tools_:
|
|
47
|
-
- [
|
|
48
|
-
- [
|
|
49
|
-
- [
|
|
50
|
-
- [
|
|
47
|
+
- [Accessibility Checker](https://www.npmjs.com/package/accessibility-checker) (IBM)
|
|
48
|
+
- [Alfa](https://alfa.siteimprove.com/) (Siteimprove)
|
|
49
|
+
- [ASLint](https://www.npmjs.com/package/@essentialaccessibility/aslint) (eSSENTIAL Accessibility)
|
|
50
|
+
- [Axe](https://www.npmjs.com/package/axe-playwright) (Deque)
|
|
51
51
|
- [Editoria11y](https://github.com/itmaybejj/editoria11y) (Princeton University)
|
|
52
52
|
- [HTML CodeSniffer](https://www.npmjs.com/package/html_codesniffer) (Squiz Labs)
|
|
53
53
|
- [Nu Html Checker](https://github.com/validator/validator) (World Wide Web Consortium)
|
|
54
|
-
- [QualWeb
|
|
54
|
+
- [QualWeb](https://www.npmjs.com/package/@qualweb/core) (University of Lisbon)
|
|
55
55
|
- [Testaro](https://www.npmjs.com/package/testaro) (CVS Health)
|
|
56
|
-
- [
|
|
56
|
+
- [WallyAX](https://www.npmjs.com/package/@wally-ax/wax-dev) (Wally Solutions)
|
|
57
|
+
- [WAVE](https://wave.webaim.org/api/) (WebAIM)
|
|
57
58
|
|
|
58
59
|
Some of the tests of Testaro are designed to act as approximate alternatives to tests of vulnerable, restricted, or no longer available tools. In all such cases the Testaro rules are independently designed and implemented, without reference to the code of the tests that inspired them.
|
|
59
60
|
|
|
60
61
|
## Rules
|
|
61
62
|
|
|
62
|
-
Each tool accessed with Testaro defines _rules_ and tests _targets_ for compliance with its rules. In total, the
|
|
63
|
+
Each tool accessed with Testaro defines _rules_ and tests _targets_ for compliance with its rules. In total, the eleven tools define more than a thousand rules. The latest tabulation of tool rules is:
|
|
63
64
|
|
|
64
65
|
```
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
66
|
+
Accessibility Checker: 132
|
|
67
|
+
Alfa: 59
|
|
68
|
+
ASLint: 136
|
|
69
|
+
Axe: 80
|
|
70
|
+
Editoria11y: 24
|
|
71
|
+
HTML CodeSniffer: 115
|
|
72
|
+
Nu Html Checker: 215
|
|
73
|
+
QualWeb: 131
|
|
74
|
+
Testaro: 40
|
|
75
|
+
WallyAX: 27
|
|
76
|
+
WAVE: 58
|
|
77
|
+
total: 1017
|
|
76
78
|
```
|
|
77
79
|
|
|
78
80
|
Some of the tools are under active development, and their rule counts change over time.
|
|
@@ -119,7 +121,7 @@ To run Testaro after installation, provide the environment variables described b
|
|
|
119
121
|
|
|
120
122
|
## Payment
|
|
121
123
|
|
|
122
|
-
All of the tests that Testaro can perform are free of cost, except those performed by the WAVE
|
|
124
|
+
All of the tests that Testaro can perform are free of cost, except those performed by the WallyAX and WAVE tools. The owners of those tools issue API keys. A free initial allowance of usage may be granted to you with a new API key. Before using Testaro to perform their tests, get your API keys for [WallyAX](mailto:technology@wallyax.com) and [WAVE](https://wave.webaim.org/api/). Then use those API keys to define environment variables, as described below under “Environment variables”.
|
|
123
125
|
|
|
124
126
|
## Jobs
|
|
125
127
|
|
|
@@ -459,7 +461,7 @@ The changes in `htmlcs/HTMLCS.js` are:
|
|
|
459
461
|
> );
|
|
460
462
|
```
|
|
461
463
|
|
|
462
|
-
####
|
|
464
|
+
#### Accessibility Checker
|
|
463
465
|
|
|
464
466
|
The `ibm` tests require the `aceconfig.js` file.
|
|
465
467
|
|
|
@@ -532,6 +534,12 @@ Several Testaro tests make use of the `init()` function in the `procs/testaro` m
|
|
|
532
534
|
|
|
533
535
|
You can add custom rules to the rules of any tool. Testaro provides a template, `data/template.js`, for the definition of a rule to be added. Once you have created a copy of the template with revisions, you can move the copy into the `testaro` directory and add an entry for your custom rule to the `evalRules` object in the `tests/testaro.js` file. Then your custom rule will act as a Testaro rule. Some `testaro` rules are simple enough to be fully specified in JSON files. You can use any of those as a template if you want to create a sufficiently simple custom rule, namely a rule whose prohibited elements are all and only the elements matching a CSS selector. More details about rule creation are in the `CONTRIBUTING.md` file.
|
|
534
536
|
|
|
537
|
+
#### WallyAX
|
|
538
|
+
|
|
539
|
+
If a `wax` test act is included in the job, an environment variable named `WAX_KEY` must exist, with your WallyAX API key as its value. You can get it from [WallyAX](mailto:technology@wallyax.com).
|
|
540
|
+
|
|
541
|
+
The `wax` tool imposes a limit on the size of a page to be tested. If the page exceeds the limit, Testaro treats the page as preventing `wax` from performing its tests. The limit is less than 500,000 characters.
|
|
542
|
+
|
|
535
543
|
#### WAVE
|
|
536
544
|
|
|
537
545
|
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "testaro",
|
|
3
|
-
"version": "45.0.
|
|
3
|
+
"version": "45.0.12",
|
|
4
4
|
"description": "Run 1000 web accessibility tests from 10 tools and get a standardized report",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"@siteimprove/alfa-playwright": "*",
|
|
33
33
|
"@siteimprove/alfa-rules": "*",
|
|
34
34
|
"@siteimprove/alfa-scraper": "*",
|
|
35
|
+
"@wally-ax/wax-dev": "*",
|
|
35
36
|
"accessibility-checker": "*",
|
|
36
37
|
"aslint-testaro": "*",
|
|
37
38
|
"axe-playwright": "*",
|
package/procs/job.js
CHANGED
|
@@ -47,6 +47,7 @@ const tools = exports.tools = {
|
|
|
47
47
|
nuVal: 'Nu Html Checker',
|
|
48
48
|
qualWeb: 'QualWeb',
|
|
49
49
|
testaro: 'Testaro',
|
|
50
|
+
wax: 'WallyAX',
|
|
50
51
|
wave: 'WAVE',
|
|
51
52
|
};
|
|
52
53
|
|
|
@@ -270,7 +271,14 @@ exports.doBy = async function(timeLimit, obj, fnName, fnArgs, noticePrefix) {
|
|
|
270
271
|
// Start the function execution.
|
|
271
272
|
const fnPromise = new Promise(async function(resolve) {
|
|
272
273
|
fnResolver = resolve;
|
|
273
|
-
|
|
274
|
+
let fnResult;
|
|
275
|
+
try {
|
|
276
|
+
fnResult = await obj[fnName](... fnArgs);
|
|
277
|
+
}
|
|
278
|
+
catch(error) {
|
|
279
|
+
fnResult = `failed (error: ${error.message})`;
|
|
280
|
+
};
|
|
281
|
+
resolve(fnResult);
|
|
274
282
|
});
|
|
275
283
|
// Start a timer.
|
|
276
284
|
const timerPromise = new Promise(resolve => {
|
package/procs/standardize.js
CHANGED
|
@@ -640,6 +640,49 @@ const convert = (toolName, data, result, standardResult) => {
|
|
|
640
640
|
});
|
|
641
641
|
}
|
|
642
642
|
}
|
|
643
|
+
// wax
|
|
644
|
+
else if (toolName === 'wax' && result.violations && result.violations.length) {
|
|
645
|
+
// For each violation:
|
|
646
|
+
result.violations.forEach(violation => {
|
|
647
|
+
// Get its standard instance properties.
|
|
648
|
+
const element = violation.element.replace(/\s+/g, ' ');
|
|
649
|
+
const {message, description, severity} = violation;
|
|
650
|
+
const ordinalSeverity = ['Minor', 'Moderate', 'Major', 'Severe', 'Critical'].indexOf(severity);
|
|
651
|
+
const tagNameCandidate = element.replace(/^<| .*$/g, '');
|
|
652
|
+
const tagName = /^[a-zA-Z0-9]+$/.test(tagNameCandidate) ? tagNameCandidate.toUpperCase() : '';
|
|
653
|
+
let id = '';
|
|
654
|
+
const location = {};
|
|
655
|
+
if (tagName) {
|
|
656
|
+
const idTerm = element
|
|
657
|
+
.replace(/>.*$/, '')
|
|
658
|
+
.split(' ')
|
|
659
|
+
.slice(1)
|
|
660
|
+
.find(term => term.startsWith('id="'));
|
|
661
|
+
if (idTerm) {
|
|
662
|
+
const idCandidate = idTerm.slice(4, -1);
|
|
663
|
+
if (! idCandidate.includes('"')) {
|
|
664
|
+
id = idCandidate;
|
|
665
|
+
location.doc = 'dom';
|
|
666
|
+
location.type = 'selector';
|
|
667
|
+
location.spec = `#${id}`;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
const instance = {
|
|
672
|
+
ruleID: message,
|
|
673
|
+
what: description,
|
|
674
|
+
ordinalSeverity,
|
|
675
|
+
tagName,
|
|
676
|
+
id,
|
|
677
|
+
location,
|
|
678
|
+
excerpt: element
|
|
679
|
+
};
|
|
680
|
+
// Add its ordinal severity to the standard result totals.
|
|
681
|
+
standardResult.totals[ordinalSeverity]++;
|
|
682
|
+
// Add the instance to the standard result.
|
|
683
|
+
standardResult.instances.push(instance);
|
|
684
|
+
});
|
|
685
|
+
}
|
|
643
686
|
// wave
|
|
644
687
|
else if (
|
|
645
688
|
toolName === 'wave'
|
package/tests/wax.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/*
|
|
2
|
+
© 2024 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
in the Software without restriction, including without limitation the rights
|
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
wax
|
|
25
|
+
This test implements the WallyAX WAX Dev Testing Framework ruleset.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
// IMPORTS
|
|
29
|
+
|
|
30
|
+
// Module to handle files.
|
|
31
|
+
const fs = require('fs/promises');
|
|
32
|
+
// Utility module.
|
|
33
|
+
const {doBy} = require('../procs/job');
|
|
34
|
+
// WAX
|
|
35
|
+
const runWax = require('@wally-ax/wax-dev');
|
|
36
|
+
const waxDev = {runWax};
|
|
37
|
+
|
|
38
|
+
// FUNCTIONS
|
|
39
|
+
|
|
40
|
+
// Conducts and reports the WAX tests.
|
|
41
|
+
exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
42
|
+
// Initialize the act report.
|
|
43
|
+
let data = {};
|
|
44
|
+
let result = {};
|
|
45
|
+
// Run WAX.
|
|
46
|
+
const act = report.acts[actIndex];
|
|
47
|
+
const rules = act.rules || [];
|
|
48
|
+
const pageCode = await page.content();
|
|
49
|
+
const waxOptions = {
|
|
50
|
+
rules,
|
|
51
|
+
apiKey: process.env.WAX_KEY || ''
|
|
52
|
+
};
|
|
53
|
+
const actReport = await doBy(
|
|
54
|
+
timeLimit, waxDev, 'runWax', [pageCode, waxOptions], 'wax report retrieval'
|
|
55
|
+
);
|
|
56
|
+
// If WAX failed:
|
|
57
|
+
if (typeof actReport === 'string') {
|
|
58
|
+
// If the failure was a timeout:
|
|
59
|
+
if (actReport === 'timedOut') {
|
|
60
|
+
// Report this.
|
|
61
|
+
data.prevented = true;
|
|
62
|
+
data.error = 'Retrieval of result timed out';
|
|
63
|
+
}
|
|
64
|
+
// Otherwise, i.e. if the failure was not a timeout:
|
|
65
|
+
else {
|
|
66
|
+
// Report this.
|
|
67
|
+
data.prevented = true;
|
|
68
|
+
data.error = actReport;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Otherwise, i.e. if WAX succeeded:
|
|
72
|
+
else {
|
|
73
|
+
// Populate the act report.
|
|
74
|
+
result = {
|
|
75
|
+
violations: actReport
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Return the results.
|
|
79
|
+
try {
|
|
80
|
+
JSON.stringify(data);
|
|
81
|
+
}
|
|
82
|
+
catch(error) {
|
|
83
|
+
const message = `ERROR: WAX result cannot be made JSON (${error.message.slice(0, 200)})`;
|
|
84
|
+
data = {
|
|
85
|
+
prevented: true,
|
|
86
|
+
error: message
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
data,
|
|
91
|
+
result
|
|
92
|
+
};
|
|
93
|
+
};
|