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
package/testaro/title.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
© 2022–2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2026 Jonathan Robert Pool.
|
|
4
|
+
|
|
5
|
+
Licensed under the MIT License. See LICENSE file at the project root or https://opensource.org/license/mit/ for details.
|
|
6
|
+
|
|
7
|
+
SPDX-License-Identifier: MIT
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// IMPORTS
|
|
11
|
+
|
|
12
|
+
import type {Page} from 'playwright';
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
title
|
|
16
|
+
This test reports the page title. Compiled to title.js by tsc (issue #73); edit this file,
|
|
17
|
+
not the emitted one.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
// Runs the test and returns the result.
|
|
21
|
+
export const reporter = async (page: Page) => {
|
|
22
|
+
const title = await page.title();
|
|
23
|
+
return {
|
|
24
|
+
data: {
|
|
25
|
+
success: true,
|
|
26
|
+
title
|
|
27
|
+
},
|
|
28
|
+
totals: [],
|
|
29
|
+
standardInstances: []
|
|
30
|
+
};
|
|
31
|
+
};
|
package/testaro/titledEl.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
© 2023–2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
4
|
© 2026 Jeff Witt.
|
|
@@ -8,28 +9,24 @@
|
|
|
8
9
|
|
|
9
10
|
SPDX-License-Identifier: MIT
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.reporter = void 0;
|
|
14
|
+
const testaro_1 = require("../procs/testaro");
|
|
12
15
|
/*
|
|
13
16
|
titledEl
|
|
14
17
|
This test reports suspicious use of title attributes.
|
|
18
|
+
Compiled to titledEl.js by tsc (issue #73); edit this file, not the emitted one.
|
|
15
19
|
*/
|
|
16
|
-
|
|
17
|
-
// IMPORTS
|
|
18
|
-
|
|
19
|
-
const {doTest} = require('../procs/testaro');
|
|
20
|
-
|
|
21
20
|
// FUNCTIONS
|
|
22
|
-
|
|
23
21
|
// Runs the test and returns the result.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
page, report, withItems, 'titledEl', selector, whats, 0, getBadWhat.toString()
|
|
34
|
-
);
|
|
22
|
+
const reporter = async (page, report, _, withItems) => {
|
|
23
|
+
const getBadWhat = element => {
|
|
24
|
+
const elementType = element.tagName.toLowerCase();
|
|
25
|
+
// Return a violation description.
|
|
26
|
+
return `Likely ineffective title attribute is used on the ${elementType} element`;
|
|
27
|
+
};
|
|
28
|
+
const selector = 'body [title]:not(iframe, link, style)';
|
|
29
|
+
const whats = 'title attributes are used on elements they are likely ineffective on';
|
|
30
|
+
return await (0, testaro_1.doTest)(page, report, withItems, 'titledEl', selector, whats, 0, getBadWhat.toString());
|
|
35
31
|
};
|
|
32
|
+
exports.reporter = reporter;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/*
|
|
2
|
+
© 2023–2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2026 Jeff Witt.
|
|
4
|
+
© 2025–2026 Jonathan Robert Pool.
|
|
5
|
+
|
|
6
|
+
Licensed under the MIT License. See LICENSE file at the project root or
|
|
7
|
+
https://opensource.org/license/mit/ for details.
|
|
8
|
+
|
|
9
|
+
SPDX-License-Identifier: MIT
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// IMPORTS
|
|
13
|
+
|
|
14
|
+
import type {Page} from 'playwright';
|
|
15
|
+
import {doTest} from '../procs/testaro';
|
|
16
|
+
import type {GetBadWhat, Report} from '../types';
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
titledEl
|
|
20
|
+
This test reports suspicious use of title attributes.
|
|
21
|
+
Compiled to titledEl.js by tsc (issue #73); edit this file, not the emitted one.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// FUNCTIONS
|
|
25
|
+
|
|
26
|
+
// Runs the test and returns the result.
|
|
27
|
+
export const reporter = async (page: Page, report: Report, _: unknown, withItems: boolean) => {
|
|
28
|
+
const getBadWhat: GetBadWhat = element => {
|
|
29
|
+
const elementType = element.tagName.toLowerCase();
|
|
30
|
+
// Return a violation description.
|
|
31
|
+
return `Likely ineffective title attribute is used on the ${elementType} element`;
|
|
32
|
+
}
|
|
33
|
+
const selector = 'body [title]:not(iframe, link, style)';
|
|
34
|
+
const whats = 'title attributes are used on elements they are likely ineffective on';
|
|
35
|
+
return await doTest(
|
|
36
|
+
page, report, withItems, 'titledEl', selector, whats, 0, getBadWhat.toString()
|
|
37
|
+
);
|
|
38
|
+
};
|
package/testaro/zIndex.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
© 2021–2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
4
|
© 2026 Jeff Witt.
|
|
@@ -8,32 +9,28 @@
|
|
|
8
9
|
|
|
9
10
|
SPDX-License-Identifier: MIT
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.reporter = void 0;
|
|
14
|
+
const testaro_1 = require("../procs/testaro");
|
|
12
15
|
/*
|
|
13
16
|
zIndex
|
|
14
17
|
This test reports elements with abnormal Z indexes. It assumes that pages are most accessible when they do not require users to perceive a third dimension (depth). Layers, popups, and dialogs that cover other content make it difficult for some or all users to interpret the content and know what parts of the content can be acted on. Layering also complicates accessibility testing. Tests for visibility of focus, for example, may fail if incapable of detecting that a focused element is covered by another element. Z indexes other than auto and 0 are considered abnormal.
|
|
18
|
+
Compiled to zIndex.js by tsc (issue #73); edit this file, not the emitted one.
|
|
15
19
|
*/
|
|
16
|
-
|
|
17
|
-
// IMPORTS
|
|
18
|
-
|
|
19
|
-
const {doTest} = require('../procs/testaro');
|
|
20
|
-
|
|
21
20
|
// FUNCTIONS
|
|
22
|
-
|
|
23
21
|
// Runs the test and returns the result.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
page, report, withItems, 'zIndex', 'body, body *', whats, 0, getBadWhat.toString()
|
|
38
|
-
);
|
|
22
|
+
const reporter = async (page, report, _, withItems) => {
|
|
23
|
+
const getBadWhat = element => {
|
|
24
|
+
// Get whether the element violates the rule.
|
|
25
|
+
const styleDec = window.getComputedStyle(element);
|
|
26
|
+
const { zIndex } = styleDec;
|
|
27
|
+
// If the Z index of the element is neither 'auto' nor 0:
|
|
28
|
+
if (!['auto', '0'].includes(zIndex)) {
|
|
29
|
+
// Return a violation description.
|
|
30
|
+
return `z-index style property of the element is ${zIndex}`;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const whats = 'Elements have non-default Z indexes';
|
|
34
|
+
return await (0, testaro_1.doTest)(page, report, withItems, 'zIndex', 'body, body *', whats, 0, getBadWhat.toString());
|
|
39
35
|
};
|
|
36
|
+
exports.reporter = reporter;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
© 2021–2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2026 Jeff Witt.
|
|
4
|
+
© 2025–2026 Jonathan Robert Pool
|
|
5
|
+
|
|
6
|
+
Licensed under the MIT License. See LICENSE file at the project root or
|
|
7
|
+
https://opensource.org/license/mit/ for details.
|
|
8
|
+
|
|
9
|
+
SPDX-License-Identifier: MIT
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// IMPORTS
|
|
13
|
+
|
|
14
|
+
import type {Page} from 'playwright';
|
|
15
|
+
import {doTest} from '../procs/testaro';
|
|
16
|
+
import type {GetBadWhat, Report} from '../types';
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
zIndex
|
|
20
|
+
This test reports elements with abnormal Z indexes. It assumes that pages are most accessible when they do not require users to perceive a third dimension (depth). Layers, popups, and dialogs that cover other content make it difficult for some or all users to interpret the content and know what parts of the content can be acted on. Layering also complicates accessibility testing. Tests for visibility of focus, for example, may fail if incapable of detecting that a focused element is covered by another element. Z indexes other than auto and 0 are considered abnormal.
|
|
21
|
+
Compiled to zIndex.js by tsc (issue #73); edit this file, not the emitted one.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// FUNCTIONS
|
|
25
|
+
|
|
26
|
+
// Runs the test and returns the result.
|
|
27
|
+
export const reporter = async (page: Page, report: Report, _: unknown, withItems: boolean) => {
|
|
28
|
+
const getBadWhat: GetBadWhat = element => {
|
|
29
|
+
// Get whether the element violates the rule.
|
|
30
|
+
const styleDec = window.getComputedStyle(element);
|
|
31
|
+
const {zIndex} = styleDec;
|
|
32
|
+
// If the Z index of the element is neither 'auto' nor 0:
|
|
33
|
+
if (! ['auto', '0'].includes(zIndex)) {
|
|
34
|
+
// Return a violation description.
|
|
35
|
+
return `z-index style property of the element is ${zIndex}`;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const whats = 'Elements have non-default Z indexes';
|
|
39
|
+
return await doTest(
|
|
40
|
+
page, report, withItems, 'zIndex', 'body, body *', whats, 0, getBadWhat.toString()
|
|
41
|
+
);
|
|
42
|
+
};
|
package/tests/alfa.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Page } from 'playwright';
|
|
2
|
+
import type { Report, StandardResult } from '../types';
|
|
3
|
+
interface AlfaEvalItem {
|
|
4
|
+
diagnostic?: {
|
|
5
|
+
errors?: {
|
|
6
|
+
element?: unknown;
|
|
7
|
+
positionedDescendants?: unknown;
|
|
8
|
+
}[];
|
|
9
|
+
};
|
|
10
|
+
expectations?: {
|
|
11
|
+
error?: {
|
|
12
|
+
message?: string;
|
|
13
|
+
};
|
|
14
|
+
}[][];
|
|
15
|
+
outcome: string;
|
|
16
|
+
rule: {
|
|
17
|
+
requirements?: {
|
|
18
|
+
title?: string;
|
|
19
|
+
}[];
|
|
20
|
+
uri: string;
|
|
21
|
+
};
|
|
22
|
+
target?: {
|
|
23
|
+
children?: unknown;
|
|
24
|
+
};
|
|
25
|
+
code?: string;
|
|
26
|
+
path?: string;
|
|
27
|
+
}
|
|
28
|
+
interface AlfaNativeResult {
|
|
29
|
+
totals: {
|
|
30
|
+
failed: number;
|
|
31
|
+
cantTell: number;
|
|
32
|
+
};
|
|
33
|
+
items: AlfaEvalItem[];
|
|
34
|
+
}
|
|
35
|
+
export declare const reporter: (page: Page, report: Report, actIndex: number) => Promise<{
|
|
36
|
+
data: {
|
|
37
|
+
prevented?: boolean;
|
|
38
|
+
error?: string;
|
|
39
|
+
};
|
|
40
|
+
result: {
|
|
41
|
+
nativeResult: AlfaNativeResult;
|
|
42
|
+
standardResult: StandardResult;
|
|
43
|
+
};
|
|
44
|
+
}>;
|
|
45
|
+
export {};
|
package/tests/alfa.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
© 2021–2024 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
4
|
© 2026 Jeff Witt.
|
|
@@ -8,159 +9,155 @@
|
|
|
8
9
|
|
|
9
10
|
SPDX-License-Identifier: MIT
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.reporter = void 0;
|
|
14
|
+
const xPath_1 = require("../procs/xPath");
|
|
15
|
+
const standard_1 = require("../procs/standard");
|
|
16
|
+
const config_1 = require("../procs/config");
|
|
17
|
+
/*
|
|
18
|
+
The alfa packages are pure ESM that Node loads via require(esm); their own
|
|
19
|
+
types do not resolve under this project's node10 module resolution, so the
|
|
20
|
+
imports stay requires and are untyped.
|
|
21
|
+
*/
|
|
22
|
+
let alfaRules = require('@siteimprove/alfa-rules').default;
|
|
23
|
+
const { Audit } = require('@siteimprove/alfa-act');
|
|
24
|
+
const { Playwright } = require('@siteimprove/alfa-playwright');
|
|
12
25
|
/*
|
|
13
26
|
alfa
|
|
14
27
|
Implements the alfa ruleset for accessibility.
|
|
28
|
+
Compiled to alfa.js by tsc (issue #73); edit this file, not the emitted one.
|
|
15
29
|
*/
|
|
16
|
-
|
|
17
|
-
// IMPORTS
|
|
18
|
-
|
|
19
|
-
let alfaRules = require('@siteimprove/alfa-rules').default;
|
|
20
|
-
const {Audit} = require('@siteimprove/alfa-act');
|
|
21
|
-
const {getNormalizedXPath, getXPathCatalogIndex} = require('../procs/xPath');
|
|
22
|
-
const {Playwright} = require('@siteimprove/alfa-playwright');
|
|
23
|
-
const {applyMultiplier} = require('../procs/config');
|
|
24
|
-
|
|
25
30
|
// FUNCTIONS
|
|
26
|
-
|
|
27
31
|
// Conducts and reports the alfa tests.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
};
|
|
48
|
-
const standard = report.standard !== 'no';
|
|
49
|
-
// If standard results are to be reported:
|
|
50
|
-
if (standard) {
|
|
51
|
-
// Initialize the standard result.
|
|
52
|
-
result.standardResult = {
|
|
53
|
-
prevented: false,
|
|
54
|
-
totals: [0, 0, 0, 0],
|
|
55
|
-
instances: []
|
|
32
|
+
const reporter = async (page, report, actIndex) => {
|
|
33
|
+
const act = report.acts[actIndex];
|
|
34
|
+
const { rules } = act;
|
|
35
|
+
// If only some rules are to be employed:
|
|
36
|
+
if (rules && rules.length) {
|
|
37
|
+
// Remove the other rules.
|
|
38
|
+
alfaRules = alfaRules.filter((rule) => rules.includes(rule.uri.replace(/^.+-/, '')));
|
|
39
|
+
}
|
|
40
|
+
// Initialize the act report.
|
|
41
|
+
const data = {};
|
|
42
|
+
const result = {
|
|
43
|
+
nativeResult: {
|
|
44
|
+
totals: {
|
|
45
|
+
failed: 0,
|
|
46
|
+
cantTell: 0
|
|
47
|
+
},
|
|
48
|
+
items: []
|
|
49
|
+
},
|
|
50
|
+
standardResult: {}
|
|
56
51
|
};
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
const standard = report.standard !== 'no';
|
|
53
|
+
// If standard results are to be reported:
|
|
54
|
+
if (standard) {
|
|
55
|
+
// Initialize the standard result.
|
|
56
|
+
result.standardResult = (0, standard_1.getStandardResult)();
|
|
57
|
+
}
|
|
59
58
|
try {
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
try {
|
|
60
|
+
// Wait for a stable page to make the page and its alfa version consistent.
|
|
61
|
+
await page.waitForLoadState('networkidle', { timeout: (0, config_1.applyMultiplier)(9000) });
|
|
62
|
+
}
|
|
63
|
+
// If that fails:
|
|
64
|
+
catch (error) {
|
|
65
|
+
// Wait for the page to be loaded.
|
|
66
|
+
await page.waitForLoadState('domcontentloaded', { timeout: (0, config_1.applyMultiplier)(6000) });
|
|
67
|
+
}
|
|
68
|
+
const doc = await page.evaluateHandle('document');
|
|
69
|
+
const alfaPage = await Playwright.toPage(doc);
|
|
70
|
+
// Test the page content with the specified rules.
|
|
71
|
+
const audit = Audit.of(alfaPage, alfaRules);
|
|
72
|
+
// Get the evaluations.
|
|
73
|
+
const evaluations = Array.from(await audit.evaluate());
|
|
74
|
+
const { nativeResult, standardResult } = result;
|
|
75
|
+
// For each of them:
|
|
76
|
+
for (const index in evaluations) {
|
|
77
|
+
const evaluation = evaluations[index];
|
|
78
|
+
const targetClass = evaluation.target;
|
|
79
|
+
// If it has a non-collection violator:
|
|
80
|
+
if (targetClass && !targetClass._members) {
|
|
81
|
+
// Convert the evaluation to an element-specific item.
|
|
82
|
+
const item = evaluation.toJSON();
|
|
83
|
+
const { diagnostic, expectations, outcome, rule, target } = item;
|
|
84
|
+
// If the outcome of the item is a failure or warning:
|
|
85
|
+
if (['failed', 'cantTell'].includes(outcome)) {
|
|
86
|
+
// Delete typically massive properties unlikely to be useful.
|
|
87
|
+
delete target.children;
|
|
88
|
+
if (diagnostic?.errors) {
|
|
89
|
+
diagnostic.errors.forEach(error => {
|
|
90
|
+
delete error.element;
|
|
91
|
+
delete error.positionedDescendants;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// Increment the applicable total.
|
|
95
|
+
nativeResult.totals[outcome]++;
|
|
96
|
+
const codeLines = targetClass.toString().split('\n');
|
|
97
|
+
if (codeLines[0] === '#document') {
|
|
98
|
+
codeLines.splice(2, codeLines.length - 3, ' … ');
|
|
99
|
+
}
|
|
100
|
+
else if (codeLines[0].startsWith('<html')) {
|
|
101
|
+
codeLines.splice(1, codeLines.length - 2, ' … ');
|
|
102
|
+
}
|
|
103
|
+
let code = codeLines.join('/n');
|
|
104
|
+
if (code.length > 400) {
|
|
105
|
+
code = `${code.slice(0, 300)} … ${code.slice(-100)}`;
|
|
106
|
+
}
|
|
107
|
+
// Add properties of the evaluation to the item.
|
|
108
|
+
item.code = code;
|
|
109
|
+
item.path = targetClass.path();
|
|
110
|
+
// Add the item to the items of the native result.
|
|
111
|
+
nativeResult.items.push(item);
|
|
112
|
+
// If standard results are to be reported:
|
|
113
|
+
if (standard) {
|
|
114
|
+
const { requirements, uri } = rule;
|
|
115
|
+
// Get the rule ID of the item.
|
|
116
|
+
const ruleID = uri.replace(/^.+-/, '');
|
|
117
|
+
// Get the rule description of the item.
|
|
118
|
+
let what = (expectations?.[0]?.[1]?.error?.message || '').trim().replace(/\s+/g, ' ');
|
|
119
|
+
if (!what) {
|
|
120
|
+
if (requirements && requirements.length && requirements[0].title) {
|
|
121
|
+
what = requirements[0].title;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// An untestable item keeps its rule ID; its outcome records the uncertainty. The
|
|
125
|
+
// contrast rules (r66, r69) cannot tell when a background needs human judgement.
|
|
126
|
+
const isCantTell = outcome === 'cantTell';
|
|
127
|
+
const xPath = (0, xPath_1.getNormalizedXPath)(item.path?.replace(/\/text\(\).*$/, '') || '/html');
|
|
128
|
+
// Add an instance to the standard instances.
|
|
129
|
+
(0, standard_1.addInstance)(standardResult, {
|
|
130
|
+
ruleID,
|
|
131
|
+
what,
|
|
132
|
+
ordinalSeverity: isCantTell ? 0 : 2,
|
|
133
|
+
outcome: isCantTell ? 'cantTell' : 'failed',
|
|
134
|
+
uncertainty: isCantTell && ['r66', 'r69'].includes(ruleID)
|
|
135
|
+
? 'judgement-required'
|
|
136
|
+
: undefined,
|
|
137
|
+
catalogIndex: (0, xPath_1.getXPathCatalogIndex)(report, xPath)
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
;
|
|
62
144
|
}
|
|
63
|
-
// If that fails:
|
|
64
145
|
catch (error) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// Test the page content with the specified rules.
|
|
71
|
-
const audit = Audit.of(alfaPage, alfaRules);
|
|
72
|
-
// Get the evaluations.
|
|
73
|
-
const evaluations = Array.from(await audit.evaluate());
|
|
74
|
-
const {nativeResult, standardResult} = result;
|
|
75
|
-
// For each of them:
|
|
76
|
-
for (const index in evaluations) {
|
|
77
|
-
const evaluation = evaluations[index];
|
|
78
|
-
const targetClass = evaluation.target;
|
|
79
|
-
// If it has a non-collection violator:
|
|
80
|
-
if (targetClass && ! targetClass._members) {
|
|
81
|
-
// Convert the evaluation to an element-specific item.
|
|
82
|
-
const item = evaluation.toJSON();
|
|
83
|
-
const {diagnostic, expectations, outcome, rule, target} = item;
|
|
84
|
-
// If the outcome of the item is a failure or warning:
|
|
85
|
-
if (['failed', 'cantTell'].includes(outcome)) {
|
|
86
|
-
// Delete typically massive properties unlikely to be useful.
|
|
87
|
-
delete target.children;
|
|
88
|
-
if (diagnostic?.errors) {
|
|
89
|
-
diagnostic.errors.forEach(error => {
|
|
90
|
-
delete error.element;
|
|
91
|
-
delete error.positionedDescendants;
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
// Increment the applicable total.
|
|
95
|
-
nativeResult.totals[outcome]++;
|
|
96
|
-
const codeLines = targetClass.toString().split('\n');
|
|
97
|
-
if (codeLines[0] === '#document') {
|
|
98
|
-
codeLines.splice(2, codeLines.length - 3, ' … ');
|
|
99
|
-
}
|
|
100
|
-
else if (codeLines[0].startsWith('<html')) {
|
|
101
|
-
codeLines.splice(1, codeLines.length - 2, ' … ');
|
|
102
|
-
}
|
|
103
|
-
let code = codeLines.join('/n');
|
|
104
|
-
if (code.length > 400) {
|
|
105
|
-
code = `${code.slice(0, 300)} … ${code.slice(-100)}`;
|
|
106
|
-
}
|
|
107
|
-
// Add properties of the evaluation to the item.
|
|
108
|
-
item.code = code;
|
|
109
|
-
item.path = targetClass.path();
|
|
110
|
-
// Add the item to the items of the native result.
|
|
111
|
-
nativeResult.items.push(item);
|
|
112
|
-
// If standard results are to be reported:
|
|
113
|
-
if (standard) {
|
|
114
|
-
const {requirements, uri} = rule;
|
|
115
|
-
// Get the rule ID of the item.
|
|
116
|
-
let ruleID = uri.replace(/^.+-/, '');
|
|
117
|
-
// Get the rule description of the item.
|
|
118
|
-
let what = (expectations?.[0]?.[1]?.error?.message || '').trim().replace(/\s+/g, ' ');
|
|
119
|
-
if (! what) {
|
|
120
|
-
if (requirements && requirements.length && requirements[0].title) {
|
|
121
|
-
what = requirements[0].title;
|
|
122
|
-
}
|
|
146
|
+
data.prevented = true;
|
|
147
|
+
const { message } = error;
|
|
148
|
+
if (message) {
|
|
149
|
+
if (message.includes('Unsupported node of type: 4')) {
|
|
150
|
+
data.error = 'Alfa cannot test page because it contains CDATA';
|
|
123
151
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
// If the outcome is untestability:
|
|
127
|
-
if (outcome === 'cantTell') {
|
|
128
|
-
// Revise the rule-specific properties.
|
|
129
|
-
ruleID = ['r66', 'r69'].includes(ruleID) ? 'cantTell' : 'cantTellTextContrast';
|
|
130
|
-
what = `cannot test for rule ${ruleID}: ${what}`;
|
|
131
|
-
ordinalSeverity = 0;
|
|
152
|
+
else {
|
|
153
|
+
data.error = message;
|
|
132
154
|
}
|
|
133
|
-
// Increment the standard total.
|
|
134
|
-
standardResult.totals[ordinalSeverity]++;
|
|
135
|
-
const xPath = getNormalizedXPath(item.path?.replace(/\/text\(\).*$/, '') || '/html');
|
|
136
|
-
// Add an instance to the standard instances.
|
|
137
|
-
standardResult.instances.push({
|
|
138
|
-
ruleID,
|
|
139
|
-
what,
|
|
140
|
-
ordinalSeverity,
|
|
141
|
-
count: 1,
|
|
142
|
-
catalogIndex: getXPathCatalogIndex(report, xPath)
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
155
|
}
|
|
146
|
-
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
catch(error) {
|
|
150
|
-
data.prevented = true;
|
|
151
|
-
const {message} = error;
|
|
152
|
-
if (message) {
|
|
153
|
-
if (message.includes('Unsupported node of type: 4')) {
|
|
154
|
-
data.error = 'Alfa cannot test page because it contains CDATA';
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
data.error = message;
|
|
158
|
-
}
|
|
156
|
+
console.log(`ERROR: ${data.error}`);
|
|
159
157
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
result
|
|
165
|
-
};
|
|
158
|
+
return {
|
|
159
|
+
data,
|
|
160
|
+
result
|
|
161
|
+
};
|
|
166
162
|
};
|
|
163
|
+
exports.reporter = reporter;
|