testaro 78.0.8 → 78.6.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 (357) hide show
  1. package/.gitattributes +94 -0
  2. package/.github/workflows/ci.yml +58 -0
  3. package/.github/workflows/publish.yml +50 -0
  4. package/.github/workflows/typescript.yml +35 -0
  5. package/AGENTS.md +2 -2
  6. package/CLAUDE.md +24 -18
  7. package/CONTAINERS.md +9 -6
  8. package/CONTRIBUTING.md +29 -3
  9. package/Dockerfile +1 -1
  10. package/README.md +143 -19
  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/dist/nameComputation.js +1 -0
  16. package/docker-compose.yml +8 -2
  17. package/docs/checkpoint-scanning.md +199 -0
  18. package/docs/standard-result-outcome.md +165 -0
  19. package/env.example +49 -10
  20. package/eslint.config.mjs +101 -0
  21. package/netWatch.js +372 -222
  22. package/package.json +46 -31
  23. package/pour/README.md +47 -0
  24. package/pour/pour.min.js +8 -0
  25. package/procs/actDo.js +808 -0
  26. package/procs/catalog.d.ts +17 -0
  27. package/procs/catalog.js +312 -221
  28. package/procs/catalog.ts +398 -0
  29. package/procs/checkpoint.js +110 -0
  30. package/procs/config.d.ts +41 -0
  31. package/procs/config.js +98 -0
  32. package/procs/dateTime.js +2 -1
  33. package/procs/doActs.js +442 -849
  34. package/procs/doTestAct.js +27 -121
  35. package/procs/flow.js +221 -0
  36. package/procs/generateRuleRegistry.js +94 -0
  37. package/procs/getSource.d.ts +26 -0
  38. package/procs/job.js +115 -1
  39. package/procs/launch.d.ts +40 -0
  40. package/procs/launch.js +243 -108
  41. package/procs/nu.d.ts +48 -0
  42. package/procs/scope.js +196 -0
  43. package/procs/shoot.d.ts +33 -0
  44. package/procs/standard.d.ts +18 -0
  45. package/procs/standard.js +83 -0
  46. package/procs/standard.ts +126 -0
  47. package/procs/testAct.js +145 -0
  48. package/procs/testaro.d.ts +20 -0
  49. package/procs/testaro.js +236 -189
  50. package/procs/testaro.ts +321 -0
  51. package/procs/userPath.js +126 -0
  52. package/procs/xPath.d.ts +4 -0
  53. package/procs/xPath.js +81 -69
  54. package/procs/xPath.ts +106 -0
  55. package/procs/xPathScript.d.ts +6 -0
  56. package/procs/xPathScript.js +70 -0
  57. package/run.js +3 -2
  58. package/surea11y/README.md +44 -0
  59. package/surea11y/surea11y.browser.js +14 -0
  60. package/testaro/adbID.d.ts +3 -0
  61. package/testaro/adbID.js +38 -41
  62. package/testaro/adbID.ts +66 -0
  63. package/testaro/allCapStyle.d.ts +3 -0
  64. package/testaro/allCapStyle.js +31 -34
  65. package/testaro/allCapStyle.ts +55 -0
  66. package/testaro/allCaps.d.ts +16 -0
  67. package/testaro/allCaps.js +179 -151
  68. package/testaro/allCaps.ts +228 -0
  69. package/testaro/allHidden.d.ts +13 -0
  70. package/testaro/allHidden.js +29 -30
  71. package/testaro/allHidden.ts +50 -0
  72. package/testaro/allSlanted.d.ts +3 -0
  73. package/testaro/allSlanted.js +30 -33
  74. package/testaro/allSlanted.ts +54 -0
  75. package/testaro/altScheme.d.ts +3 -0
  76. package/testaro/altScheme.js +27 -30
  77. package/testaro/altScheme.ts +50 -0
  78. package/testaro/attVal.d.ts +3 -0
  79. package/testaro/attVal.js +20 -21
  80. package/testaro/attVal.ts +52 -0
  81. package/testaro/autocomplete.d.ts +3 -0
  82. package/testaro/autocomplete.js +59 -75
  83. package/testaro/autocomplete.ts +101 -0
  84. package/testaro/bulk.d.ts +13 -0
  85. package/testaro/bulk.js +32 -33
  86. package/testaro/bulk.ts +55 -0
  87. package/testaro/buttonMenu.d.ts +9 -0
  88. package/testaro/buttonMenu.js +317 -319
  89. package/testaro/buttonMenu.ts +391 -0
  90. package/testaro/captionLoc.d.ts +3 -0
  91. package/testaro/captionLoc.js +17 -20
  92. package/testaro/captionLoc.ts +40 -0
  93. package/testaro/datalistRef.d.ts +3 -0
  94. package/testaro/datalistRef.js +33 -36
  95. package/testaro/datalistRef.ts +55 -0
  96. package/testaro/distortion.d.ts +3 -0
  97. package/testaro/distortion.js +57 -26
  98. package/testaro/distortion.ts +81 -0
  99. package/testaro/docType.d.ts +15 -0
  100. package/testaro/docType.js +25 -25
  101. package/testaro/docType.ts +45 -0
  102. package/testaro/dupAtt.d.ts +16 -0
  103. package/testaro/dupAtt.js +113 -104
  104. package/testaro/dupAtt.ts +144 -0
  105. package/testaro/elements.d.ts +6 -0
  106. package/testaro/elements.js +153 -153
  107. package/testaro/elements.ts +215 -0
  108. package/testaro/embAc.d.ts +3 -0
  109. package/testaro/embAc.js +19 -20
  110. package/testaro/embAc.ts +40 -0
  111. package/testaro/focAll.d.ts +13 -0
  112. package/testaro/focAll.js +185 -191
  113. package/testaro/focAll.ts +217 -0
  114. package/testaro/focAndOp.d.ts +3 -0
  115. package/testaro/focAndOp.js +100 -104
  116. package/testaro/focAndOp.ts +128 -0
  117. package/testaro/focInd.d.ts +3 -0
  118. package/testaro/focInd.js +64 -66
  119. package/testaro/focInd.ts +96 -0
  120. package/testaro/focVis.d.ts +3 -0
  121. package/testaro/focVis.js +28 -30
  122. package/testaro/focVis.ts +52 -0
  123. package/testaro/headEl.d.ts +10 -0
  124. package/testaro/headEl.js +61 -62
  125. package/testaro/headEl.ts +82 -0
  126. package/testaro/headingAmb.d.ts +3 -0
  127. package/testaro/headingAmb.js +54 -63
  128. package/testaro/headingAmb.ts +72 -0
  129. package/testaro/hovInd.d.ts +12 -0
  130. package/testaro/hovInd.js +163 -130
  131. package/testaro/hovInd.ts +199 -0
  132. package/testaro/hover.d.ts +3 -0
  133. package/testaro/hover.js +155 -126
  134. package/testaro/hover.ts +154 -0
  135. package/testaro/hr.d.ts +3 -0
  136. package/testaro/hr.js +14 -17
  137. package/testaro/hr.ts +36 -0
  138. package/testaro/imageLink.d.ts +3 -0
  139. package/testaro/imageLink.js +17 -20
  140. package/testaro/imageLink.ts +42 -0
  141. package/testaro/labClash.d.ts +3 -0
  142. package/testaro/labClash.js +31 -33
  143. package/testaro/labClash.ts +54 -0
  144. package/testaro/legendLoc.d.ts +3 -0
  145. package/testaro/legendLoc.js +17 -20
  146. package/testaro/legendLoc.ts +42 -0
  147. package/testaro/lineHeight.d.ts +3 -0
  148. package/testaro/lineHeight.js +43 -48
  149. package/testaro/lineHeight.ts +70 -0
  150. package/testaro/linkAmb.d.ts +7 -0
  151. package/testaro/linkAmb.js +79 -80
  152. package/testaro/linkAmb.ts +105 -0
  153. package/testaro/linkExt.d.ts +3 -0
  154. package/testaro/linkExt.js +13 -16
  155. package/testaro/linkExt.ts +35 -0
  156. package/testaro/linkOldAtt.d.ts +3 -0
  157. package/testaro/linkOldAtt.js +25 -28
  158. package/testaro/linkOldAtt.ts +48 -0
  159. package/testaro/linkTo.d.ts +3 -0
  160. package/testaro/linkTo.js +22 -22
  161. package/testaro/linkTo.ts +43 -0
  162. package/testaro/linkUl.d.ts +3 -0
  163. package/testaro/linkUl.js +30 -34
  164. package/testaro/linkUl.ts +54 -0
  165. package/testaro/miniText.d.ts +3 -0
  166. package/testaro/miniText.js +41 -44
  167. package/testaro/miniText.ts +68 -0
  168. package/testaro/motion.d.ts +10 -0
  169. package/testaro/motion.js +92 -96
  170. package/testaro/motion.ts +125 -0
  171. package/testaro/nonTable.d.ts +3 -0
  172. package/testaro/nonTable.js +39 -45
  173. package/testaro/nonTable.ts +66 -0
  174. package/testaro/optRoleSel.d.ts +3 -0
  175. package/testaro/optRoleSel.js +16 -19
  176. package/testaro/optRoleSel.ts +41 -0
  177. package/testaro/phOnly.d.ts +3 -0
  178. package/testaro/phOnly.js +18 -21
  179. package/testaro/phOnly.ts +43 -0
  180. package/testaro/pseudoP.d.ts +3 -0
  181. package/testaro/pseudoP.js +36 -38
  182. package/testaro/pseudoP.ts +59 -0
  183. package/testaro/radioSet.d.ts +3 -0
  184. package/testaro/radioSet.js +57 -59
  185. package/testaro/radioSet.ts +79 -0
  186. package/testaro/registry.d.ts +63 -0
  187. package/testaro/registry.js +67 -0
  188. package/testaro/registry.ts +141 -0
  189. package/testaro/role.d.ts +3 -0
  190. package/testaro/role.js +27 -29
  191. package/testaro/role.ts +53 -0
  192. package/testaro/secHeading.d.ts +3 -0
  193. package/testaro/secHeading.js +30 -33
  194. package/testaro/secHeading.ts +53 -0
  195. package/testaro/styleDiff.d.ts +25 -0
  196. package/testaro/styleDiff.js +248 -252
  197. package/testaro/styleDiff.ts +303 -0
  198. package/testaro/tabNav.d.ts +33 -0
  199. package/testaro/tabNav.js +272 -342
  200. package/testaro/tabNav.ts +454 -0
  201. package/testaro/targetsNear.d.ts +9 -0
  202. package/testaro/targetsNear.js +130 -132
  203. package/testaro/targetsNear.ts +160 -0
  204. package/testaro/textNodes.d.ts +6 -0
  205. package/testaro/textNodes.js +139 -135
  206. package/testaro/textNodes.ts +185 -0
  207. package/testaro/textSem.d.ts +3 -0
  208. package/testaro/textSem.js +25 -28
  209. package/testaro/textSem.ts +47 -0
  210. package/testaro/title.d.ts +9 -0
  211. package/testaro/title.js +16 -13
  212. package/testaro/title.ts +31 -0
  213. package/testaro/titledEl.d.ts +3 -0
  214. package/testaro/titledEl.js +15 -18
  215. package/testaro/titledEl.ts +38 -0
  216. package/testaro/zIndex.d.ts +3 -0
  217. package/testaro/zIndex.js +19 -22
  218. package/testaro/zIndex.ts +42 -0
  219. package/tests/alfa.d.ts +45 -0
  220. package/tests/alfa.js +138 -141
  221. package/tests/alfa.ts +214 -0
  222. package/tests/aslint.d.ts +33 -0
  223. package/tests/aslint.js +272 -249
  224. package/tests/aslint.ts +301 -0
  225. package/tests/axe.d.ts +27 -0
  226. package/tests/axe.js +199 -200
  227. package/tests/axe.ts +277 -0
  228. package/tests/ed11y.d.ts +28 -0
  229. package/tests/ed11y.js +141 -99
  230. package/tests/ed11y.ts +178 -0
  231. package/tests/htmlcs.d.ts +21 -0
  232. package/tests/htmlcs.js +174 -140
  233. package/tests/htmlcs.ts +181 -0
  234. package/tests/ibm.d.ts +57 -0
  235. package/tests/ibm.js +182 -175
  236. package/tests/ibm.ts +287 -0
  237. package/tests/nuVal.d.ts +13 -0
  238. package/tests/nuVal.js +107 -112
  239. package/tests/nuVal.ts +145 -0
  240. package/tests/nuVnu.d.ts +15 -0
  241. package/tests/nuVnu.js +141 -111
  242. package/tests/nuVnu.ts +144 -0
  243. package/tests/pour.d.ts +31 -0
  244. package/tests/pour.js +242 -0
  245. package/tests/pour.ts +273 -0
  246. package/tests/qualWeb.d.ts +39 -0
  247. package/tests/qualWeb.js +262 -273
  248. package/tests/qualWeb.ts +344 -0
  249. package/tests/surea11y.d.ts +33 -0
  250. package/tests/surea11y.js +288 -0
  251. package/tests/surea11y.ts +334 -0
  252. package/tests/testaro.d.ts +25 -0
  253. package/tests/testaro.js +745 -652
  254. package/tests/testaro.ts +862 -0
  255. package/tests/wave.d.ts +46 -0
  256. package/tests/wave.js +166 -177
  257. package/tests/wave.ts +252 -0
  258. package/tsconfig.json +17 -0
  259. package/types.d.ts +243 -0
  260. package/types.js +10 -0
  261. package/types.ts +376 -0
  262. package/validation/act/README.md +46 -0
  263. package/validation/act/capture.js +877 -0
  264. package/validation/act/chromium-issue-draft.md +66 -0
  265. package/validation/act/fp-triage-2026-08-22.md +86 -0
  266. package/validation/act/isolation-notes.md +159 -0
  267. package/validation/act/playwright-issue-draft.md +73 -0
  268. package/validation/act/propose-mappings.js +0 -0
  269. package/validation/act/repro-cdp-raw.js +105 -0
  270. package/validation/act/repro-metarefresh.js +65 -0
  271. package/validation/act/score.js +184 -0
  272. package/validation/act/stage3a-stress-report.md +69 -0
  273. package/validation/act/stage3b-mapping-proposals.md +94 -0
  274. package/validation/act/stage3b-triage-draft.md +138 -0
  275. package/validation/act/surea11y-track-a-2026-09-01.md +50 -0
  276. package/validation/executors/netWatch.js +180 -90
  277. package/validation/executors/test.js +17 -2
  278. package/validation/executors/tests.js +118 -10
  279. package/validation/jobs/reports/raw/260901T1000-surea11y-validation.json +964 -0
  280. package/validation/jobs/todo/240101T1200-simple-example.json +14 -6
  281. package/validation/jobs/todo/240101T1300-shoot-example.json +2 -1
  282. package/validation/jobs/todo/260821T1900-pour-validation.json +45 -0
  283. package/validation/jobs/todo/260901T1000-surea11y-validation.json +45 -0
  284. package/validation/knownFailures.json +1 -0
  285. package/validation/tests/jobProperties/adbID.json +27 -2
  286. package/validation/tests/jobProperties/{focOp.json → allCapStyle.json} +56 -53
  287. package/validation/tests/jobProperties/allCaps.json +25 -0
  288. package/validation/tests/jobProperties/allHidden.json +133 -13
  289. package/validation/tests/jobProperties/allSlanted.json +3 -3
  290. package/validation/tests/jobProperties/altScheme.json +23 -8
  291. package/validation/tests/jobProperties/attVal.json +57 -57
  292. package/validation/tests/jobProperties/autocomplete.json +11 -1
  293. package/validation/tests/jobProperties/bulk.json +6 -1
  294. package/validation/tests/jobProperties/buttonMenu.json +63 -42
  295. package/validation/tests/jobProperties/captionLoc.json +1 -6
  296. package/validation/tests/jobProperties/checkpoint-browser.json +401 -0
  297. package/validation/tests/jobProperties/checkpoint-page.json +397 -0
  298. package/validation/tests/jobProperties/checkpoint.json +395 -0
  299. package/validation/tests/jobProperties/datalistRef.json +20 -5
  300. package/validation/tests/jobProperties/distortion.json +28 -3
  301. package/validation/tests/jobProperties/docType.json +2 -2
  302. package/validation/tests/jobProperties/dupAtt.json +48 -33
  303. package/validation/tests/jobProperties/elements.json +28 -28
  304. package/validation/tests/jobProperties/embAc.json +36 -31
  305. package/validation/tests/jobProperties/focAndOp.json +284 -0
  306. package/validation/tests/jobProperties/focInd.json +34 -34
  307. package/validation/tests/jobProperties/focVis.json +1 -1
  308. package/validation/tests/jobProperties/hover.json +39 -37
  309. package/validation/tests/jobProperties/hr.json +13 -3
  310. package/validation/tests/jobProperties/imageLink.json +0 -5
  311. package/validation/tests/jobProperties/labClash.json +68 -33
  312. package/validation/tests/jobProperties/legendLoc.json +1 -6
  313. package/validation/tests/jobProperties/lineHeight.json +2 -2
  314. package/validation/tests/jobProperties/linkAmb.json +13 -18
  315. package/validation/tests/jobProperties/linkExt.json +1 -1
  316. package/validation/tests/jobProperties/linkOldAtt.json +12 -2
  317. package/validation/tests/jobProperties/linkTo.json +1 -1
  318. package/validation/tests/jobProperties/linkUl.json +65 -65
  319. package/validation/tests/jobProperties/miniText.json +7 -2
  320. package/validation/tests/jobProperties/motion.json +4 -50
  321. package/validation/tests/jobProperties/nonTable.json +48 -3
  322. package/validation/tests/jobProperties/optRoleSel.json +12 -2
  323. package/validation/tests/jobProperties/phOnly.json +6 -16
  324. package/validation/tests/jobProperties/pseudoP.json +17 -2
  325. package/validation/tests/jobProperties/radioSet.json +30 -30
  326. package/validation/tests/jobProperties/role.json +25 -5
  327. package/validation/tests/jobProperties/secHeading.json +26 -21
  328. package/validation/tests/jobProperties/styleDiff.json +35 -5
  329. package/validation/tests/jobProperties/tabNav.json +3 -1
  330. package/validation/tests/jobProperties/targetsNear.json +237 -0
  331. package/validation/tests/jobProperties/textNodes.json +29 -29
  332. package/validation/tests/jobProperties/textSem.json +26 -1
  333. package/validation/tests/jobProperties/title.json +12 -2
  334. package/validation/tests/jobProperties/titledEl.json +39 -9
  335. package/validation/tests/jobProperties/userPath.json +317 -0
  336. package/validation/tests/jobProperties/zIndex.json +40 -35
  337. package/validation/tests/targets/allCapStyle/index.html +26 -0
  338. package/validation/tests/targets/checkpoint/index.html +38 -0
  339. package/validation/tests/targets/datalistRef/index.html +1 -1
  340. package/validation/tests/targets/focAndOp/bad.html +29 -0
  341. package/validation/tests/targets/{focOp → focAndOp}/good.html +3 -1
  342. package/validation/tests/targets/focInd/bad.html +2 -1
  343. package/validation/tests/targets/headEl/index.html +10 -1
  344. package/validation/tests/targets/{targetSmall → targetsNear}/index.html +15 -1
  345. package/validation/tests/targets/userPath/index.html +42 -0
  346. package/validation/validateTest.js +61 -9
  347. package/.claude/settings.local.json +0 -11
  348. package/.eslintrc.json +0 -41
  349. package/htmlcs/.eslintrc.json +0 -67
  350. package/validation/tests/jobProperties/linkTitle.json +0 -127
  351. package/validation/tests/jobProperties/opFoc.json +0 -164
  352. package/validation/tests/jobProperties/targetSmall.json +0 -152
  353. package/validation/tests/jobProperties/targetTiny.json +0 -142
  354. package/validation/tests/targets/focOp/bad.html +0 -25
  355. package/validation/tests/targets/linkTitle/index.html +0 -24
  356. package/validation/tests/targets/opFoc/bad.html +0 -26
  357. 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,3 +1,4 @@
1
+ "use strict";
1
2
  /*
2
3
  © 2021–2023 CVS Health and/or one of its affiliates. All rights reserved.
3
4
  © 2026 Jeff Witt.
@@ -8,30 +9,28 @@
8
9
 
9
10
  SPDX-License-Identifier: MIT
10
11
  */
11
-
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.reporter = void 0;
14
+ const testaro_1 = require("../procs/testaro");
12
15
  /*
13
16
  embAc
14
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.
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
- exports.reporter = async (page, report, _, withItems) => {
25
- const getBadWhat = element => {
26
- // Get whether the embedding element is a link or a button.
27
- const embedder = element.parentElement.closest('a, button');
28
- const embedderWhat = embedder.tagName.toLowerCase() === 'a' ? 'a link' : 'a button';
29
- // Return a violation description.
30
- return `interactive element is embedded in ${embedderWhat}`;
31
- };
32
- const selector = ['a', 'button', 'input', 'select']
33
- .map(tag => `a ${tag}, button ${tag}`)
34
- .join(', ');
35
- const whats = 'interactive elements are embedded in links or buttons';
36
- 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());
37
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
+ }>;