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/tests/pour.js
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
© 2026 Jeff Witt.
|
|
4
|
+
|
|
5
|
+
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
|
+
https://opensource.org/license/mit/ for details.
|
|
7
|
+
|
|
8
|
+
SPDX-License-Identifier: MIT
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
+
var ownKeys = function(o) {
|
|
28
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
+
var ar = [];
|
|
30
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
return ownKeys(o);
|
|
34
|
+
};
|
|
35
|
+
return function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
})();
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.reporter = void 0;
|
|
45
|
+
// IMPORTS
|
|
46
|
+
const fs = __importStar(require("fs/promises"));
|
|
47
|
+
const xPath_1 = require("../procs/xPath");
|
|
48
|
+
const standard_1 = require("../procs/standard");
|
|
49
|
+
/*
|
|
50
|
+
pour
|
|
51
|
+
Implements the Pour Engine (https://github.com/pourdev/pour-engine) WCAG 2.2 ruleset.
|
|
52
|
+
Compiled to pour.js by tsc (issue #73); edit this file, not the emitted one.
|
|
53
|
+
|
|
54
|
+
Pour ships as ES modules with no dist build, so a vendored IIFE bundle is expected at
|
|
55
|
+
../pour/pour.min.js, exposing a `pourEngine` global with {run, name, version}. See
|
|
56
|
+
../pour/README.md for the build command and the pinned upstream commit.
|
|
57
|
+
|
|
58
|
+
Instance policy (engine-candidacy-pipeline.md, Stage 1): `violations` become instances with
|
|
59
|
+
outcome `failed` at ordinalSeverity 2-3; `incomplete` become instances with outcome `cantTell`
|
|
60
|
+
at 0-1; `passes`, `inapplicable`, and `manualReview` are tallied in `data` only and never
|
|
61
|
+
become instances.
|
|
62
|
+
*/
|
|
63
|
+
// CONSTANTS
|
|
64
|
+
// Severity weights within a certainty band, mirroring tests/axe.ts.
|
|
65
|
+
const severityWeights = {
|
|
66
|
+
minor: 0,
|
|
67
|
+
moderate: 0,
|
|
68
|
+
serious: 1,
|
|
69
|
+
critical: 1
|
|
70
|
+
};
|
|
71
|
+
// FUNCTIONS
|
|
72
|
+
// Performs and reports the Pour Engine tests.
|
|
73
|
+
const reporter = async (page, report, actIndex) => {
|
|
74
|
+
// Get the nonce, if any.
|
|
75
|
+
const act = report.acts[actIndex];
|
|
76
|
+
const { jobData } = report;
|
|
77
|
+
const scriptNonce = (jobData && jobData.lastScriptNonce);
|
|
78
|
+
// Initialize the act report.
|
|
79
|
+
let data = {};
|
|
80
|
+
const result = {
|
|
81
|
+
nativeResult: {},
|
|
82
|
+
standardResult: {}
|
|
83
|
+
};
|
|
84
|
+
const standard = report.standard !== 'no';
|
|
85
|
+
// If standard results are to be reported:
|
|
86
|
+
if (standard) {
|
|
87
|
+
// Initialize the standard result.
|
|
88
|
+
result.standardResult = (0, standard_1.getStandardResult)();
|
|
89
|
+
}
|
|
90
|
+
// Get the vendored tool bundle.
|
|
91
|
+
let script;
|
|
92
|
+
try {
|
|
93
|
+
script = await fs.readFile(`${__dirname}/../pour/pour.min.js`, 'utf8');
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
data.prevented = true;
|
|
97
|
+
data.error = 'ERROR: pour bundle missing (see pour/README.md for vendoring instructions)';
|
|
98
|
+
return { data, result };
|
|
99
|
+
}
|
|
100
|
+
// Perform the tests and populate the native result.
|
|
101
|
+
result.nativeResult = await page.evaluate(args => new Promise(async (resolve) => {
|
|
102
|
+
const { scriptNonce, script } = args;
|
|
103
|
+
// Detect page-CSP blocking of the injection (the violation event is
|
|
104
|
+
// dispatched as a task, so the check below waits a tick).
|
|
105
|
+
let cspBlocked = false;
|
|
106
|
+
document.addEventListener('securitypolicyviolation', event => {
|
|
107
|
+
if ((event.violatedDirective || '').startsWith('script-src')) {
|
|
108
|
+
cspBlocked = true;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
// Add the tool script to the page.
|
|
112
|
+
const toolScript = document.createElement('script');
|
|
113
|
+
if (scriptNonce) {
|
|
114
|
+
toolScript.nonce = scriptNonce;
|
|
115
|
+
console.log(`Added nonce ${scriptNonce} to tool script`);
|
|
116
|
+
}
|
|
117
|
+
toolScript.textContent = script;
|
|
118
|
+
document.body.insertAdjacentElement('beforeend', toolScript);
|
|
119
|
+
// If the bundle failed to define its global:
|
|
120
|
+
if (typeof pourEngine === 'undefined' || typeof pourEngine.run !== 'function') {
|
|
121
|
+
// Let a pending securitypolicyviolation event fire before diagnosing.
|
|
122
|
+
await new Promise(tick => setTimeout(tick, 0));
|
|
123
|
+
// A CSP block is a per-page condition, not a browser fault — report it
|
|
124
|
+
// distinctly (wedge canaries must not match this message).
|
|
125
|
+
resolve({
|
|
126
|
+
prevented: true,
|
|
127
|
+
error: cspBlocked
|
|
128
|
+
? 'pour injection blocked by page CSP (script-src)'
|
|
129
|
+
: `pourEngine global not defined (contentType ${document.contentType}, `
|
|
130
|
+
+ `scriptChars ${script.length}, readyState ${document.readyState})`
|
|
131
|
+
});
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
// Run the engine on the top document. An empty tag selection runs every
|
|
136
|
+
// rule (all WCAG levels incl. AAA, plus pour's best-practice extras) —
|
|
137
|
+
// matching the axe adapter's kitchen-sink default; testilo's taxonomy
|
|
138
|
+
// decides per rule what counts downstream.
|
|
139
|
+
const pourReport = await pourEngine.run(document, {});
|
|
140
|
+
// Normalizes one certainty bucket (axe-style rule entries) to flat per-element findings.
|
|
141
|
+
const flatten = (bucket) => (bucket || [])
|
|
142
|
+
.flatMap(entry => {
|
|
143
|
+
// Criterion tag (e.g. wcag143) → dotted criterion (1.4.3).
|
|
144
|
+
const criterionTag = (entry.tags || []).find(tag => /^wcag\d{3,4}$/.test(tag));
|
|
145
|
+
const digits = criterionTag ? criterionTag.slice(4) : '';
|
|
146
|
+
const wcag = digits ? `${digits[0]}.${digits[1]}.${digits.slice(2)}` : '';
|
|
147
|
+
return (entry.nodes || []).map(node => {
|
|
148
|
+
const cssPath = Array.isArray(node.target) ? node.target[0] : '';
|
|
149
|
+
let xPath = '';
|
|
150
|
+
try {
|
|
151
|
+
const element = cssPath && document.querySelector(cssPath);
|
|
152
|
+
if (element && typeof window.getXPath === 'function') {
|
|
153
|
+
xPath = window.getXPath(element) ?? '';
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
// Unresolvable path: instance falls back to excerpt only.
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
ruleID: entry.id || '',
|
|
161
|
+
what: (entry.help || '').replace(/\s+/g, ' ').trim(),
|
|
162
|
+
wcag,
|
|
163
|
+
severity: (entry.impact || 'moderate').toLowerCase(),
|
|
164
|
+
html: (node.html || '').slice(0, 500),
|
|
165
|
+
cssPath,
|
|
166
|
+
xPath
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
resolve({
|
|
171
|
+
engineVersion: pourReport.testEngine && pourReport.testEngine.version || '',
|
|
172
|
+
violations: flatten(pourReport.violations),
|
|
173
|
+
incomplete: flatten(pourReport.incomplete),
|
|
174
|
+
// Tallied only; never instances. Passes serialize no nodes upstream;
|
|
175
|
+
// nodeCount carries the per-rule passing-element total.
|
|
176
|
+
passRuleCount: (pourReport.passes || []).length,
|
|
177
|
+
passElementCount: (pourReport.passes || [])
|
|
178
|
+
.reduce((total, entry) => total + (entry.nodeCount || 0), 0),
|
|
179
|
+
inapplicableRuleCount: (pourReport.inapplicable || []).length,
|
|
180
|
+
manualReviewCriterionCount: (pourReport.manualReview || []).length
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
resolve({
|
|
185
|
+
prevented: true,
|
|
186
|
+
error: error.message
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
;
|
|
190
|
+
}), {
|
|
191
|
+
scriptNonce,
|
|
192
|
+
script
|
|
193
|
+
});
|
|
194
|
+
const { nativeResult } = result;
|
|
195
|
+
// If the tool ran and rules were selected:
|
|
196
|
+
if (!nativeResult.prevented && act.rules) {
|
|
197
|
+
// Remove results of other rules.
|
|
198
|
+
const { rules } = act;
|
|
199
|
+
nativeResult.violations = (nativeResult.violations || [])
|
|
200
|
+
.filter(finding => rules.includes(finding.ruleID));
|
|
201
|
+
nativeResult.incomplete = (nativeResult.incomplete || [])
|
|
202
|
+
.filter(finding => rules.includes(finding.ruleID));
|
|
203
|
+
}
|
|
204
|
+
// If the tool was prevented from running:
|
|
205
|
+
if (nativeResult.prevented) {
|
|
206
|
+
data.prevented = true;
|
|
207
|
+
data.error = nativeResult.error;
|
|
208
|
+
}
|
|
209
|
+
// Otherwise, if a standard result is to be reported:
|
|
210
|
+
else if (standard) {
|
|
211
|
+
const { standardResult } = result;
|
|
212
|
+
// Record the tallied-only bucket sizes.
|
|
213
|
+
data.passRuleCount = nativeResult.passRuleCount;
|
|
214
|
+
data.passElementCount = nativeResult.passElementCount;
|
|
215
|
+
data.inapplicableRuleCount = nativeResult.inapplicableRuleCount;
|
|
216
|
+
data.manualReviewCriterionCount = nativeResult.manualReviewCriterionCount;
|
|
217
|
+
// For each certainty band:
|
|
218
|
+
const bands = [
|
|
219
|
+
[nativeResult.incomplete || [], 0, 'cantTell'],
|
|
220
|
+
[nativeResult.violations || [], 2, 'failed']
|
|
221
|
+
];
|
|
222
|
+
bands.forEach(([findings, baseSeverity, outcome]) => {
|
|
223
|
+
// For each native-result finding:
|
|
224
|
+
findings.forEach(finding => {
|
|
225
|
+
// Add a standard-result instance.
|
|
226
|
+
const { ruleID, what, severity, xPath } = finding;
|
|
227
|
+
(0, standard_1.addInstance)(standardResult, {
|
|
228
|
+
ruleID,
|
|
229
|
+
what,
|
|
230
|
+
ordinalSeverity: baseSeverity + (severityWeights[severity] ?? 0),
|
|
231
|
+
outcome,
|
|
232
|
+
catalogIndex: (0, xPath_1.getXPathCatalogIndex)(report, xPath)
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
data,
|
|
239
|
+
result
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
exports.reporter = reporter;
|
package/tests/pour.ts
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
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
|
+
// IMPORTS
|
|
11
|
+
|
|
12
|
+
import * as fs from 'fs/promises';
|
|
13
|
+
import type {Page} from 'playwright';
|
|
14
|
+
import {getXPathCatalogIndex} from '../procs/xPath';
|
|
15
|
+
import {getStandardResult, addInstance} from '../procs/standard';
|
|
16
|
+
import type {Act, Outcome, Report, StandardResult} from '../types';
|
|
17
|
+
|
|
18
|
+
// TYPES
|
|
19
|
+
|
|
20
|
+
// The pour-act properties this reporter consumes.
|
|
21
|
+
interface PourAct extends Act {
|
|
22
|
+
rules?: string[];
|
|
23
|
+
}
|
|
24
|
+
// A pour severity (axe-style impact).
|
|
25
|
+
type PourSeverity = 'minor' | 'moderate' | 'serious' | 'critical';
|
|
26
|
+
// One element finding, flattened from the engine's per-rule results.
|
|
27
|
+
interface PourFinding {
|
|
28
|
+
ruleID: string;
|
|
29
|
+
what: string;
|
|
30
|
+
wcag: string;
|
|
31
|
+
severity: PourSeverity;
|
|
32
|
+
html: string;
|
|
33
|
+
cssPath: string;
|
|
34
|
+
xPath: string;
|
|
35
|
+
}
|
|
36
|
+
// The native result: flattened findings and tallies, or a prevention report.
|
|
37
|
+
interface PourNativeResult {
|
|
38
|
+
engineVersion?: string;
|
|
39
|
+
violations?: PourFinding[];
|
|
40
|
+
incomplete?: PourFinding[];
|
|
41
|
+
passRuleCount?: number;
|
|
42
|
+
passElementCount?: number;
|
|
43
|
+
inapplicableRuleCount?: number;
|
|
44
|
+
manualReviewCriterionCount?: number;
|
|
45
|
+
prevented?: boolean;
|
|
46
|
+
error?: string;
|
|
47
|
+
}
|
|
48
|
+
// One per-rule entry of a pour result bucket (verified against pour-engine 1.37.0).
|
|
49
|
+
interface PourRuleEntry {
|
|
50
|
+
id?: string;
|
|
51
|
+
help?: string;
|
|
52
|
+
impact?: string;
|
|
53
|
+
tags?: string[];
|
|
54
|
+
nodeCount?: number;
|
|
55
|
+
nodes?: {target?: string[]; html?: string}[];
|
|
56
|
+
}
|
|
57
|
+
// The pour report.
|
|
58
|
+
interface PourReport {
|
|
59
|
+
testEngine?: {version?: string};
|
|
60
|
+
violations?: PourRuleEntry[];
|
|
61
|
+
incomplete?: PourRuleEntry[];
|
|
62
|
+
passes?: PourRuleEntry[];
|
|
63
|
+
inapplicable?: PourRuleEntry[];
|
|
64
|
+
manualReview?: unknown[];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
The pourEngine global that the vendored bundle defines in the page. Declared without a
|
|
69
|
+
value, so this declaration is erased at emit and the references inside the page.evaluate
|
|
70
|
+
callback remain bare page-global references.
|
|
71
|
+
*/
|
|
72
|
+
declare const pourEngine: {
|
|
73
|
+
run: (context: Document, options: Record<string, unknown>) => Promise<PourReport>;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/*
|
|
77
|
+
pour
|
|
78
|
+
Implements the Pour Engine (https://github.com/pourdev/pour-engine) WCAG 2.2 ruleset.
|
|
79
|
+
Compiled to pour.js by tsc (issue #73); edit this file, not the emitted one.
|
|
80
|
+
|
|
81
|
+
Pour ships as ES modules with no dist build, so a vendored IIFE bundle is expected at
|
|
82
|
+
../pour/pour.min.js, exposing a `pourEngine` global with {run, name, version}. See
|
|
83
|
+
../pour/README.md for the build command and the pinned upstream commit.
|
|
84
|
+
|
|
85
|
+
Instance policy (engine-candidacy-pipeline.md, Stage 1): `violations` become instances with
|
|
86
|
+
outcome `failed` at ordinalSeverity 2-3; `incomplete` become instances with outcome `cantTell`
|
|
87
|
+
at 0-1; `passes`, `inapplicable`, and `manualReview` are tallied in `data` only and never
|
|
88
|
+
become instances.
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
// CONSTANTS
|
|
92
|
+
|
|
93
|
+
// Severity weights within a certainty band, mirroring tests/axe.ts.
|
|
94
|
+
const severityWeights: Record<PourSeverity, number> = {
|
|
95
|
+
minor: 0,
|
|
96
|
+
moderate: 0,
|
|
97
|
+
serious: 1,
|
|
98
|
+
critical: 1
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// FUNCTIONS
|
|
102
|
+
|
|
103
|
+
// Performs and reports the Pour Engine tests.
|
|
104
|
+
export const reporter = async (page: Page, report: Report, actIndex: number) => {
|
|
105
|
+
// Get the nonce, if any.
|
|
106
|
+
const act = report.acts[actIndex] as PourAct;
|
|
107
|
+
const {jobData} = report;
|
|
108
|
+
const scriptNonce = (jobData && jobData.lastScriptNonce) as string | undefined;
|
|
109
|
+
// Initialize the act report.
|
|
110
|
+
let data: Record<string, unknown> = {};
|
|
111
|
+
const result: {nativeResult: PourNativeResult; standardResult: StandardResult} = {
|
|
112
|
+
nativeResult: {},
|
|
113
|
+
standardResult: {}
|
|
114
|
+
};
|
|
115
|
+
const standard = report.standard !== 'no';
|
|
116
|
+
// If standard results are to be reported:
|
|
117
|
+
if (standard) {
|
|
118
|
+
// Initialize the standard result.
|
|
119
|
+
result.standardResult = getStandardResult();
|
|
120
|
+
}
|
|
121
|
+
// Get the vendored tool bundle.
|
|
122
|
+
let script: string;
|
|
123
|
+
try {
|
|
124
|
+
script = await fs.readFile(`${__dirname}/../pour/pour.min.js`, 'utf8');
|
|
125
|
+
}
|
|
126
|
+
catch(error) {
|
|
127
|
+
data.prevented = true;
|
|
128
|
+
data.error = 'ERROR: pour bundle missing (see pour/README.md for vendoring instructions)';
|
|
129
|
+
return {data, result};
|
|
130
|
+
}
|
|
131
|
+
// Perform the tests and populate the native result.
|
|
132
|
+
result.nativeResult = await page.evaluate(args => new Promise<PourNativeResult>(
|
|
133
|
+
async resolve => {
|
|
134
|
+
const {scriptNonce, script} = args;
|
|
135
|
+
// Detect page-CSP blocking of the injection (the violation event is
|
|
136
|
+
// dispatched as a task, so the check below waits a tick).
|
|
137
|
+
let cspBlocked = false;
|
|
138
|
+
document.addEventListener('securitypolicyviolation', event => {
|
|
139
|
+
if ((event.violatedDirective || '').startsWith('script-src')) {
|
|
140
|
+
cspBlocked = true;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
// Add the tool script to the page.
|
|
144
|
+
const toolScript = document.createElement('script');
|
|
145
|
+
if (scriptNonce) {
|
|
146
|
+
toolScript.nonce = scriptNonce;
|
|
147
|
+
console.log(`Added nonce ${scriptNonce} to tool script`);
|
|
148
|
+
}
|
|
149
|
+
toolScript.textContent = script;
|
|
150
|
+
document.body.insertAdjacentElement('beforeend', toolScript);
|
|
151
|
+
// If the bundle failed to define its global:
|
|
152
|
+
if (typeof pourEngine === 'undefined' || typeof pourEngine.run !== 'function') {
|
|
153
|
+
// Let a pending securitypolicyviolation event fire before diagnosing.
|
|
154
|
+
await new Promise(tick => setTimeout(tick, 0));
|
|
155
|
+
// A CSP block is a per-page condition, not a browser fault — report it
|
|
156
|
+
// distinctly (wedge canaries must not match this message).
|
|
157
|
+
resolve({
|
|
158
|
+
prevented: true,
|
|
159
|
+
error: cspBlocked
|
|
160
|
+
? 'pour injection blocked by page CSP (script-src)'
|
|
161
|
+
: `pourEngine global not defined (contentType ${document.contentType}, `
|
|
162
|
+
+ `scriptChars ${script.length}, readyState ${document.readyState})`
|
|
163
|
+
});
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
// Run the engine on the top document. An empty tag selection runs every
|
|
168
|
+
// rule (all WCAG levels incl. AAA, plus pour's best-practice extras) —
|
|
169
|
+
// matching the axe adapter's kitchen-sink default; testilo's taxonomy
|
|
170
|
+
// decides per rule what counts downstream.
|
|
171
|
+
const pourReport = await pourEngine.run(document, {});
|
|
172
|
+
// Normalizes one certainty bucket (axe-style rule entries) to flat per-element findings.
|
|
173
|
+
const flatten = (bucket: PourRuleEntry[] | undefined): PourFinding[] => (bucket || [])
|
|
174
|
+
.flatMap(entry => {
|
|
175
|
+
// Criterion tag (e.g. wcag143) → dotted criterion (1.4.3).
|
|
176
|
+
const criterionTag = (entry.tags || []).find(tag => /^wcag\d{3,4}$/.test(tag));
|
|
177
|
+
const digits = criterionTag ? criterionTag.slice(4) : '';
|
|
178
|
+
const wcag = digits ? `${digits[0]}.${digits[1]}.${digits.slice(2)}` : '';
|
|
179
|
+
return (entry.nodes || []).map(node => {
|
|
180
|
+
const cssPath = Array.isArray(node.target) ? node.target[0] : '';
|
|
181
|
+
let xPath = '';
|
|
182
|
+
try {
|
|
183
|
+
const element = cssPath && document.querySelector(cssPath);
|
|
184
|
+
if (element && typeof window.getXPath === 'function') {
|
|
185
|
+
xPath = window.getXPath(element) ?? '';
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch(error) {
|
|
189
|
+
// Unresolvable path: instance falls back to excerpt only.
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
ruleID: entry.id || '',
|
|
193
|
+
what: (entry.help || '').replace(/\s+/g, ' ').trim(),
|
|
194
|
+
wcag,
|
|
195
|
+
severity: (entry.impact || 'moderate').toLowerCase() as PourSeverity,
|
|
196
|
+
html: (node.html || '').slice(0, 500),
|
|
197
|
+
cssPath,
|
|
198
|
+
xPath
|
|
199
|
+
};
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
resolve({
|
|
203
|
+
engineVersion: pourReport.testEngine && pourReport.testEngine.version || '',
|
|
204
|
+
violations: flatten(pourReport.violations),
|
|
205
|
+
incomplete: flatten(pourReport.incomplete),
|
|
206
|
+
// Tallied only; never instances. Passes serialize no nodes upstream;
|
|
207
|
+
// nodeCount carries the per-rule passing-element total.
|
|
208
|
+
passRuleCount: (pourReport.passes || []).length,
|
|
209
|
+
passElementCount: (pourReport.passes || [])
|
|
210
|
+
.reduce((total, entry) => total + (entry.nodeCount || 0), 0),
|
|
211
|
+
inapplicableRuleCount: (pourReport.inapplicable || []).length,
|
|
212
|
+
manualReviewCriterionCount: (pourReport.manualReview || []).length
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
catch(error) {
|
|
216
|
+
resolve({
|
|
217
|
+
prevented: true,
|
|
218
|
+
error: (error as Error).message
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
), {
|
|
223
|
+
scriptNonce,
|
|
224
|
+
script
|
|
225
|
+
});
|
|
226
|
+
const {nativeResult} = result;
|
|
227
|
+
// If the tool ran and rules were selected:
|
|
228
|
+
if (! nativeResult.prevented && act.rules) {
|
|
229
|
+
// Remove results of other rules.
|
|
230
|
+
const {rules} = act;
|
|
231
|
+
nativeResult.violations = (nativeResult.violations || [])
|
|
232
|
+
.filter(finding => rules.includes(finding.ruleID));
|
|
233
|
+
nativeResult.incomplete = (nativeResult.incomplete || [])
|
|
234
|
+
.filter(finding => rules.includes(finding.ruleID));
|
|
235
|
+
}
|
|
236
|
+
// If the tool was prevented from running:
|
|
237
|
+
if (nativeResult.prevented) {
|
|
238
|
+
data.prevented = true;
|
|
239
|
+
data.error = nativeResult.error;
|
|
240
|
+
}
|
|
241
|
+
// Otherwise, if a standard result is to be reported:
|
|
242
|
+
else if (standard) {
|
|
243
|
+
const {standardResult} = result;
|
|
244
|
+
// Record the tallied-only bucket sizes.
|
|
245
|
+
data.passRuleCount = nativeResult.passRuleCount;
|
|
246
|
+
data.passElementCount = nativeResult.passElementCount;
|
|
247
|
+
data.inapplicableRuleCount = nativeResult.inapplicableRuleCount;
|
|
248
|
+
data.manualReviewCriterionCount = nativeResult.manualReviewCriterionCount;
|
|
249
|
+
// For each certainty band:
|
|
250
|
+
const bands: [PourFinding[], number, Outcome][] = [
|
|
251
|
+
[nativeResult.incomplete || [], 0, 'cantTell'],
|
|
252
|
+
[nativeResult.violations || [], 2, 'failed']
|
|
253
|
+
];
|
|
254
|
+
bands.forEach(([findings, baseSeverity, outcome]) => {
|
|
255
|
+
// For each native-result finding:
|
|
256
|
+
findings.forEach(finding => {
|
|
257
|
+
// Add a standard-result instance.
|
|
258
|
+
const {ruleID, what, severity, xPath} = finding;
|
|
259
|
+
addInstance(standardResult, {
|
|
260
|
+
ruleID,
|
|
261
|
+
what,
|
|
262
|
+
ordinalSeverity: baseSeverity + (severityWeights[severity] ?? 0),
|
|
263
|
+
outcome,
|
|
264
|
+
catalogIndex: getXPathCatalogIndex(report, xPath)
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
data,
|
|
271
|
+
result
|
|
272
|
+
};
|
|
273
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Page } from 'playwright';
|
|
2
|
+
import type { Report, StandardResult } from '../types';
|
|
3
|
+
interface QwElement {
|
|
4
|
+
htmlCode?: string;
|
|
5
|
+
}
|
|
6
|
+
interface QwRaResult {
|
|
7
|
+
verdict: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
elements?: QwElement[];
|
|
10
|
+
}
|
|
11
|
+
interface QwRuleAssertions {
|
|
12
|
+
metadata?: {
|
|
13
|
+
warning?: number;
|
|
14
|
+
failed?: number;
|
|
15
|
+
};
|
|
16
|
+
results: QwRaResult[];
|
|
17
|
+
}
|
|
18
|
+
interface QwModuleReport {
|
|
19
|
+
assertions?: Record<string, QwRuleAssertions>;
|
|
20
|
+
}
|
|
21
|
+
interface QwNativeResult {
|
|
22
|
+
system?: {
|
|
23
|
+
page?: {
|
|
24
|
+
dom?: unknown;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
modules?: Record<string, QwModuleReport>;
|
|
28
|
+
}
|
|
29
|
+
export declare const reporter: (page: Page, report: Report, actIndex: number, timeLimit: number) => Promise<{
|
|
30
|
+
data: {
|
|
31
|
+
prevented?: boolean;
|
|
32
|
+
error?: string;
|
|
33
|
+
};
|
|
34
|
+
result: {
|
|
35
|
+
nativeResult: QwNativeResult;
|
|
36
|
+
standardResult: StandardResult;
|
|
37
|
+
};
|
|
38
|
+
}>;
|
|
39
|
+
export {};
|