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/autocomplete.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
© 2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
4
|
© 2026 Jeff Witt.
|
|
@@ -8,90 +9,73 @@
|
|
|
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
|
autocomplete
|
|
14
17
|
This test reports failures to equip name and email inputs with correct autocomplete attributes.
|
|
18
|
+
Compiled to autocomplete.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
|
-
page,
|
|
26
|
-
report,
|
|
27
|
-
_0,
|
|
28
|
-
withItems,
|
|
29
|
-
labels = {
|
|
22
|
+
const reporter = async (page, report, _0, withItems, labels = {
|
|
30
23
|
name: ['your name', 'full name', 'first and last name'],
|
|
31
24
|
email: ['email'],
|
|
32
25
|
given: ['first name', 'forename', 'given name'],
|
|
33
26
|
family: ['last name', 'surname', 'family name']
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
27
|
+
}) => {
|
|
28
|
+
// The candidate selector guarantees input elements, so the parameter is typed as one.
|
|
29
|
+
const getBadWhat = (element) => {
|
|
30
|
+
// Get the lower-cased accessible name of the element.
|
|
31
|
+
const accessibleName = window.getAccessibleName(element).toLowerCase();
|
|
32
|
+
const { type } = element;
|
|
33
|
+
let requiredAuto = '';
|
|
34
|
+
const labels = {
|
|
35
|
+
name: ['__nameLabels__'],
|
|
36
|
+
email: ['__emailLabels__'],
|
|
37
|
+
given: ['__givenLabels__'],
|
|
38
|
+
family: ['__familyLabels__']
|
|
39
|
+
};
|
|
40
|
+
// Get its required autocomplete value.
|
|
41
|
+
if (type === 'email'
|
|
42
|
+
|| accessibleName && labels.email.some(label => accessibleName.includes(label))) {
|
|
43
|
+
requiredAuto = 'email';
|
|
44
|
+
}
|
|
45
|
+
else if (accessibleName && type === 'text' && labels.name.some(label => accessibleName.includes(label))) {
|
|
46
|
+
requiredAuto = 'name';
|
|
47
|
+
}
|
|
48
|
+
else if (accessibleName
|
|
49
|
+
&& type === 'text'
|
|
50
|
+
&& labels.given.some(label => accessibleName.includes(label))) {
|
|
51
|
+
requiredAuto = 'given-name';
|
|
52
|
+
}
|
|
53
|
+
else if (accessibleName
|
|
54
|
+
&& type === 'text'
|
|
55
|
+
&& labels.family.some(label => accessibleName.includes(label))) {
|
|
56
|
+
requiredAuto = 'family-name';
|
|
57
|
+
}
|
|
58
|
+
// Get its actual autocomplete value.
|
|
59
|
+
const actualAuto = element.getAttribute('autocomplete');
|
|
60
|
+
// If an autocomplete value is required but not present:
|
|
61
|
+
if (requiredAuto && !(actualAuto && actualAuto.includes(requiredAuto))) {
|
|
62
|
+
// Return a violation description.
|
|
63
|
+
return `input has no autocomplete="${requiredAuto}" attribute`;
|
|
64
|
+
}
|
|
46
65
|
};
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
&& type === 'text'
|
|
62
|
-
&& labels.given.some(label => accessibleName.includes(label))
|
|
63
|
-
) {
|
|
64
|
-
requiredAuto = 'given-name';
|
|
65
|
-
}
|
|
66
|
-
else if (
|
|
67
|
-
accessibleName
|
|
68
|
-
&& type === 'text'
|
|
69
|
-
&& labels.family.some(label => accessibleName.includes(label))
|
|
70
|
-
) {
|
|
71
|
-
requiredAuto = 'family-name';
|
|
72
|
-
}
|
|
73
|
-
// Get its actual autocomplete value.
|
|
74
|
-
const actualAuto = element.getAttribute('autocomplete');
|
|
75
|
-
// If an autocomplete value is required but not present:
|
|
76
|
-
if (requiredAuto && ! (actualAuto && actualAuto.includes(requiredAuto))) {
|
|
77
|
-
// Return a violation description.
|
|
78
|
-
return `input has no autocomplete="${requiredAuto}" attribute`;
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
const selector = 'body input[type=text], body input[type=email], body input:not([type])';
|
|
82
|
-
const whats = 'Inputs are missing required autocomplete attributes';
|
|
83
|
-
// Each placeholder sits inside single quotes in getBadWhat (e.g. name: ['__nameLabels__']).
|
|
84
|
-
// Replace the quoted placeholder with the bracket-stripped JSON so the result is a proper
|
|
85
|
-
// element list (name: ["your name", ...]) rather than a one-element array holding the JSON
|
|
86
|
-
// text of the array (name: ['["your name", ...]']), which never matches an accessible name.
|
|
87
|
-
const placeHolders = Object.keys(labels).map(key => `'__${key}Labels__'`);
|
|
88
|
-
const replacers = Object.values(labels).map(value => JSON.stringify(value).slice(1, -1));
|
|
89
|
-
// Create a stringified getBadWhat, with placeholders replaced with the specified label arrays.
|
|
90
|
-
let getBadWhatString = getBadWhat.toString();
|
|
91
|
-
[0, 1, 2, 3].forEach(index => {
|
|
92
|
-
getBadWhatString = getBadWhatString.replace(placeHolders[index], replacers[index]);
|
|
93
|
-
});
|
|
94
|
-
return doTest(
|
|
95
|
-
page, report, withItems, 'autocomplete', selector, whats, 2, getBadWhatString
|
|
96
|
-
);
|
|
66
|
+
const selector = 'body input[type=text], body input[type=email], body input:not([type])';
|
|
67
|
+
const whats = 'Inputs are missing required autocomplete attributes';
|
|
68
|
+
// Each placeholder sits inside single quotes in getBadWhat (e.g. name: ['__nameLabels__']).
|
|
69
|
+
// Replace the quoted placeholder with the bracket-stripped JSON so the result is a proper
|
|
70
|
+
// element list (name: ["your name", ...]) rather than a one-element array holding the JSON
|
|
71
|
+
// text of the array (name: ['["your name", ...]']), which never matches an accessible name.
|
|
72
|
+
const placeHolders = Object.keys(labels).map(key => `'__${key}Labels__'`);
|
|
73
|
+
const replacers = Object.values(labels).map(value => JSON.stringify(value).slice(1, -1));
|
|
74
|
+
// Create a stringified getBadWhat, with placeholders replaced with the specified label arrays.
|
|
75
|
+
let getBadWhatString = getBadWhat.toString();
|
|
76
|
+
[0, 1, 2, 3].forEach(index => {
|
|
77
|
+
getBadWhatString = getBadWhatString.replace(placeHolders[index], replacers[index]);
|
|
78
|
+
});
|
|
79
|
+
return (0, testaro_1.doTest)(page, report, withItems, 'autocomplete', selector, whats, 2, getBadWhatString);
|
|
97
80
|
};
|
|
81
|
+
exports.reporter = reporter;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/*
|
|
2
|
+
© 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 {BadWhat, Report} from '../types';
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
autocomplete
|
|
20
|
+
This test reports failures to equip name and email inputs with correct autocomplete attributes.
|
|
21
|
+
Compiled to autocomplete.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 (
|
|
28
|
+
page: Page,
|
|
29
|
+
report: Report,
|
|
30
|
+
_0: unknown,
|
|
31
|
+
withItems: boolean,
|
|
32
|
+
labels: Record<'name' | 'email' | 'given' | 'family', string[]> = {
|
|
33
|
+
name: ['your name', 'full name', 'first and last name'],
|
|
34
|
+
email: ['email'],
|
|
35
|
+
given: ['first name', 'forename', 'given name'],
|
|
36
|
+
family: ['last name', 'surname', 'family name']
|
|
37
|
+
}
|
|
38
|
+
) => {
|
|
39
|
+
// The candidate selector guarantees input elements, so the parameter is typed as one.
|
|
40
|
+
const getBadWhat = (element: HTMLInputElement): BadWhat => {
|
|
41
|
+
// Get the lower-cased accessible name of the element.
|
|
42
|
+
const accessibleName = window.getAccessibleName(element).toLowerCase();
|
|
43
|
+
const {type} = element;
|
|
44
|
+
let requiredAuto = '';
|
|
45
|
+
const labels = {
|
|
46
|
+
name: ['__nameLabels__'],
|
|
47
|
+
email: ['__emailLabels__'],
|
|
48
|
+
given: ['__givenLabels__'],
|
|
49
|
+
family: ['__familyLabels__']
|
|
50
|
+
};
|
|
51
|
+
// Get its required autocomplete value.
|
|
52
|
+
if (
|
|
53
|
+
type === 'email'
|
|
54
|
+
|| accessibleName && labels.email.some(label => accessibleName.includes(label))
|
|
55
|
+
) {
|
|
56
|
+
requiredAuto = 'email';
|
|
57
|
+
}
|
|
58
|
+
else if (
|
|
59
|
+
accessibleName && type === 'text' && labels.name.some(label => accessibleName.includes(label))
|
|
60
|
+
) {
|
|
61
|
+
requiredAuto = 'name';
|
|
62
|
+
}
|
|
63
|
+
else if (
|
|
64
|
+
accessibleName
|
|
65
|
+
&& type === 'text'
|
|
66
|
+
&& labels.given.some(label => accessibleName.includes(label))
|
|
67
|
+
) {
|
|
68
|
+
requiredAuto = 'given-name';
|
|
69
|
+
}
|
|
70
|
+
else if (
|
|
71
|
+
accessibleName
|
|
72
|
+
&& type === 'text'
|
|
73
|
+
&& labels.family.some(label => accessibleName.includes(label))
|
|
74
|
+
) {
|
|
75
|
+
requiredAuto = 'family-name';
|
|
76
|
+
}
|
|
77
|
+
// Get its actual autocomplete value.
|
|
78
|
+
const actualAuto = element.getAttribute('autocomplete');
|
|
79
|
+
// If an autocomplete value is required but not present:
|
|
80
|
+
if (requiredAuto && ! (actualAuto && actualAuto.includes(requiredAuto))) {
|
|
81
|
+
// Return a violation description.
|
|
82
|
+
return `input has no autocomplete="${requiredAuto}" attribute`;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const selector = 'body input[type=text], body input[type=email], body input:not([type])';
|
|
86
|
+
const whats = 'Inputs are missing required autocomplete attributes';
|
|
87
|
+
// Each placeholder sits inside single quotes in getBadWhat (e.g. name: ['__nameLabels__']).
|
|
88
|
+
// Replace the quoted placeholder with the bracket-stripped JSON so the result is a proper
|
|
89
|
+
// element list (name: ["your name", ...]) rather than a one-element array holding the JSON
|
|
90
|
+
// text of the array (name: ['["your name", ...]']), which never matches an accessible name.
|
|
91
|
+
const placeHolders = Object.keys(labels).map(key => `'__${key}Labels__'`);
|
|
92
|
+
const replacers = Object.values(labels).map(value => JSON.stringify(value).slice(1, -1));
|
|
93
|
+
// Create a stringified getBadWhat, with placeholders replaced with the specified label arrays.
|
|
94
|
+
let getBadWhatString = getBadWhat.toString();
|
|
95
|
+
[0, 1, 2, 3].forEach(index => {
|
|
96
|
+
getBadWhatString = getBadWhatString.replace(placeHolders[index], replacers[index]);
|
|
97
|
+
});
|
|
98
|
+
return doTest(
|
|
99
|
+
page, report, withItems, 'autocomplete', selector, whats, 2, getBadWhatString
|
|
100
|
+
);
|
|
101
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Page } from 'playwright';
|
|
2
|
+
import type { Report } from '../types';
|
|
3
|
+
export declare const reporter: (page: Page, report: Report) => Promise<{
|
|
4
|
+
data: {};
|
|
5
|
+
totals: number[];
|
|
6
|
+
standardInstances: {
|
|
7
|
+
ruleID: string;
|
|
8
|
+
what: string;
|
|
9
|
+
ordinalSeverity: number;
|
|
10
|
+
count: number;
|
|
11
|
+
catalogIndex: string;
|
|
12
|
+
}[];
|
|
13
|
+
}>;
|
package/testaro/bulk.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,45 +9,43 @@
|
|
|
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");
|
|
12
15
|
/*
|
|
13
16
|
bulk
|
|
14
17
|
This test reports the count of visible elements. The test assumes that simplicity and compactness, with one page having one purpose, is an accessibility virtue. Users with visual, motor, and cognitive disabilities often have trouble finding what they want or understanding the purpose of a page if the page is cluttered with content.
|
|
18
|
+
Compiled to bulk.js by tsc (issue #73); edit this file, not the emitted one.
|
|
15
19
|
*/
|
|
16
|
-
|
|
17
|
-
// IMPORTS
|
|
18
|
-
|
|
19
|
-
const {getXPathCatalogIndex} = require('../procs/xPath');
|
|
20
|
-
|
|
21
20
|
// FUNCTIONS
|
|
22
|
-
|
|
23
21
|
// Runs the test and returns the result.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
const reporter = async (page, report) => {
|
|
23
|
+
// Get a count of elements deemed visible by Playwright.
|
|
24
|
+
const visibleElementCount = await page.locator('body :visible').count();
|
|
25
|
+
// Convert the count to a severity level, treating up to 400 as non-reportable.
|
|
26
|
+
const severity = Math.min(4, Math.round(visibleElementCount / 400)) - 1;
|
|
27
|
+
const totals = [0, 0, 0, 0];
|
|
28
|
+
// If the severity is reportable:
|
|
29
|
+
if (severity > -1) {
|
|
30
|
+
totals[severity] = 1;
|
|
31
|
+
// Return data, totals, and a summary standard instance.
|
|
32
|
+
return {
|
|
33
|
+
data: {},
|
|
34
|
+
totals,
|
|
35
|
+
standardInstances: [{
|
|
36
|
+
ruleID: 'bulk',
|
|
37
|
+
what: `Page contains ${visibleElementCount} visible elements`,
|
|
38
|
+
ordinalSeverity: severity,
|
|
39
|
+
count: 1,
|
|
40
|
+
catalogIndex: (0, xPath_1.getXPathCatalogIndex)(report, '/html')
|
|
41
|
+
}]
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// Otherwise, return data, totals, and an empty array of standard instances.
|
|
34
45
|
return {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
ruleID: 'bulk',
|
|
39
|
-
what: `Page contains ${visibleElementCount} visible elements`,
|
|
40
|
-
ordinalSeverity: severity,
|
|
41
|
-
count: 1,
|
|
42
|
-
catalogIndex: getXPathCatalogIndex(report, '/html')
|
|
43
|
-
}]
|
|
46
|
+
data: {},
|
|
47
|
+
totals,
|
|
48
|
+
standardInstances: []
|
|
44
49
|
};
|
|
45
|
-
}
|
|
46
|
-
// Otherwise, return data, totals, and an empty array of standard instances.
|
|
47
|
-
return {
|
|
48
|
-
data: {},
|
|
49
|
-
totals,
|
|
50
|
-
standardInstances: []
|
|
51
|
-
};
|
|
52
50
|
};
|
|
51
|
+
exports.reporter = reporter;
|
package/testaro/bulk.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
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 {getXPathCatalogIndex} from '../procs/xPath';
|
|
16
|
+
import type {Report} from '../types';
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
bulk
|
|
20
|
+
This test reports the count of visible elements. The test assumes that simplicity and compactness, with one page having one purpose, is an accessibility virtue. Users with visual, motor, and cognitive disabilities often have trouble finding what they want or understanding the purpose of a page if the page is cluttered with content.
|
|
21
|
+
Compiled to bulk.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) => {
|
|
28
|
+
// Get a count of elements deemed visible by Playwright.
|
|
29
|
+
const visibleElementCount = await page.locator('body :visible').count();
|
|
30
|
+
// Convert the count to a severity level, treating up to 400 as non-reportable.
|
|
31
|
+
const severity = Math.min(4, Math.round(visibleElementCount / 400)) - 1;
|
|
32
|
+
const totals = [0, 0, 0, 0];
|
|
33
|
+
// If the severity is reportable:
|
|
34
|
+
if (severity > -1) {
|
|
35
|
+
totals[severity] = 1;
|
|
36
|
+
// Return data, totals, and a summary standard instance.
|
|
37
|
+
return {
|
|
38
|
+
data: {},
|
|
39
|
+
totals,
|
|
40
|
+
standardInstances: [{
|
|
41
|
+
ruleID: 'bulk',
|
|
42
|
+
what: `Page contains ${visibleElementCount} visible elements`,
|
|
43
|
+
ordinalSeverity: severity,
|
|
44
|
+
count: 1,
|
|
45
|
+
catalogIndex: getXPathCatalogIndex(report, '/html')
|
|
46
|
+
}]
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// Otherwise, return data, totals, and an empty array of standard instances.
|
|
50
|
+
return {
|
|
51
|
+
data: {},
|
|
52
|
+
totals,
|
|
53
|
+
standardInstances: []
|
|
54
|
+
};
|
|
55
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Page } from 'playwright';
|
|
2
|
+
import type { Report, StandardInstance } from '../types';
|
|
3
|
+
export declare const reporter: (page: Page, report: Report, _0: unknown, withItems: boolean, trialKeySpecs?: string[]) => Promise<{
|
|
4
|
+
data: {
|
|
5
|
+
trialKeys?: string[];
|
|
6
|
+
};
|
|
7
|
+
totals: number[];
|
|
8
|
+
standardInstances: StandardInstance[];
|
|
9
|
+
}>;
|