testaro 76.0.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 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.60.0-noble
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 tools
18
- - standardize and integrate the reports of the tools
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 tools to test the page. Testaro adds the results of the testing to the job, thereby converting the job to a _report_.
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 _tools_:
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 tools that are open-source, the identified organizations are their principal or original sponsors.
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 tools. That is because it provides about 50 tests of its own, mostly to complement tests provided by the other tools. Some of those Testaro tests are designed to act as approximate alternatives to tests of vulnerable, restricted, or no longer available tools. In all such cases the Testaro tests are independently designed and implemented, without reference to the code of the tests that inspired them.
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
- - `tool`: one of the testing applications in the ensemble assembled by Testaro.
72
- - `rule`: a success or failure criterion defined by a tool (currently about 1300 across all tools).
73
- - `test`: the software that a tool uses to apply a rule.
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 tool.
76
- - `native result`: the outcomes of the tests of a tool in exactly or approximately the original form.
77
- - `standard result`: the outcomes of the tests of a tool in a uniform Testaro-defined form.
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 or Puppeteer (a dependency of Playwright and of some tools, including QualWeb) 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 Puppeteer, 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.
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 and Puppeteer to launch `chromium` non-sandboxed. In both cases, launch arguments `'--no-sandbox'` and `'--disable-setuid-sandbox'` are available to specify this.
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
- - For Playwright, `'--no-sandbox'` and `'--disable-setuid-sandbox'` are added to the arguments of `browserOptionArgs.push` in the Testaro `run.js` file.
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 tool)
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 tool
185
- detailLevel: 2, // An argument required by this tool
186
- rules: ['landmark-complementary-is-top-level'], // Which rules of the tool to test for
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
- withNewContent: false, // An argument required by this tool
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 tools. Most rule violations that tools report are blamed on particular HTML elements. A tool typically reports that an element violated a rule by having some defect in its configuration or behavior. But tools describe elements differently. Testaro makes the tools identify the XPaths of the elements they report as violators. Testaro then finds, for each XPath, the correct catalog entry.
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 tools calculate XPaths:
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 tool reports an element, Testaro computes its XPath.
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 tools include code excerpts, with the `data-xpath` attributes, in the reported violations.
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 tools 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.
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 tool
358
- - `result`: Result of the testing by the tool
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 tool
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 tool was prevented from performing the act
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 tool
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 tool 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.
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
- ## Tool details
389
+ ## Rule-engine details
393
390
 
394
- The tools whose tests Testaro performs have particularities described below.
391
+ The rule engines whose tests Testaro performs have particularities described below.
395
392
 
396
393
  ### ASLint
397
394
 
398
- The `aslint` tool 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.
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` tool makes use of the `htmlcs/HTMLCS.js` file. That file was created, and can be recreated if necessary, as follows:
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` 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:
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` 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.
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` tools perform the tests of the Nu Html Checker. The `nuVal` tool is a remote service with an API. The `nuVnu` tool is installed as a dependency. A job can choose either one, or can try `nuVal` and if it fails then invoke `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` 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.
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` tool, Testaro will test for its default rules, in the order in which they appear in the array.
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` tool (like the `ibm` tool) 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.
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 tool, the `testaro` tool 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.
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 tools take apparently infinite time to perform their tests on some pages. One website whose pages prevent 5 of the tools from ever completing their tests is the site of BrowserStack.
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 tool in a separate forked child process that executes the `procs/doTestAct.js` module. The parent process subjects each tool to a time limit and kills the child if the time limit expires.
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 tools 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 tool adds that nonce to the script as the value of a `nonce` attribute when it inserts its script into the target.
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
- ### Tool duplicativity
554
+ ### Rule-engine duplicativity
560
555
 
561
- Tools sometimes do redundant testing, in that two or more tools test for the same defects, although such duplications are not necessarily perfect. This fact creates problems:
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 tools on the assumption that they perfectly duplicate tests of other tools.
564
- - The Testaro report from a job documents each tool’s results separately, so a single defect may be documented in multiple locations within the report, making the direct consumption of the report inefficient.
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 tools.
566
- - Tools use different methods for identifying the locations of elements that violate tool rules.
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
- ### Tool malfunctions
563
+ ### Rule-engine malfunctions
569
564
 
570
- Tools 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 tool maker corrects the fault. In others, the tool changes and forces Testaro to change its handling of the tool.
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 tools run, is defined by the `Dockerfile` and `docker-compose.yml` files at the project root and documented in [CONTAINERS.md](CONTAINERS.md).
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 tool, and that compensate for duplicative tests when computing scores.
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/UPGRADES.md CHANGED
@@ -8708,3 +8708,15 @@ Your SVG example illustrates this perfectly:
8708
8708
  ## Conclusion
8709
8709
 
8710
8710
  Your investigation reveals that **current accessibility testing is fundamentally incomplete**. The solution requires both technical improvements (state management) and philosophical shifts (hygiene-based rules). This significantly raises the complexity bar but also the potential effectiveness of automated accessibility testing.
8711
+
8712
+ # This branch
8713
+
8714
+ you'll get notified when `#334` merges and when the subsequent changesets "Version Packages" PR is opened/merged in `qualweb/qualweb`.
8715
+
8716
+ ## Plan recap
8717
+
8718
+ - **No action needed now.** Wait for notifications on both PRs.
8719
+ - **Once the "Version Packages" PR merges** (bumping `@qualweb/playwright-driver`): check `npmjs.com/package/@qualweb/playwright-driver` for the new patch version, then bump it in `@/Users/pool/Documents/Topics/repos/a11yTesting/testaro/package.json`.
8720
+ - **Re-test**: run a job with a `qualWeb` act and confirm the `No DOM` error is gone before merging your `qwpw` branch.
8721
+
8722
+ I'll be ready to help with the dependency bump and verification when that release lands.
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 Chromium (Playwright's and QualWeb's) without its sandbox (normally false).
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 the container with a seccomp profile that permits user-namespace cloning.
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.0.0",
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,9 +29,11 @@
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": "*",
36
+ "@qualweb/playwright-driver": "*",
35
37
  "@qualweb/wcag-techniques": "*",
36
38
  "@qualweb/best-practices": "*",
37
39
  "@siteimprove/alfa-act": "*",
@@ -43,7 +45,7 @@
43
45
  "axe-playwright": "*",
44
46
  "dotenv": "*",
45
47
  "pixelmatch": "*",
46
- "playwright": "*",
48
+ "playwright": "1.61.1",
47
49
  "playwright-dompath": "*",
48
50
  "playwright-extra": "*",
49
51
  "playwright-extra-plugin-stealth": "*",
@@ -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 data to the act.
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 data to the job data.
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, webkit, firefox} = require('playwright-extra');
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
@@ -10,7 +10,7 @@
10
10
 
11
11
  /*
12
12
  alfa
13
- This test implements the alfa ruleset for accessibility.
13
+ Implements the alfa ruleset for accessibility.
14
14
  */
15
15
 
16
16
  // IMPORTS
package/tests/aslint.js CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  /*
12
12
  aslint
13
- This test implements the ASLint ruleset for accessibility.
13
+ Implements the ASLint ruleset for accessibility.
14
14
  */
15
15
 
16
16
  // IMPORTS
package/tests/axe.js CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  /*
12
12
  axe
13
- This test implements the axe-core ruleset for accessibility.
13
+ Implements the axe-core ruleset for accessibility.
14
14
 
15
15
  The rules argument defaults to all rules; otherwise, specify an array of rule names.
16
16
 
package/tests/ed11y.js CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  /*
12
12
  ed11y
13
- This test implements the Editoria11y ruleset for accessibility.
13
+ Implements the Editoria11y ruleset for accessibility.
14
14
  */
15
15
 
16
16
  // IMPORTS
package/tests/htmlcs.js CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  /*
12
12
  htmlcs
13
- This test implements the HTML CodeSniffer ruleset.
13
+ Implements the HTML CodeSniffer ruleset.
14
14
  */
15
15
 
16
16
  // IMPORTS
package/tests/ibm.js CHANGED
@@ -10,11 +10,11 @@
10
10
 
11
11
  /*
12
12
  ibm
13
- This tool implements the IBM Equal Access ruleset for accessibility. The 'withNewContent' argument determines whether the test package is given the URL of the page to be tested (true) or the page (false).
13
+ Implements the IBM Equal Access ruleset for accessibility.
14
14
 
15
- This tool depends on aceconfig.js.
15
+ This rule engine depends on aceconfig.js.
16
16
 
17
- This tool is compatible with Windows only if the accessibility-checker package
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, withNewContent, rules} = act;
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(typeContent);
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
- This tool 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 tool is the API version of the Nu Html Checker. It is an alternative to the nuVnu tool, which uses the same validator as an installed dependency. Each tool 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 tool calls the W3C validation service unless a TESTARO_NU_URL environment variable is defined with the URL of another instance of the API.
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
- This tool 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 tool is the installed version of the Nu Html Checker. It is an alternative to the nuVal tool, which uses the same validator as a web service of the World Wide Web Consortium (W3C). Each tool has advantages and disadvantages. The main advantage of the nuVnu tool 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.
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
- This test implements the QualWeb ruleset for accessibility.
13
+ Implements the QualWeb ruleset for accessibility.
14
14
  */
15
15
 
16
16
  // IMPORTS
@@ -19,17 +19,20 @@ const {QualWeb} = require('@qualweb/core');
19
19
  const {ACTRules} = require('@qualweb/act-rules');
20
20
  const {WCAGTechniques} = require('@qualweb/wcag-techniques');
21
21
  const {BestPractices} = require('@qualweb/best-practices');
22
+ const {PlaywrightDriver} = require('@qualweb/playwright-driver');
22
23
  const {getAttributeXPath, getXPathCatalogIndex} = require('../procs/xPath');
23
24
 
24
25
  // CONSTANTS
25
26
 
26
- const qualWeb = new QualWeb({
27
+ // QualWeb core engine with Playwright as driver.
28
+ const qualWeb = new QualWeb(undefined, new PlaywrightDriver({
27
29
  adBlock: true,
28
30
  stealth: true
29
- });
31
+ }));
30
32
  const actRulesModule = new ACTRules({});
31
33
  const wcagModule = new WCAGTechniques({});
32
34
  const bpModule = new BestPractices({});
35
+ // Mapping of QualWeb module violation types to ordinal severities.
33
36
  const ordinalSeverities = {
34
37
  'act-rules': {
35
38
  'warning': 1,
@@ -50,7 +53,7 @@ const ordinalSeverities = {
50
53
  // Conducts and reports the QualWeb tests.
51
54
  exports.reporter = async (page, report, actIndex, timeLimit) => {
52
55
  const act = report.acts[actIndex];
53
- const {withNewContent, rules} = act;
56
+ const {rules} = act;
54
57
  const clusterOptions = {
55
58
  maxConcurrency: 1,
56
59
  timeout: timeLimit * 1000,
@@ -72,19 +75,9 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
72
75
  instances: []
73
76
  };
74
77
  }
75
- // Specify the options for the Puppeteer browser launched by QualWeb.
76
- const puppeteerOptions = {
77
- headless: true
78
- };
79
- // If launching Chromium without its sandbox was specified (e.g., in a
80
- // container or on a host that restricts unprivileged user namespaces):
81
- if (process.env.TESTARO_CHROMIUM_NO_SANDBOX === 'true') {
82
- // Disable the sandbox of the QualWeb browser, too.
83
- puppeteerOptions.args = ['--no-sandbox'];
84
- }
85
78
  try {
86
- // Start the QualWeb core engine.
87
- await qualWeb.start(clusterOptions, puppeteerOptions);
79
+ // Start the QualWeb core engine, which launches a Playwright browser.
80
+ await qualWeb.start(clusterOptions);
88
81
  }
89
82
  // If the start fails:
90
83
  catch(error) {
@@ -114,14 +107,9 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
114
107
  },
115
108
  modules: []
116
109
  };
117
- // Specify a URL or provide the content.
118
110
  try {
119
- if (withNewContent) {
120
- qualWebOptions.url = page.url();
121
- }
122
- else {
123
- qualWebOptions.html = await page.content();
124
- }
111
+ // Provide the page content, including the data-xpath attributes.
112
+ qualWebOptions.html = await page.content();
125
113
  // Specify which rules to test for, adding a custom execute property for report processing.
126
114
  const actSpec = rules ? rules.find(typeRules => typeRules.startsWith('act:')) : null;
127
115
  const wcagSpec = rules ? rules.find(typeRules => typeRules.startsWith('wcag:')) : null;
@@ -195,7 +183,7 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
195
183
  };
196
184
  }
197
185
  // Add the report to the result.
198
- result.nativeResult = qwReport[withNewContent ? qualWebOptions.url : 'customHtml'];
186
+ result.nativeResult = qwReport.customHtml;
199
187
  const {nativeResult, standardResult} = result;
200
188
  // If the report contains, as it should, a copy of the DOM:
201
189
  if (nativeResult?.system?.page?.dom) {
@@ -301,7 +289,7 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
301
289
  }
302
290
  catch(error) {
303
291
  data.prevented = true;
304
- data.error = `qualWeb result cannot be made JSON (${error.message})`;
292
+ data.error = `QualWeb result cannot be made JSON (${error.message})`;
305
293
  }
306
294
  }
307
295
  catch(error) {
package/tests/testaro.js CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  /*
12
12
  testaro
13
- This test implements the Testaro evaluative rules.
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
@@ -10,7 +10,7 @@
10
10
 
11
11
  /*
12
12
  wave
13
- This test implements the WebAIM WAVE ruleset for accessibility. The 'reportType' argument
13
+ Implements the WebAIM WAVE ruleset for accessibility. The 'reportType' argument
14
14
  specifies a WAVE report type: 1, 2, 3, or 4.
15
15
  */
16
16