testaro 78.0.6 → 78.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +94 -0
- package/.github/workflows/ci.yml +58 -0
- package/.github/workflows/publish.yml +49 -0
- package/.github/workflows/typescript.yml +35 -0
- package/AGENTS.md +2 -2
- package/CLAUDE.md +25 -19
- package/CONTAINERS.md +10 -6
- package/CONTRIBUTING.md +29 -3
- package/Dockerfile +1 -1
- package/README.md +75 -20
- package/UPGRADES.md +4 -0
- package/actSpecs-doc.md +13 -1
- package/actSpecs.js +29 -5
- package/call.js +6 -5
- package/docker-compose.yml +8 -2
- package/docs/checkpoint-scanning.md +199 -0
- package/docs/standard-result-outcome.md +165 -0
- package/env.example +44 -10
- package/eslint.config.mjs +101 -0
- package/netWatch.js +373 -222
- package/package.json +46 -31
- package/pour/README.md +47 -0
- package/pour/pour.min.js +8 -0
- package/procs/actDo.js +808 -0
- package/procs/catalog.d.ts +17 -0
- package/procs/catalog.js +313 -221
- package/procs/catalog.ts +398 -0
- package/procs/checkpoint.js +110 -0
- package/procs/config.d.ts +35 -0
- package/procs/config.js +63 -0
- package/procs/dateTime.js +2 -1
- package/procs/doActs.js +442 -849
- package/procs/doTestAct.js +27 -121
- package/procs/flow.js +221 -0
- package/procs/generateRuleRegistry.js +94 -0
- package/procs/getSource.d.ts +26 -0
- package/procs/getSource.js +1 -0
- package/procs/job.js +116 -1
- package/procs/launch.d.ts +40 -0
- package/procs/launch.js +239 -108
- package/procs/nu.d.ts +48 -0
- package/procs/nu.js +1 -0
- package/procs/scope.js +196 -0
- package/procs/shoot.d.ts +33 -0
- package/procs/shoot.js +3 -1
- package/procs/standard.d.ts +18 -0
- package/procs/standard.js +83 -0
- package/procs/standard.ts +126 -0
- package/procs/testAct.js +145 -0
- package/procs/testaro.d.ts +20 -0
- package/procs/testaro.js +237 -189
- package/procs/testaro.ts +321 -0
- package/procs/userPath.js +126 -0
- package/procs/xPath.d.ts +4 -0
- package/procs/xPath.js +82 -64
- package/procs/xPath.ts +106 -0
- package/procs/xPathScript.d.ts +6 -0
- package/procs/xPathScript.js +70 -0
- package/run.js +3 -2
- package/surea11y/README.md +44 -0
- package/surea11y/surea11y.browser.js +14 -0
- package/testaro/adbID.d.ts +3 -0
- package/testaro/adbID.js +39 -41
- package/testaro/adbID.ts +66 -0
- package/testaro/allCapStyle.d.ts +3 -0
- package/testaro/allCapStyle.js +32 -34
- package/testaro/allCapStyle.ts +55 -0
- package/testaro/allCaps.d.ts +16 -0
- package/testaro/allCaps.js +179 -151
- package/testaro/allCaps.ts +228 -0
- package/testaro/allHidden.d.ts +13 -0
- package/testaro/allHidden.js +30 -30
- package/testaro/allHidden.ts +50 -0
- package/testaro/allSlanted.d.ts +3 -0
- package/testaro/allSlanted.js +31 -33
- package/testaro/allSlanted.ts +54 -0
- package/testaro/altScheme.d.ts +3 -0
- package/testaro/altScheme.js +28 -30
- package/testaro/altScheme.ts +50 -0
- package/testaro/attVal.d.ts +3 -0
- package/testaro/attVal.js +21 -21
- package/testaro/attVal.ts +52 -0
- package/testaro/autocomplete.d.ts +3 -0
- package/testaro/autocomplete.js +60 -75
- package/testaro/autocomplete.ts +101 -0
- package/testaro/bulk.d.ts +13 -0
- package/testaro/bulk.js +33 -33
- package/testaro/bulk.ts +55 -0
- package/testaro/buttonMenu.d.ts +9 -0
- package/testaro/buttonMenu.js +318 -319
- package/testaro/buttonMenu.ts +391 -0
- package/testaro/captionLoc.d.ts +3 -0
- package/testaro/captionLoc.js +18 -20
- package/testaro/captionLoc.ts +40 -0
- package/testaro/datalistRef.d.ts +3 -0
- package/testaro/datalistRef.js +34 -36
- package/testaro/datalistRef.ts +55 -0
- package/testaro/distortion.d.ts +3 -0
- package/testaro/distortion.js +58 -26
- package/testaro/distortion.ts +81 -0
- package/testaro/docType.d.ts +15 -0
- package/testaro/docType.js +26 -25
- package/testaro/docType.ts +45 -0
- package/testaro/dupAtt.d.ts +16 -0
- package/testaro/dupAtt.js +114 -104
- package/testaro/dupAtt.ts +144 -0
- package/testaro/elements.d.ts +6 -0
- package/testaro/elements.js +153 -153
- package/testaro/elements.ts +215 -0
- package/testaro/embAc.d.ts +3 -0
- package/testaro/embAc.js +20 -20
- package/testaro/embAc.ts +40 -0
- package/testaro/focAll.d.ts +13 -0
- package/testaro/focAll.js +186 -191
- package/testaro/focAll.ts +217 -0
- package/testaro/focAndOp.d.ts +3 -0
- package/testaro/focAndOp.js +101 -104
- package/testaro/focAndOp.ts +128 -0
- package/testaro/focInd.d.ts +3 -0
- package/testaro/focInd.js +65 -66
- package/testaro/focInd.ts +96 -0
- package/testaro/focVis.d.ts +3 -0
- package/testaro/focVis.js +29 -30
- package/testaro/focVis.ts +52 -0
- package/testaro/headEl.d.ts +10 -0
- package/testaro/headEl.js +62 -62
- package/testaro/headEl.ts +82 -0
- package/testaro/headingAmb.d.ts +3 -0
- package/testaro/headingAmb.js +55 -63
- package/testaro/headingAmb.ts +72 -0
- package/testaro/hovInd.d.ts +12 -0
- package/testaro/hovInd.js +164 -130
- package/testaro/hovInd.ts +199 -0
- package/testaro/hover.d.ts +3 -0
- package/testaro/hover.js +156 -126
- package/testaro/hover.ts +154 -0
- package/testaro/hr.d.ts +3 -0
- package/testaro/hr.js +15 -17
- package/testaro/hr.ts +36 -0
- package/testaro/imageLink.d.ts +3 -0
- package/testaro/imageLink.js +18 -20
- package/testaro/imageLink.ts +42 -0
- package/testaro/labClash.d.ts +3 -0
- package/testaro/labClash.js +32 -33
- package/testaro/labClash.ts +54 -0
- package/testaro/legendLoc.d.ts +3 -0
- package/testaro/legendLoc.js +18 -20
- package/testaro/legendLoc.ts +42 -0
- package/testaro/lineHeight.d.ts +3 -0
- package/testaro/lineHeight.js +44 -48
- package/testaro/lineHeight.ts +70 -0
- package/testaro/linkAmb.d.ts +7 -0
- package/testaro/linkAmb.js +80 -80
- package/testaro/linkAmb.ts +105 -0
- package/testaro/linkExt.d.ts +3 -0
- package/testaro/linkExt.js +14 -16
- package/testaro/linkExt.ts +35 -0
- package/testaro/linkOldAtt.d.ts +3 -0
- package/testaro/linkOldAtt.js +26 -28
- package/testaro/linkOldAtt.ts +48 -0
- package/testaro/linkTo.d.ts +3 -0
- package/testaro/linkTo.js +23 -22
- package/testaro/linkTo.ts +43 -0
- package/testaro/linkUl.d.ts +3 -0
- package/testaro/linkUl.js +31 -34
- package/testaro/linkUl.ts +54 -0
- package/testaro/miniText.d.ts +3 -0
- package/testaro/miniText.js +42 -44
- package/testaro/miniText.ts +68 -0
- package/testaro/motion.d.ts +10 -0
- package/testaro/motion.js +93 -96
- package/testaro/motion.ts +125 -0
- package/testaro/nonTable.d.ts +3 -0
- package/testaro/nonTable.js +40 -45
- package/testaro/nonTable.ts +66 -0
- package/testaro/optRoleSel.d.ts +3 -0
- package/testaro/optRoleSel.js +17 -19
- package/testaro/optRoleSel.ts +41 -0
- package/testaro/phOnly.d.ts +3 -0
- package/testaro/phOnly.js +19 -21
- package/testaro/phOnly.ts +43 -0
- package/testaro/pseudoP.d.ts +3 -0
- package/testaro/pseudoP.js +37 -38
- package/testaro/pseudoP.ts +59 -0
- package/testaro/radioSet.d.ts +3 -0
- package/testaro/radioSet.js +58 -59
- package/testaro/radioSet.ts +79 -0
- package/testaro/registry.d.ts +63 -0
- package/testaro/registry.js +67 -0
- package/testaro/registry.ts +141 -0
- package/testaro/role.d.ts +3 -0
- package/testaro/role.js +28 -29
- package/testaro/role.ts +53 -0
- package/testaro/secHeading.d.ts +3 -0
- package/testaro/secHeading.js +31 -33
- package/testaro/secHeading.ts +53 -0
- package/testaro/styleDiff.d.ts +25 -0
- package/testaro/styleDiff.js +249 -252
- package/testaro/styleDiff.ts +303 -0
- package/testaro/tabNav.d.ts +33 -0
- package/testaro/tabNav.js +273 -342
- package/testaro/tabNav.ts +454 -0
- package/testaro/targetsNear.d.ts +9 -0
- package/testaro/targetsNear.js +131 -132
- package/testaro/targetsNear.ts +160 -0
- package/testaro/textNodes.d.ts +6 -0
- package/testaro/textNodes.js +139 -135
- package/testaro/textNodes.ts +185 -0
- package/testaro/textSem.d.ts +3 -0
- package/testaro/textSem.js +26 -28
- package/testaro/textSem.ts +47 -0
- package/testaro/title.d.ts +9 -0
- package/testaro/title.js +16 -13
- package/testaro/title.ts +31 -0
- package/testaro/titledEl.d.ts +3 -0
- package/testaro/titledEl.js +16 -18
- package/testaro/titledEl.ts +38 -0
- package/testaro/zIndex.d.ts +3 -0
- package/testaro/zIndex.js +20 -22
- package/testaro/zIndex.ts +42 -0
- package/tests/alfa.d.ts +45 -0
- package/tests/alfa.js +139 -141
- package/tests/alfa.ts +214 -0
- package/tests/aslint.d.ts +33 -0
- package/tests/aslint.js +273 -249
- package/tests/aslint.ts +301 -0
- package/tests/axe.d.ts +27 -0
- package/tests/axe.js +200 -200
- package/tests/axe.ts +277 -0
- package/tests/ed11y.d.ts +28 -0
- package/tests/ed11y.js +142 -99
- package/tests/ed11y.ts +178 -0
- package/tests/htmlcs.d.ts +21 -0
- package/tests/htmlcs.js +175 -140
- package/tests/htmlcs.ts +181 -0
- package/tests/ibm.d.ts +52 -0
- package/tests/ibm.js +165 -166
- package/tests/ibm.ts +251 -0
- package/tests/nuVal.d.ts +13 -0
- package/tests/nuVal.js +107 -112
- package/tests/nuVal.ts +145 -0
- package/tests/nuVnu.d.ts +15 -0
- package/tests/nuVnu.js +142 -111
- package/tests/nuVnu.ts +144 -0
- package/tests/pour.d.ts +31 -0
- package/tests/pour.js +242 -0
- package/tests/pour.ts +273 -0
- package/tests/qualWeb.d.ts +39 -0
- package/tests/qualWeb.js +303 -272
- package/tests/qualWeb.ts +415 -0
- package/tests/surea11y.d.ts +33 -0
- package/tests/surea11y.js +288 -0
- package/tests/surea11y.ts +334 -0
- package/tests/testaro.d.ts +25 -0
- package/tests/testaro.js +746 -652
- package/tests/testaro.ts +862 -0
- package/tests/wave.d.ts +46 -0
- package/tests/wave.js +167 -177
- package/tests/wave.ts +252 -0
- package/tsconfig.json +17 -0
- package/types.d.ts +243 -0
- package/types.js +10 -0
- package/types.ts +376 -0
- package/validation/act/README.md +46 -0
- package/validation/act/capture.js +424 -0
- package/validation/act/chromium-issue-draft.md +66 -0
- package/validation/act/fp-triage-2026-08-22.md +86 -0
- package/validation/act/isolation-notes.md +159 -0
- package/validation/act/playwright-issue-draft.md +73 -0
- package/validation/act/propose-mappings.js +0 -0
- package/validation/act/repro-cdp-raw.js +105 -0
- package/validation/act/repro-metarefresh.js +65 -0
- package/validation/act/score.js +184 -0
- package/validation/act/stage3a-stress-report.md +69 -0
- package/validation/act/stage3b-mapping-proposals.md +94 -0
- package/validation/act/stage3b-triage-draft.md +138 -0
- package/validation/act/surea11y-track-a-2026-09-01.md +50 -0
- package/validation/executors/netWatch.js +180 -90
- package/validation/executors/test.js +17 -2
- package/validation/executors/tests.js +118 -10
- package/validation/jobs/reports/raw/260901T1000-surea11y-validation.json +964 -0
- package/validation/jobs/todo/240101T1200-simple-example.json +14 -6
- package/validation/jobs/todo/240101T1300-shoot-example.json +2 -1
- package/validation/jobs/todo/260821T1900-pour-validation.json +45 -0
- package/validation/jobs/todo/260901T1000-surea11y-validation.json +45 -0
- package/validation/knownFailures.json +1 -0
- package/validation/tests/jobProperties/adbID.json +27 -2
- package/validation/tests/jobProperties/{focOp.json → allCapStyle.json} +56 -53
- package/validation/tests/jobProperties/allCaps.json +25 -0
- package/validation/tests/jobProperties/allHidden.json +133 -13
- package/validation/tests/jobProperties/allSlanted.json +3 -3
- package/validation/tests/jobProperties/altScheme.json +23 -8
- package/validation/tests/jobProperties/attVal.json +57 -57
- package/validation/tests/jobProperties/autocomplete.json +11 -1
- package/validation/tests/jobProperties/bulk.json +6 -1
- package/validation/tests/jobProperties/buttonMenu.json +63 -42
- package/validation/tests/jobProperties/captionLoc.json +1 -6
- package/validation/tests/jobProperties/checkpoint-browser.json +401 -0
- package/validation/tests/jobProperties/checkpoint-page.json +397 -0
- package/validation/tests/jobProperties/checkpoint.json +395 -0
- package/validation/tests/jobProperties/datalistRef.json +20 -5
- package/validation/tests/jobProperties/distortion.json +28 -3
- package/validation/tests/jobProperties/docType.json +2 -2
- package/validation/tests/jobProperties/dupAtt.json +48 -33
- package/validation/tests/jobProperties/elements.json +28 -28
- package/validation/tests/jobProperties/embAc.json +36 -31
- package/validation/tests/jobProperties/focAndOp.json +284 -0
- package/validation/tests/jobProperties/focInd.json +34 -34
- package/validation/tests/jobProperties/focVis.json +1 -1
- package/validation/tests/jobProperties/hover.json +39 -37
- package/validation/tests/jobProperties/hr.json +13 -3
- package/validation/tests/jobProperties/imageLink.json +0 -5
- package/validation/tests/jobProperties/labClash.json +68 -33
- package/validation/tests/jobProperties/legendLoc.json +1 -6
- package/validation/tests/jobProperties/lineHeight.json +2 -2
- package/validation/tests/jobProperties/linkAmb.json +13 -18
- package/validation/tests/jobProperties/linkExt.json +1 -1
- package/validation/tests/jobProperties/linkOldAtt.json +12 -2
- package/validation/tests/jobProperties/linkTo.json +1 -1
- package/validation/tests/jobProperties/linkUl.json +65 -65
- package/validation/tests/jobProperties/miniText.json +7 -2
- package/validation/tests/jobProperties/motion.json +4 -50
- package/validation/tests/jobProperties/nonTable.json +48 -3
- package/validation/tests/jobProperties/optRoleSel.json +12 -2
- package/validation/tests/jobProperties/phOnly.json +6 -16
- package/validation/tests/jobProperties/pseudoP.json +17 -2
- package/validation/tests/jobProperties/radioSet.json +30 -30
- package/validation/tests/jobProperties/role.json +25 -5
- package/validation/tests/jobProperties/secHeading.json +26 -21
- package/validation/tests/jobProperties/styleDiff.json +35 -5
- package/validation/tests/jobProperties/tabNav.json +3 -1
- package/validation/tests/jobProperties/targetsNear.json +237 -0
- package/validation/tests/jobProperties/textNodes.json +29 -29
- package/validation/tests/jobProperties/textSem.json +26 -1
- package/validation/tests/jobProperties/title.json +12 -2
- package/validation/tests/jobProperties/titledEl.json +39 -9
- package/validation/tests/jobProperties/userPath.json +317 -0
- package/validation/tests/jobProperties/zIndex.json +40 -35
- package/validation/tests/targets/allCapStyle/index.html +26 -0
- package/validation/tests/targets/checkpoint/index.html +38 -0
- package/validation/tests/targets/datalistRef/index.html +1 -1
- package/validation/tests/targets/focAndOp/bad.html +29 -0
- package/validation/tests/targets/{focOp → focAndOp}/good.html +3 -1
- package/validation/tests/targets/focInd/bad.html +2 -1
- package/validation/tests/targets/headEl/index.html +10 -1
- package/validation/tests/targets/{targetSmall → targetsNear}/index.html +15 -1
- package/validation/tests/targets/userPath/index.html +42 -0
- package/validation/validateTest.js +62 -10
- package/.claude/settings.local.json +0 -11
- package/.eslintrc.json +0 -41
- package/htmlcs/.eslintrc.json +0 -67
- package/memory/MEMORY.md +0 -3
- package/memory/project_validation_pause.md +0 -10
- package/validation/tests/jobProperties/linkTitle.json +0 -127
- package/validation/tests/jobProperties/opFoc.json +0 -164
- package/validation/tests/jobProperties/targetSmall.json +0 -152
- package/validation/tests/jobProperties/targetTiny.json +0 -142
- package/validation/tests/targets/focOp/bad.html +0 -25
- package/validation/tests/targets/linkTitle/index.html +0 -24
- package/validation/tests/targets/opFoc/bad.html +0 -26
- package/validation/tests/targets/opFoc/good.html +0 -23
package/README.md
CHANGED
|
@@ -53,11 +53,13 @@ Testaro can perform tests of these _rule engines_:
|
|
|
53
53
|
- [Editoria11y](https://github.com/itmaybejj/editoria11y) (Princeton University)
|
|
54
54
|
- [HTML CodeSniffer](https://www.npmjs.com/package/html_codesniffer) (Squiz Labs)
|
|
55
55
|
- [Nu Html Checker](https://github.com/validator/validator) (World Wide Web Consortium)
|
|
56
|
+
- [Pour Engine](https://github.com/pourdev/pour-engine) (David Yarham and Geoffrey Crofte)
|
|
56
57
|
- [QualWeb](https://www.npmjs.com/package/@qualweb/core) (University of Lisbon)
|
|
58
|
+
- [SureA11y](https://github.com/SureA11y/core) (Jorge Rumoroso)
|
|
57
59
|
- [Testaro](https://www.npmjs.com/package/testaro) (CVS Health)
|
|
58
60
|
- [WAVE](https://wave.webaim.org/api/) (WebAIM)
|
|
59
61
|
|
|
60
|
-
For the rule engines that are open-source, the identified organizations are their principal or original sponsors.
|
|
62
|
+
For the rule engines that are open-source, the identified organizations or persons are their principal or original sponsors or authors.
|
|
61
63
|
|
|
62
64
|
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
65
|
|
|
@@ -81,7 +83,7 @@ The main concepts of Testaro are:
|
|
|
81
83
|
|
|
82
84
|
### Operating system and Node.js version
|
|
83
85
|
|
|
84
|
-
Testaro can be installed under a MacOS, Windows, Debian, or Ubuntu operating system with the latest long-term-support version of [Node.js](https://nodejs.org/en/).
|
|
86
|
+
Testaro can be installed under a MacOS, Windows, Debian, or Ubuntu operating system with the latest long-term-support version of [Node.js](https://nodejs.org/en/). The minimum version is Node 22.12: Node 20 reached end of life in April 2026, and some dependencies (the Alfa packages and pixelmatch) are ES modules that Testaro loads with `require()`, which the Node 22 line supports from 22.12 onward. When Node 22 reaches end of life in April 2027, the minimum is expected to rise to Node 24.
|
|
85
87
|
|
|
86
88
|
### Browser security
|
|
87
89
|
|
|
@@ -115,7 +117,7 @@ This application implements option B.
|
|
|
115
117
|
|
|
116
118
|
## Installation as an independent application
|
|
117
119
|
|
|
118
|
-
To install Testaro as an independent application, rather than a dependency, clone the [Testaro repository](https://github.com/
|
|
120
|
+
To install Testaro as an independent application, rather than a dependency, clone the [Testaro repository](https://github.com/YRA-Tech/testaro). To ensure that the binary browsers of its Playwright dependency get installed, execute `(p)npx playwright install` after executing `(p)npm install`.
|
|
119
121
|
|
|
120
122
|
To update Testaro when it is an independent application, execute:
|
|
121
123
|
|
|
@@ -129,6 +131,8 @@ git pull
|
|
|
129
131
|
|
|
130
132
|
The `.env` file stores your decisions about the environment in which Testaro runs. The variables that can be defined there are documented in the `env.example` file.
|
|
131
133
|
|
|
134
|
+
Deployment options let an operator set a fleet-wide policy that a job can override: the load state and time limit a navigation waits for and whether a 4xx response ends launch retries at once (`NAV_WAIT_UNTIL`, `NAV_TIMEOUT`, `NAV_FAIL_FAST_4XX`, or a job's `navigation` property); a scanner identity sent as the `X-YRA-Scanner` request header (`SCANNER_ID` or a job's `scannerId`); a full-page scroll after navigation so lazily loaded content is present (`PRESCAN_SCROLL` or a job's `scroll`); a branded Chromium channel (a job's `browserChannel`); launch retries per rule of the `testaro` tool (`TESTARO_RULE_RETRIES` or a `testaro` test act's `retries`); and whether the `qualWeb` tool's browser runs stealth evasions and blocks ads and trackers (`QUALWEB_STEALTH`, `QUALWEB_ADBLOCK`, or a `qualWeb` test act's `stealth` and `adBlock`). The defaults keep the behavior of earlier versions.
|
|
135
|
+
|
|
132
136
|
## Jobs
|
|
133
137
|
|
|
134
138
|
Jobs tell Testaro what to do.
|
|
@@ -141,7 +145,7 @@ Here is a sample job, showing properties that you can set:
|
|
|
141
145
|
what: 'monthly health check', // Job description
|
|
142
146
|
strict: true, // Whether to reject redirections from the target URL
|
|
143
147
|
standard: 'only', // Report native (no), standard (only), or both (also) results
|
|
144
|
-
imageColor: 0, // Color type (0, 2, 4, 6)
|
|
148
|
+
imageColor: 0, // Color type (0 (grayscale), 2 (RGB), 4 (grayscale alpha), 6 (RGBA)) if initial page image required
|
|
145
149
|
imageScale: 2, // Optional: also capture the page image at this device pixel density (see the images section)
|
|
146
150
|
device: { // Device to emulate
|
|
147
151
|
id: 'iPhone 8',
|
|
@@ -164,6 +168,20 @@ Here is a sample job, showing properties that you can set:
|
|
|
164
168
|
// Chromium-specific). Defaults to true. Set false to opt
|
|
165
169
|
// out — useful for sites whose anti-bot heuristics react
|
|
166
170
|
// badly to stealth's patches.
|
|
171
|
+
browserChannel: 'chrome', // Optional. Run an installed branded Chromium (chrome or msedge)
|
|
172
|
+
// instead of the bundled build; bundled or absent keeps the default.
|
|
173
|
+
scannerId: 'MyScanner/1.0; +https://example.com/scanner', // Optional. Sent as the
|
|
174
|
+
// X-YRA-Scanner request header (default SCANNER_ID, else no header).
|
|
175
|
+
scroll: false, // Optional. Scroll the full page after navigation so lazily loaded content
|
|
176
|
+
// is present before tools run (default PRESCAN_SCROLL, else false).
|
|
177
|
+
navigation: { // Optional. Load state to wait for (networkidle, load, or domcontentloaded),
|
|
178
|
+
// time limit in ms, and whether a 4xx response ends launch retries at once
|
|
179
|
+
// (defaults NAV_WAIT_UNTIL, NAV_TIMEOUT, NAV_FAIL_FAST_4XX, else networkidle,
|
|
180
|
+
// 10000, false).
|
|
181
|
+
waitUntil: 'load',
|
|
182
|
+
timeout: 30000,
|
|
183
|
+
failFast4xx: true
|
|
184
|
+
},
|
|
167
185
|
creationTimeStamp: '241229T0537', // When job was created
|
|
168
186
|
executionTimeStamp: '250110T1200', // When job will be ready to be performed
|
|
169
187
|
target: {
|
|
@@ -288,32 +306,34 @@ In both cases, the first argument of `dirWatch` tells Testaro whether to continu
|
|
|
288
306
|
|
|
289
307
|
### Server polling
|
|
290
308
|
|
|
291
|
-
Testaro can poll a server for jobs to be performed. The server can act as the “controller” described in [How to run a thousand accessibility tests](https://medium.com/cvs-health-tech-blog/how-to-run-a-thousand-accessibility-tests-63692ad120c3). The server is responsible for preparing Testaro jobs, assigning them to Testaro
|
|
309
|
+
Testaro can poll a server for jobs to be performed. The server can act as the “controller” described in [How to run a thousand accessibility tests](https://medium.com/cvs-health-tech-blog/how-to-run-a-thousand-accessibility-tests-63692ad120c3). The server is responsible for preparing Testaro jobs, assigning them to Testaro workers, receiving reports back from those workers, and performing any further processing of the reports, including enhancement, storage, and disclosure to audiences. It can be any server reachable with a URL. That includes a server running on the same host as Testaro, with a URL such as `localhost:3000`.
|
|
310
|
+
|
|
311
|
+
To allow Testaro to poll a server for jobs, define the environment variables documented under `netWatch variables` in the [env.example](env.example) file. The URL paths are determined by agreement between Testaro and the server. A single Testaro instance can watch one server.
|
|
292
312
|
|
|
293
|
-
|
|
313
|
+
`NETWATCH_AUTH_TYPE` selects how Testaro authenticates to the server:
|
|
294
314
|
|
|
295
|
-
- `
|
|
296
|
-
- `
|
|
297
|
-
- `
|
|
315
|
+
- `none`: no credentials are sent. `NETWATCH_WORKER_ID` and `NETWATCH_WORKER_SECRET` are not required.
|
|
316
|
+
- `pathBody`: the password (`NETWATCH_WORKER_SECRET`) is transmitted in the request body as the value of an `agentPW` property. If the server requires the ID of the Testaro instance in the URL path, include it in `NETWATCH_URL_JOB` and `NETWATCH_URL_REPORT` yourself; Testaro does not insert it.
|
|
317
|
+
- `header`: the request carries an `authorization` header whose value is `Basic`, followed by a space and the base64 encoding of `NETWATCH_WORKER_ID:NETWATCH_WORKER_SECRET`. The worker ID must not contain a colon.
|
|
298
318
|
|
|
299
|
-
|
|
319
|
+
Testaro sends job requests and completed reports as `POST` requests. When Testaro sends a report to the server, the report is the value of a `report` property in the request body. If `NETWATCH_WORKER_ID` is defined, Testaro also records it as the `sources.agent` property of the report, so the server can attribute the report to this instance under any auth type.
|
|
300
320
|
|
|
301
|
-
|
|
321
|
+
The `AGENT` and `NETWATCH_URL_AUTH` variables of earlier versions are deprecated. Testaro still honors them (as `NETWATCH_WORKER_ID` and as a `pathBody` password, respectively) but warns; rename them.
|
|
302
322
|
|
|
303
323
|
An application can make Testaro poll a server for jobs with:
|
|
304
324
|
|
|
305
325
|
```javaScript
|
|
306
326
|
const {netWatch} = require('testaro/netWatch');
|
|
307
|
-
netWatch(true, 300
|
|
327
|
+
netWatch(true, 300);
|
|
308
328
|
```
|
|
309
329
|
|
|
310
330
|
A user can make Testaro poll a server for jobs with:
|
|
311
331
|
|
|
312
332
|
```bash
|
|
313
|
-
node call netWatch true 300
|
|
333
|
+
node call netWatch true 300
|
|
314
334
|
```
|
|
315
335
|
|
|
316
|
-
The first argument of `netWatch` tells Testaro whether to continue polling after performing the first job. The second argument tells Testaro how many seconds to wait after receiving a no-jobs response before polling again. The third argument tells Testaro whether to be certificate-tolerant, i.e. to accept SSL certificates that fail verification against a list of certificate authorities (the default is `
|
|
336
|
+
The first argument of `netWatch` tells Testaro whether to continue polling after performing the first job. The second argument tells Testaro how many seconds to wait after receiving a no-jobs response before polling again. The optional third argument tells Testaro whether to be certificate-tolerant, i.e. to accept SSL certificates that fail verification against a list of certificate authorities (the default is `false`). Certificate tolerance disables the protection of an `https` connection, exposing credentials and reports to interception, so use it only against servers you control, such as local test servers with self-signed certificates.
|
|
317
337
|
|
|
318
338
|
## Reports
|
|
319
339
|
|
|
@@ -361,6 +381,7 @@ Testaro uses the following techniques to make the rule engines calculate XPaths:
|
|
|
361
381
|
|
|
362
382
|
- `alfa` and `aslint`: They report XPaths, so Testaro needs only to normalize them.
|
|
363
383
|
- `ed11y`: Testaro adds it and a `window.getXPath` method to the page. When the rule engine reports an element, Testaro computes its XPath.
|
|
384
|
+
- `pour` and `surea11y`: Testaro adds the vendored engine bundle and a `window.getXPath` method to the page. Each engine reports a CSS selector for each element; Testaro finds the element in the page via its selector and executes `window.getXPath` on it.
|
|
364
385
|
- `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.
|
|
365
386
|
- `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.
|
|
366
387
|
- `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.
|
|
@@ -405,24 +426,49 @@ Details about these expectation properties are documened in the `VALIDATION.md`
|
|
|
405
426
|
|
|
406
427
|
#### Standard results
|
|
407
428
|
|
|
408
|
-
If the job instructs Testaro to include standard results, then the `result.standardResult` property of each act of type `test` will have
|
|
429
|
+
If the job instructs Testaro to include standard results, then the `result.standardResult` property of each act of type `test` will have four properties:
|
|
409
430
|
|
|
410
431
|
- `prevented`: Whether the rule engine was prevented from performing the act
|
|
411
432
|
- `totals`: An array of 4 integers, counting the rule violations at 4 severity levels
|
|
433
|
+
- `outcomeTotals`: An object counting the rule violations by outcome: `{failed, cantTell}`
|
|
412
434
|
- `instances`: An array of data about the violations reported by the rule engine
|
|
413
435
|
|
|
414
436
|
More specifically:
|
|
415
437
|
|
|
416
438
|
- 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.
|
|
439
|
+
- The `outcomeTotals` value is an object like this: `{failed: 87, cantTell: 7}`. It counts the violations (weighted by `count`) that the rule engine asserted versus those it flagged as uncertain.
|
|
417
440
|
- The `instances` value is an array of objects, each having these properties:
|
|
418
|
-
- `
|
|
441
|
+
- `ruleID`: The ID of the rule that was violated
|
|
419
442
|
- `what`: A description of the rule or of the violation
|
|
420
443
|
- `ordinalSeverity`: The severity of the violation
|
|
444
|
+
- `outcome`: `failed` if the rule engine asserted the violation, or `cantTell` if the rule engine reported that it could not determine whether the rule was violated (the vocabulary of the ACT Rules Format). Every instance has an outcome.
|
|
445
|
+
- `uncertainty` (only with `cantTell`, and only if the rule engine gave a reason): One of `not-computable`, `judgement-required`, `runtime-dependent`, `spec-only`, `equivalence-unknown`, `out-of-scope`
|
|
446
|
+
- `needed` (only with `cantTell`, and only if the rule engine said): What a reviewer must determine to resolve the uncertainty
|
|
421
447
|
- `count`: How many violations of the rule this instance reports
|
|
422
448
|
- `catalogIndex`: Key of the HTML element in the catalog
|
|
423
449
|
|
|
424
450
|
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.
|
|
425
451
|
|
|
452
|
+
The `outcome` property is the authoritative certainty signal. In version 78, each tool's `ordinalSeverity` conventions are unchanged from earlier versions: most tools encode uncertainty as a low severity (for example, axe `incomplete` results have severities 0 and 1, and `violations` have severities 2 and 3), so `ordinalSeverity` still mixes certainty with impact, and it mixes them differently per tool. Consumers should read `outcome` for certainty and should not infer it from `ordinalSeverity`. A later major version will redefine `ordinalSeverity` as impact only (0 minor, 1 moderate, 2 serious, 3 critical). Design record: `docs/standard-result-outcome.md`.
|
|
453
|
+
|
|
454
|
+
Testaro's own rules report `failed` unless the rule's entry in `allRules` (in `tests/testaro.ts`) specifies `outcome: 'cantTell'` (for example, `allCaps`, whose violations are AI estimates) or a violation description carries a prefix: `2:` sets severity 2, `2?:` sets severity 2 and outcome `cantTell`, and `?:` sets outcome `cantTell` at the rule's default severity.
|
|
455
|
+
|
|
456
|
+
### Checkpoints
|
|
457
|
+
|
|
458
|
+
A job's acts run in order: a `launch` act opens a page, interaction acts (`button`, `link`, `text`, `press`, `url`, and so on) act on it, and `test` acts run rule engines. A **checkpoint** is a named page state reached by that flow, snapshotted and tested. Checkpoint 0 is the job target as launched; a `checkpoint` act (`{type: 'checkpoint', which: 'name'}`) creates the next one from the live page. A `test` act tests the most recent checkpoint, and each of its standard instances carries the `checkpoint` index. `report.checkpoints[k]` describes each checkpoint: its name, URL, title, the page images (`imageIndexes` into `report.images`), the catalog entries it added (`catalogRange`; every catalog entry also carries `checkpoint`), an ARIA snapshot, and, for a state reached by interaction, the acts (`replay`) that a test act's browser re-enacts after navigating to `launchURL` before the rule engine runs. Each such test act records `data.replay` with the count of replayed acts and a `fidelity` of `exact` or `divergent`, comparing the replayed page's DOM with the snapshot.
|
|
459
|
+
|
|
460
|
+
A job's `isolation` property (or the `ISOLATION` environment default) sets how test acts are isolated: `process` (the default, and the previous behavior) runs each test act in a child process with its own browser; `browser` runs test acts in the job's process, each in a fresh context of one browser shared by the job; `page` runs them in the job's process on the live page of the current checkpoint, with no replay, so tools may contaminate one another's page (contaminating testaro rules still get a fresh page). `jobData.isolation` records the level used. Only `process` isolation kills a tool that overruns its time limit; the others report the act as timed out and continue.
|
|
461
|
+
|
|
462
|
+
When a job has two or more checkpoints, the report gains `flow`, the running list of issues across them. `flow.checkpoints[k]` summarizes each checkpoint (the tools that observed it and its issue count), and `flow.deltas[k - 1]` compares checkpoints `k - 1` and `k`: the issues `added` by the acts between them, those that `persisted`, and those `removed`, each identified by tool, rule ID, element XPath (`pathID`), and start tag, so the same element in two page states is one issue. Only tools that observed both checkpoints are compared (`tools`); the rest are listed as `notObserved`. An earlier issue that a tool did not re-test at the later checkpoint, because its acts there were all scoped to changed subtrees that exclude the issue's element, is listed as `notRetested`, not `removed`. Each delta also carries `structure`, the difference between the two checkpoints' catalogs as XPaths (`added`, `removed`, `changed` start tags, `textChanged`, and the outermost changed elements as `roots`), and `aria`, a line diff of the two ARIA snapshots.
|
|
463
|
+
|
|
464
|
+
Interaction acts can identify their elements by a `selector` property (any Playwright selector, such as `#name`, `text="Continue"`, or `role=button[name="Continue"]`) instead of an element type and text substring; a `text` act with `clear: true` replaces the input's value. With these, a recorded user path (a start URL and actions of the kinds a Playwright recording yields: `click`, `fill`, `select`, `navigate`, `wait`, `checkpoint`) converts directly into a job: `require('testaro/procs/userPath').getUserPathActs({startUrl, actions, testActs})` returns the acts, one per action, with each `checkpoint` action becoming a `checkpoint` act followed by a copy of each test act in `testActs`.
|
|
465
|
+
|
|
466
|
+
When a checkpoint is created, the catalog entries of the previous checkpoint that none of its test acts cited are pruned at once, since no later test act can cite them, so a long flow does not accumulate every page state's catalog in the report that each test act reads.
|
|
467
|
+
|
|
468
|
+
A `test` act may have a `scope` property. The default, `page`, tests the whole page of the act's checkpoint. With `changed`, the act tests only the subtrees that changed since the previous checkpoint (the `roots` of the structure diff, as CSS selectors), for the rules and tools that can be so restricted: the `testaro` rules declared element-local (`local: true` in `allRules`), `axe` (by its `include` context), and `surea11y` (by its context selector, the nearest common ancestor of the roots). Page-level `testaro` rules (heading order, landmarks, duplicate IDs, focus order, hover, motion, and others) and all other tools test the whole page whatever the scope, because any change can alter their verdicts. The act records `data.scope` (`requested`, `applied`, `reason`, `roots`, `pathIDs`, and for `testaro` the `localRules` and `pageRules`), so a reader can see what was and was not re-tested. The act is not scoped, and `jobData.warnings` says why, when there is no previous checkpoint, nothing changed, more than 50 subtrees changed, or the tool cannot restrict itself.
|
|
469
|
+
|
|
470
|
+
Checkpoint acts are optional. A job without one behaves as before: every test act tests checkpoint 0, and interaction acts before a test act only produce a warning in `jobData.warnings`. In a job with checkpoint acts, interaction acts followed by a test act without a checkpoint act produce an implicit checkpoint and a warning. A rule engine that tests a URL rather than a page (WAVE, and the Nu checkers with `withSource`) cannot test a state reached by interaction; such a test act is prevented with the reason. Details: `docs/checkpoint-scanning.md`.
|
|
471
|
+
|
|
426
472
|
## Rule-engine details
|
|
427
473
|
|
|
428
474
|
The rule engines whose tests Testaro performs have particularities described below.
|
|
@@ -494,6 +540,10 @@ The `nuVal` and `nuVnu` rule engines perform the tests of the Nu Html Checker. T
|
|
|
494
540
|
|
|
495
541
|
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.
|
|
496
542
|
|
|
543
|
+
### Pour Engine
|
|
544
|
+
|
|
545
|
+
The `pour` rule engine makes use of the `pour/pour.min.js` file, a bundle that Testaro builds from the upstream [pour-engine](https://github.com/pourdev/pour-engine) repository (MIT), because upstream publishes no distributable bundle. The `pour/README.md` file documents the build command and the pinned upstream version. Testaro injects the bundle into the page and runs every rule. Findings in the engine's `violations` bucket become standard instances with outcome `failed`; findings in its `incomplete` bucket become instances with outcome `cantTell`. The engine's `passes`, `inapplicable`, and `manualReview` buckets are tallied in the act's `data` property and never become instances. If the bundle is missing or fails to define its global, the act is reported as prevented.
|
|
546
|
+
|
|
497
547
|
### QualWeb
|
|
498
548
|
|
|
499
549
|
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.
|
|
@@ -519,13 +569,17 @@ Thus, when the `rules` argument is omitted, QualWeb will test for all of the rul
|
|
|
519
569
|
|
|
520
570
|
The target can be provided to QualWeb either as HTML or as a URL. Experience indicates that the results can differ between these methods, with each method reporting some rule violations or some instances that the other method does not report. For at least some cases, more rules are reported violated when HTML is provided (`withNewItems: false`).
|
|
521
571
|
|
|
522
|
-
QualWeb creates sandboxed
|
|
572
|
+
QualWeb creates sandboxed Playwright pages to perform its tests on. Therefore, the host must permit sandboxed browsers to be launched. See the discussion above about browser security.
|
|
573
|
+
|
|
574
|
+
### SureA11y
|
|
575
|
+
|
|
576
|
+
The `surea11y` rule engine makes use of the `surea11y/surea11y.browser.js` file, the standalone browser bundle that [`@surea11y/core`](https://github.com/SureA11y/core) publishes, vendored verbatim. That package is licensed under the Mozilla Public License 2.0, unlike the MIT-licensed or Apache-licensed rule engines; the vendored file must not be modified. The `surea11y/README.md` file documents the pinned upstream version and the result shape. Testaro injects the bundle into the page and runs every automatic rule. The engine reports an outcome per rule (`pass`, `fail`, `cantTell`, or `notApplicable`) and may grade individual occurrences of a `fail` rule as `cantTell`. Occurrences graded `fail` become standard instances with outcome `failed`; occurrences graded `cantTell` become instances with outcome `cantTell`, carrying the engine's `uncertainty` code and `needed` guidance when it supplies them. Rules of type `manual` and rules with outcome `pass` or `notApplicable` are tallied in the act's `data` property and never become instances.
|
|
523
577
|
|
|
524
578
|
### Testaro
|
|
525
579
|
|
|
526
580
|
The rules that Testaro can test for are implemented in files within the `testaro` directory.
|
|
527
581
|
|
|
528
|
-
The Testaro rules are classified by an `allRules` array defined in the `tests/testaro.
|
|
582
|
+
The Testaro rules are classified by an `allRules` array defined in the `tests/testaro.ts` file. Each item in that array is an object with these properties:
|
|
529
583
|
|
|
530
584
|
- `id`: the rule ID.
|
|
531
585
|
- `what`: a description of the rule.
|
|
@@ -558,7 +612,7 @@ If you want the stand-alone API to perform the tests, you need to have that API
|
|
|
558
612
|
|
|
559
613
|
You can define additional Testaro rules and functionality. Contributions are welcome.
|
|
560
614
|
|
|
561
|
-
Please report any issues, including feature requests, at the [repository](https://github.com/
|
|
615
|
+
Please report any issues, including feature requests, at the [repository](https://github.com/YRA-Tech/testaro/issues).
|
|
562
616
|
|
|
563
617
|
## Accessibility principles
|
|
564
618
|
|
|
@@ -654,7 +708,7 @@ From 12 February 2024 through 30 September 2025, contributors of code to Testaro
|
|
|
654
708
|
|
|
655
709
|
## Future work
|
|
656
710
|
|
|
657
|
-
Future work contemplated for this project is described in its [issues](https://github.com/
|
|
711
|
+
Future work contemplated for this project is described in its [issues](https://github.com/YRA-Tech/testaro/issues) and also discussed in the [UPGRADES.md](UPGRADES.md) file.
|
|
658
712
|
|
|
659
713
|
## Etymology
|
|
660
714
|
|
|
@@ -663,6 +717,7 @@ Future work contemplated for this project is described in its [issues](https://g
|
|
|
663
717
|
## License
|
|
664
718
|
|
|
665
719
|
© 2021–2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
720
|
+
© 2026 Jeff Witt.
|
|
666
721
|
© 2025–2026 Jonathan Robert Pool.
|
|
667
722
|
|
|
668
723
|
Licensed under the [MIT License](https://opensource.org/license/mit/). See [LICENSE](../../LICENSE) file at the project root for details.
|
package/UPGRADES.md
CHANGED
|
@@ -8720,3 +8720,7 @@ you'll get notified when `#334` merges and when the subsequent changesets "Versi
|
|
|
8720
8720
|
- **Re-test**: run a job with a `qualWeb` act and confirm the `No DOM` error is gone before merging your `qwpw` branch.
|
|
8721
8721
|
|
|
8722
8722
|
I'll be ready to help with the dependency bump and verification when that release lands.
|
|
8723
|
+
|
|
8724
|
+
# Certainty in the standard result (2026-09-01)
|
|
8725
|
+
|
|
8726
|
+
Decision: add a first-class `outcome` (`failed` | `cantTell`) to every standard instance, with optional `uncertainty` (six ACT-style codes borrowed from surea11y) and `needed` (reviewer guidance), plus `standardResult.outcomeTotals`. `ordinalSeverity` and `totals` are unchanged in 78.x; a later major version redefines `ordinalSeverity` as impact only. This follows the `allCaps` ruling above (do not overload `ordinalSeverity` with confidence) by giving certainty its own field rather than by hiding it in `what`. Shared shape helpers live in `procs/standard.js`; the alfa adapter no longer rewrites rule IDs to `cantTell` / `cantTellTextContrast`. Full design, including the recommended Testilo tic consolidation of the 57 `*Risk` issues and certainty-aware scoring: `docs/standard-result-outcome.md`.
|
package/actSpecs-doc.md
CHANGED
|
@@ -55,9 +55,13 @@ The validity criterion named in item 2 may be any of these:
|
|
|
55
55
|
- `'isWaitable'`: is `'url'`, `'title'`, or `'body'`
|
|
56
56
|
- `'areStrings'`: is an array of strings
|
|
57
57
|
|
|
58
|
+
## qualWeb tool
|
|
59
|
+
|
|
60
|
+
A `qualWeb` test act may have `stealth` and `adBlock` boolean properties, which set whether the tool's browser runs stealth evasions and blocks ads and trackers (defaults `QUALWEB_STEALTH` and `QUALWEB_ADBLOCK`, else true).
|
|
61
|
+
|
|
58
62
|
## testaro tool
|
|
59
63
|
|
|
60
|
-
The `tools.testaro` object has an `args` property specifying that a `testaro` test act may include an `args` property with an object value.
|
|
64
|
+
The `tools.testaro` object has a `retries` property (launch retries per rule; default `TESTARO_RULE_RETRIES`, else 2) and an `args` property specifying that a `testaro` test act may include an `args` property with an object value.
|
|
61
65
|
|
|
62
66
|
If it does, the property names of the object value must be `testaro` rule IDs. Any property value must be an array of the positional arguments to be concatenated to the four default arguments (`page`, `report`, `actIndex`, and `withItems`) in the signature of the `reporter` function of each `testaro` rule.
|
|
63
67
|
|
|
@@ -84,3 +88,11 @@ Licensed under the [MIT License](https://opensource.org/license/mit/). See [LICE
|
|
|
84
88
|
at the project root for details.
|
|
85
89
|
|
|
86
90
|
SPDX-License-Identifier: MIT
|
|
91
|
+
|
|
92
|
+
## Checkpoint acts
|
|
93
|
+
|
|
94
|
+
The move acts (`button`, `checkbox`, `link`, `radio`, `search`, `select`, `text`) may have a `selector` property, any Playwright selector, which replaces the act type's element selector and the text matching of `which`; `index` still selects among the matches. A `checkbox` or `radio` act must have `which` or `selector`. A `text` act with `clear: true` replaces the input's value instead of appending to it. A `select` act whose `what` matches no option text falls back to Playwright's matching of `what` as an option value or label. `procs/userPath.js` builds acts of these kinds from a recorded user path.
|
|
95
|
+
|
|
96
|
+
A `test` act may have a `scope` property: `page` (the default) tests the whole page of the act's checkpoint; `changed` tests only the subtrees that changed since the previous checkpoint, for the rules and tools that can be so restricted (the element-local `testaro` rules, `axe`, and `surea11y`), and the whole page for the rest. A job with a changed-scope test act must have a checkpoint act. The act records what it was given as `data.scope`. See `docs/checkpoint-scanning.md`.
|
|
97
|
+
|
|
98
|
+
A `checkpoint` act snapshots the current page state as a checkpoint that subsequent `test` acts observe. Its `which` property names the checkpoint (unique within the job, and not `start`, the name of checkpoint 0). A checkpoint act must follow a `launch` act. See `docs/checkpoint-scanning.md`.
|
package/actSpecs.js
CHANGED
|
@@ -19,15 +19,24 @@ exports.actSpecs = {
|
|
|
19
19
|
button: [
|
|
20
20
|
'Click a button or submit input',
|
|
21
21
|
{
|
|
22
|
+
selector: [false, 'string', 'hasLength', 'Playwright selector of the element, instead of an element type and text substring'],
|
|
22
23
|
which: [false, 'string', 'hasLength', 'substring of button text'],
|
|
23
24
|
index: [false, 'number', '', 'index among matches if not 0'],
|
|
24
25
|
what: [false, 'string', 'hasLength', 'comment']
|
|
25
26
|
}
|
|
26
27
|
],
|
|
28
|
+
checkpoint: [
|
|
29
|
+
'Snapshot the current page state (catalog, page image, ARIA snapshot) as a checkpoint that subsequent test acts observe',
|
|
30
|
+
{
|
|
31
|
+
which: [true, 'string', 'hasLength', 'checkpoint name, unique within the job'],
|
|
32
|
+
what: [false, 'string', 'hasLength', 'comment']
|
|
33
|
+
}
|
|
34
|
+
],
|
|
27
35
|
checkbox: [
|
|
28
36
|
'Check a checkbox',
|
|
29
37
|
{
|
|
30
|
-
|
|
38
|
+
selector: [false, 'string', 'hasLength', 'Playwright selector of the element, instead of an element type and text substring'],
|
|
39
|
+
which: [false, 'string', 'hasLength', 'substring of checkbox text (required unless selector is given)'],
|
|
31
40
|
index: [false, 'number', '', 'index among matches if not 0'],
|
|
32
41
|
what: [false, 'string', 'hasLength', 'comment']
|
|
33
42
|
}
|
|
@@ -52,6 +61,7 @@ exports.actSpecs = {
|
|
|
52
61
|
link: [
|
|
53
62
|
'Click a link and wait for the page to be idle or loaded',
|
|
54
63
|
{
|
|
64
|
+
selector: [false, 'string', 'hasLength', 'Playwright selector of the element, instead of an element type and text substring'],
|
|
55
65
|
which: [false, 'string', 'hasLength', 'substring of link text'],
|
|
56
66
|
index: [false, 'number', '', 'index among matches if not 0'],
|
|
57
67
|
what: [false, 'string', 'hasLength', 'comment']
|
|
@@ -96,7 +106,8 @@ exports.actSpecs = {
|
|
|
96
106
|
radio: [
|
|
97
107
|
'Check a radio button',
|
|
98
108
|
{
|
|
99
|
-
|
|
109
|
+
selector: [false, 'string', 'hasLength', 'Playwright selector of the element, instead of an element type and text substring'],
|
|
110
|
+
which: [false, 'string', 'hasLength', 'substring of radio-button text (required unless selector is given)'],
|
|
100
111
|
index: [false, 'number', '', 'index among matches if not 0'],
|
|
101
112
|
what: [false, 'string', 'hasLength', 'comment']
|
|
102
113
|
}
|
|
@@ -110,6 +121,7 @@ exports.actSpecs = {
|
|
|
110
121
|
search: [
|
|
111
122
|
'Enter text into a search input, optionally with 1 placeholder for an all-caps literal environment variable',
|
|
112
123
|
{
|
|
124
|
+
selector: [false, 'string', 'hasLength', 'Playwright selector of the element, instead of an element type and text substring'],
|
|
113
125
|
which: [false, 'string', 'hasLength', 'substring of input text'],
|
|
114
126
|
index: [false, 'number', '', 'index among matches if not 0'],
|
|
115
127
|
what: [true, 'string', 'hasLength', 'text to enter, with optional __PLACEHOLDER__']
|
|
@@ -118,6 +130,7 @@ exports.actSpecs = {
|
|
|
118
130
|
select: [
|
|
119
131
|
'Select a select option',
|
|
120
132
|
{
|
|
133
|
+
selector: [false, 'string', 'hasLength', 'Playwright selector of the element, instead of an element type and text substring'],
|
|
121
134
|
which: [false, 'string', 'hasLength', 'substring of select-list text'],
|
|
122
135
|
index: [false, 'number', '', 'index among matches if not 0'],
|
|
123
136
|
what: [true, 'string', 'hasLength', 'substring of option text content']
|
|
@@ -144,15 +157,18 @@ exports.actSpecs = {
|
|
|
144
157
|
{
|
|
145
158
|
which: [true, 'string', 'isTest', 'tool name'],
|
|
146
159
|
launch: [false, 'object', '', 'new target, browserID, and/or what, if any'],
|
|
147
|
-
rules: [false, 'array', 'areStrings', 'rule IDs or (for testaro, nuVal, or nuVnu) specifications, if not all']
|
|
160
|
+
rules: [false, 'array', 'areStrings', 'rule IDs or (for testaro, nuVal, or nuVnu) specifications, if not all'],
|
|
161
|
+
scope: [false, 'string', 'isScope', 'page (default) or changed (only the subtrees changed since the previous checkpoint, for rules and tools that can be so restricted)']
|
|
148
162
|
}
|
|
149
163
|
],
|
|
150
164
|
text: [
|
|
151
165
|
'Enter text into a text input, optionally with 1 placeholder for an all-caps literal environment variable',
|
|
152
166
|
{
|
|
167
|
+
selector: [false, 'string', 'hasLength', 'Playwright selector of the element, instead of an element type and text substring'],
|
|
153
168
|
which: [false, 'string', 'hasLength', 'substring of input text'],
|
|
154
169
|
index: [false, 'number', '', 'index among matches if not 0'],
|
|
155
|
-
what: [true, 'string', 'hasLength', 'text to enter, with optional __PLACEHOLDER__']
|
|
170
|
+
what: [true, 'string', 'hasLength', 'text to enter, with optional __PLACEHOLDER__'],
|
|
171
|
+
clear: [false, 'boolean', '', 'whether to replace any existing value instead of appending']
|
|
156
172
|
}
|
|
157
173
|
],
|
|
158
174
|
url: [
|
|
@@ -196,12 +212,20 @@ exports.actSpecs = {
|
|
|
196
212
|
withSource: [false, 'boolean', '', 'whether to use the page source and not the browser page']
|
|
197
213
|
}
|
|
198
214
|
],
|
|
215
|
+
qualWeb: [
|
|
216
|
+
'Perform QualWeb tests',
|
|
217
|
+
{
|
|
218
|
+
stealth: [false, 'boolean', '', 'whether the browser runs stealth evasions (default QUALWEB_STEALTH, else true)'],
|
|
219
|
+
adBlock: [false, 'boolean', '', 'whether the browser blocks ads and trackers (default QUALWEB_ADBLOCK, else true)']
|
|
220
|
+
}
|
|
221
|
+
],
|
|
199
222
|
testaro: [
|
|
200
223
|
'Perform Testaro tests',
|
|
201
224
|
{
|
|
202
225
|
withItems: [true, 'boolean', '', 'itemize'],
|
|
203
226
|
stopOnFail: [true, 'boolean', '', 'whether testing is to stop after first failure'],
|
|
204
|
-
args: [false, 'object', 'areArrays', 'extra arguments of rules taking any']
|
|
227
|
+
args: [false, 'object', 'areArrays', 'extra arguments of rules taking any'],
|
|
228
|
+
retries: [false, 'number', '', 'launch retries per rule (default TESTARO_RULE_RETRIES, else 2)']
|
|
205
229
|
}
|
|
206
230
|
],
|
|
207
231
|
wave: [
|
package/call.js
CHANGED
|
@@ -45,8 +45,8 @@ const callRun = async jobIDStart => {
|
|
|
45
45
|
const jobDirFileNames = await fs.readdir(todoDir);
|
|
46
46
|
const jobFileNames = jobDirFileNames.filter(fileName => fileName.endsWith('.json'));
|
|
47
47
|
const specifiedJobFileNames = jobIDStart
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
? jobFileNames.filter(fileName => fileName.startsWith(jobIDStart))
|
|
49
|
+
: jobFileNames;
|
|
50
50
|
const jobFileName = specifiedJobFileNames[0];
|
|
51
51
|
// If it exists:
|
|
52
52
|
if (jobFileName) {
|
|
@@ -74,7 +74,7 @@ const callDirWatch = async (isForever, intervalInSeconds) => {
|
|
|
74
74
|
};
|
|
75
75
|
// Starts a network watch, converting the interval argument to a number.
|
|
76
76
|
const callNetWatch = async (isForever, intervalInSeconds, isCertTolerant) => {
|
|
77
|
-
await netWatch(
|
|
77
|
+
return await netWatch(
|
|
78
78
|
isForever === 'true',
|
|
79
79
|
Number.parseInt(intervalInSeconds, 10),
|
|
80
80
|
isCertTolerant ? isCertTolerant === 'true' : undefined
|
|
@@ -100,9 +100,10 @@ else if (fn === 'dirWatch' && fnArgs.length === 2) {
|
|
|
100
100
|
}
|
|
101
101
|
else if (fn === 'netWatch' && [2, 3].includes(fnArgs.length)) {
|
|
102
102
|
callNetWatch(... fnArgs)
|
|
103
|
-
.then(
|
|
103
|
+
.then(isOK => {
|
|
104
104
|
console.log('Network watch ended');
|
|
105
|
-
|
|
105
|
+
// Exit with a failure code if the watch was misconfigured or aborted, so supervisors notice.
|
|
106
|
+
process.exit(isOK ? 0 : 1);
|
|
106
107
|
});
|
|
107
108
|
}
|
|
108
109
|
else {
|
package/docker-compose.yml
CHANGED
|
@@ -26,10 +26,16 @@ services:
|
|
|
26
26
|
# Send nuVal requests to the sidecar instead of the W3C service.
|
|
27
27
|
TESTARO_NU_URL: "http://nu:8888/?parser=html&out=json"
|
|
28
28
|
# JODBIR and REPORTDIR from Dockerfile override those from .env.
|
|
29
|
-
# Import other specific environment variables from .env file.
|
|
30
|
-
|
|
29
|
+
# Import other specific environment variables from .env file. The
|
|
30
|
+
# NETWATCH_* variables default to empty so that directory-watch use
|
|
31
|
+
# needs no .env entries for them; set them in .env for server polling.
|
|
31
32
|
WAVE_KEY: ${WAVE_KEY}
|
|
32
33
|
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
|
|
34
|
+
NETWATCH_URL_JOB: ${NETWATCH_URL_JOB:-}
|
|
35
|
+
NETWATCH_URL_REPORT: ${NETWATCH_URL_REPORT:-}
|
|
36
|
+
NETWATCH_AUTH_TYPE: ${NETWATCH_AUTH_TYPE:-}
|
|
37
|
+
NETWATCH_WORKER_ID: ${NETWATCH_WORKER_ID:-}
|
|
38
|
+
NETWATCH_WORKER_SECRET: ${NETWATCH_WORKER_SECRET:-}
|
|
33
39
|
volumes:
|
|
34
40
|
# Host directories for jobs and reports. The container runs as the
|
|
35
41
|
# unprivileged pwuser; the host directories must be writable by it
|