testaro 76.1.0 → 76.1.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/Dockerfile +1 -1
- package/README.md +56 -61
- package/actSpecs.js +1 -10
- package/env.example +2 -2
- package/package.json +3 -2
- package/procs/doTestAct.js +4 -4
- package/run.js +1 -1
- package/tests/alfa.js +1 -1
- package/tests/aslint.js +1 -1
- package/tests/axe.js +1 -1
- package/tests/ed11y.js +1 -1
- package/tests/htmlcs.js +1 -1
- package/tests/ibm.js +5 -7
- package/tests/nuVal.js +3 -3
- package/tests/nuVnu.js +2 -2
- package/tests/qualWeb.js +10 -23
- package/tests/testaro.js +4 -9
- package/tests/wave.js +1 -1
package/Dockerfile
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
# The base-image tag must match the version of the playwright package in
|
|
11
11
|
# package-lock.json, so that the browsers baked into the image are the ones
|
|
12
12
|
# the installed Playwright expects.
|
|
13
|
-
FROM mcr.microsoft.com/playwright:v1.
|
|
13
|
+
FROM mcr.microsoft.com/playwright:v1.61.1-noble
|
|
14
14
|
|
|
15
15
|
# Install a headless Java runtime for the nuVnu test (vnu-jar); baking it in
|
|
16
16
|
# prevents vnu-jar from downloading a Temurin runtime over the network on
|
package/README.md
CHANGED
|
@@ -14,8 +14,8 @@ Testaro is an application that performs ensemble testing of web pages for access
|
|
|
14
14
|
|
|
15
15
|
The purposes of Testaro are to:
|
|
16
16
|
|
|
17
|
-
- provide programmatic access to tests defined by multiple
|
|
18
|
-
- standardize and integrate the reports of the
|
|
17
|
+
- provide programmatic access to tests defined by multiple rule engines
|
|
18
|
+
- standardize and integrate the reports of the rule engines
|
|
19
19
|
|
|
20
20
|
The need for ensemble testing of web accessibility, and the obstacles to it, are discussed in [Accessibility Metatesting: Comparing Nine Testing Tools](https://arxiv.org/abs/2304.07591).
|
|
21
21
|
|
|
@@ -26,7 +26,7 @@ Testaro is described in two papers:
|
|
|
26
26
|
|
|
27
27
|
## Functionality
|
|
28
28
|
|
|
29
|
-
Testaro performs tasks defined by a _job_. Typically, a job identifies the URL of a web page and asks Testaro to call an ensemble of
|
|
29
|
+
Testaro performs tasks defined by a _job_. Typically, a job identifies the URL of a web page and asks Testaro to call an ensemble of rule engines to test the page. Testaro adds the results of the testing to the job, thereby converting the job to a _report_.
|
|
30
30
|
|
|
31
31
|
Testaro can be given a job to perform, in which case it performs the job, delivers the report, and quits.
|
|
32
32
|
|
|
@@ -44,7 +44,7 @@ Testaro uses:
|
|
|
44
44
|
- [pixelmatch](https://www.npmjs.com/package/pixelmatch) to measure motion
|
|
45
45
|
- [dotenv](https://www.npmjs.com/package/dotenv) to load environment variables
|
|
46
46
|
|
|
47
|
-
Testaro can perform tests of these
|
|
47
|
+
Testaro can perform tests of these _rule engines_:
|
|
48
48
|
|
|
49
49
|
- [Accessibility Checker](https://www.npmjs.com/package/accessibility-checker) (IBM)
|
|
50
50
|
- [Alfa](https://alfa.siteimprove.com/) (Siteimprove)
|
|
@@ -57,9 +57,9 @@ Testaro can perform tests of these _tools_:
|
|
|
57
57
|
- [Testaro](https://www.npmjs.com/package/testaro) (CVS Health)
|
|
58
58
|
- [WAVE](https://wave.webaim.org/api/) (WebAIM)
|
|
59
59
|
|
|
60
|
-
For the
|
|
60
|
+
For the rule engines that are open-source, the identified organizations are their principal or original sponsors.
|
|
61
61
|
|
|
62
|
-
As shown, Testaro is not only an integrator but also one of the integrated
|
|
62
|
+
As shown, Testaro is not only an integrator but also one of the integrated rule engines. That is because it provides about 50 tests of its own, mostly to complement tests provided by the other rule engines. Some of those Testaro tests are designed to act as approximate alternatives to tests of vulnerable, restricted, or no longer available rule engines. In all such cases the Testaro tests are independently designed and implemented, without reference to the code of the tests that inspired them.
|
|
63
63
|
|
|
64
64
|
## Concepts and terms
|
|
65
65
|
|
|
@@ -68,13 +68,13 @@ The main concepts of Testaro are:
|
|
|
68
68
|
- `job`: a document that tells Testaro what to do.
|
|
69
69
|
- `act`: one step in a job.
|
|
70
70
|
- `report`: a job that Testaro has added results to.
|
|
71
|
-
- `
|
|
72
|
-
- `rule`: a success or failure criterion defined by a
|
|
73
|
-
- `test`: the software that a
|
|
71
|
+
- `rule engine`: one of the testing applications in the ensemble assembled by Testaro.
|
|
72
|
+
- `rule`: a success or failure criterion defined by a rule engine (currently about 1300 across all rule engines).
|
|
73
|
+
- `test`: the software that a rule engine uses to apply a rule.
|
|
74
74
|
- `target`: a web page that a job tells Testaro to test.
|
|
75
|
-
- `result`: the information that Testaro adds to a job to describe the outcomes of the tests of a
|
|
76
|
-
- `native result`: the outcomes of the tests of a
|
|
77
|
-
- `standard result`: the outcomes of the tests of a
|
|
75
|
+
- `result`: the information that Testaro adds to a job to describe the outcomes of the tests of a rule engine.
|
|
76
|
+
- `native result`: the outcomes of the tests of a rule engine in exactly or approximately the original form.
|
|
77
|
+
- `standard result`: the outcomes of the tests of a rule engine in a uniform Testaro-defined form.
|
|
78
78
|
- `catalog`: a collection of data on the HTML elements of a target relevant to one or more tests.
|
|
79
79
|
|
|
80
80
|
## System requirements
|
|
@@ -85,17 +85,15 @@ Testaro can be installed under a MacOS, Windows, Debian, or Ubuntu operating sys
|
|
|
85
85
|
|
|
86
86
|
### Browser security
|
|
87
87
|
|
|
88
|
-
Testaro is configured so that, when Playwright
|
|
88
|
+
Testaro is configured so that, when Playwright launches a `chromium` browser, the browser is [sandboxed](https://www.geeksforgeeks.org/ethical-hacking/what-is-browser-sandboxing/) for improved security. That is the default for Playwright, and Testaro does not override that default. The host must therefore permit sandboxed browsers. If you try to run Testaro on a host that prohibits sandboxed browsers, each attempted launch of a `chromium` browser will throw an error with a message complaining about the unavailability of a sandbox.
|
|
89
89
|
|
|
90
90
|
In some operating systems a sandboxed browser requires an [unprivileged user namespace](https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces). In one case, a `…userns.conf` file in the `/etc/sysctl.d` directory with the content `kernel.apparmor_restrict_unprivileged_userns = 1` prohibits unprivileged user namespaces and thereby makes sandboxed browsers unlaunchable.
|
|
91
91
|
|
|
92
92
|
#### Option A
|
|
93
93
|
|
|
94
|
-
One way to cope with this prohibition is to configure Playwright
|
|
94
|
+
One way to cope with this prohibition is to configure Playwright to launch `chromium` non-sandboxed. Launch arguments `'--no-sandbox'` and `'--disable-setuid-sandbox'` are available to specify this. They are added to the arguments of `browserOptionArgs.push` in the Testaro `run.js` file.
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
- For the `qualWeb` tool, this is done in the Testaro `tests/qualweb.js` file, where the `qualWeb.start` method is called with an options argument. Its `args` array property is modified to include `'--no-sandbox'` and `'--disable-setuid-sandbox'`.
|
|
98
|
-
- The `ibm` tool, too, can launch a Puppeteer `chromium` browser, if page content instead of a Playwright page is passed to the `accessibilityChecker.getCompliance` method, or if the implementation of the tool is changed in the future. For anticipation of such a case, the Testaro `aceconfig.js` file is modified. That file defines a `module.exports` object with a `puppeteerArgs` property, and, `--no-sandbox` and `--disable-setuid-sandbox` are added to its array value.
|
|
96
|
+
This option is **not available for the Playwright `chromium` browser launched by QualWeb**.
|
|
99
97
|
|
|
100
98
|
Non-sandboxed browsers are less secure than sandboxed ones, particularly when there is no restriction on who can use Testaro and what targets (web pages) they can test with it.
|
|
101
99
|
|
|
@@ -115,7 +113,7 @@ sudo sysctl --system
|
|
|
115
113
|
|
|
116
114
|
This application implements option B.
|
|
117
115
|
|
|
118
|
-
## Installation an independent application
|
|
116
|
+
## Installation as an independent application
|
|
119
117
|
|
|
120
118
|
To install Testaro as an independent application, rather than a dependency, clone the [Testaro repository](https://github.com/jrpool/testaro). To ensure that the binary browsers of its Playwright dependency get installed, execute `(p)npx playwright install` after executing `(p)npm install`.
|
|
121
119
|
|
|
@@ -179,11 +177,11 @@ Here is a sample job, showing properties that you can set:
|
|
|
179
177
|
},
|
|
180
178
|
acts: [ // Steps in this job
|
|
181
179
|
{
|
|
182
|
-
type: 'test', // Act type (the 'test' type performs tests of a
|
|
180
|
+
type: 'test', // Act type (the 'test' type performs tests of a rule engine)
|
|
183
181
|
launch: {}, // Act-specific overrides for the browserID and/or target
|
|
184
|
-
which: 'axe', // ID of the
|
|
185
|
-
detailLevel: 2, // An argument required by this
|
|
186
|
-
rules: ['landmark-complementary-is-top-level'], // Which rules of the
|
|
182
|
+
which: 'axe', // ID of the rule engine
|
|
183
|
+
detailLevel: 2, // An argument required by this rule engine
|
|
184
|
+
rules: ['landmark-complementary-is-top-level'], // Which rules of the rule engine to test for
|
|
187
185
|
},
|
|
188
186
|
{
|
|
189
187
|
type: 'test',
|
|
@@ -195,8 +193,7 @@ Here is a sample job, showing properties that you can set:
|
|
|
195
193
|
}
|
|
196
194
|
},
|
|
197
195
|
which: 'qualWeb',
|
|
198
|
-
|
|
199
|
-
rules: ['QW-BP25', 'QW-BP26'] // Which rules of the tool to test for
|
|
196
|
+
rules: ['QW-BP25', 'QW-BP26'] // Which rules of the rule engine to test for
|
|
200
197
|
}
|
|
201
198
|
]
|
|
202
199
|
}
|
|
@@ -323,18 +320,18 @@ The `textLinkable` property has a true value whenever `text` is non-empty and ca
|
|
|
323
320
|
|
|
324
321
|
The segments of `boxID` are `x`, `y`, `width`, and `height`.
|
|
325
322
|
|
|
326
|
-
The catalog is a mechanism for the integration of the
|
|
323
|
+
The catalog is a mechanism for the integration of the rule engines. Most rule violations that rule engines report are blamed on particular HTML elements. A rule engine typically reports that an element violated a rule by having some defect in its configuration or behavior. But rule engines describe elements differently. Testaro makes the rule engines identify the XPaths of the elements they report as violators. Testaro then finds, for each XPath, the correct catalog entry.
|
|
327
324
|
|
|
328
|
-
Testaro uses the following techniques to make the
|
|
325
|
+
Testaro uses the following techniques to make the rule engines calculate XPaths:
|
|
329
326
|
|
|
330
327
|
- `alfa` and `aslint`: They report XPaths, so Testaro needs only to normalize them.
|
|
331
|
-
- `ed11y`: Testaro adds it and a `window.getXPath` method to the page. When the
|
|
328
|
+
- `ed11y`: Testaro adds it and a `window.getXPath` method to the page. When the rule engine reports an element, Testaro computes its XPath.
|
|
332
329
|
- `wave`: It reports a selector for each element; Testaro finds each element in the page via its selector and executes `window.getXPath` on the element.
|
|
333
|
-
- `htmlcs`, `ibm`, `nuVal`, `nuVnu`, `qualWeb`: Testaro adds `data-xpath` attributes to all elements. The
|
|
330
|
+
- `htmlcs`, `ibm`, `nuVal`, `nuVnu`, `qualWeb`: Testaro adds `data-xpath` attributes to all elements. The rule engines include code excerpts, with the `data-xpath` attributes, in the reported violations.
|
|
334
331
|
- `axe`: It reports a selector for each element, and Testaro adds `data-xpath` attributes to all elements. Testaro finds each element in the page via its selector and uses the `data-xpath` attribute. When this fails, Testaro uses the `data-xpath` attribute if its complete value is included in the reported `node.html` value.
|
|
335
332
|
- `testaro`: Testaro designs each of its own tests to report element XPaths.
|
|
336
333
|
|
|
337
|
-
By attaching a catalog entry to each reported element, Testaro allows an application that uses Testaro to tell users, for any particular HTML element, which
|
|
334
|
+
By attaching a catalog entry to each reported element, Testaro allows an application that uses Testaro to tell users, for any particular HTML element, which rule engines ascribed violations of which rules to that element. An application could, for example, use a screenshot or a text-fragment link or could ask the user to paste the XPath into a browser developer tool.
|
|
338
335
|
|
|
339
336
|
In some cases no catalog entry can be found. The reasons may include:
|
|
340
337
|
|
|
@@ -354,12 +351,12 @@ As Testaro performs the acts of a job, information about the result of each act
|
|
|
354
351
|
|
|
355
352
|
- `startTime`: When Testaro began to perform the act
|
|
356
353
|
- `actualURL`: The tested URL (different from the target URL if the request was redirected)
|
|
357
|
-
- `data`: Data generated by the
|
|
358
|
-
- `result`: Result of the testing by the
|
|
354
|
+
- `data`: Data generated by the rule engine
|
|
355
|
+
- `result`: Result of the testing by the rule engine
|
|
359
356
|
|
|
360
357
|
The `result` property is an object with one or two (depending on the value of `standard`, as described above) subproperties:
|
|
361
358
|
|
|
362
|
-
- `nativeResult`: The result (or a compact version of the result) natively produced by the
|
|
359
|
+
- `nativeResult`: The result (or a compact version of the result) natively produced by the rule engine
|
|
363
360
|
- `standardResult`: A Testaro-standardized version of the result
|
|
364
361
|
|
|
365
362
|
If an act of type `test` contains an `expect` property (specifying expectations about the result), then Testaro also inserts these properties into the act:
|
|
@@ -373,13 +370,13 @@ Details about these expectation properties are documened in the `VALIDATION.md`
|
|
|
373
370
|
|
|
374
371
|
If the job instructs Testaro to include standard results, then the `result.standardResult` property of each act of type `test` will have three properties:
|
|
375
372
|
|
|
376
|
-
- `prevented`: Whether the
|
|
373
|
+
- `prevented`: Whether the rule engine was prevented from performing the act
|
|
377
374
|
- `totals`: An array of 4 integers, counting the rule violations at 4 severity levels
|
|
378
|
-
- `instances`: An array of data about the violations reported by the
|
|
375
|
+
- `instances`: An array of data about the violations reported by the rule engine
|
|
379
376
|
|
|
380
377
|
More specifically:
|
|
381
378
|
|
|
382
|
-
- The `totals` value is an array like this: `[3, 0, 87, 4]`. This example would mean that the
|
|
379
|
+
- The `totals` value is an array like this: `[3, 0, 87, 4]`. This example would mean that the rule engine reported 3 failures at severity 0 (the least severe level), none at severity 1, 87 at severity 2, and 4 at severity 3. These four severities are conceptually ordinal, not metric.
|
|
383
380
|
- The `instances` value is an array of objects, each having these properties:
|
|
384
381
|
- `ruleId`: The ID of the rule that was violated
|
|
385
382
|
- `what`: A description of the rule or of the violation
|
|
@@ -389,17 +386,17 @@ More specifically:
|
|
|
389
386
|
|
|
390
387
|
If no catalog entry was found for the instance, then instead of a `catalogIndex` property Testaro tries to insert a `pathID` property, whose value is a normalized XPath of the offending HTML element.
|
|
391
388
|
|
|
392
|
-
##
|
|
389
|
+
## Rule-engine details
|
|
393
390
|
|
|
394
|
-
The
|
|
391
|
+
The rule engines whose tests Testaro performs have particularities described below.
|
|
395
392
|
|
|
396
393
|
### ASLint
|
|
397
394
|
|
|
398
|
-
The `aslint`
|
|
395
|
+
The `aslint` rule engine makes use of the [`aslint-testaro` fork](https://www.npmjs.com/package/aslint-testaro) of the [`aslint` repository](https://github.com/essentialaccessibility/aslint), which, unlike the published `aslint` package, contains the `aslint.bundle.js` file.
|
|
399
396
|
|
|
400
397
|
### HTML CodeSniffer
|
|
401
398
|
|
|
402
|
-
The `htmlcs`
|
|
399
|
+
The `htmlcs` rule engine makes use of the `htmlcs/HTMLCS.js` file. That file was created, and can be recreated if necessary, as follows:
|
|
403
400
|
|
|
404
401
|
1. Clone the [HTML CodeSniffer package](https://github.com/squizlabs/HTML_CodeSniffer).
|
|
405
402
|
1. Make that package’s directory the active directory.
|
|
@@ -433,7 +430,7 @@ The changes in `htmlcs/HTMLCS.js` are:
|
|
|
433
430
|
|
|
434
431
|
The `ibm` tests require the `aceconfig.js` file.
|
|
435
432
|
|
|
436
|
-
As of 2 March 2023 (version 3.1.45 of `accessibility-checker`), the `ibm`
|
|
433
|
+
As of 2 March 2023 (version 3.1.45 of `accessibility-checker`), the `ibm` rule engine 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:
|
|
437
434
|
|
|
438
435
|
In `node_modules/accessibility-checker/lib/ACEngineManager.js`, remove or comment out these lines starting on line 169:
|
|
439
436
|
|
|
@@ -452,19 +449,17 @@ results.label = results.label.replace(/:/g, '-');
|
|
|
452
449
|
|
|
453
450
|
These changes were proposed as [pull requests 1333 and 1334](https://github.com/IBMa/equal-access/pulls).
|
|
454
451
|
|
|
455
|
-
The `ibm`
|
|
456
|
-
|
|
457
|
-
In a previous version of the package, the tool operated on the page content when the `withNewContent` property was `false`. In some cases the tool threw untrappable errors for some targets under that condition. The tool launched a Puppeteer browser to create pages to perform its tests on. On any host that did not permit sandboxed browsers to be launched, the `aceconfig.js` file needed to specify nonsandboxed browsers. Starting in December 2025, the tool operates on the page rather than the page content.
|
|
452
|
+
The `ibm` rule engine is one of two rule engines (`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.
|
|
458
453
|
|
|
459
454
|
### Nu Html Checker
|
|
460
455
|
|
|
461
|
-
The `nuVal` and `nuVnu`
|
|
456
|
+
The `nuVal` and `nuVnu` rule engines perform the tests of the Nu Html Checker. The `nuVal` rule engine is a remote service with an API. The `nuVnu` rule engine is installed as a dependency. A job can choose either one, or can try `nuVal` and if it fails then invoke `nuVnu`.
|
|
462
457
|
|
|
463
458
|
Its `rules` argument is **not** an array of rule IDs, but instead is an array of rule _specifications_. A rule specification for `nuVal` or `nuVnu` is a string with the format `=ruleID` or `~ruleID`. The `=` prefix indicates that the rule ID is invariable. The `~` prefix indicates that the rule ID is variable, in which case the `ruleID` part of the specification is a matching regular expression, rather than the exact text of a message. This `rules` format arises from the fact that `nuVal` and `nuVnu` generate customized messages and do not accompany them with rule identifiers.
|
|
464
459
|
|
|
465
460
|
### QualWeb
|
|
466
461
|
|
|
467
|
-
The `qualWeb`
|
|
462
|
+
The `qualWeb` rule engine 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.
|
|
468
463
|
|
|
469
464
|
QualWeb allows specification of rules for 3 modules: `act-rules`, `wcag-techniques`, and `best-practices`. If you include a `rules` argument in a QualWeb test act, its value must be an array of 1, 2, or 3 strings. Any string in that array is a specification for one of these modules. The string has this format:
|
|
470
465
|
|
|
@@ -502,13 +497,13 @@ The Testaro rules are classified by an `allRules` array defined in the `tests/te
|
|
|
502
497
|
- `timeOut`: the maximum time in seconds allowed for a test of the rule
|
|
503
498
|
- `defaultOn`: whether the rule is to be tested for by default
|
|
504
499
|
|
|
505
|
-
If you do not specify rules when using the `testaro`
|
|
500
|
+
If you do not specify rules when using the `testaro` rule engine, Testaro will test for its default rules, in the order in which they appear in the array.
|
|
506
501
|
|
|
507
502
|
The optional `rules` argument for a `testaro` test act is an array whose first item is either `'y'` or `'n'` and whose remaining items are rule IDs. If `'y'`, then only the specified rules’ tests are performed. If `'n'`, then all the default rules are tested for, **except** for the specified rules.
|
|
508
503
|
|
|
509
|
-
The `testaro`
|
|
504
|
+
The `testaro` rule engine (like the `ibm` rule engine) has a `withItems` property. If you set it to `false`, the `standardResult` object 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.
|
|
510
505
|
|
|
511
|
-
Unlike any other
|
|
506
|
+
Unlike any other rule engine, the `testaro` rule engine requires a `stopOnFail` property, which specifies whether a failure to conform to any rule (i.e. any value of `totals` other than `[0, 0, 0, 0]`) should terminate the execution of tests for the remaining rules.
|
|
512
507
|
|
|
513
508
|
Tests of the `testaro` tests (i.e. _validation_) could previously be performed as documented in the `VALIDATION.md` file. This functionality has broken and its redesign is planned.
|
|
514
509
|
|
|
@@ -538,9 +533,9 @@ The rationales motivating the Testaro-defined tests can be found in comments wit
|
|
|
538
533
|
|
|
539
534
|
On some occasions a test throws an error that cannot be handled with a `try`-`catch` structure. It has been observed, for example, that the `ibm` test does this when the page content, rather than the page URL, is given to `getCompliance()` and the target is `https://globalsolutions.org`, `https://monsido.com`, or `https://www.ambetterhealth.com/`.
|
|
540
535
|
|
|
541
|
-
Some
|
|
536
|
+
Some rule engines take apparently infinite time to perform their tests on some pages. One website whose pages prevent 5 of the rule engines from ever completing their tests is the site of BrowserStack.
|
|
542
537
|
|
|
543
|
-
To handle such fatal errors and stalls, Testaro runs the tests of each
|
|
538
|
+
To handle such fatal errors and stalls, Testaro runs the tests of each rule engine in a separate forked child process that executes the `procs/doTestAct.js` module. The parent process subjects each rule engine to a time limit and kills the child if the time limit expires.
|
|
544
539
|
|
|
545
540
|
### Activation
|
|
546
541
|
|
|
@@ -552,22 +547,22 @@ The Playwright “Receives Events” actionability check does **not** check whet
|
|
|
552
547
|
|
|
553
548
|
Test targets employ mechanisms to prevent scraping, multiple requests within a short time, automated form submission, and other automated actions. These mechanisms may interfere with testing. When a test act is prevented, Testaro reports this prevention.
|
|
554
549
|
|
|
555
|
-
Some targets prohibit the execution of alien scripts unless the client can demonstrate that it is the requester of the page. Failure to provide that evidence results in the script being blocked and an error message being logged, saying “Refused to execute a script because its hash, its nonce, or unsafe-inline does not appear in the script-src directive of the Content Security Policy”. This mechanism affects
|
|
550
|
+
Some targets prohibit the execution of alien scripts unless the client can demonstrate that it is the requester of the page. Failure to provide that evidence results in the script being blocked and an error message being logged, saying “Refused to execute a script because its hash, its nonce, or unsafe-inline does not appear in the script-src directive of the Content Security Policy”. This mechanism affects rule engines that insert scripts into a target in order to test it. To comply with this requirement, Testaro obtains a _nonce_ from the response that serves the target. Then the file that runs the rule engine adds that nonce to the script as the value of a `nonce` attribute when it inserts its script into the target.
|
|
556
551
|
|
|
557
552
|
Some targets have been found erratically to prevent the creation of page images. When page images have been created, during the `motion` test in `testaro` some targets have been found to prevent their comparison by BlazeDiff, but comparison by `pixelmatch` has succeeded. For this reason, although reportedly slower, `pixelmatch` is the library used for image comparison.
|
|
558
553
|
|
|
559
|
-
###
|
|
554
|
+
### Rule-engine duplicativity
|
|
560
555
|
|
|
561
|
-
|
|
556
|
+
Rule engines sometimes do redundant testing, in that two or more rule engines test for the same defects, although such duplications are not necessarily perfect. This fact creates problems:
|
|
562
557
|
|
|
563
|
-
- One cannot be confident in excluding some tests of some
|
|
564
|
-
- The Testaro report from a job documents each
|
|
565
|
-
- An effort to aggregate the results into a single score may distort the scores by inflating the weights of defects that happen to be discovered by multiple
|
|
566
|
-
-
|
|
558
|
+
- One cannot be confident in excluding some tests of some rule engines on the assumption that they perfectly duplicate tests of other rule engines.
|
|
559
|
+
- The Testaro report from a job documents each rule engine’s results separately, so a single defect may be documented in multiple locations within the report, making the direct consumption of the report inefficient.
|
|
560
|
+
- An effort to aggregate the results into a single score may distort the scores by inflating the weights of defects that happen to be discovered by multiple rule engines.
|
|
561
|
+
- Rule engines use different methods for identifying the locations of elements that violate rule-engine rules.
|
|
567
562
|
|
|
568
|
-
###
|
|
563
|
+
### Rule-engine malfunctions
|
|
569
564
|
|
|
570
|
-
|
|
565
|
+
Rule engines can become faulty. For example, Alfa stopped reporting any rule violations in mid-April 2024 and resumed doing so at the end of April. In some cases, such as this, the rule-engine maker corrects the fault. In others, the rule engine changes and forces Testaro to change its handling of the rule engine.
|
|
571
566
|
|
|
572
567
|
### Dependency deployment
|
|
573
568
|
|
|
@@ -575,7 +570,7 @@ The behavior of Testaro as a dependency of an application deployed on a virtual
|
|
|
575
570
|
|
|
576
571
|
### Containerized deployment
|
|
577
572
|
|
|
578
|
-
A reference container image for stand-alone deployment, in which all
|
|
573
|
+
A reference container image for stand-alone deployment, in which all rule engines run, is defined by the `Dockerfile` and `docker-compose.yml` files at the project root and documented in [CONTAINERS.md](CONTAINERS.md).
|
|
579
574
|
|
|
580
575
|
### Headless browser fidelity
|
|
581
576
|
|
|
@@ -596,7 +591,7 @@ Any files in the `temp` or `tmp` directory are presumed ephemeral and are not tr
|
|
|
596
591
|
- produces human-oriented HTML digests from scored reports
|
|
597
592
|
- produces human-oriented HTML comparisons of the scores of targets
|
|
598
593
|
|
|
599
|
-
Testilo contains procedures that reorganize report data by issue and by element, rather than
|
|
594
|
+
Testilo contains procedures that reorganize report data by issue and by element, rather than rule engine, and that compensate for duplicative tests when computing scores.
|
|
600
595
|
|
|
601
596
|
Report standardization could be performed by other software rather than by Testaro. That would require sending the original reports to the server. They are typically larger than standardized reports. Whenever users want only standardized reports, the fact that Testaro standardizes them eliminates the need to send the original reports anywhere.
|
|
602
597
|
|
package/actSpecs.js
CHANGED
|
@@ -181,16 +181,7 @@ exports.actSpecs = {
|
|
|
181
181
|
ibm: [
|
|
182
182
|
'Perform IBM Equal Access tests',
|
|
183
183
|
{
|
|
184
|
-
withItems: [true, 'boolean', '', 'itemize']
|
|
185
|
-
withNewContent: [
|
|
186
|
-
true, 'boolean', '', 'true: use a URL; false: use page content (risky)'
|
|
187
|
-
]
|
|
188
|
-
}
|
|
189
|
-
],
|
|
190
|
-
qualWeb: [
|
|
191
|
-
'Perform QualWeb tests',
|
|
192
|
-
{
|
|
193
|
-
withNewContent: [true, 'boolean', '', 'whether to use a URL instead of page content']
|
|
184
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
194
185
|
}
|
|
195
186
|
],
|
|
196
187
|
nuVal: [
|
package/env.example
CHANGED
|
@@ -31,10 +31,10 @@ TIMEOUT_MULTIPLIER=1
|
|
|
31
31
|
ABORT_ASSERTIVELY=false
|
|
32
32
|
# URL of any non-default (e.g., self-hosted) Nu Html Checker API (see ghcr.io/validator/validator).
|
|
33
33
|
TESTARO_NU_URL=__placeholder__
|
|
34
|
-
# Whether to launch
|
|
34
|
+
# Whether to launch the Playwright chromium browser without its sandbox (normally false).
|
|
35
35
|
# The sandbox requires unprivileged user-namespace cloning, which default container
|
|
36
36
|
# seccomp policies and some hardened hosts prohibit. Set this to true in containers,
|
|
37
|
-
# or run
|
|
37
|
+
# or run containers with a seccomp profile that permits user-namespace cloning.
|
|
38
38
|
TESTARO_CHROMIUM_NO_SANDBOX=false
|
|
39
39
|
|
|
40
40
|
## License
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "testaro",
|
|
3
|
-
"version": "76.1.
|
|
3
|
+
"version": "76.1.1",
|
|
4
4
|
"description": "Run 1300 web accessibility tests from 10 tools and get a standardized report",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"url": "https://github.com/jrpool/testaro/issues"
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://github.com/jrpool/testaro#readme",
|
|
32
|
+
"//": "playwright is temporarily pinned to version 1.61.1 because mcr.microsoft.com/playwright:v1.62.0-noble has not yet been released, so containerized deployment requires version 1.61.1.",
|
|
32
33
|
"dependencies": {
|
|
33
34
|
"@qualweb/core": "*",
|
|
34
35
|
"@qualweb/act-rules": "*",
|
|
@@ -44,7 +45,7 @@
|
|
|
44
45
|
"axe-playwright": "*",
|
|
45
46
|
"dotenv": "*",
|
|
46
47
|
"pixelmatch": "*",
|
|
47
|
-
"playwright": "
|
|
48
|
+
"playwright": "1.61.1",
|
|
48
49
|
"playwright-dompath": "*",
|
|
49
50
|
"playwright-extra": "*",
|
|
50
51
|
"playwright-extra-plugin-stealth": "*",
|
package/procs/doTestAct.js
CHANGED
|
@@ -111,7 +111,7 @@ const doTestAct = async (reportPath, actIndex) => {
|
|
|
111
111
|
process.exit(1);
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
-
// If the page exists or the tool is Testaro:
|
|
114
|
+
// If the page exists after the launch, or if the tool is Testaro:
|
|
115
115
|
if (page || which === 'testaro') {
|
|
116
116
|
try {
|
|
117
117
|
// Make the act reporter perform the specified tests of the tool.
|
|
@@ -157,13 +157,13 @@ const doTestAct = async (reportPath, actIndex) => {
|
|
|
157
157
|
process.exit(1);
|
|
158
158
|
};
|
|
159
159
|
}
|
|
160
|
-
// Otherwise, i.e. if the page does not exist:
|
|
160
|
+
// Otherwise, i.e. if the page does not exist after the launch:
|
|
161
161
|
else {
|
|
162
|
-
// Add
|
|
162
|
+
// Add this to the act.
|
|
163
163
|
act.data ??= {};
|
|
164
164
|
act.data.prevented = true;
|
|
165
165
|
act.data.error = 'No page';
|
|
166
|
-
// Add prevention
|
|
166
|
+
// Add the prevention to the job data.
|
|
167
167
|
report.jobData.preventions[which] = act.data.error;
|
|
168
168
|
const reportJSON = JSON.stringify(report);
|
|
169
169
|
// Save the revised report.
|
package/run.js
CHANGED
|
@@ -21,7 +21,7 @@ require('dotenv').config({quiet: true});
|
|
|
21
21
|
const {isValidJob} = require('./procs/job');
|
|
22
22
|
const {getCatalog} = require('./procs/catalog');
|
|
23
23
|
const {nowString} = require('./procs/dateTime');
|
|
24
|
-
const {chromium
|
|
24
|
+
const {chromium} = require('playwright-extra');
|
|
25
25
|
const fs = require('fs').promises;
|
|
26
26
|
const os = require('os');
|
|
27
27
|
/*
|
package/tests/alfa.js
CHANGED
package/tests/aslint.js
CHANGED
package/tests/axe.js
CHANGED
package/tests/ed11y.js
CHANGED
package/tests/htmlcs.js
CHANGED
package/tests/ibm.js
CHANGED
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
|
|
11
11
|
/*
|
|
12
12
|
ibm
|
|
13
|
-
|
|
13
|
+
Implements the IBM Equal Access ruleset for accessibility.
|
|
14
14
|
|
|
15
|
-
This
|
|
15
|
+
This rule engine depends on aceconfig.js.
|
|
16
16
|
|
|
17
|
-
This
|
|
17
|
+
This rule engine is compatible with Windows only if the accessibility-checker package
|
|
18
18
|
is revised. See README.md for details.
|
|
19
19
|
*/
|
|
20
20
|
|
|
@@ -119,8 +119,7 @@ const trimActReport = (actReport, withItems, rules) => {
|
|
|
119
119
|
// Conducts and reports the IBM Equal Access tests.
|
|
120
120
|
exports.reporter = async (page, report, actIndex) => {
|
|
121
121
|
const act = report.acts[actIndex];
|
|
122
|
-
const {withItems,
|
|
123
|
-
const contentType = withNewContent ? 'new' : 'existing';
|
|
122
|
+
const {withItems, rules} = act;
|
|
124
123
|
// Initialize the act report.
|
|
125
124
|
const result = {
|
|
126
125
|
nativeResult: {},
|
|
@@ -137,9 +136,8 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
137
136
|
};
|
|
138
137
|
}
|
|
139
138
|
try {
|
|
140
|
-
const typeContent = contentType === 'existing' ? page : page.url();
|
|
141
139
|
// Conduct the tests.
|
|
142
|
-
const runReport = await run(
|
|
140
|
+
const runReport = await run(page);
|
|
143
141
|
const actReport = runReport.report;
|
|
144
142
|
// If there were results:
|
|
145
143
|
if (actReport) {
|
package/tests/nuVal.js
CHANGED
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
|
|
12
12
|
/*
|
|
13
13
|
nuVal
|
|
14
|
-
|
|
15
|
-
This
|
|
16
|
-
This
|
|
14
|
+
Subjects a page and its source to the Nu Html Checker, thereby testing scripted content found only in the loaded page and erroneous content before the browser corrects it. The API erratically replaces left and right double quotation marks with invalid UTF-8, which appears as 2 or 3 successive instances of the replacement character (U+fffd). Therefore, this test removes all such quotation marks and the replacement character. That causes 'Bad value “” for' to become 'Bad value for'. Since the corruption of quotation marks is erratic, no better solution is known.
|
|
15
|
+
This rule engine is the API version of the Nu Html Checker. It is an alternative to the nuVnu rule engine, which uses the same validator as an installed dependency. Each rule engine has advantages and disadvantages. The main advantage of nuVal is that it does not require the Testaro host to provide a Java virtual machine. The main advantage of the nuVnu tool is that it can evaluate pages reachable from the host that Testaro runs on even if not reachable from the public Internet.
|
|
16
|
+
This rule engine calls the W3C validation service unless a TESTARO_NU_URL environment variable is defined with the URL of another instance of the API.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
// IMPORTS
|
package/tests/nuVnu.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/*
|
|
12
|
-
|
|
13
|
-
This
|
|
12
|
+
Subjects a page and its source to the Nu Html Checker, thereby testing scripted content found only in the loaded page and erroneous content before the browser corrects it. The API erratically replaces left and right double quotation marks with invalid UTF-8, which appears as 2 or 3 successive instances of the replacement character (U+fffd). Therefore, this test removes all such quotation marks and the replacement character. That causes 'Bad value “” for' to become 'Bad value for'. Since the corruption of quotation marks is erratic, no better solution is known.
|
|
13
|
+
This rule engine is the installed version of the Nu Html Checker. It is an alternative to the nuVal rule engine, which uses the same validator as a web service of the World Wide Web Consortium (W3C). Each rule engine has advantages and disadvantages. The main advantage of the nuVnu rule engine is that it can evaluate pages larger than about 80,000 bytes and pages reachable from the host that Testaro runs on even if not reachable from the public Internet. The main advantages of nuVal are that it usually runs faster than nuVnu and it does not require the Testaro host to provide a Java virtual machine.
|
|
14
14
|
When both nuVal and nuVnu are included in a job, nuVal should precede nuVnu. If nuVal succeeds, nuVnu aborts. So, only one of the two tools contributes instances to the job report.
|
|
15
15
|
*/
|
|
16
16
|
|
package/tests/qualWeb.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
/*
|
|
12
12
|
qualWeb
|
|
13
|
-
|
|
13
|
+
Implements the QualWeb ruleset for accessibility.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
// IMPORTS
|
|
@@ -24,6 +24,7 @@ const {getAttributeXPath, getXPathCatalogIndex} = require('../procs/xPath');
|
|
|
24
24
|
|
|
25
25
|
// CONSTANTS
|
|
26
26
|
|
|
27
|
+
// QualWeb core engine with Playwright as driver.
|
|
27
28
|
const qualWeb = new QualWeb(undefined, new PlaywrightDriver({
|
|
28
29
|
adBlock: true,
|
|
29
30
|
stealth: true
|
|
@@ -31,6 +32,7 @@ const qualWeb = new QualWeb(undefined, new PlaywrightDriver({
|
|
|
31
32
|
const actRulesModule = new ACTRules({});
|
|
32
33
|
const wcagModule = new WCAGTechniques({});
|
|
33
34
|
const bpModule = new BestPractices({});
|
|
35
|
+
// Mapping of QualWeb module violation types to ordinal severities.
|
|
34
36
|
const ordinalSeverities = {
|
|
35
37
|
'act-rules': {
|
|
36
38
|
'warning': 1,
|
|
@@ -51,7 +53,7 @@ const ordinalSeverities = {
|
|
|
51
53
|
// Conducts and reports the QualWeb tests.
|
|
52
54
|
exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
53
55
|
const act = report.acts[actIndex];
|
|
54
|
-
const {
|
|
56
|
+
const {rules} = act;
|
|
55
57
|
const clusterOptions = {
|
|
56
58
|
maxConcurrency: 1,
|
|
57
59
|
timeout: timeLimit * 1000,
|
|
@@ -73,19 +75,9 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
|
73
75
|
instances: []
|
|
74
76
|
};
|
|
75
77
|
}
|
|
76
|
-
// Specify the options for the Puppeteer browser launched by QualWeb.
|
|
77
|
-
const puppeteerOptions = {
|
|
78
|
-
headless: true
|
|
79
|
-
};
|
|
80
|
-
// If launching Chromium without its sandbox was specified (e.g., in a
|
|
81
|
-
// container or on a host that restricts unprivileged user namespaces):
|
|
82
|
-
if (process.env.TESTARO_CHROMIUM_NO_SANDBOX === 'true') {
|
|
83
|
-
// Disable the sandbox of the QualWeb browser, too.
|
|
84
|
-
puppeteerOptions.args = ['--no-sandbox'];
|
|
85
|
-
}
|
|
86
78
|
try {
|
|
87
|
-
// Start the QualWeb core engine.
|
|
88
|
-
await qualWeb.start(clusterOptions
|
|
79
|
+
// Start the QualWeb core engine, which launches a Playwright browser.
|
|
80
|
+
await qualWeb.start(clusterOptions);
|
|
89
81
|
}
|
|
90
82
|
// If the start fails:
|
|
91
83
|
catch(error) {
|
|
@@ -115,14 +107,9 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
|
115
107
|
},
|
|
116
108
|
modules: []
|
|
117
109
|
};
|
|
118
|
-
// Specify a URL or provide the content.
|
|
119
110
|
try {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
qualWebOptions.html = await page.content();
|
|
125
|
-
}
|
|
111
|
+
// Provide the page content, including the data-xpath attributes.
|
|
112
|
+
qualWebOptions.html = await page.content();
|
|
126
113
|
// Specify which rules to test for, adding a custom execute property for report processing.
|
|
127
114
|
const actSpec = rules ? rules.find(typeRules => typeRules.startsWith('act:')) : null;
|
|
128
115
|
const wcagSpec = rules ? rules.find(typeRules => typeRules.startsWith('wcag:')) : null;
|
|
@@ -196,7 +183,7 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
|
196
183
|
};
|
|
197
184
|
}
|
|
198
185
|
// Add the report to the result.
|
|
199
|
-
result.nativeResult = qwReport
|
|
186
|
+
result.nativeResult = qwReport.customHtml;
|
|
200
187
|
const {nativeResult, standardResult} = result;
|
|
201
188
|
// If the report contains, as it should, a copy of the DOM:
|
|
202
189
|
if (nativeResult?.system?.page?.dom) {
|
|
@@ -302,7 +289,7 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
|
302
289
|
}
|
|
303
290
|
catch(error) {
|
|
304
291
|
data.prevented = true;
|
|
305
|
-
data.error = `
|
|
292
|
+
data.error = `QualWeb result cannot be made JSON (${error.message})`;
|
|
306
293
|
}
|
|
307
294
|
}
|
|
308
295
|
catch(error) {
|
package/tests/testaro.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
/*
|
|
12
12
|
testaro
|
|
13
|
-
|
|
13
|
+
Implements the Testaro evaluative rules.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
// IMPORTS
|
|
@@ -471,20 +471,15 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
471
471
|
};
|
|
472
472
|
const {standardResult} = result;
|
|
473
473
|
const allRuleIDs = allRules.map(rule => rule.id);
|
|
474
|
-
// If the rule specification is valid:
|
|
475
474
|
if (
|
|
475
|
+
// If the rule specification has at least 2 items
|
|
476
476
|
ruleSpec.length > 1
|
|
477
|
+
// and the first item is y or n
|
|
477
478
|
&& ['y', 'n'].includes(ruleSpec[0])
|
|
479
|
+
// and all subsequent items are rule IDs to be included (if y) or excluded (if n):
|
|
478
480
|
&& ruleSpec.slice(1).every(ruleID => allRuleIDs.includes(ruleID))
|
|
479
481
|
) {
|
|
480
482
|
// Get the rules to be tested for and their execution order.
|
|
481
|
-
// 'y' = include-list: run exactly the rules in ruleSpec.slice(1).
|
|
482
|
-
// 'n' = exclude-list: run all defaultOn rules EXCEPT those in
|
|
483
|
-
// ruleSpec.slice(1). (The prior implementation was a no-op:
|
|
484
|
-
// it checked against `allRuleIDs` — which is every rule's id —
|
|
485
|
-
// so the predicate was never true, and it returned rule
|
|
486
|
-
// objects rather than IDs, which then never matched the
|
|
487
|
-
// string comparison on the next line.)
|
|
488
483
|
const excludeIDs = ruleSpec.slice(1);
|
|
489
484
|
const jobRuleIDs = ruleSpec[0] === 'y'
|
|
490
485
|
? excludeIDs
|
package/tests/wave.js
CHANGED