testaro 78.0.6 → 78.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/.gitattributes +94 -0
  2. package/.github/workflows/ci.yml +58 -0
  3. package/.github/workflows/publish.yml +49 -0
  4. package/.github/workflows/typescript.yml +35 -0
  5. package/AGENTS.md +2 -2
  6. package/CLAUDE.md +25 -19
  7. package/CONTAINERS.md +10 -6
  8. package/CONTRIBUTING.md +29 -3
  9. package/Dockerfile +1 -1
  10. package/README.md +75 -20
  11. package/UPGRADES.md +4 -0
  12. package/actSpecs-doc.md +13 -1
  13. package/actSpecs.js +29 -5
  14. package/call.js +6 -5
  15. package/docker-compose.yml +8 -2
  16. package/docs/checkpoint-scanning.md +199 -0
  17. package/docs/standard-result-outcome.md +165 -0
  18. package/env.example +44 -10
  19. package/eslint.config.mjs +101 -0
  20. package/netWatch.js +373 -222
  21. package/package.json +46 -31
  22. package/pour/README.md +47 -0
  23. package/pour/pour.min.js +8 -0
  24. package/procs/actDo.js +808 -0
  25. package/procs/catalog.d.ts +17 -0
  26. package/procs/catalog.js +313 -221
  27. package/procs/catalog.ts +398 -0
  28. package/procs/checkpoint.js +110 -0
  29. package/procs/config.d.ts +35 -0
  30. package/procs/config.js +63 -0
  31. package/procs/dateTime.js +2 -1
  32. package/procs/doActs.js +442 -849
  33. package/procs/doTestAct.js +27 -121
  34. package/procs/flow.js +221 -0
  35. package/procs/generateRuleRegistry.js +94 -0
  36. package/procs/getSource.d.ts +26 -0
  37. package/procs/getSource.js +1 -0
  38. package/procs/job.js +116 -1
  39. package/procs/launch.d.ts +40 -0
  40. package/procs/launch.js +239 -108
  41. package/procs/nu.d.ts +48 -0
  42. package/procs/nu.js +1 -0
  43. package/procs/scope.js +196 -0
  44. package/procs/shoot.d.ts +33 -0
  45. package/procs/shoot.js +3 -1
  46. package/procs/standard.d.ts +18 -0
  47. package/procs/standard.js +83 -0
  48. package/procs/standard.ts +126 -0
  49. package/procs/testAct.js +145 -0
  50. package/procs/testaro.d.ts +20 -0
  51. package/procs/testaro.js +237 -189
  52. package/procs/testaro.ts +321 -0
  53. package/procs/userPath.js +126 -0
  54. package/procs/xPath.d.ts +4 -0
  55. package/procs/xPath.js +82 -64
  56. package/procs/xPath.ts +106 -0
  57. package/procs/xPathScript.d.ts +6 -0
  58. package/procs/xPathScript.js +70 -0
  59. package/run.js +3 -2
  60. package/surea11y/README.md +44 -0
  61. package/surea11y/surea11y.browser.js +14 -0
  62. package/testaro/adbID.d.ts +3 -0
  63. package/testaro/adbID.js +39 -41
  64. package/testaro/adbID.ts +66 -0
  65. package/testaro/allCapStyle.d.ts +3 -0
  66. package/testaro/allCapStyle.js +32 -34
  67. package/testaro/allCapStyle.ts +55 -0
  68. package/testaro/allCaps.d.ts +16 -0
  69. package/testaro/allCaps.js +179 -151
  70. package/testaro/allCaps.ts +228 -0
  71. package/testaro/allHidden.d.ts +13 -0
  72. package/testaro/allHidden.js +30 -30
  73. package/testaro/allHidden.ts +50 -0
  74. package/testaro/allSlanted.d.ts +3 -0
  75. package/testaro/allSlanted.js +31 -33
  76. package/testaro/allSlanted.ts +54 -0
  77. package/testaro/altScheme.d.ts +3 -0
  78. package/testaro/altScheme.js +28 -30
  79. package/testaro/altScheme.ts +50 -0
  80. package/testaro/attVal.d.ts +3 -0
  81. package/testaro/attVal.js +21 -21
  82. package/testaro/attVal.ts +52 -0
  83. package/testaro/autocomplete.d.ts +3 -0
  84. package/testaro/autocomplete.js +60 -75
  85. package/testaro/autocomplete.ts +101 -0
  86. package/testaro/bulk.d.ts +13 -0
  87. package/testaro/bulk.js +33 -33
  88. package/testaro/bulk.ts +55 -0
  89. package/testaro/buttonMenu.d.ts +9 -0
  90. package/testaro/buttonMenu.js +318 -319
  91. package/testaro/buttonMenu.ts +391 -0
  92. package/testaro/captionLoc.d.ts +3 -0
  93. package/testaro/captionLoc.js +18 -20
  94. package/testaro/captionLoc.ts +40 -0
  95. package/testaro/datalistRef.d.ts +3 -0
  96. package/testaro/datalistRef.js +34 -36
  97. package/testaro/datalistRef.ts +55 -0
  98. package/testaro/distortion.d.ts +3 -0
  99. package/testaro/distortion.js +58 -26
  100. package/testaro/distortion.ts +81 -0
  101. package/testaro/docType.d.ts +15 -0
  102. package/testaro/docType.js +26 -25
  103. package/testaro/docType.ts +45 -0
  104. package/testaro/dupAtt.d.ts +16 -0
  105. package/testaro/dupAtt.js +114 -104
  106. package/testaro/dupAtt.ts +144 -0
  107. package/testaro/elements.d.ts +6 -0
  108. package/testaro/elements.js +153 -153
  109. package/testaro/elements.ts +215 -0
  110. package/testaro/embAc.d.ts +3 -0
  111. package/testaro/embAc.js +20 -20
  112. package/testaro/embAc.ts +40 -0
  113. package/testaro/focAll.d.ts +13 -0
  114. package/testaro/focAll.js +186 -191
  115. package/testaro/focAll.ts +217 -0
  116. package/testaro/focAndOp.d.ts +3 -0
  117. package/testaro/focAndOp.js +101 -104
  118. package/testaro/focAndOp.ts +128 -0
  119. package/testaro/focInd.d.ts +3 -0
  120. package/testaro/focInd.js +65 -66
  121. package/testaro/focInd.ts +96 -0
  122. package/testaro/focVis.d.ts +3 -0
  123. package/testaro/focVis.js +29 -30
  124. package/testaro/focVis.ts +52 -0
  125. package/testaro/headEl.d.ts +10 -0
  126. package/testaro/headEl.js +62 -62
  127. package/testaro/headEl.ts +82 -0
  128. package/testaro/headingAmb.d.ts +3 -0
  129. package/testaro/headingAmb.js +55 -63
  130. package/testaro/headingAmb.ts +72 -0
  131. package/testaro/hovInd.d.ts +12 -0
  132. package/testaro/hovInd.js +164 -130
  133. package/testaro/hovInd.ts +199 -0
  134. package/testaro/hover.d.ts +3 -0
  135. package/testaro/hover.js +156 -126
  136. package/testaro/hover.ts +154 -0
  137. package/testaro/hr.d.ts +3 -0
  138. package/testaro/hr.js +15 -17
  139. package/testaro/hr.ts +36 -0
  140. package/testaro/imageLink.d.ts +3 -0
  141. package/testaro/imageLink.js +18 -20
  142. package/testaro/imageLink.ts +42 -0
  143. package/testaro/labClash.d.ts +3 -0
  144. package/testaro/labClash.js +32 -33
  145. package/testaro/labClash.ts +54 -0
  146. package/testaro/legendLoc.d.ts +3 -0
  147. package/testaro/legendLoc.js +18 -20
  148. package/testaro/legendLoc.ts +42 -0
  149. package/testaro/lineHeight.d.ts +3 -0
  150. package/testaro/lineHeight.js +44 -48
  151. package/testaro/lineHeight.ts +70 -0
  152. package/testaro/linkAmb.d.ts +7 -0
  153. package/testaro/linkAmb.js +80 -80
  154. package/testaro/linkAmb.ts +105 -0
  155. package/testaro/linkExt.d.ts +3 -0
  156. package/testaro/linkExt.js +14 -16
  157. package/testaro/linkExt.ts +35 -0
  158. package/testaro/linkOldAtt.d.ts +3 -0
  159. package/testaro/linkOldAtt.js +26 -28
  160. package/testaro/linkOldAtt.ts +48 -0
  161. package/testaro/linkTo.d.ts +3 -0
  162. package/testaro/linkTo.js +23 -22
  163. package/testaro/linkTo.ts +43 -0
  164. package/testaro/linkUl.d.ts +3 -0
  165. package/testaro/linkUl.js +31 -34
  166. package/testaro/linkUl.ts +54 -0
  167. package/testaro/miniText.d.ts +3 -0
  168. package/testaro/miniText.js +42 -44
  169. package/testaro/miniText.ts +68 -0
  170. package/testaro/motion.d.ts +10 -0
  171. package/testaro/motion.js +93 -96
  172. package/testaro/motion.ts +125 -0
  173. package/testaro/nonTable.d.ts +3 -0
  174. package/testaro/nonTable.js +40 -45
  175. package/testaro/nonTable.ts +66 -0
  176. package/testaro/optRoleSel.d.ts +3 -0
  177. package/testaro/optRoleSel.js +17 -19
  178. package/testaro/optRoleSel.ts +41 -0
  179. package/testaro/phOnly.d.ts +3 -0
  180. package/testaro/phOnly.js +19 -21
  181. package/testaro/phOnly.ts +43 -0
  182. package/testaro/pseudoP.d.ts +3 -0
  183. package/testaro/pseudoP.js +37 -38
  184. package/testaro/pseudoP.ts +59 -0
  185. package/testaro/radioSet.d.ts +3 -0
  186. package/testaro/radioSet.js +58 -59
  187. package/testaro/radioSet.ts +79 -0
  188. package/testaro/registry.d.ts +63 -0
  189. package/testaro/registry.js +67 -0
  190. package/testaro/registry.ts +141 -0
  191. package/testaro/role.d.ts +3 -0
  192. package/testaro/role.js +28 -29
  193. package/testaro/role.ts +53 -0
  194. package/testaro/secHeading.d.ts +3 -0
  195. package/testaro/secHeading.js +31 -33
  196. package/testaro/secHeading.ts +53 -0
  197. package/testaro/styleDiff.d.ts +25 -0
  198. package/testaro/styleDiff.js +249 -252
  199. package/testaro/styleDiff.ts +303 -0
  200. package/testaro/tabNav.d.ts +33 -0
  201. package/testaro/tabNav.js +273 -342
  202. package/testaro/tabNav.ts +454 -0
  203. package/testaro/targetsNear.d.ts +9 -0
  204. package/testaro/targetsNear.js +131 -132
  205. package/testaro/targetsNear.ts +160 -0
  206. package/testaro/textNodes.d.ts +6 -0
  207. package/testaro/textNodes.js +139 -135
  208. package/testaro/textNodes.ts +185 -0
  209. package/testaro/textSem.d.ts +3 -0
  210. package/testaro/textSem.js +26 -28
  211. package/testaro/textSem.ts +47 -0
  212. package/testaro/title.d.ts +9 -0
  213. package/testaro/title.js +16 -13
  214. package/testaro/title.ts +31 -0
  215. package/testaro/titledEl.d.ts +3 -0
  216. package/testaro/titledEl.js +16 -18
  217. package/testaro/titledEl.ts +38 -0
  218. package/testaro/zIndex.d.ts +3 -0
  219. package/testaro/zIndex.js +20 -22
  220. package/testaro/zIndex.ts +42 -0
  221. package/tests/alfa.d.ts +45 -0
  222. package/tests/alfa.js +139 -141
  223. package/tests/alfa.ts +214 -0
  224. package/tests/aslint.d.ts +33 -0
  225. package/tests/aslint.js +273 -249
  226. package/tests/aslint.ts +301 -0
  227. package/tests/axe.d.ts +27 -0
  228. package/tests/axe.js +200 -200
  229. package/tests/axe.ts +277 -0
  230. package/tests/ed11y.d.ts +28 -0
  231. package/tests/ed11y.js +142 -99
  232. package/tests/ed11y.ts +178 -0
  233. package/tests/htmlcs.d.ts +21 -0
  234. package/tests/htmlcs.js +175 -140
  235. package/tests/htmlcs.ts +181 -0
  236. package/tests/ibm.d.ts +52 -0
  237. package/tests/ibm.js +165 -166
  238. package/tests/ibm.ts +251 -0
  239. package/tests/nuVal.d.ts +13 -0
  240. package/tests/nuVal.js +107 -112
  241. package/tests/nuVal.ts +145 -0
  242. package/tests/nuVnu.d.ts +15 -0
  243. package/tests/nuVnu.js +142 -111
  244. package/tests/nuVnu.ts +144 -0
  245. package/tests/pour.d.ts +31 -0
  246. package/tests/pour.js +242 -0
  247. package/tests/pour.ts +273 -0
  248. package/tests/qualWeb.d.ts +39 -0
  249. package/tests/qualWeb.js +303 -272
  250. package/tests/qualWeb.ts +415 -0
  251. package/tests/surea11y.d.ts +33 -0
  252. package/tests/surea11y.js +288 -0
  253. package/tests/surea11y.ts +334 -0
  254. package/tests/testaro.d.ts +25 -0
  255. package/tests/testaro.js +746 -652
  256. package/tests/testaro.ts +862 -0
  257. package/tests/wave.d.ts +46 -0
  258. package/tests/wave.js +167 -177
  259. package/tests/wave.ts +252 -0
  260. package/tsconfig.json +17 -0
  261. package/types.d.ts +243 -0
  262. package/types.js +10 -0
  263. package/types.ts +376 -0
  264. package/validation/act/README.md +46 -0
  265. package/validation/act/capture.js +424 -0
  266. package/validation/act/chromium-issue-draft.md +66 -0
  267. package/validation/act/fp-triage-2026-08-22.md +86 -0
  268. package/validation/act/isolation-notes.md +159 -0
  269. package/validation/act/playwright-issue-draft.md +73 -0
  270. package/validation/act/propose-mappings.js +0 -0
  271. package/validation/act/repro-cdp-raw.js +105 -0
  272. package/validation/act/repro-metarefresh.js +65 -0
  273. package/validation/act/score.js +184 -0
  274. package/validation/act/stage3a-stress-report.md +69 -0
  275. package/validation/act/stage3b-mapping-proposals.md +94 -0
  276. package/validation/act/stage3b-triage-draft.md +138 -0
  277. package/validation/act/surea11y-track-a-2026-09-01.md +50 -0
  278. package/validation/executors/netWatch.js +180 -90
  279. package/validation/executors/test.js +17 -2
  280. package/validation/executors/tests.js +118 -10
  281. package/validation/jobs/reports/raw/260901T1000-surea11y-validation.json +964 -0
  282. package/validation/jobs/todo/240101T1200-simple-example.json +14 -6
  283. package/validation/jobs/todo/240101T1300-shoot-example.json +2 -1
  284. package/validation/jobs/todo/260821T1900-pour-validation.json +45 -0
  285. package/validation/jobs/todo/260901T1000-surea11y-validation.json +45 -0
  286. package/validation/knownFailures.json +1 -0
  287. package/validation/tests/jobProperties/adbID.json +27 -2
  288. package/validation/tests/jobProperties/{focOp.json → allCapStyle.json} +56 -53
  289. package/validation/tests/jobProperties/allCaps.json +25 -0
  290. package/validation/tests/jobProperties/allHidden.json +133 -13
  291. package/validation/tests/jobProperties/allSlanted.json +3 -3
  292. package/validation/tests/jobProperties/altScheme.json +23 -8
  293. package/validation/tests/jobProperties/attVal.json +57 -57
  294. package/validation/tests/jobProperties/autocomplete.json +11 -1
  295. package/validation/tests/jobProperties/bulk.json +6 -1
  296. package/validation/tests/jobProperties/buttonMenu.json +63 -42
  297. package/validation/tests/jobProperties/captionLoc.json +1 -6
  298. package/validation/tests/jobProperties/checkpoint-browser.json +401 -0
  299. package/validation/tests/jobProperties/checkpoint-page.json +397 -0
  300. package/validation/tests/jobProperties/checkpoint.json +395 -0
  301. package/validation/tests/jobProperties/datalistRef.json +20 -5
  302. package/validation/tests/jobProperties/distortion.json +28 -3
  303. package/validation/tests/jobProperties/docType.json +2 -2
  304. package/validation/tests/jobProperties/dupAtt.json +48 -33
  305. package/validation/tests/jobProperties/elements.json +28 -28
  306. package/validation/tests/jobProperties/embAc.json +36 -31
  307. package/validation/tests/jobProperties/focAndOp.json +284 -0
  308. package/validation/tests/jobProperties/focInd.json +34 -34
  309. package/validation/tests/jobProperties/focVis.json +1 -1
  310. package/validation/tests/jobProperties/hover.json +39 -37
  311. package/validation/tests/jobProperties/hr.json +13 -3
  312. package/validation/tests/jobProperties/imageLink.json +0 -5
  313. package/validation/tests/jobProperties/labClash.json +68 -33
  314. package/validation/tests/jobProperties/legendLoc.json +1 -6
  315. package/validation/tests/jobProperties/lineHeight.json +2 -2
  316. package/validation/tests/jobProperties/linkAmb.json +13 -18
  317. package/validation/tests/jobProperties/linkExt.json +1 -1
  318. package/validation/tests/jobProperties/linkOldAtt.json +12 -2
  319. package/validation/tests/jobProperties/linkTo.json +1 -1
  320. package/validation/tests/jobProperties/linkUl.json +65 -65
  321. package/validation/tests/jobProperties/miniText.json +7 -2
  322. package/validation/tests/jobProperties/motion.json +4 -50
  323. package/validation/tests/jobProperties/nonTable.json +48 -3
  324. package/validation/tests/jobProperties/optRoleSel.json +12 -2
  325. package/validation/tests/jobProperties/phOnly.json +6 -16
  326. package/validation/tests/jobProperties/pseudoP.json +17 -2
  327. package/validation/tests/jobProperties/radioSet.json +30 -30
  328. package/validation/tests/jobProperties/role.json +25 -5
  329. package/validation/tests/jobProperties/secHeading.json +26 -21
  330. package/validation/tests/jobProperties/styleDiff.json +35 -5
  331. package/validation/tests/jobProperties/tabNav.json +3 -1
  332. package/validation/tests/jobProperties/targetsNear.json +237 -0
  333. package/validation/tests/jobProperties/textNodes.json +29 -29
  334. package/validation/tests/jobProperties/textSem.json +26 -1
  335. package/validation/tests/jobProperties/title.json +12 -2
  336. package/validation/tests/jobProperties/titledEl.json +39 -9
  337. package/validation/tests/jobProperties/userPath.json +317 -0
  338. package/validation/tests/jobProperties/zIndex.json +40 -35
  339. package/validation/tests/targets/allCapStyle/index.html +26 -0
  340. package/validation/tests/targets/checkpoint/index.html +38 -0
  341. package/validation/tests/targets/datalistRef/index.html +1 -1
  342. package/validation/tests/targets/focAndOp/bad.html +29 -0
  343. package/validation/tests/targets/{focOp → focAndOp}/good.html +3 -1
  344. package/validation/tests/targets/focInd/bad.html +2 -1
  345. package/validation/tests/targets/headEl/index.html +10 -1
  346. package/validation/tests/targets/{targetSmall → targetsNear}/index.html +15 -1
  347. package/validation/tests/targets/userPath/index.html +42 -0
  348. package/validation/validateTest.js +62 -10
  349. package/.claude/settings.local.json +0 -11
  350. package/.eslintrc.json +0 -41
  351. package/htmlcs/.eslintrc.json +0 -67
  352. package/memory/MEMORY.md +0 -3
  353. package/memory/project_validation_pause.md +0 -10
  354. package/validation/tests/jobProperties/linkTitle.json +0 -127
  355. package/validation/tests/jobProperties/opFoc.json +0 -164
  356. package/validation/tests/jobProperties/targetSmall.json +0 -152
  357. package/validation/tests/jobProperties/targetTiny.json +0 -142
  358. package/validation/tests/targets/focOp/bad.html +0 -25
  359. package/validation/tests/targets/linkTitle/index.html +0 -24
  360. package/validation/tests/targets/opFoc/bad.html +0 -26
  361. package/validation/tests/targets/opFoc/good.html +0 -23
@@ -1,5 +1,7 @@
1
+ "use strict";
1
2
  /*
2
3
  © 2023 CVS Health and/or one of its affiliates. All rights reserved.
4
+ © 2026 Jeff Witt.
3
5
  © 2025–2026 Jonathan Robert Pool.
4
6
 
5
7
  Licensed under the MIT License. See LICENSE file at the project root or
@@ -7,90 +9,73 @@
7
9
 
8
10
  SPDX-License-Identifier: MIT
9
11
  */
10
-
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.reporter = void 0;
14
+ const testaro_1 = require("../procs/testaro");
11
15
  /*
12
16
  autocomplete
13
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.
14
19
  */
15
-
16
- // IMPORTS
17
-
18
- const {doTest} = require('../procs/testaro');
19
-
20
20
  // FUNCTIONS
21
-
22
21
  // Runs the test and returns the result.
23
- exports.reporter = async (
24
- page,
25
- report,
26
- _0,
27
- withItems,
28
- labels = {
22
+ const reporter = async (page, report, _0, withItems, labels = {
29
23
  name: ['your name', 'full name', 'first and last name'],
30
24
  email: ['email'],
31
25
  given: ['first name', 'forename', 'given name'],
32
26
  family: ['last name', 'surname', 'family name']
33
- }
34
- ) => {
35
- const getBadWhat = element => {
36
- // Get the lower-cased accessible name of the element.
37
- const accessibleName = window.getAccessibleName(element).toLowerCase();
38
- const {type} = element;
39
- let requiredAuto = '';
40
- const labels = {
41
- name: ['__nameLabels__'],
42
- email: ['__emailLabels__'],
43
- given: ['__givenLabels__'],
44
- family: ['__familyLabels__']
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
+ }
45
65
  };
46
- // Get its required autocomplete value.
47
- if (
48
- type === 'email'
49
- || accessibleName && labels.email.some(label => accessibleName.includes(label))
50
- ) {
51
- requiredAuto = 'email';
52
- }
53
- else if (
54
- accessibleName && type === 'text' && labels.name.some(label => accessibleName.includes(label))
55
- ) {
56
- requiredAuto = 'name';
57
- }
58
- else if (
59
- accessibleName
60
- && type === 'text'
61
- && labels.given.some(label => accessibleName.includes(label))
62
- ) {
63
- requiredAuto = 'given-name';
64
- }
65
- else if (
66
- accessibleName
67
- && type === 'text'
68
- && labels.family.some(label => accessibleName.includes(label))
69
- ) {
70
- requiredAuto = 'family-name';
71
- }
72
- // Get its actual autocomplete value.
73
- const actualAuto = element.getAttribute('autocomplete');
74
- // If an autocomplete value is required but not present:
75
- if (requiredAuto && ! (actualAuto && actualAuto.includes(requiredAuto))) {
76
- // Return a violation description.
77
- return `input has no autocomplete="${requiredAuto}" attribute`;
78
- }
79
- };
80
- const selector = 'body input[type=text], body input[type=email], body input:not([type])';
81
- const whats = 'Inputs are missing required autocomplete attributes';
82
- // Each placeholder sits inside single quotes in getBadWhat (e.g. name: ['__nameLabels__']).
83
- // Replace the quoted placeholder with the bracket-stripped JSON so the result is a proper
84
- // element list (name: ["your name", ...]) rather than a one-element array holding the JSON
85
- // text of the array (name: ['["your name", ...]']), which never matches an accessible name.
86
- const placeHolders = Object.keys(labels).map(key => `'__${key}Labels__'`);
87
- const replacers = Object.values(labels).map(value => JSON.stringify(value).slice(1, -1));
88
- // Create a stringified getBadWhat, with placeholders replaced with the specified label arrays.
89
- let getBadWhatString = getBadWhat.toString();
90
- [0, 1, 2, 3].forEach(index => {
91
- getBadWhatString = getBadWhatString.replace(placeHolders[index], replacers[index]);
92
- });
93
- return doTest(
94
- page, report, withItems, 'autocomplete', selector, whats, 2, getBadWhatString
95
- );
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);
96
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,5 +1,7 @@
1
+ "use strict";
1
2
  /*
2
3
  © 2021–2023 CVS Health and/or one of its affiliates. All rights reserved.
4
+ © 2026 Jeff Witt.
3
5
  © 2025–2026 Jonathan Robert Pool.
4
6
 
5
7
  Licensed under the MIT License. See LICENSE file at the project root or
@@ -7,45 +9,43 @@
7
9
 
8
10
  SPDX-License-Identifier: MIT
9
11
  */
10
-
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.reporter = void 0;
14
+ const xPath_1 = require("../procs/xPath");
11
15
  /*
12
16
  bulk
13
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.
14
19
  */
15
-
16
- // IMPORTS
17
-
18
- const {getXPathCatalogIndex} = require('../procs/xPath');
19
-
20
20
  // FUNCTIONS
21
-
22
21
  // Runs the test and returns the result.
23
- exports.reporter = async (page, report) => {
24
- // Get a count of elements deemed visible by Playwright.
25
- const visibleElementCount = await page.locator('body :visible').count();
26
- // Convert the count to a severity level, treating up to 400 as non-reportable.
27
- const severity = Math.min(4, Math.round(visibleElementCount / 400)) - 1;
28
- const totals = [0, 0, 0, 0];
29
- // If the severity is reportable:
30
- if (severity > -1) {
31
- totals[severity] = 1;
32
- // Return data, totals, and a summary standard instance.
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.
33
45
  return {
34
- data: {},
35
- totals,
36
- standardInstances: [{
37
- ruleID: 'bulk',
38
- what: `Page contains ${visibleElementCount} visible elements`,
39
- ordinalSeverity: severity,
40
- count: 1,
41
- catalogIndex: getXPathCatalogIndex(report, '/html')
42
- }]
46
+ data: {},
47
+ totals,
48
+ standardInstances: []
43
49
  };
44
- }
45
- // Otherwise, return data, totals, and an empty array of standard instances.
46
- return {
47
- data: {},
48
- totals,
49
- standardInstances: []
50
- };
51
50
  };
51
+ exports.reporter = reporter;
@@ -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
+ }>;