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
@@ -0,0 +1,215 @@
1
+ /*
2
+ © 2023 CVS Health and/or one of its affiliates. All rights reserved.
3
+ © 2026 Jonathan Robert Pool.
4
+
5
+ Licensed under the MIT License. See LICENSE file at the project root or https://opensource.org/license/mit/ for details.
6
+
7
+ SPDX-License-Identifier: MIT
8
+ */
9
+
10
+ // IMPORTS
11
+
12
+ import type {Page} from 'playwright';
13
+
14
+ // TYPES
15
+
16
+ // Data on one attribute of an element.
17
+ interface AttributeDatum {
18
+ name: string;
19
+ value: string;
20
+ }
21
+ // Data on one sibling node of an element.
22
+ interface SibInfo {
23
+ type: number;
24
+ tagName?: string;
25
+ attributes?: AttributeDatum[];
26
+ text?: string;
27
+ }
28
+ // Data on one specified element.
29
+ interface ElementDatum {
30
+ tagName: string;
31
+ parentTagName: string;
32
+ code: string;
33
+ attributes: AttributeDatum[];
34
+ textContent: string;
35
+ labelers?: string[];
36
+ labels?: string[];
37
+ parentTextContent?: string;
38
+ siblings?: {before: SibInfo[]; after: SibInfo[]};
39
+ }
40
+
41
+ /*
42
+ elements
43
+ This test reports data about specified elements within the document body. Meanings of detailLevel values:
44
+ 0. Only total element count; no detail.
45
+ 1. Also data on each specified element.
46
+ 2. Data on each specified element also include the text content of the parent element.
47
+ 3. Data on each specified element also include data on its sibling nodes.
48
+ Compiled to elements.js by tsc (issue #73); edit this file, not the emitted one.
49
+ */
50
+
51
+ // FUNCTIONS
52
+
53
+ export const reporter = async (
54
+ page: Page,
55
+ _0: unknown,
56
+ _1: unknown,
57
+ _2: unknown,
58
+ detailLevel = 0,
59
+ tagName: string | null = null,
60
+ onlyVisible = false,
61
+ attribute?: string
62
+ ) => {
63
+ // Determine a selector of the specified elements, including any descendants of open shadow roots.
64
+ let selector = `body ${tagName ? tagName.toLowerCase() : '*'}`;
65
+ if (attribute) {
66
+ selector += `[${attribute}]`;
67
+ }
68
+ if (onlyVisible) {
69
+ selector += ':visible';
70
+ }
71
+ let data: Record<string, unknown> = {};
72
+ // Get the data on the elements.
73
+ try {
74
+ const locator = page.locator(selector);
75
+ data = await locator.evaluateAll((elements, detailLevel) => {
76
+ // FUNCTION DEFINITIONS START
77
+ // Compacts a string.
78
+ const compact = (string: string) => string.replace(/\s+/g, ' ').trim();
79
+ // Gets data on a sibling node of an element.
80
+ const getSibInfo = (node: Node, nodeType: number, text: string | null) => {
81
+ const sibInfo: SibInfo = {
82
+ type: nodeType
83
+ };
84
+ // If the sibling node is an element:
85
+ if (nodeType === 1) {
86
+ sibInfo.tagName = (node as Element).tagName;
87
+ sibInfo.attributes = [];
88
+ Array.from((node as Element).attributes).forEach(attribute => {
89
+ sibInfo.attributes!.push({
90
+ name: attribute.name,
91
+ value: attribute.value
92
+ });
93
+ });
94
+ }
95
+ else if (nodeType === 3) {
96
+ sibInfo.text = compact(text!);
97
+ }
98
+ return sibInfo;
99
+ };
100
+ // FUNCTION DEFINITIONS END
101
+ // Initialize the data with the count of the specified elements.
102
+ const data: {total: number; items?: ElementDatum[]} = {
103
+ total: elements.length
104
+ };
105
+ // If no itemization is required:
106
+ if (detailLevel === 0) {
107
+ // Return the element count.
108
+ return data;
109
+ }
110
+ // Otherwise, i.e. if itemization is required:
111
+ else {
112
+ // Initialize the item data.
113
+ data.items = [];
114
+ // For each specified element:
115
+ elements.forEach(element => {
116
+ // Initialize data on it.
117
+ const parent = element.parentElement;
118
+ const datum: ElementDatum = {
119
+ tagName: element.tagName,
120
+ parentTagName: parent ? parent.tagName : '',
121
+ code: compact(element.outerHTML),
122
+ attributes: [],
123
+ textContent: compact(element.textContent!)
124
+ };
125
+ // For each of its attributes:
126
+ for (const attribute of element.attributes) {
127
+ // Add data on the attribute to the element data.
128
+ const {name, value} = attribute;
129
+ datum.attributes.push({
130
+ name,
131
+ value
132
+ });
133
+ // If the element has reference labels:
134
+ if (name === 'aria-labelledby') {
135
+ // Add their texts to the element data.
136
+ const labelerIDs = value.split(/\s+/);
137
+ const labelers: string[] = [];
138
+ labelerIDs.forEach(id => {
139
+ const labeler = document.getElementById(id);
140
+ if (labeler) {
141
+ labelers.push(compact(labeler.textContent!));
142
+ }
143
+ });
144
+ if (labelers.length) {
145
+ datum.labelers = labelers;
146
+ }
147
+ }
148
+ }
149
+ // If the element has text content:
150
+ const {labels, textContent} = element as HTMLInputElement;
151
+ const compactContent = compact(textContent!);
152
+ if (compactContent) {
153
+ // Add it to the element data.
154
+ datum.textContent = compactContent;
155
+ }
156
+ // If the element has labels:
157
+ if (labels && labels.length) {
158
+ // Add their texts to the element data.
159
+ datum.labels = Array.from(labels).map(label => compact(label.textContent!));
160
+ }
161
+ // If the parental text content is required:
162
+ if (detailLevel > 1) {
163
+ // Add it (excluding any shadow-root descendants) to the element data.
164
+ datum.parentTextContent = parent ? compact(parent.textContent!) : '';
165
+ }
166
+ // If sibling itemization is required:
167
+ if (detailLevel === 3) {
168
+ // Add data on the siblings, excluding any descendants of shadow roots, to the data.
169
+ datum.siblings = {
170
+ before: [],
171
+ after: []
172
+ };
173
+ let more: Node | null = element;
174
+ while (more) {
175
+ more = more.previousSibling;
176
+ if (more) {
177
+ const {nodeType, nodeValue} = more;
178
+ if (! (nodeType === 3 && nodeValue === '')) {
179
+ const sibInfo = getSibInfo(more, nodeType, nodeValue);
180
+ datum.siblings!.before.unshift(sibInfo);
181
+ }
182
+ }
183
+ }
184
+ more = element;
185
+ while (more) {
186
+ more = more.nextSibling;
187
+ if (more) {
188
+ const {nodeType, textContent} = more;
189
+ if (! (nodeType === 3 && textContent === '')) {
190
+ const sibInfo = getSibInfo(more, nodeType, compact(textContent!));
191
+ datum.siblings!.after.push(sibInfo);
192
+ }
193
+ }
194
+ }
195
+ }
196
+ data.items!.push(datum);
197
+ });
198
+ return data;
199
+ }
200
+ }, detailLevel);
201
+ }
202
+ catch(error) {
203
+ console.log(`ERROR performing test (${(error as Error).message})`);
204
+ data = {
205
+ prevented: true,
206
+ error: 'ERROR performing test'
207
+ };
208
+ }
209
+ // Return the result.
210
+ return {
211
+ data,
212
+ totals: [],
213
+ standardInstances: []
214
+ };
215
+ };
@@ -0,0 +1,3 @@
1
+ import type { Page } from 'playwright';
2
+ import type { Report } from '../types';
3
+ export declare const reporter: (page: Page, report: Report, _: unknown, withItems: boolean) => Promise<import("../procs/testaro").RuleResult>;
package/testaro/embAc.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
  © 2026 Jonathan Robert Pool.
4
6
 
5
7
  Licensed under the MIT License. See LICENSE file at the project root or
@@ -7,30 +9,28 @@
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
  embAc
13
17
  This test reports interactive elements (links, buttons, inputs, and select lists) contained by links or buttons. Such embedding not only violates the HTML standard, but also complicates user interaction and creates risks of error. It becomes non-obvious what a user will activate with a click.
18
+ Compiled to embAc.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 (page, report, _, withItems) => {
24
- const getBadWhat = element => {
25
- // Get whether the embedding element is a link or a button.
26
- const embedder = element.parentElement.closest('a, button');
27
- const embedderWhat = embedder.tagName.toLowerCase() === 'a' ? 'a link' : 'a button';
28
- // Return a violation description.
29
- return `interactive element is embedded in ${embedderWhat}`;
30
- };
31
- const selector = ['a', 'button', 'input', 'select']
32
- .map(tag => `a ${tag}, button ${tag}`)
33
- .join(', ');
34
- const whats = 'interactive elements are embedded in links or buttons';
35
- return await doTest(page, report, withItems, 'embAc', selector, whats, 2, getBadWhat.toString());
22
+ const reporter = async (page, report, _, withItems) => {
23
+ const getBadWhat = element => {
24
+ // Get whether the embedding element is a link or a button.
25
+ const embedder = element.parentElement.closest('a, button');
26
+ const embedderWhat = embedder.tagName.toLowerCase() === 'a' ? 'a link' : 'a button';
27
+ // Return a violation description.
28
+ return `interactive element is embedded in ${embedderWhat}`;
29
+ };
30
+ const selector = ['a', 'button', 'input', 'select']
31
+ .map(tag => `a ${tag}, button ${tag}`)
32
+ .join(', ');
33
+ const whats = 'interactive elements are embedded in links or buttons';
34
+ return await (0, testaro_1.doTest)(page, report, withItems, 'embAc', selector, whats, 2, getBadWhat.toString());
36
35
  };
36
+ exports.reporter = reporter;
@@ -0,0 +1,40 @@
1
+ /*
2
+ © 2021–2023 CVS Health and/or one of its affiliates. All rights reserved.
3
+ © 2026 Jeff Witt.
4
+ © 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
+ embAc
20
+ This test reports interactive elements (links, buttons, inputs, and select lists) contained by links or buttons. Such embedding not only violates the HTML standard, but also complicates user interaction and creates risks of error. It becomes non-obvious what a user will activate with a click.
21
+ Compiled to embAc.js by tsc (issue #73); edit this file, not the emitted one.
22
+ */
23
+
24
+ // FUNCTIONS
25
+
26
+ // Runs the test and returns the result.
27
+ export const reporter = async (page: Page, report: Report, _: unknown, withItems: boolean) => {
28
+ const getBadWhat: GetBadWhat = element => {
29
+ // Get whether the embedding element is a link or a button.
30
+ const embedder = element.parentElement!.closest('a, button');
31
+ const embedderWhat = embedder!.tagName.toLowerCase() === 'a' ? 'a link' : 'a button';
32
+ // Return a violation description.
33
+ return `interactive element is embedded in ${embedderWhat}`;
34
+ };
35
+ const selector = ['a', 'button', 'input', 'select']
36
+ .map(tag => `a ${tag}, button ${tag}`)
37
+ .join(', ');
38
+ const whats = 'interactive elements are embedded in links or buttons';
39
+ return await doTest(page, report, withItems, 'embAc', selector, whats, 2, getBadWhat.toString());
40
+ };
@@ -0,0 +1,13 @@
1
+ import type { Page } from 'playwright';
2
+ import type { Report, StandardInstance } from '../types';
3
+ export declare const reporter: (page: Page, report: Report, _: unknown, withItems: boolean) => Promise<{
4
+ data: {
5
+ focusableCount: number;
6
+ tabFocused: number;
7
+ discrepancy: number;
8
+ unreachedCount: number;
9
+ unexpectedCount: number;
10
+ };
11
+ totals: number[];
12
+ standardInstances: StandardInstance[];
13
+ }>;