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/miniText.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
© 2022–2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
4
|
© 2026 Jeff Witt.
|
|
@@ -8,58 +9,54 @@
|
|
|
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
|
miniText
|
|
14
17
|
Derived from the bbc-a11y textCannotBeTooSmall test.
|
|
15
18
|
Related to Tenon rule 134.
|
|
16
19
|
This test reports elements with font sizes smaller than 11 pixels.
|
|
20
|
+
Compiled to miniText.js by tsc (issue #73); edit this file, not the emitted one.
|
|
17
21
|
*/
|
|
18
|
-
|
|
19
|
-
// IMPORTS
|
|
20
|
-
|
|
21
|
-
const {doTest} = require('../procs/testaro');
|
|
22
|
-
|
|
23
22
|
// FUNCTIONS
|
|
24
|
-
|
|
25
23
|
// Runs the test and returns the result.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
24
|
+
const reporter = async (page, report, _, withItems) => {
|
|
25
|
+
const getBadWhat = element => {
|
|
26
|
+
const rawText = element.textContent || '';
|
|
27
|
+
// If the element has text content with any non-whitespace:
|
|
28
|
+
if (/[^\s]/.test(rawText)) {
|
|
29
|
+
const isVisible = element.checkVisibility({
|
|
30
|
+
contentVisibilityAuto: true,
|
|
31
|
+
opacityProperty: true,
|
|
32
|
+
visibilityProperty: true
|
|
33
|
+
});
|
|
34
|
+
// If the element is visible:
|
|
35
|
+
if (isVisible) {
|
|
36
|
+
const styleDec = window.getComputedStyle(element);
|
|
37
|
+
// Get its font size.
|
|
38
|
+
const fontSizeString = styleDec.fontSize;
|
|
39
|
+
const fontSize = Number.parseFloat(fontSizeString);
|
|
40
|
+
// If its font size is smaller than 11 pixels:
|
|
41
|
+
if (fontSize < 11) {
|
|
42
|
+
const parent = element.parentElement;
|
|
43
|
+
// If the element has a parent:
|
|
44
|
+
if (parent) {
|
|
45
|
+
const parentStyleDec = window.getComputedStyle(parent);
|
|
46
|
+
const parentFontSize = Number.parseFloat(parentStyleDec.fontSize);
|
|
47
|
+
// If the parent also has a font size smaller than 11 pixels:
|
|
48
|
+
if (parentFontSize < 11) {
|
|
49
|
+
// Do not report a violation, because the font size may be inherited.
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Return a violation description.
|
|
54
|
+
return `Element is visible but its font size is ${fontSize}px, smaller than 11px`;
|
|
55
|
+
}
|
|
53
56
|
}
|
|
54
|
-
}
|
|
55
|
-
// Return a violation description.
|
|
56
|
-
return `Element is visible but its font size is ${fontSize}px, smaller than 11px`;
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const whats = 'Visible elements have font sizes smaller than 11 pixels';
|
|
62
|
-
return await doTest(
|
|
63
|
-
page, report, withItems, 'miniText', 'body, body *:not(script, style)', whats, 2, getBadWhat.toString()
|
|
64
|
-
);
|
|
58
|
+
};
|
|
59
|
+
const whats = 'Visible elements have font sizes smaller than 11 pixels';
|
|
60
|
+
return await (0, testaro_1.doTest)(page, report, withItems, 'miniText', 'body, body *:not(script, style)', whats, 2, getBadWhat.toString());
|
|
65
61
|
};
|
|
62
|
+
exports.reporter = reporter;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/*
|
|
2
|
+
© 2022–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
|
+
miniText
|
|
20
|
+
Derived from the bbc-a11y textCannotBeTooSmall test.
|
|
21
|
+
Related to Tenon rule 134.
|
|
22
|
+
This test reports elements with font sizes smaller than 11 pixels.
|
|
23
|
+
Compiled to miniText.js by tsc (issue #73); edit this file, not the emitted one.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
// FUNCTIONS
|
|
27
|
+
|
|
28
|
+
// Runs the test and returns the result.
|
|
29
|
+
export const reporter = async (page: Page, report: Report, _: unknown, withItems: boolean) => {
|
|
30
|
+
const getBadWhat: GetBadWhat = element => {
|
|
31
|
+
const rawText = element.textContent || '';
|
|
32
|
+
// If the element has text content with any non-whitespace:
|
|
33
|
+
if (/[^\s]/.test(rawText)) {
|
|
34
|
+
const isVisible = element.checkVisibility({
|
|
35
|
+
contentVisibilityAuto: true,
|
|
36
|
+
opacityProperty: true,
|
|
37
|
+
visibilityProperty: true
|
|
38
|
+
});
|
|
39
|
+
// If the element is visible:
|
|
40
|
+
if (isVisible) {
|
|
41
|
+
const styleDec = window.getComputedStyle(element);
|
|
42
|
+
// Get its font size.
|
|
43
|
+
const fontSizeString = styleDec.fontSize;
|
|
44
|
+
const fontSize = Number.parseFloat(fontSizeString);
|
|
45
|
+
// If its font size is smaller than 11 pixels:
|
|
46
|
+
if (fontSize < 11) {
|
|
47
|
+
const parent = element.parentElement;
|
|
48
|
+
// If the element has a parent:
|
|
49
|
+
if (parent) {
|
|
50
|
+
const parentStyleDec = window.getComputedStyle(parent);
|
|
51
|
+
const parentFontSize = Number.parseFloat(parentStyleDec.fontSize);
|
|
52
|
+
// If the parent also has a font size smaller than 11 pixels:
|
|
53
|
+
if (parentFontSize < 11) {
|
|
54
|
+
// Do not report a violation, because the font size may be inherited.
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Return a violation description.
|
|
59
|
+
return `Element is visible but its font size is ${fontSize}px, smaller than 11px`;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const whats = 'Visible elements have font sizes smaller than 11 pixels';
|
|
65
|
+
return await doTest(
|
|
66
|
+
page, report, withItems, 'miniText', 'body, body *:not(script, style)', whats, 2, getBadWhat.toString()
|
|
67
|
+
);
|
|
68
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Page } from 'playwright';
|
|
2
|
+
import type { Report, StandardInstance } from '../types';
|
|
3
|
+
export declare const reporter: (page: Page, report: Report) => Promise<{
|
|
4
|
+
data: {
|
|
5
|
+
prevented?: boolean;
|
|
6
|
+
error?: string;
|
|
7
|
+
};
|
|
8
|
+
totals: number[];
|
|
9
|
+
standardInstances: StandardInstance[];
|
|
10
|
+
}>;
|
package/testaro/motion.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
© 2026 Jeff Witt.
|
|
3
4
|
© 2025–2026 Jonathan Robert Pool.
|
|
4
5
|
Licensed under the MIT License. See LICENSE for details.
|
|
5
6
|
*/
|
|
6
|
-
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.reporter = void 0;
|
|
9
|
+
const xPath_1 = require("../procs/xPath");
|
|
10
|
+
const shoot_1 = require("../procs/shoot");
|
|
11
|
+
// pixelmatch and pngjs ship no bundled declarations, so their imports stay requires, untyped.
|
|
12
|
+
const pixelmatch = require('pixelmatch').default;
|
|
13
|
+
const { PNG } = require('pngjs');
|
|
7
14
|
/*
|
|
8
15
|
motion
|
|
9
16
|
This test reports motion in a page by making a page image and comparing it with the initial one, i.e. the one made by the catalog proc.
|
|
@@ -11,107 +18,96 @@
|
|
|
11
18
|
For minimal accessibility, standards require motion to be brief, or else stoppable by the user. But stopping motion can be difficult or impossible, and, by the time a user manages to stop motion, the motion may have caused annoyance or harm. For superior accessibility, a page contains no motion until and unless the user authorizes it. The test reports a rule violation if any pixels differ between the screenshots. The larger the change fraction, the greater the ordinal severity.
|
|
12
19
|
|
|
13
20
|
WARNING: The shoot test uses the procs/screenShot module. See the warning in that module about browser types.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
// IMPORTS
|
|
17
|
-
|
|
18
|
-
const {getXPathCatalogIndex} = require('../procs/xPath');
|
|
19
|
-
const {shoot} = require('../procs/shoot');
|
|
20
|
-
const pixelmatch = require('pixelmatch').default;
|
|
21
|
-
const {PNG} = require('pngjs');
|
|
22
21
|
|
|
22
|
+
Compiled to motion.js by tsc (issue #73); edit this file, not the emitted one.
|
|
23
|
+
*/
|
|
23
24
|
// FUNCTIONS
|
|
24
|
-
|
|
25
25
|
// Runs the test and returns the result.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
26
|
+
const reporter = async (page, report) => {
|
|
27
|
+
// Initialize the totals and standard instances.
|
|
28
|
+
const data = {};
|
|
29
|
+
const totals = [0, 0, 0, 0];
|
|
30
|
+
const standardInstances = [];
|
|
31
|
+
// Identify the image of the checkpoint being tested (images[0] for checkpoint 0).
|
|
32
|
+
const checkpointIndex = report.activeCheckpoint ?? 0;
|
|
33
|
+
const imageIndex = report.checkpoints?.[checkpointIndex]?.imageIndexes?.[0] ?? 0;
|
|
34
|
+
// If the initial image exists:
|
|
35
|
+
if (report.images?.[imageIndex] !== undefined) {
|
|
36
|
+
let violationWhat = '';
|
|
37
|
+
let ordinalSeverity = 0;
|
|
38
|
+
// Make an image with the same color type as the initial one and get its base64 encoding.
|
|
39
|
+
const png = await (0, shoot_1.shoot)(page, report, {
|
|
40
|
+
exclusionSelector: null,
|
|
41
|
+
colorType: report.imageColor,
|
|
42
|
+
action: 'return'
|
|
43
|
+
});
|
|
44
|
+
// If this succeeded:
|
|
45
|
+
if (png) {
|
|
46
|
+
// Parse both base64 encodings into PNG objects.
|
|
47
|
+
const initialPNG = PNG.sync.read(Buffer.from(report.images[imageIndex], 'base64'));
|
|
48
|
+
const finalPNG = PNG.sync.read(Buffer.from(png, 'base64'));
|
|
49
|
+
// If their dimensions differ:
|
|
50
|
+
if (finalPNG.width !== initialPNG.width || finalPNG.height !== initialPNG.height) {
|
|
51
|
+
const fromSize = `${initialPNG.width}×${initialPNG.height}`;
|
|
52
|
+
const toSize = `${finalPNG.width}×${finalPNG.height}`;
|
|
53
|
+
// Describe the violation.
|
|
54
|
+
violationWhat = `Page size changes spontaneously (from ${fromSize} to ${toSize})`;
|
|
55
|
+
}
|
|
56
|
+
// Otherwise, i.e. if their dimensions are identical:
|
|
57
|
+
else {
|
|
58
|
+
// Get the count of differing pixels between the images, using the default sensitivity.
|
|
59
|
+
try {
|
|
60
|
+
const pixelChanges = pixelmatch(initialPNG.data, finalPNG.data, null, initialPNG.width, initialPNG.height, {
|
|
61
|
+
threshold: 0.1
|
|
62
|
+
});
|
|
63
|
+
// Get the ratio of differing to all pixels as a percentage.
|
|
64
|
+
const changePercent = Math.round(100 * pixelChanges / (initialPNG.width * initialPNG.height));
|
|
65
|
+
// If any pixels were changed:
|
|
66
|
+
if (pixelChanges) {
|
|
67
|
+
// Describe the violation.
|
|
68
|
+
violationWhat = `Content changes spontaneously (${changePercent}% of pixels changed)`;
|
|
69
|
+
// Get the ordinal severity from the fractional pixel change.
|
|
70
|
+
ordinalSeverity = Math.floor(Math.min(3, 0.4 * Math.sqrt(changePercent)));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
console.log(`pixelmatch error: ${err.message}, ${err.stack}`);
|
|
75
|
+
data.prevented = true;
|
|
76
|
+
data.error = `Pixel comparison failed: ${err.message}`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// If there was a violation:
|
|
80
|
+
if (violationWhat) {
|
|
81
|
+
// Add to the totals.
|
|
82
|
+
totals[ordinalSeverity] = 1;
|
|
83
|
+
// Get a summary standard instance.
|
|
84
|
+
standardInstances.push({
|
|
85
|
+
ruleID: 'motion',
|
|
86
|
+
what: violationWhat,
|
|
87
|
+
ordinalSeverity: ordinalSeverity,
|
|
88
|
+
count: 1,
|
|
89
|
+
catalogIndex: (0, xPath_1.getXPathCatalogIndex)(report, '/html/body')
|
|
90
|
+
});
|
|
65
91
|
}
|
|
66
|
-
);
|
|
67
|
-
// Get the ratio of differing to all pixels as a percentage.
|
|
68
|
-
const changePercent = Math.round(
|
|
69
|
-
100 * pixelChanges / (initialPNG.width * initialPNG.height)
|
|
70
|
-
);
|
|
71
|
-
// If any pixels were changed:
|
|
72
|
-
if (pixelChanges) {
|
|
73
|
-
// Describe the violation.
|
|
74
|
-
violationWhat = `Content changes spontaneously (${changePercent}% of pixels changed)`;
|
|
75
|
-
// Get the ordinal severity from the fractional pixel change.
|
|
76
|
-
ordinalSeverity = Math.floor(Math.min(3, 0.4 * Math.sqrt(changePercent)));
|
|
77
|
-
}
|
|
78
|
-
} catch (err) {
|
|
79
|
-
console.log(`pixelmatch error: ${err.message}, ${err.stack}`);
|
|
80
|
-
data.prevented = true;
|
|
81
|
-
data.error = `Pixel comparison failed: ${err.message}`;
|
|
82
92
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
standardInstances.push({
|
|
90
|
-
ruleID: 'motion',
|
|
91
|
-
what: violationWhat,
|
|
92
|
-
ordinalSeverity,
|
|
93
|
-
count: 1,
|
|
94
|
-
catalogIndex: getXPathCatalogIndex(report, '/html/body')
|
|
95
|
-
});
|
|
96
|
-
}
|
|
93
|
+
// Otherwise, i.e. if it failed:
|
|
94
|
+
else {
|
|
95
|
+
// Report this.
|
|
96
|
+
data.prevented = true;
|
|
97
|
+
data.error = 'Image creation failed';
|
|
98
|
+
}
|
|
97
99
|
}
|
|
98
|
-
// Otherwise, i.e. if
|
|
100
|
+
// Otherwise, i.e. if the initial image does not exist:
|
|
99
101
|
else {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
// Report this.
|
|
103
|
+
data.prevented = true;
|
|
104
|
+
data.error = 'Initial image missing';
|
|
103
105
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
// Return the result.
|
|
112
|
-
return {
|
|
113
|
-
data,
|
|
114
|
-
totals,
|
|
115
|
-
standardInstances
|
|
116
|
-
};
|
|
106
|
+
// Return the result.
|
|
107
|
+
return {
|
|
108
|
+
data,
|
|
109
|
+
totals,
|
|
110
|
+
standardInstances
|
|
111
|
+
};
|
|
117
112
|
};
|
|
113
|
+
exports.reporter = reporter;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/*
|
|
2
|
+
© 2026 Jeff Witt.
|
|
3
|
+
© 2025–2026 Jonathan Robert Pool.
|
|
4
|
+
Licensed under the MIT License. See LICENSE for details.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// IMPORTS
|
|
8
|
+
|
|
9
|
+
import type {Page} from 'playwright';
|
|
10
|
+
import {getXPathCatalogIndex} from '../procs/xPath';
|
|
11
|
+
import {shoot} from '../procs/shoot';
|
|
12
|
+
import type {Report, StandardInstance} from '../types';
|
|
13
|
+
// pixelmatch and pngjs ship no bundled declarations, so their imports stay requires, untyped.
|
|
14
|
+
const pixelmatch = require('pixelmatch').default;
|
|
15
|
+
const {PNG} = require('pngjs');
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
motion
|
|
19
|
+
This test reports motion in a page by making a page image and comparing it with the initial one, i.e. the one made by the catalog proc.
|
|
20
|
+
|
|
21
|
+
For minimal accessibility, standards require motion to be brief, or else stoppable by the user. But stopping motion can be difficult or impossible, and, by the time a user manages to stop motion, the motion may have caused annoyance or harm. For superior accessibility, a page contains no motion until and unless the user authorizes it. The test reports a rule violation if any pixels differ between the screenshots. The larger the change fraction, the greater the ordinal severity.
|
|
22
|
+
|
|
23
|
+
WARNING: The shoot test uses the procs/screenShot module. See the warning in that module about browser types.
|
|
24
|
+
|
|
25
|
+
Compiled to motion.js by tsc (issue #73); edit this file, not the emitted one.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
// FUNCTIONS
|
|
29
|
+
|
|
30
|
+
// Runs the test and returns the result.
|
|
31
|
+
export const reporter = async (page: Page, report: Report) => {
|
|
32
|
+
// Initialize the totals and standard instances.
|
|
33
|
+
const data: {prevented?: boolean; error?: string} = {};
|
|
34
|
+
const totals = [0, 0, 0, 0];
|
|
35
|
+
const standardInstances: StandardInstance[] = [];
|
|
36
|
+
// Identify the image of the checkpoint being tested (images[0] for checkpoint 0).
|
|
37
|
+
const checkpointIndex = report.activeCheckpoint ?? 0;
|
|
38
|
+
const imageIndex = report.checkpoints?.[checkpointIndex]?.imageIndexes?.[0] ?? 0;
|
|
39
|
+
// If the initial image exists:
|
|
40
|
+
if (report.images?.[imageIndex] !== undefined) {
|
|
41
|
+
let violationWhat = '';
|
|
42
|
+
let ordinalSeverity = 0;
|
|
43
|
+
// Make an image with the same color type as the initial one and get its base64 encoding.
|
|
44
|
+
const png = await shoot(page, report, {
|
|
45
|
+
exclusionSelector: null,
|
|
46
|
+
colorType: report.imageColor,
|
|
47
|
+
action: 'return'
|
|
48
|
+
});
|
|
49
|
+
// If this succeeded:
|
|
50
|
+
if (png) {
|
|
51
|
+
// Parse both base64 encodings into PNG objects.
|
|
52
|
+
const initialPNG = PNG.sync.read(Buffer.from(report.images[imageIndex], 'base64'));
|
|
53
|
+
const finalPNG = PNG.sync.read(Buffer.from(png, 'base64'));
|
|
54
|
+
// If their dimensions differ:
|
|
55
|
+
if (finalPNG.width !== initialPNG.width || finalPNG.height !== initialPNG.height) {
|
|
56
|
+
const fromSize = `${initialPNG.width}×${initialPNG.height}`;
|
|
57
|
+
const toSize = `${finalPNG.width}×${finalPNG.height}`;
|
|
58
|
+
// Describe the violation.
|
|
59
|
+
violationWhat = `Page size changes spontaneously (from ${fromSize} to ${toSize})`;
|
|
60
|
+
}
|
|
61
|
+
// Otherwise, i.e. if their dimensions are identical:
|
|
62
|
+
else {
|
|
63
|
+
// Get the count of differing pixels between the images, using the default sensitivity.
|
|
64
|
+
try {
|
|
65
|
+
const pixelChanges = pixelmatch(
|
|
66
|
+
initialPNG.data,
|
|
67
|
+
finalPNG.data,
|
|
68
|
+
null,
|
|
69
|
+
initialPNG.width,
|
|
70
|
+
initialPNG.height,
|
|
71
|
+
{
|
|
72
|
+
threshold: 0.1
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
// Get the ratio of differing to all pixels as a percentage.
|
|
76
|
+
const changePercent = Math.round(
|
|
77
|
+
100 * pixelChanges / (initialPNG.width * initialPNG.height)
|
|
78
|
+
);
|
|
79
|
+
// If any pixels were changed:
|
|
80
|
+
if (pixelChanges) {
|
|
81
|
+
// Describe the violation.
|
|
82
|
+
violationWhat = `Content changes spontaneously (${changePercent}% of pixels changed)`;
|
|
83
|
+
// Get the ordinal severity from the fractional pixel change.
|
|
84
|
+
ordinalSeverity = Math.floor(Math.min(3, 0.4 * Math.sqrt(changePercent)));
|
|
85
|
+
}
|
|
86
|
+
} catch (err) {
|
|
87
|
+
console.log(`pixelmatch error: ${(err as Error).message}, ${(err as Error).stack}`);
|
|
88
|
+
data.prevented = true;
|
|
89
|
+
data.error = `Pixel comparison failed: ${(err as Error).message}`;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// If there was a violation:
|
|
93
|
+
if (violationWhat) {
|
|
94
|
+
// Add to the totals.
|
|
95
|
+
totals[ordinalSeverity] = 1;
|
|
96
|
+
// Get a summary standard instance.
|
|
97
|
+
standardInstances.push({
|
|
98
|
+
ruleID: 'motion',
|
|
99
|
+
what: violationWhat,
|
|
100
|
+
ordinalSeverity: ordinalSeverity as StandardInstance['ordinalSeverity'],
|
|
101
|
+
count: 1,
|
|
102
|
+
catalogIndex: getXPathCatalogIndex(report, '/html/body')
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Otherwise, i.e. if it failed:
|
|
107
|
+
else {
|
|
108
|
+
// Report this.
|
|
109
|
+
data.prevented = true;
|
|
110
|
+
data.error = 'Image creation failed';
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Otherwise, i.e. if the initial image does not exist:
|
|
114
|
+
else {
|
|
115
|
+
// Report this.
|
|
116
|
+
data.prevented = true;
|
|
117
|
+
data.error = 'Initial image missing';
|
|
118
|
+
}
|
|
119
|
+
// Return the result.
|
|
120
|
+
return {
|
|
121
|
+
data,
|
|
122
|
+
totals,
|
|
123
|
+
standardInstances
|
|
124
|
+
};
|
|
125
|
+
};
|
package/testaro/nonTable.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
© 2022–2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
4
|
© 2026 Jeff Witt.
|
|
@@ -7,56 +8,49 @@
|
|
|
7
8
|
|
|
8
9
|
SPDX-License-Identifier: MIT
|
|
9
10
|
*/
|
|
10
|
-
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.reporter = void 0;
|
|
13
|
+
const testaro_1 = require("../procs/testaro");
|
|
11
14
|
/*
|
|
12
15
|
nonTable
|
|
13
16
|
Derived from the bbc-a11y useTablesForData test. Crude heuristics omitted.
|
|
14
17
|
This test reports tables used for layout.
|
|
18
|
+
Compiled to nonTable.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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
};
|
|
58
|
-
const whats = 'table elements are misused for non-table content';
|
|
59
|
-
return await doTest(
|
|
60
|
-
page, report, withItems, 'nonTable', 'body table', whats, 2, getBadWhat.toString()
|
|
61
|
-
);
|
|
22
|
+
const reporter = async (page, report, _, withItems) => {
|
|
23
|
+
// The candidate selector yields table elements.
|
|
24
|
+
const getBadWhat = (element) => {
|
|
25
|
+
// If the element contains another table:
|
|
26
|
+
if (element.querySelector('table')) {
|
|
27
|
+
// Return a violation description.
|
|
28
|
+
return 'Element contains another table';
|
|
29
|
+
}
|
|
30
|
+
const rowCount = element.querySelectorAll('tr').length;
|
|
31
|
+
const columnCount = Math.max(...Array
|
|
32
|
+
.from(element.querySelectorAll('tr'))
|
|
33
|
+
.map(row => Array.from(row.querySelectorAll('th, td')).length));
|
|
34
|
+
// Otherwise, if it has only 1 column or 1 row:
|
|
35
|
+
if (rowCount === 1 || columnCount === 1) {
|
|
36
|
+
// Return a violation description.
|
|
37
|
+
return 'Element has only one row or one column';
|
|
38
|
+
}
|
|
39
|
+
// Otherwise, if it contains an object or player:
|
|
40
|
+
if (element.querySelector('object, embed, applet, audio, video')) {
|
|
41
|
+
// Return a violation description.
|
|
42
|
+
return 'Element contains an object or player';
|
|
43
|
+
}
|
|
44
|
+
const role = element.getAttribute('role');
|
|
45
|
+
// Otherwise, if it has no table-compatible explicit role or descendant element:
|
|
46
|
+
if (!(['grid', 'treegrid'].includes(role)
|
|
47
|
+
|| element.caption
|
|
48
|
+
|| element.querySelector('col, colgroup, tfoot, th, thead'))) {
|
|
49
|
+
// Return a violation description.
|
|
50
|
+
return 'Element has no table-compatible explicit role or descendant element';
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const whats = 'table elements are misused for non-table content';
|
|
54
|
+
return await (0, testaro_1.doTest)(page, report, withItems, 'nonTable', 'body table', whats, 2, getBadWhat.toString());
|
|
62
55
|
};
|
|
56
|
+
exports.reporter = reporter;
|