testaro 78.0.8 → 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 +24 -18
- package/CONTAINERS.md +9 -6
- package/CONTRIBUTING.md +29 -3
- package/Dockerfile +1 -1
- package/README.md +73 -19
- 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 +372 -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 +312 -221
- package/procs/catalog.ts +398 -0
- package/procs/checkpoint.js +110 -0
- package/procs/config.d.ts +35 -0
- package/procs/config.js +62 -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/job.js +115 -1
- package/procs/launch.d.ts +40 -0
- package/procs/launch.js +239 -108
- package/procs/nu.d.ts +48 -0
- package/procs/scope.js +196 -0
- package/procs/shoot.d.ts +33 -0
- 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 +236 -189
- package/procs/testaro.ts +321 -0
- package/procs/userPath.js +126 -0
- package/procs/xPath.d.ts +4 -0
- package/procs/xPath.js +81 -69
- 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 +38 -41
- package/testaro/adbID.ts +66 -0
- package/testaro/allCapStyle.d.ts +3 -0
- package/testaro/allCapStyle.js +31 -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 +29 -30
- package/testaro/allHidden.ts +50 -0
- package/testaro/allSlanted.d.ts +3 -0
- package/testaro/allSlanted.js +30 -33
- package/testaro/allSlanted.ts +54 -0
- package/testaro/altScheme.d.ts +3 -0
- package/testaro/altScheme.js +27 -30
- package/testaro/altScheme.ts +50 -0
- package/testaro/attVal.d.ts +3 -0
- package/testaro/attVal.js +20 -21
- package/testaro/attVal.ts +52 -0
- package/testaro/autocomplete.d.ts +3 -0
- package/testaro/autocomplete.js +59 -75
- package/testaro/autocomplete.ts +101 -0
- package/testaro/bulk.d.ts +13 -0
- package/testaro/bulk.js +32 -33
- package/testaro/bulk.ts +55 -0
- package/testaro/buttonMenu.d.ts +9 -0
- package/testaro/buttonMenu.js +317 -319
- package/testaro/buttonMenu.ts +391 -0
- package/testaro/captionLoc.d.ts +3 -0
- package/testaro/captionLoc.js +17 -20
- package/testaro/captionLoc.ts +40 -0
- package/testaro/datalistRef.d.ts +3 -0
- package/testaro/datalistRef.js +33 -36
- package/testaro/datalistRef.ts +55 -0
- package/testaro/distortion.d.ts +3 -0
- package/testaro/distortion.js +57 -26
- package/testaro/distortion.ts +81 -0
- package/testaro/docType.d.ts +15 -0
- package/testaro/docType.js +25 -25
- package/testaro/docType.ts +45 -0
- package/testaro/dupAtt.d.ts +16 -0
- package/testaro/dupAtt.js +113 -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 +19 -20
- package/testaro/embAc.ts +40 -0
- package/testaro/focAll.d.ts +13 -0
- package/testaro/focAll.js +185 -191
- package/testaro/focAll.ts +217 -0
- package/testaro/focAndOp.d.ts +3 -0
- package/testaro/focAndOp.js +100 -104
- package/testaro/focAndOp.ts +128 -0
- package/testaro/focInd.d.ts +3 -0
- package/testaro/focInd.js +64 -66
- package/testaro/focInd.ts +96 -0
- package/testaro/focVis.d.ts +3 -0
- package/testaro/focVis.js +28 -30
- package/testaro/focVis.ts +52 -0
- package/testaro/headEl.d.ts +10 -0
- package/testaro/headEl.js +61 -62
- package/testaro/headEl.ts +82 -0
- package/testaro/headingAmb.d.ts +3 -0
- package/testaro/headingAmb.js +54 -63
- package/testaro/headingAmb.ts +72 -0
- package/testaro/hovInd.d.ts +12 -0
- package/testaro/hovInd.js +163 -130
- package/testaro/hovInd.ts +199 -0
- package/testaro/hover.d.ts +3 -0
- package/testaro/hover.js +155 -126
- package/testaro/hover.ts +154 -0
- package/testaro/hr.d.ts +3 -0
- package/testaro/hr.js +14 -17
- package/testaro/hr.ts +36 -0
- package/testaro/imageLink.d.ts +3 -0
- package/testaro/imageLink.js +17 -20
- package/testaro/imageLink.ts +42 -0
- package/testaro/labClash.d.ts +3 -0
- package/testaro/labClash.js +31 -33
- package/testaro/labClash.ts +54 -0
- package/testaro/legendLoc.d.ts +3 -0
- package/testaro/legendLoc.js +17 -20
- package/testaro/legendLoc.ts +42 -0
- package/testaro/lineHeight.d.ts +3 -0
- package/testaro/lineHeight.js +43 -48
- package/testaro/lineHeight.ts +70 -0
- package/testaro/linkAmb.d.ts +7 -0
- package/testaro/linkAmb.js +79 -80
- package/testaro/linkAmb.ts +105 -0
- package/testaro/linkExt.d.ts +3 -0
- package/testaro/linkExt.js +13 -16
- package/testaro/linkExt.ts +35 -0
- package/testaro/linkOldAtt.d.ts +3 -0
- package/testaro/linkOldAtt.js +25 -28
- package/testaro/linkOldAtt.ts +48 -0
- package/testaro/linkTo.d.ts +3 -0
- package/testaro/linkTo.js +22 -22
- package/testaro/linkTo.ts +43 -0
- package/testaro/linkUl.d.ts +3 -0
- package/testaro/linkUl.js +30 -34
- package/testaro/linkUl.ts +54 -0
- package/testaro/miniText.d.ts +3 -0
- package/testaro/miniText.js +41 -44
- package/testaro/miniText.ts +68 -0
- package/testaro/motion.d.ts +10 -0
- package/testaro/motion.js +92 -96
- package/testaro/motion.ts +125 -0
- package/testaro/nonTable.d.ts +3 -0
- package/testaro/nonTable.js +39 -45
- package/testaro/nonTable.ts +66 -0
- package/testaro/optRoleSel.d.ts +3 -0
- package/testaro/optRoleSel.js +16 -19
- package/testaro/optRoleSel.ts +41 -0
- package/testaro/phOnly.d.ts +3 -0
- package/testaro/phOnly.js +18 -21
- package/testaro/phOnly.ts +43 -0
- package/testaro/pseudoP.d.ts +3 -0
- package/testaro/pseudoP.js +36 -38
- package/testaro/pseudoP.ts +59 -0
- package/testaro/radioSet.d.ts +3 -0
- package/testaro/radioSet.js +57 -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 +27 -29
- package/testaro/role.ts +53 -0
- package/testaro/secHeading.d.ts +3 -0
- package/testaro/secHeading.js +30 -33
- package/testaro/secHeading.ts +53 -0
- package/testaro/styleDiff.d.ts +25 -0
- package/testaro/styleDiff.js +248 -252
- package/testaro/styleDiff.ts +303 -0
- package/testaro/tabNav.d.ts +33 -0
- package/testaro/tabNav.js +272 -342
- package/testaro/tabNav.ts +454 -0
- package/testaro/targetsNear.d.ts +9 -0
- package/testaro/targetsNear.js +130 -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 +25 -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 +15 -18
- package/testaro/titledEl.ts +38 -0
- package/testaro/zIndex.d.ts +3 -0
- package/testaro/zIndex.js +19 -22
- package/testaro/zIndex.ts +42 -0
- package/tests/alfa.d.ts +45 -0
- package/tests/alfa.js +138 -141
- package/tests/alfa.ts +214 -0
- package/tests/aslint.d.ts +33 -0
- package/tests/aslint.js +272 -249
- package/tests/aslint.ts +301 -0
- package/tests/axe.d.ts +27 -0
- package/tests/axe.js +199 -200
- package/tests/axe.ts +277 -0
- package/tests/ed11y.d.ts +28 -0
- package/tests/ed11y.js +141 -99
- package/tests/ed11y.ts +178 -0
- package/tests/htmlcs.d.ts +21 -0
- package/tests/htmlcs.js +174 -140
- package/tests/htmlcs.ts +181 -0
- package/tests/ibm.d.ts +52 -0
- package/tests/ibm.js +164 -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 +141 -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 +302 -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 +745 -652
- package/tests/testaro.ts +862 -0
- package/tests/wave.d.ts +46 -0
- package/tests/wave.js +166 -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 +61 -9
- package/.claude/settings.local.json +0 -11
- package/.eslintrc.json +0 -41
- package/htmlcs/.eslintrc.json +0 -67
- 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
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Certainty in the standard result: the `outcome` field
|
|
2
|
+
|
|
3
|
+
**Status:** Phase A shipped in Testaro 78.1.0 (2026-09-01). Phases B–D are recommendations for
|
|
4
|
+
the Testilo fork and yra-monitor, and for a later Testaro major version.
|
|
5
|
+
**Companion:** yra-monitor `docs/plans/engine-candidacy-pipeline.md` (Stage-1 instance policy,
|
|
6
|
+
Stage-3b taxonomy mapping).
|
|
7
|
+
|
|
8
|
+
## Why
|
|
9
|
+
|
|
10
|
+
Rule engines report two different things about a finding: how bad it is (impact) and whether
|
|
11
|
+
they are sure it is a defect (certainty). Every Testaro adapter used to fold certainty into
|
|
12
|
+
`ordinalSeverity`, and each did it differently:
|
|
13
|
+
|
|
14
|
+
| tool | uncertain native value | ordinal | certain native value | ordinal |
|
|
15
|
+
| --- | --- | --- | --- | --- |
|
|
16
|
+
| axe, pour, surea11y | incomplete / cantTell | 0–1 | violation / fail | 2–3 |
|
|
17
|
+
| htmlcs | Warning | 0 | Error | 2 |
|
|
18
|
+
| ibm | recommendation | 0 | violation and potential violation | 2 |
|
|
19
|
+
| alfa | cantTell (rule ID rewritten) | 0 | failed | 2 |
|
|
20
|
+
| aslint | warning | 1 | error | 2 |
|
|
21
|
+
| qualWeb act-rules | warning | 1 | failed | 3 |
|
|
22
|
+
| qualWeb best-practices | warning | 0 | failed | 1 |
|
|
23
|
+
| wave | alert | 0 | error, contrast | 3 |
|
|
24
|
+
| ed11y | dismissable warning | 0 | error | 2 |
|
|
25
|
+
| nuVal, nuVnu | info | 0 | error | 3 |
|
|
26
|
+
|
|
27
|
+
So severity 0 meant "definitely minor" for some tools and "possibly critical" for others, and
|
|
28
|
+
nothing downstream could recover certainty except by the heuristic "ordinal 2 or above means
|
|
29
|
+
asserted". The ACT validation harness had to read native results to score sensitivity and
|
|
30
|
+
specificity by certainty band. The Testilo issue classification (tic) grew 57 `*Risk` issues to
|
|
31
|
+
hold uncertain findings at weight 1, and its scorer counted an axe `incomplete` contrast finding
|
|
32
|
+
exactly like an asserted violation because it maps rule IDs only.
|
|
33
|
+
|
|
34
|
+
The two new candidate engines make the loss visible: pour separates `violations`, `incomplete`,
|
|
35
|
+
and `manualReview`; surea11y grades per occurrence (`fail` / `cantTell`) and publishes six
|
|
36
|
+
machine-readable `uncertainty` codes with a `needed` sentence saying what a reviewer must
|
|
37
|
+
determine.
|
|
38
|
+
|
|
39
|
+
## The model
|
|
40
|
+
|
|
41
|
+
Four dimensions, kept separate:
|
|
42
|
+
|
|
43
|
+
| dimension | meaning | where it lives |
|
|
44
|
+
| --- | --- | --- |
|
|
45
|
+
| outcome (per instance) | did the engine assert a failure, or could it not tell | standard instance, set by the adapter |
|
|
46
|
+
| rule certainty (per rule) | is the check deterministic, or a heuristic that can only say "suspicious" | tic tool-rule entry, as an override |
|
|
47
|
+
| impact (per instance) | how bad for a user | `ordinalSeverity`, once it means impact only |
|
|
48
|
+
| issue weight (per issue) | severity of the defect class | tic `weight` |
|
|
49
|
+
|
|
50
|
+
Certainty exists at two levels because engines both under-assert (axe `incomplete`) and
|
|
51
|
+
over-assert (a heuristic reported as an error). The instance level is Testaro's job; the rule
|
|
52
|
+
level is the taxonomy's.
|
|
53
|
+
|
|
54
|
+
## Phase A: Testaro 78.1.0 (shipped)
|
|
55
|
+
|
|
56
|
+
Every standard instance now has:
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
{
|
|
60
|
+
ruleID, what, ordinalSeverity, count, catalogIndex, // unchanged
|
|
61
|
+
outcome: 'failed' | 'cantTell', // required; ACT Rules Format vocabulary
|
|
62
|
+
uncertainty: 'not-computable' | 'judgement-required' | 'runtime-dependent'
|
|
63
|
+
| 'spec-only' | 'equivalence-unknown' | 'out-of-scope', // optional, cantTell only
|
|
64
|
+
needed: '<what a reviewer must determine>' // optional, cantTell only, ≤ 300 chars
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
and `standardResult.outcomeTotals = {failed, cantTell}` (count-weighted).
|
|
69
|
+
|
|
70
|
+
- `procs/standard.ts` is the one place the shape is built (`getStandardResult`, `getInstance`,
|
|
71
|
+
`addInstance`, `pushInstance`). Adapters that compute `totals` from native counts (ibm, htmlcs,
|
|
72
|
+
ed11y, wave, testaro) use `pushInstance`; the rest use `addInstance`.
|
|
73
|
+
- `ordinalSeverity` and `totals` are unchanged for every tool. The golden diff on the pour and
|
|
74
|
+
surea11y validation jobs is identical after stripping the new fields.
|
|
75
|
+
- Per-tool mapping: axe/pour/surea11y violations → `failed`, incomplete → `cantTell`; htmlcs
|
|
76
|
+
Warning → `cantTell`; ibm potential violation, potential recommendation, and manual →
|
|
77
|
+
`cantTell`; alfa `cantTell` → `cantTell` (the adapter no longer rewrites the rule ID to
|
|
78
|
+
`cantTell` / `cantTellTextContrast` or prefixes `what`; r66 and r69 carry
|
|
79
|
+
`judgement-required`); aslint warning, qualWeb warning, wave alert, nuVal/nuVnu info →
|
|
80
|
+
`cantTell`; ed11y dismissable warning → `cantTell` with `judgement-required`.
|
|
81
|
+
- surea11y forwards `uncertainty.code` and `uncertainty.needed` (occurrence first, then check).
|
|
82
|
+
Its `confidence` value is dropped as non-portable.
|
|
83
|
+
- Testaro's own rules default to `failed`. An `allRules` entry may set `outcome` and
|
|
84
|
+
`uncertainty` (`allCaps` is `cantTell` / `judgement-required`, consistent with the earlier
|
|
85
|
+
ruling that AI confidence must not be encoded in `ordinalSeverity`). A violation description
|
|
86
|
+
may carry a prefix: `2:` severity only, `2?:` severity plus `cantTell`, `?:` `cantTell` at the
|
|
87
|
+
rule's default severity. `getBasicResult` accepts `outcome`, `uncertainty`, and `needed` on
|
|
88
|
+
each violation.
|
|
89
|
+
- `validation/act/capture.js` records `outcomeTotals` and per-instance `outcome` and
|
|
90
|
+
`uncertainty`, and marks a row as an error if any instance lacks a valid outcome.
|
|
91
|
+
|
|
92
|
+
Why `outcome` and not `certainty`: the ACT Rules Format and EARL already use `failed` /
|
|
93
|
+
`cantTell`, the ACT testcase feed the harness scores against uses `failed`, and a closed
|
|
94
|
+
two-value enum keeps consumer logic total. A graded `certainty` would invite scales no two
|
|
95
|
+
engines share and collide with surea11y's separate `confidence`.
|
|
96
|
+
|
|
97
|
+
Why `needed` is its own field: `what` is an identity key downstream (unique-issue rows, tsp
|
|
98
|
+
description sampling). Appending guidance to it would fracture identity across pages.
|
|
99
|
+
|
|
100
|
+
## Phase B: Testilo fork (recommended)
|
|
101
|
+
|
|
102
|
+
Tool-rule entries in the tic gain optional properties; issues gain two:
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
tools: { htmlcs: { 'W-AAA.1_4_3.G18.BgImage': {
|
|
106
|
+
variable: false, quality: 1, what: '…',
|
|
107
|
+
outcome: 'cantTell', // override; 'cantTell' is the common case
|
|
108
|
+
uncertainty: 'not-computable', // rule-level default; the instance value wins
|
|
109
|
+
review: '…', // fallback "what to confirm" when the engine gives no `needed`
|
|
110
|
+
ignore: 'invalid' // replaces prose [invalid]/[irrelevant]/[duplicative]/[unreliable]
|
|
111
|
+
}}}
|
|
112
|
+
issue: { how: '<one imperative fix sentence>', group: 'landmarkNotTop' }
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
- Precedence: `rule.outcome` > `instance.outcome` > legacy inference > `failed`. Legacy
|
|
116
|
+
inference (reports without `outcome`) is per tool: axe, pour, surea11y, htmlcs, ibm, wave,
|
|
117
|
+
qualWeb → `ordinalSeverity >= 2 ? failed : cantTell`; alfa → rule ID starts with `cantTell`;
|
|
118
|
+
testaro, ed11y, aslint, nuVal, nuVnu → `failed`.
|
|
119
|
+
- `[speculative]` becomes `outcome: 'cantTell'`; the other bracket tags become `ignore`. The
|
|
120
|
+
`ignorable` pseudo-issue dissolves into per-rule `ignore`. A loader assertion rejects any
|
|
121
|
+
`what` still carrying a bracket tag.
|
|
122
|
+
- Consolidate the 57 `*Risk` issues: merge into the base issue when one exists with the same fix
|
|
123
|
+
(7 name twins plus about 11 semantic twins such as contrastRisk → contrastAA/AAA by level);
|
|
124
|
+
rename (drop `Risk`) when the issue is the sole home of a defect class with a concrete fix
|
|
125
|
+
(pseudoHeadingRisk → pseudoHeading, which already holds axe `p-as-heading` and takes pour's
|
|
126
|
+
at `failed`; eventKeyboardRisk → eventKeyboard; labelConfusionRisk → labelPlacement with every
|
|
127
|
+
rule `cantTell` / `judgement-required`); keep three page-environment advisories
|
|
128
|
+
(applicationRisk, browserSupportRisk, noScriptRisk) with every rule `cantTell`. Export a
|
|
129
|
+
`migrations` map (`{contrastRisk: 'contrastAA', …}`) for downstream issue-ID rewrites.
|
|
130
|
+
- Scoring: `cantTellWeight = 0.25` per instance inside the quality-weighted count (a weight-1
|
|
131
|
+
Risk issue merged into a weight-4 base is score-neutral). Element-aware dedup: an element's
|
|
132
|
+
outcome is `failed` if any tool says so, corroborated when more than one does;
|
|
133
|
+
`effectiveCount = max(old per-tool max with the factor applied, element-union count)`.
|
|
134
|
+
Output stays additive (`instanceCounts` numeric; add `outcomeCounts`, `elementCounts`,
|
|
135
|
+
`details.elements`; `details.element` byte-identical).
|
|
136
|
+
- Granularity principle: one tic issue = one remediation class = one WCAG success criterion ×
|
|
137
|
+
one fix. `ruleID` and `what` carry the diagnosis; certainty is never a reason to split an
|
|
138
|
+
issue. Families get `group`; element-conditioned splits (pour `link-name` → image link vs text
|
|
139
|
+
link) are done in the adapter with a `.`-suffixed faceted rule ID, two tic entries each.
|
|
140
|
+
|
|
141
|
+
## Phase C: yra-monitor (recommended)
|
|
142
|
+
|
|
143
|
+
Types, `tic-manager` `resolveOutcome`, scoring-service passthrough, standardized rows and DB
|
|
144
|
+
columns (`outcome`, `uncertainty`, `needed`) with a promote-only conflict rule (`failed` wins),
|
|
145
|
+
issue-ID rewrite from `migrations`, a "Needs review" badge and filter, and for `cantTell` rows
|
|
146
|
+
the text `instance.needed ?? rule.review ?? 'Manual review required'` under a "To confirm"
|
|
147
|
+
heading.
|
|
148
|
+
|
|
149
|
+
## Phase D: Testaro 79 (recommended)
|
|
150
|
+
|
|
151
|
+
Redefine `ordinalSeverity` as impact only: 0 minor, 1 moderate, 2 serious, 3 critical, which is
|
|
152
|
+
what yra-monitor already labels it as. `totals` keeps its shape but its composition changes
|
|
153
|
+
(an axe incomplete + critical finding moves from `totals[1]` to `totals[3]`). Safe only after
|
|
154
|
+
Phases B and C, when every consumer reads `outcome`.
|
|
155
|
+
|
|
156
|
+
## Open decisions
|
|
157
|
+
|
|
158
|
+
1. `cantTellWeight = 0.25`: confirm against Stage-4 precision on surea11y's `cantTell` band.
|
|
159
|
+
2. The semantic Risk merges need a "same fix?" pass; videoCaptionRisk → videoNoText and
|
|
160
|
+
fieldSetRisk → fieldSetMissing are the least certain.
|
|
161
|
+
3. Weights for renamed heuristic issues once they can carry a `failed` band.
|
|
162
|
+
4. The alfa rule-ID change is visible to the current Testilo now: r66/r69 `cantTell` instances
|
|
163
|
+
map to contrastAAA/contrastAA at full weight until the scorer reads `outcome`. Pin Testaro
|
|
164
|
+
78.1 in the worker only together with the Phase-B Testilo.
|
|
165
|
+
5. Whether `unique_issues.severity` should roll up (`GREATEST`) on conflict.
|
package/env.example
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
WAVE_KEY=__placeholder__
|
|
3
3
|
# You can get an Anthropic API key at https://console.anthropic.com/.
|
|
4
4
|
ANTHROPIC_API_KEY=__placeholder__
|
|
5
|
-
# Name to identify this Testaro instance to a server.
|
|
6
|
-
AGENT=__placeholder__
|
|
7
5
|
# Whether to make the browser visible (normally false).
|
|
8
6
|
HEADED_BROWSER=false
|
|
9
7
|
# Whether to output even forked-job logging to the primary log (normally false).
|
|
@@ -12,23 +10,44 @@ DEBUG=false
|
|
|
12
10
|
WAITS=0
|
|
13
11
|
# See https://nodejs.org/api/cli.html#options for all permitted options.
|
|
14
12
|
NODE_OPTIONS='--trace-uncaught --trace-warnings'
|
|
15
|
-
#
|
|
13
|
+
# Whether to suppress a routine warning from QualWeb.
|
|
16
14
|
PUPPETEER_DISABLE_HEADLESS_WARNING=true
|
|
17
|
-
# Replace the next 2 placeholders with http://localhost:3000 if Kilotest and Testaro are on the same host or the URL of the server (e.g., https://kilotest.com) if they are on different hosts.
|
|
18
|
-
# URL to poll for available jobs when watching the network.
|
|
19
|
-
NETWATCH_URL_JOB=__placeholder__/api/testaro-agent/job
|
|
20
|
-
# URL to report results to when watching the network.
|
|
21
|
-
NETWATCH_URL_REPORT=__placeholder__/api/testaro-agent/report
|
|
22
|
-
# Password of this Testaro agent
|
|
23
|
-
NETWATCH_URL_AUTH=__placeholder__
|
|
24
15
|
# Directory (relative to project root) to watch for jobs.
|
|
25
16
|
JOBDIR=__placeholder__
|
|
26
17
|
# Directory (relative to project root) to write reports to when watching a directory for jobs.
|
|
27
18
|
REPORTDIR=__placeholder__
|
|
28
19
|
# Multiplier for time limits (normally 1).
|
|
29
20
|
TIMEOUT_MULTIPLIER=1
|
|
21
|
+
# Default isolation of test acts when a job does not specify one: process (a child process and
|
|
22
|
+
# browser per test act), browser (one browser per job, a fresh context per test act), or page
|
|
23
|
+
# (test acts share the live page of the current checkpoint). See docs/checkpoint-scanning.md.
|
|
24
|
+
ISOLATION=process
|
|
30
25
|
# Whether to abort the job when launch retries are exhausted or a test act crashes (default false).
|
|
31
26
|
ABORT_ASSERTIVELY=false
|
|
27
|
+
|
|
28
|
+
# Deployment options. A job property of the same meaning overrides each of these.
|
|
29
|
+
|
|
30
|
+
# Load state a navigation waits for before tools run: networkidle (default), load, or
|
|
31
|
+
# domcontentloaded. Retries relax it one step. networkidle never arrives on pages whose
|
|
32
|
+
# network never quiets (beacons, polling), so a deployment scanning such pages may prefer load.
|
|
33
|
+
NAV_WAIT_UNTIL=networkidle
|
|
34
|
+
# Navigation time limit in milliseconds (default 10000).
|
|
35
|
+
NAV_TIMEOUT=10000
|
|
36
|
+
# Whether a 4xx response (other than 408 and 429) ends launch retries at once (default false).
|
|
37
|
+
NAV_FAIL_FAST_4XX=false
|
|
38
|
+
# Scanner identity sent as the X-YRA-Scanner request header, so firewalls can recognize the
|
|
39
|
+
# scanner by a stable value (default none; jobs may set scannerId).
|
|
40
|
+
SCANNER_ID=__placeholder__
|
|
41
|
+
# Whether to scroll the full page after navigation so lazily loaded content is present before
|
|
42
|
+
# cataloguing, imaging, and each tool (default false; jobs may set scroll).
|
|
43
|
+
PRESCAN_SCROLL=false
|
|
44
|
+
# Launch retries per rule of the testaro tool, which relaunches per contaminating rule
|
|
45
|
+
# (default 2; raise for non-Chromium browsers, which navigate flakily on relaunch).
|
|
46
|
+
TESTARO_RULE_RETRIES=2
|
|
47
|
+
# Whether the qualWeb tool's browser runs stealth evasions and blocks ads and trackers
|
|
48
|
+
# (default true; a qualWeb test act may set stealth and adBlock).
|
|
49
|
+
QUALWEB_STEALTH=true
|
|
50
|
+
QUALWEB_ADBLOCK=true
|
|
32
51
|
# URL of any non-default (e.g., self-hosted) Nu Html Checker API (see ghcr.io/validator/validator).
|
|
33
52
|
TESTARO_NU_URL=__placeholder__
|
|
34
53
|
# Whether to launch the Playwright chromium browser without its sandbox (normally false).
|
|
@@ -37,6 +56,21 @@ TESTARO_NU_URL=__placeholder__
|
|
|
37
56
|
# or run containers with a seccomp profile that permits user-namespace cloning.
|
|
38
57
|
TESTARO_CHROMIUM_NO_SANDBOX=false
|
|
39
58
|
|
|
59
|
+
# netWatch variables
|
|
60
|
+
|
|
61
|
+
# Replace the next 2 placeholders with the URL of the server (e.g., http://localhost:3000 or https://kilotest.com), including the path required by the server.
|
|
62
|
+
# URL to poll for available jobs.
|
|
63
|
+
NETWATCH_URL_JOB=__placeholder__
|
|
64
|
+
# URL to send a job report.
|
|
65
|
+
NETWATCH_URL_REPORT=__placeholder__
|
|
66
|
+
# Type of authentication (none, pathBody, or header) required by the server.
|
|
67
|
+
NETWATCH_AUTH_TYPE=__placeholder__
|
|
68
|
+
# ID of this instance. Recorded in reports as sources.agent and used by header
|
|
69
|
+
# authentication (where it must not contain a colon).
|
|
70
|
+
NETWATCH_WORKER_ID=__placeholder__
|
|
71
|
+
# Password of this instance. Required when NETWATCH_AUTH_TYPE is pathBody or header.
|
|
72
|
+
NETWATCH_WORKER_SECRET=__placeholder__
|
|
73
|
+
|
|
40
74
|
## License
|
|
41
75
|
|
|
42
76
|
# © 2021–2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/*
|
|
2
|
+
© 2026 Jeff Witt.
|
|
3
|
+
|
|
4
|
+
Licensed under the MIT License. See LICENSE file at the project root or
|
|
5
|
+
https://opensource.org/license/mit/ for details.
|
|
6
|
+
|
|
7
|
+
SPDX-License-Identifier: MIT
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
eslint.config.mjs
|
|
12
|
+
Flat ESLint configuration, replacing .eslintrc.json (unsupported since ESLint 9).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// IMPORTS
|
|
16
|
+
|
|
17
|
+
import js from '@eslint/js';
|
|
18
|
+
import globals from 'globals';
|
|
19
|
+
import {defineConfig, globalIgnores} from 'eslint/config';
|
|
20
|
+
|
|
21
|
+
// CONFIGURATION
|
|
22
|
+
|
|
23
|
+
export default defineConfig([
|
|
24
|
+
globalIgnores([
|
|
25
|
+
// Build output.
|
|
26
|
+
'dist/',
|
|
27
|
+
// Vendored HTML CodeSniffer bundle; not to be reformatted.
|
|
28
|
+
'htmlcs/HTMLCS.js',
|
|
29
|
+
// Vendored Editoria11y bundles.
|
|
30
|
+
'ed11y/',
|
|
31
|
+
// Vendored SureA11y standalone browser bundle (MPL-2.0; not to be modified).
|
|
32
|
+
'surea11y/surea11y.browser.js',
|
|
33
|
+
// Vendored Pour Engine bundle, built with esbuild (see pour/README.md).
|
|
34
|
+
'pour/pour.min.js',
|
|
35
|
+
// Files emitted by tsc from TypeScript sources (issue #73); lint the .ts sources instead.
|
|
36
|
+
'types.js',
|
|
37
|
+
'procs/catalog.js',
|
|
38
|
+
'procs/standard.js',
|
|
39
|
+
'procs/testaro.js',
|
|
40
|
+
'procs/xPath.js',
|
|
41
|
+
'testaro/*.js',
|
|
42
|
+
'tests/*.js',
|
|
43
|
+
'**/*.d.ts',
|
|
44
|
+
// Validation fixtures, some of which are intentionally defective.
|
|
45
|
+
'validation/tests/targets/'
|
|
46
|
+
]),
|
|
47
|
+
{
|
|
48
|
+
files: ['**/*.js'],
|
|
49
|
+
extends: [js.configs.recommended],
|
|
50
|
+
languageOptions: {
|
|
51
|
+
ecmaVersion: 2021,
|
|
52
|
+
sourceType: 'commonjs',
|
|
53
|
+
globals: {
|
|
54
|
+
...globals.browser,
|
|
55
|
+
...globals.node
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
rules: {
|
|
59
|
+
indent: [
|
|
60
|
+
'error',
|
|
61
|
+
2,
|
|
62
|
+
{
|
|
63
|
+
MemberExpression: 0,
|
|
64
|
+
ObjectExpression: 'first'
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
'linebreak-style': [
|
|
68
|
+
'error',
|
|
69
|
+
'unix'
|
|
70
|
+
],
|
|
71
|
+
quotes: [
|
|
72
|
+
'error',
|
|
73
|
+
'single'
|
|
74
|
+
],
|
|
75
|
+
semi: [
|
|
76
|
+
'error',
|
|
77
|
+
'always'
|
|
78
|
+
],
|
|
79
|
+
'no-use-before-define': [
|
|
80
|
+
'error'
|
|
81
|
+
],
|
|
82
|
+
'brace-style': [
|
|
83
|
+
'error',
|
|
84
|
+
'stroustrup'
|
|
85
|
+
],
|
|
86
|
+
/*
|
|
87
|
+
Transitional demotions to warnings, so linting can gate changes now.
|
|
88
|
+
These rules have pre-existing violations, some of them latent defects.
|
|
89
|
+
Each is to be restored to an error once its violations are repaired.
|
|
90
|
+
*/
|
|
91
|
+
'no-async-promise-executor': 'warn',
|
|
92
|
+
'no-const-assign': 'warn',
|
|
93
|
+
'no-constant-binary-expression': 'warn',
|
|
94
|
+
'no-empty': 'warn',
|
|
95
|
+
'no-undef': 'warn',
|
|
96
|
+
'no-unused-vars': 'warn',
|
|
97
|
+
'no-use-before-define': 'warn',
|
|
98
|
+
'no-useless-assignment': 'warn'
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
]);
|