testaro 78.0.8 → 78.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) 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 +24 -18
  7. package/CONTAINERS.md +9 -6
  8. package/CONTRIBUTING.md +29 -3
  9. package/Dockerfile +1 -1
  10. package/README.md +73 -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/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 +372 -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 +312 -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 +62 -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/job.js +115 -1
  38. package/procs/launch.d.ts +40 -0
  39. package/procs/launch.js +239 -108
  40. package/procs/nu.d.ts +48 -0
  41. package/procs/scope.js +196 -0
  42. package/procs/shoot.d.ts +33 -0
  43. package/procs/standard.d.ts +18 -0
  44. package/procs/standard.js +83 -0
  45. package/procs/standard.ts +126 -0
  46. package/procs/testAct.js +145 -0
  47. package/procs/testaro.d.ts +20 -0
  48. package/procs/testaro.js +236 -189
  49. package/procs/testaro.ts +321 -0
  50. package/procs/userPath.js +126 -0
  51. package/procs/xPath.d.ts +4 -0
  52. package/procs/xPath.js +81 -69
  53. package/procs/xPath.ts +106 -0
  54. package/procs/xPathScript.d.ts +6 -0
  55. package/procs/xPathScript.js +70 -0
  56. package/run.js +3 -2
  57. package/surea11y/README.md +44 -0
  58. package/surea11y/surea11y.browser.js +14 -0
  59. package/testaro/adbID.d.ts +3 -0
  60. package/testaro/adbID.js +38 -41
  61. package/testaro/adbID.ts +66 -0
  62. package/testaro/allCapStyle.d.ts +3 -0
  63. package/testaro/allCapStyle.js +31 -34
  64. package/testaro/allCapStyle.ts +55 -0
  65. package/testaro/allCaps.d.ts +16 -0
  66. package/testaro/allCaps.js +179 -151
  67. package/testaro/allCaps.ts +228 -0
  68. package/testaro/allHidden.d.ts +13 -0
  69. package/testaro/allHidden.js +29 -30
  70. package/testaro/allHidden.ts +50 -0
  71. package/testaro/allSlanted.d.ts +3 -0
  72. package/testaro/allSlanted.js +30 -33
  73. package/testaro/allSlanted.ts +54 -0
  74. package/testaro/altScheme.d.ts +3 -0
  75. package/testaro/altScheme.js +27 -30
  76. package/testaro/altScheme.ts +50 -0
  77. package/testaro/attVal.d.ts +3 -0
  78. package/testaro/attVal.js +20 -21
  79. package/testaro/attVal.ts +52 -0
  80. package/testaro/autocomplete.d.ts +3 -0
  81. package/testaro/autocomplete.js +59 -75
  82. package/testaro/autocomplete.ts +101 -0
  83. package/testaro/bulk.d.ts +13 -0
  84. package/testaro/bulk.js +32 -33
  85. package/testaro/bulk.ts +55 -0
  86. package/testaro/buttonMenu.d.ts +9 -0
  87. package/testaro/buttonMenu.js +317 -319
  88. package/testaro/buttonMenu.ts +391 -0
  89. package/testaro/captionLoc.d.ts +3 -0
  90. package/testaro/captionLoc.js +17 -20
  91. package/testaro/captionLoc.ts +40 -0
  92. package/testaro/datalistRef.d.ts +3 -0
  93. package/testaro/datalistRef.js +33 -36
  94. package/testaro/datalistRef.ts +55 -0
  95. package/testaro/distortion.d.ts +3 -0
  96. package/testaro/distortion.js +57 -26
  97. package/testaro/distortion.ts +81 -0
  98. package/testaro/docType.d.ts +15 -0
  99. package/testaro/docType.js +25 -25
  100. package/testaro/docType.ts +45 -0
  101. package/testaro/dupAtt.d.ts +16 -0
  102. package/testaro/dupAtt.js +113 -104
  103. package/testaro/dupAtt.ts +144 -0
  104. package/testaro/elements.d.ts +6 -0
  105. package/testaro/elements.js +153 -153
  106. package/testaro/elements.ts +215 -0
  107. package/testaro/embAc.d.ts +3 -0
  108. package/testaro/embAc.js +19 -20
  109. package/testaro/embAc.ts +40 -0
  110. package/testaro/focAll.d.ts +13 -0
  111. package/testaro/focAll.js +185 -191
  112. package/testaro/focAll.ts +217 -0
  113. package/testaro/focAndOp.d.ts +3 -0
  114. package/testaro/focAndOp.js +100 -104
  115. package/testaro/focAndOp.ts +128 -0
  116. package/testaro/focInd.d.ts +3 -0
  117. package/testaro/focInd.js +64 -66
  118. package/testaro/focInd.ts +96 -0
  119. package/testaro/focVis.d.ts +3 -0
  120. package/testaro/focVis.js +28 -30
  121. package/testaro/focVis.ts +52 -0
  122. package/testaro/headEl.d.ts +10 -0
  123. package/testaro/headEl.js +61 -62
  124. package/testaro/headEl.ts +82 -0
  125. package/testaro/headingAmb.d.ts +3 -0
  126. package/testaro/headingAmb.js +54 -63
  127. package/testaro/headingAmb.ts +72 -0
  128. package/testaro/hovInd.d.ts +12 -0
  129. package/testaro/hovInd.js +163 -130
  130. package/testaro/hovInd.ts +199 -0
  131. package/testaro/hover.d.ts +3 -0
  132. package/testaro/hover.js +155 -126
  133. package/testaro/hover.ts +154 -0
  134. package/testaro/hr.d.ts +3 -0
  135. package/testaro/hr.js +14 -17
  136. package/testaro/hr.ts +36 -0
  137. package/testaro/imageLink.d.ts +3 -0
  138. package/testaro/imageLink.js +17 -20
  139. package/testaro/imageLink.ts +42 -0
  140. package/testaro/labClash.d.ts +3 -0
  141. package/testaro/labClash.js +31 -33
  142. package/testaro/labClash.ts +54 -0
  143. package/testaro/legendLoc.d.ts +3 -0
  144. package/testaro/legendLoc.js +17 -20
  145. package/testaro/legendLoc.ts +42 -0
  146. package/testaro/lineHeight.d.ts +3 -0
  147. package/testaro/lineHeight.js +43 -48
  148. package/testaro/lineHeight.ts +70 -0
  149. package/testaro/linkAmb.d.ts +7 -0
  150. package/testaro/linkAmb.js +79 -80
  151. package/testaro/linkAmb.ts +105 -0
  152. package/testaro/linkExt.d.ts +3 -0
  153. package/testaro/linkExt.js +13 -16
  154. package/testaro/linkExt.ts +35 -0
  155. package/testaro/linkOldAtt.d.ts +3 -0
  156. package/testaro/linkOldAtt.js +25 -28
  157. package/testaro/linkOldAtt.ts +48 -0
  158. package/testaro/linkTo.d.ts +3 -0
  159. package/testaro/linkTo.js +22 -22
  160. package/testaro/linkTo.ts +43 -0
  161. package/testaro/linkUl.d.ts +3 -0
  162. package/testaro/linkUl.js +30 -34
  163. package/testaro/linkUl.ts +54 -0
  164. package/testaro/miniText.d.ts +3 -0
  165. package/testaro/miniText.js +41 -44
  166. package/testaro/miniText.ts +68 -0
  167. package/testaro/motion.d.ts +10 -0
  168. package/testaro/motion.js +92 -96
  169. package/testaro/motion.ts +125 -0
  170. package/testaro/nonTable.d.ts +3 -0
  171. package/testaro/nonTable.js +39 -45
  172. package/testaro/nonTable.ts +66 -0
  173. package/testaro/optRoleSel.d.ts +3 -0
  174. package/testaro/optRoleSel.js +16 -19
  175. package/testaro/optRoleSel.ts +41 -0
  176. package/testaro/phOnly.d.ts +3 -0
  177. package/testaro/phOnly.js +18 -21
  178. package/testaro/phOnly.ts +43 -0
  179. package/testaro/pseudoP.d.ts +3 -0
  180. package/testaro/pseudoP.js +36 -38
  181. package/testaro/pseudoP.ts +59 -0
  182. package/testaro/radioSet.d.ts +3 -0
  183. package/testaro/radioSet.js +57 -59
  184. package/testaro/radioSet.ts +79 -0
  185. package/testaro/registry.d.ts +63 -0
  186. package/testaro/registry.js +67 -0
  187. package/testaro/registry.ts +141 -0
  188. package/testaro/role.d.ts +3 -0
  189. package/testaro/role.js +27 -29
  190. package/testaro/role.ts +53 -0
  191. package/testaro/secHeading.d.ts +3 -0
  192. package/testaro/secHeading.js +30 -33
  193. package/testaro/secHeading.ts +53 -0
  194. package/testaro/styleDiff.d.ts +25 -0
  195. package/testaro/styleDiff.js +248 -252
  196. package/testaro/styleDiff.ts +303 -0
  197. package/testaro/tabNav.d.ts +33 -0
  198. package/testaro/tabNav.js +272 -342
  199. package/testaro/tabNav.ts +454 -0
  200. package/testaro/targetsNear.d.ts +9 -0
  201. package/testaro/targetsNear.js +130 -132
  202. package/testaro/targetsNear.ts +160 -0
  203. package/testaro/textNodes.d.ts +6 -0
  204. package/testaro/textNodes.js +139 -135
  205. package/testaro/textNodes.ts +185 -0
  206. package/testaro/textSem.d.ts +3 -0
  207. package/testaro/textSem.js +25 -28
  208. package/testaro/textSem.ts +47 -0
  209. package/testaro/title.d.ts +9 -0
  210. package/testaro/title.js +16 -13
  211. package/testaro/title.ts +31 -0
  212. package/testaro/titledEl.d.ts +3 -0
  213. package/testaro/titledEl.js +15 -18
  214. package/testaro/titledEl.ts +38 -0
  215. package/testaro/zIndex.d.ts +3 -0
  216. package/testaro/zIndex.js +19 -22
  217. package/testaro/zIndex.ts +42 -0
  218. package/tests/alfa.d.ts +45 -0
  219. package/tests/alfa.js +138 -141
  220. package/tests/alfa.ts +214 -0
  221. package/tests/aslint.d.ts +33 -0
  222. package/tests/aslint.js +272 -249
  223. package/tests/aslint.ts +301 -0
  224. package/tests/axe.d.ts +27 -0
  225. package/tests/axe.js +199 -200
  226. package/tests/axe.ts +277 -0
  227. package/tests/ed11y.d.ts +28 -0
  228. package/tests/ed11y.js +141 -99
  229. package/tests/ed11y.ts +178 -0
  230. package/tests/htmlcs.d.ts +21 -0
  231. package/tests/htmlcs.js +174 -140
  232. package/tests/htmlcs.ts +181 -0
  233. package/tests/ibm.d.ts +52 -0
  234. package/tests/ibm.js +164 -166
  235. package/tests/ibm.ts +251 -0
  236. package/tests/nuVal.d.ts +13 -0
  237. package/tests/nuVal.js +107 -112
  238. package/tests/nuVal.ts +145 -0
  239. package/tests/nuVnu.d.ts +15 -0
  240. package/tests/nuVnu.js +141 -111
  241. package/tests/nuVnu.ts +144 -0
  242. package/tests/pour.d.ts +31 -0
  243. package/tests/pour.js +242 -0
  244. package/tests/pour.ts +273 -0
  245. package/tests/qualWeb.d.ts +39 -0
  246. package/tests/qualWeb.js +302 -272
  247. package/tests/qualWeb.ts +415 -0
  248. package/tests/surea11y.d.ts +33 -0
  249. package/tests/surea11y.js +288 -0
  250. package/tests/surea11y.ts +334 -0
  251. package/tests/testaro.d.ts +25 -0
  252. package/tests/testaro.js +745 -652
  253. package/tests/testaro.ts +862 -0
  254. package/tests/wave.d.ts +46 -0
  255. package/tests/wave.js +166 -177
  256. package/tests/wave.ts +252 -0
  257. package/tsconfig.json +17 -0
  258. package/types.d.ts +243 -0
  259. package/types.js +10 -0
  260. package/types.ts +376 -0
  261. package/validation/act/README.md +46 -0
  262. package/validation/act/capture.js +424 -0
  263. package/validation/act/chromium-issue-draft.md +66 -0
  264. package/validation/act/fp-triage-2026-08-22.md +86 -0
  265. package/validation/act/isolation-notes.md +159 -0
  266. package/validation/act/playwright-issue-draft.md +73 -0
  267. package/validation/act/propose-mappings.js +0 -0
  268. package/validation/act/repro-cdp-raw.js +105 -0
  269. package/validation/act/repro-metarefresh.js +65 -0
  270. package/validation/act/score.js +184 -0
  271. package/validation/act/stage3a-stress-report.md +69 -0
  272. package/validation/act/stage3b-mapping-proposals.md +94 -0
  273. package/validation/act/stage3b-triage-draft.md +138 -0
  274. package/validation/act/surea11y-track-a-2026-09-01.md +50 -0
  275. package/validation/executors/netWatch.js +180 -90
  276. package/validation/executors/test.js +17 -2
  277. package/validation/executors/tests.js +118 -10
  278. package/validation/jobs/reports/raw/260901T1000-surea11y-validation.json +964 -0
  279. package/validation/jobs/todo/240101T1200-simple-example.json +14 -6
  280. package/validation/jobs/todo/240101T1300-shoot-example.json +2 -1
  281. package/validation/jobs/todo/260821T1900-pour-validation.json +45 -0
  282. package/validation/jobs/todo/260901T1000-surea11y-validation.json +45 -0
  283. package/validation/knownFailures.json +1 -0
  284. package/validation/tests/jobProperties/adbID.json +27 -2
  285. package/validation/tests/jobProperties/{focOp.json → allCapStyle.json} +56 -53
  286. package/validation/tests/jobProperties/allCaps.json +25 -0
  287. package/validation/tests/jobProperties/allHidden.json +133 -13
  288. package/validation/tests/jobProperties/allSlanted.json +3 -3
  289. package/validation/tests/jobProperties/altScheme.json +23 -8
  290. package/validation/tests/jobProperties/attVal.json +57 -57
  291. package/validation/tests/jobProperties/autocomplete.json +11 -1
  292. package/validation/tests/jobProperties/bulk.json +6 -1
  293. package/validation/tests/jobProperties/buttonMenu.json +63 -42
  294. package/validation/tests/jobProperties/captionLoc.json +1 -6
  295. package/validation/tests/jobProperties/checkpoint-browser.json +401 -0
  296. package/validation/tests/jobProperties/checkpoint-page.json +397 -0
  297. package/validation/tests/jobProperties/checkpoint.json +395 -0
  298. package/validation/tests/jobProperties/datalistRef.json +20 -5
  299. package/validation/tests/jobProperties/distortion.json +28 -3
  300. package/validation/tests/jobProperties/docType.json +2 -2
  301. package/validation/tests/jobProperties/dupAtt.json +48 -33
  302. package/validation/tests/jobProperties/elements.json +28 -28
  303. package/validation/tests/jobProperties/embAc.json +36 -31
  304. package/validation/tests/jobProperties/focAndOp.json +284 -0
  305. package/validation/tests/jobProperties/focInd.json +34 -34
  306. package/validation/tests/jobProperties/focVis.json +1 -1
  307. package/validation/tests/jobProperties/hover.json +39 -37
  308. package/validation/tests/jobProperties/hr.json +13 -3
  309. package/validation/tests/jobProperties/imageLink.json +0 -5
  310. package/validation/tests/jobProperties/labClash.json +68 -33
  311. package/validation/tests/jobProperties/legendLoc.json +1 -6
  312. package/validation/tests/jobProperties/lineHeight.json +2 -2
  313. package/validation/tests/jobProperties/linkAmb.json +13 -18
  314. package/validation/tests/jobProperties/linkExt.json +1 -1
  315. package/validation/tests/jobProperties/linkOldAtt.json +12 -2
  316. package/validation/tests/jobProperties/linkTo.json +1 -1
  317. package/validation/tests/jobProperties/linkUl.json +65 -65
  318. package/validation/tests/jobProperties/miniText.json +7 -2
  319. package/validation/tests/jobProperties/motion.json +4 -50
  320. package/validation/tests/jobProperties/nonTable.json +48 -3
  321. package/validation/tests/jobProperties/optRoleSel.json +12 -2
  322. package/validation/tests/jobProperties/phOnly.json +6 -16
  323. package/validation/tests/jobProperties/pseudoP.json +17 -2
  324. package/validation/tests/jobProperties/radioSet.json +30 -30
  325. package/validation/tests/jobProperties/role.json +25 -5
  326. package/validation/tests/jobProperties/secHeading.json +26 -21
  327. package/validation/tests/jobProperties/styleDiff.json +35 -5
  328. package/validation/tests/jobProperties/tabNav.json +3 -1
  329. package/validation/tests/jobProperties/targetsNear.json +237 -0
  330. package/validation/tests/jobProperties/textNodes.json +29 -29
  331. package/validation/tests/jobProperties/textSem.json +26 -1
  332. package/validation/tests/jobProperties/title.json +12 -2
  333. package/validation/tests/jobProperties/titledEl.json +39 -9
  334. package/validation/tests/jobProperties/userPath.json +317 -0
  335. package/validation/tests/jobProperties/zIndex.json +40 -35
  336. package/validation/tests/targets/allCapStyle/index.html +26 -0
  337. package/validation/tests/targets/checkpoint/index.html +38 -0
  338. package/validation/tests/targets/datalistRef/index.html +1 -1
  339. package/validation/tests/targets/focAndOp/bad.html +29 -0
  340. package/validation/tests/targets/{focOp → focAndOp}/good.html +3 -1
  341. package/validation/tests/targets/focInd/bad.html +2 -1
  342. package/validation/tests/targets/headEl/index.html +10 -1
  343. package/validation/tests/targets/{targetSmall → targetsNear}/index.html +15 -1
  344. package/validation/tests/targets/userPath/index.html +42 -0
  345. package/validation/validateTest.js +61 -9
  346. package/.claude/settings.local.json +0 -11
  347. package/.eslintrc.json +0 -41
  348. package/htmlcs/.eslintrc.json +0 -67
  349. package/validation/tests/jobProperties/linkTitle.json +0 -127
  350. package/validation/tests/jobProperties/opFoc.json +0 -164
  351. package/validation/tests/jobProperties/targetSmall.json +0 -152
  352. package/validation/tests/jobProperties/targetTiny.json +0 -142
  353. package/validation/tests/targets/focOp/bad.html +0 -25
  354. package/validation/tests/targets/linkTitle/index.html +0 -24
  355. package/validation/tests/targets/opFoc/bad.html +0 -26
  356. package/validation/tests/targets/opFoc/good.html +0 -23
@@ -0,0 +1,105 @@
1
+ /*
2
+ © 2023–2025 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, StandardInstance} from '../types';
17
+
18
+ /*
19
+ linkAmb
20
+ Related to Tenon rule 98.
21
+ This test reports text contents that are shared by links with distinct destinations. Text contents are compared case-insensitively.
22
+ Compiled to linkAmb.js by tsc (issue #73); edit this file, not the emitted one.
23
+ */
24
+
25
+ // FUNCTIONS
26
+
27
+ // Runs the test and returns the result.
28
+ export const reporter = async (page: Page, report: Report, _: unknown, withItems: boolean) => {
29
+ const catalogIndex = getXPathCatalogIndex(report, '/html/body');
30
+ return await page.evaluate(args => {
31
+ const [withItems, catalogIndex] = args;
32
+ // Get all links.
33
+ const allLinks = Array.from(document.body.getElementsByTagName('a'));
34
+ // Get the visible ones.
35
+ const visibleLinks = allLinks.filter(link => link.checkVisibility({
36
+ contentVisibilityAuto: true,
37
+ opacityProperty: true,
38
+ visibilityProperty: true
39
+ }));
40
+ // Initialize the data.
41
+ const linksData: {
42
+ elementData: [string, string | null][];
43
+ textTotals: Record<string, {linkCount: number; hrefs: Set<string | null>}>;
44
+ } = {
45
+ elementData: [],
46
+ textTotals: {}
47
+ };
48
+ // For each visible link:
49
+ visibleLinks.forEach(element => {
50
+ // Get its trimmed and lowercased text.
51
+ const text = element.textContent!.trim().toLowerCase();
52
+ // Get its destination.
53
+ const href = element.getAttribute('href');
54
+ // Add to the data.
55
+ linksData.elementData.push([text, href]);
56
+ linksData.textTotals[text] ??= {
57
+ linkCount: 0,
58
+ hrefs: new Set()
59
+ };
60
+ const linkData = linksData.textTotals[text];
61
+ linkData.linkCount++;
62
+ linkData.hrefs.add(href);
63
+ });
64
+ let violationCount = 0;
65
+ const standardInstances: StandardInstance[] = [];
66
+ // For each link text:
67
+ for (const [text, {linkCount, hrefs}] of Object.entries(linksData.textTotals)) {
68
+ const destinationCount = hrefs.size;
69
+ // If links with it violate the rule:
70
+ if (destinationCount > 1) {
71
+ // Increment the violation count.
72
+ violationCount += linkCount;
73
+ // If itemization is required:
74
+ if (withItems) {
75
+ const what = `${linkCount} links with the text “${text}” have ${destinationCount} different destinations`;
76
+ // Add an instance to the standard instances.
77
+ standardInstances.push({
78
+ ruleID: 'linkAmb',
79
+ what,
80
+ ordinalSeverity: 2,
81
+ count: linkCount,
82
+ catalogIndex
83
+ });
84
+ }
85
+ }
86
+ }
87
+ // If there were any violations and itemization is not required:
88
+ if (violationCount && ! withItems) {
89
+ const what = 'Links have the same text but different destinations';
90
+ // Add a summary instance to the instances.
91
+ standardInstances.push({
92
+ ruleID: 'linkAmb',
93
+ what,
94
+ ordinalSeverity: 2,
95
+ count: violationCount,
96
+ catalogIndex
97
+ });
98
+ }
99
+ return {
100
+ data: {},
101
+ totals: [0, 0, violationCount, 0],
102
+ standardInstances
103
+ };
104
+ }, [withItems, catalogIndex] as const);
105
+ };
@@ -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>;
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*
2
3
  © 2023 CVS Health and/or one of its affiliates. All rights reserved.
3
4
  © 2026 Jeff Witt.
@@ -7,26 +8,22 @@
7
8
 
8
9
  SPDX-License-Identifier: MIT
9
10
  */
10
-
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.reporter = void 0;
13
+ const testaro_1 = require("../procs/testaro");
11
14
  /*
12
15
  linkExt
13
16
  This test reports links with target=_blank attributes.
17
+ Compiled to linkExt.js by tsc (issue #73); edit this file, not the emitted one.
14
18
  */
15
-
16
- // IMPORTS
17
-
18
- const {doTest} = require('../procs/testaro');
19
-
20
19
  // FUNCTIONS
21
-
22
20
  // Runs the test and returns the result.
23
- exports.reporter = async (page, report, _, withItems) => {
24
- const getBadWhat = element => {
25
- // Return a violation description.
26
- return `Link has a target=_blank attribute`;
27
- };
28
- const whats = 'Links have target=_blank attributes';
29
- return await doTest(
30
- page, report, withItems, 'linkExt', 'body a[target=_blank]', whats, 0, getBadWhat.toString()
31
- );
21
+ const reporter = async (page, report, _, withItems) => {
22
+ const getBadWhat = element => {
23
+ // Return a violation description.
24
+ return `Link has a target=_blank attribute`;
25
+ };
26
+ const whats = 'Links have target=_blank attributes';
27
+ return await (0, testaro_1.doTest)(page, report, withItems, 'linkExt', 'body a[target=_blank]', whats, 0, getBadWhat.toString());
32
28
  };
29
+ exports.reporter = reporter;
@@ -0,0 +1,35 @@
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 https://opensource.org/license/mit/ for details.
7
+
8
+ SPDX-License-Identifier: MIT
9
+ */
10
+
11
+ // IMPORTS
12
+
13
+ import type {Page} from 'playwright';
14
+ import {doTest} from '../procs/testaro';
15
+ import type {GetBadWhat, Report} from '../types';
16
+
17
+ /*
18
+ linkExt
19
+ This test reports links with target=_blank attributes.
20
+ Compiled to linkExt.js by tsc (issue #73); edit this file, not the emitted one.
21
+ */
22
+
23
+ // FUNCTIONS
24
+
25
+ // Runs the test and returns the result.
26
+ export const reporter = async (page: Page, report: Report, _: unknown, withItems: boolean) => {
27
+ const getBadWhat: GetBadWhat = element => {
28
+ // Return a violation description.
29
+ return `Link has a target=_blank attribute`;
30
+ };
31
+ const whats = 'Links have target=_blank attributes';
32
+ return await doTest(
33
+ page, report, withItems, 'linkExt', 'body a[target=_blank]', whats, 0, getBadWhat.toString()
34
+ );
35
+ };
@@ -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>;
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*
2
3
  © 2023 CVS Health and/or one of its affiliates. All rights reserved.
3
4
  © 2026 Jeff Witt.
@@ -8,38 +9,34 @@
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
  linkOldAtt
14
17
  This test reports links with deprecated attributes.
18
+ Compiled to linkOldAtt.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
- const attNames = element.getAttributeNames();
27
- const allBadAttNames = ['charset', 'coords', 'name', 'rev', 'shape'];
28
- const elementBadAttNames = allBadAttNames.filter(att => attNames.includes(att));
29
- // If the element has 1 deprecated attribute:
30
- if (elementBadAttNames.length === 1) {
31
- // Return a violation description.
32
- return `${elementBadAttNames[0]} attribute is deprecated`;
33
- }
34
- // Otherwise, if the element has 2 or more deprecated attributes:
35
- if (elementBadAttNames.length > 1) {
36
- // Return a violation description.
37
- return `Element has deprecated attributes: ${elementBadAttNames.join(', ')}`;
38
- }
39
- };
40
- const selector = 'body a[charset], body a[coords], body a[name], body a[rev], body a[shape]';
41
- const whats = 'Links have deprecated attributes';
42
- return await doTest(
43
- page, report, withItems, 'linkOldAtt', selector, whats, 1, getBadWhat.toString()
44
- );
22
+ const reporter = async (page, report, _, withItems) => {
23
+ const getBadWhat = element => {
24
+ const attNames = element.getAttributeNames();
25
+ const allBadAttNames = ['charset', 'coords', 'name', 'rev', 'shape'];
26
+ const elementBadAttNames = allBadAttNames.filter(att => attNames.includes(att));
27
+ // If the element has 1 deprecated attribute:
28
+ if (elementBadAttNames.length === 1) {
29
+ // Return a violation description.
30
+ return `${elementBadAttNames[0]} attribute is deprecated`;
31
+ }
32
+ // Otherwise, if the element has 2 or more deprecated attributes:
33
+ if (elementBadAttNames.length > 1) {
34
+ // Return a violation description.
35
+ return `Element has deprecated attributes: ${elementBadAttNames.join(', ')}`;
36
+ }
37
+ };
38
+ const selector = 'body a[charset], body a[coords], body a[name], body a[rev], body a[shape]';
39
+ const whats = 'Links have deprecated attributes';
40
+ return await (0, testaro_1.doTest)(page, report, withItems, 'linkOldAtt', selector, whats, 1, getBadWhat.toString());
45
41
  };
42
+ exports.reporter = reporter;
@@ -0,0 +1,48 @@
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 {GetBadWhat, Report} from '../types';
17
+
18
+ /*
19
+ linkOldAtt
20
+ This test reports links with deprecated attributes.
21
+ Compiled to linkOldAtt.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
+ const attNames = element.getAttributeNames();
30
+ const allBadAttNames = ['charset', 'coords', 'name', 'rev', 'shape'];
31
+ const elementBadAttNames = allBadAttNames.filter(att => attNames.includes(att));
32
+ // If the element has 1 deprecated attribute:
33
+ if (elementBadAttNames.length === 1) {
34
+ // Return a violation description.
35
+ return `${elementBadAttNames[0]} attribute is deprecated`;
36
+ }
37
+ // Otherwise, if the element has 2 or more deprecated attributes:
38
+ if (elementBadAttNames.length > 1) {
39
+ // Return a violation description.
40
+ return `Element has deprecated attributes: ${elementBadAttNames.join(', ')}`;
41
+ }
42
+ };
43
+ const selector = 'body a[charset], body a[coords], body a[name], body a[rev], body a[shape]';
44
+ const whats = 'Links have deprecated attributes';
45
+ return await doTest(
46
+ page, report, withItems, 'linkOldAtt', selector, whats, 1, getBadWhat.toString()
47
+ );
48
+ };
@@ -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/linkTo.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*
2
3
  © 2023 CVS Health and/or one of its affiliates. All rights reserved.
3
4
  © 2026 Jeff Witt.
@@ -8,32 +9,31 @@
8
9
 
9
10
  SPDX-License-Identifier: MIT
10
11
  */
12
+ // IMPORTS
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.reporter = void 0;
15
+ const testaro_1 = require("../procs/testaro");
11
16
  /*
12
17
  linkTo
13
18
  This test reports links without href attributes.
19
+ Compiled to linkTo.js by tsc (issue #73); edit this file, not the emitted one.
14
20
  */
15
- // IMPORTS
16
-
17
- const {doTest} = require('../procs/testaro');
18
-
19
21
  // FUNCTIONS
20
-
21
22
  // Runs the test and returns the result.
22
- exports.reporter = async (page, report, _, withItems) => {
23
- const getBadWhat = element => {
24
- const isVisible = element.checkVisibility({
25
- contentVisibilityAuto: true,
26
- opacityProperty: true,
27
- visibilityProperty: true
28
- });
29
- // If the element is visible:
30
- if (isVisible) {
31
- // Return a violation description.
32
- return `Element has no href attribute`;
33
- }
34
- };
35
- const whats = 'Links are missing href attributes';
36
- return await doTest(
37
- page, report, withItems, 'linkTo', 'body a:not([href]', whats, 2, getBadWhat.toString()
38
- );
23
+ const reporter = async (page, report, _, withItems) => {
24
+ const getBadWhat = element => {
25
+ const isVisible = element.checkVisibility({
26
+ contentVisibilityAuto: true,
27
+ opacityProperty: true,
28
+ visibilityProperty: true
29
+ });
30
+ // If the element is visible:
31
+ if (isVisible) {
32
+ // Return a violation description.
33
+ return `Element has no href attribute`;
34
+ }
35
+ };
36
+ const whats = 'Links are missing href attributes';
37
+ return await (0, testaro_1.doTest)(page, report, withItems, 'linkTo', 'body a:not([href]', whats, 2, getBadWhat.toString());
39
38
  };
39
+ exports.reporter = reporter;
@@ -0,0 +1,43 @@
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
+ // IMPORTS
12
+
13
+ import type {Page} from 'playwright';
14
+ import {doTest} from '../procs/testaro';
15
+ import type {GetBadWhat, Report} from '../types';
16
+
17
+ /*
18
+ linkTo
19
+ This test reports links without href attributes.
20
+ Compiled to linkTo.js by tsc (issue #73); edit this file, not the emitted one.
21
+ */
22
+
23
+ // FUNCTIONS
24
+
25
+ // Runs the test and returns the result.
26
+ export const reporter = async (page: Page, report: Report, _: unknown, withItems: boolean) => {
27
+ const getBadWhat: GetBadWhat = element => {
28
+ const isVisible = element.checkVisibility({
29
+ contentVisibilityAuto: true,
30
+ opacityProperty: true,
31
+ visibilityProperty: true
32
+ });
33
+ // If the element is visible:
34
+ if (isVisible) {
35
+ // Return a violation description.
36
+ return `Element has no href attribute`;
37
+ }
38
+ };
39
+ const whats = 'Links are missing href attributes';
40
+ return await doTest(
41
+ page, report, withItems, 'linkTo', 'body a:not([href]', whats, 2, getBadWhat.toString()
42
+ );
43
+ };
@@ -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/linkUl.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.
@@ -7,44 +8,39 @@
7
8
 
8
9
  SPDX-License-Identifier: MIT
9
10
  */
10
-
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.reporter = void 0;
13
+ const testaro_1 = require("../procs/testaro");
11
14
  /*
12
15
  linkUl
13
16
  This test reports failures to underline links that have adjacent text. Underlining and color are the traditional style properties that identify links. A link whose text is the entire text of its block may be recognizable without underlining, but otherwise links are difficult or impossible to distinguish visually from surrounding text if not underlined. Underlining links only on hover provides an indicator valuable only to mouse users, and even they must traverse the text with a mouse merely to discover which passages are links.
17
+ Compiled to linkUl.js by tsc (issue #73); edit this file, not the emitted one.
14
18
  */
15
-
16
- // IMPORTS
17
-
18
- const {doTest} = require('../procs/testaro');
19
-
20
19
  // FUNCTIONS
21
-
22
20
  // Runs the test and returns the result.
23
- exports.reporter = async (page, report, _, withItems) => {
24
- const getBadWhat = element => {
25
- let {display, textDecorationLine} = window.getComputedStyle(element);
26
- // If the element is not underlined:
27
- if (! textDecorationLine.includes('underline')) {
28
- let ancestor = element;
29
- // Get its closest non-inline ancestor.
30
- while (display === 'inline') {
31
- ancestor = ancestor.parentElement;
32
- display = ancestor ? window.getComputedStyle(ancestor).display : null;
33
- }
34
- // Removes superfluous whitespace from a string.
35
- const compact = string => string?.replace(/\s+/g, ' ')?.trim();
36
- // If the rendered compacted text of that ancestor includes more than that of the element:
37
- if (
38
- compact(element.textContent) !== compact(ancestor?.textContent)
39
- && compact(element.innerText) !== compact(ancestor?.innerText)
40
- ) {
41
- // Return a violation description.
42
- return 'Element has adjacent text but is not underlined';
43
- }
44
- }
45
- };
46
- const whats = 'Links with adjacent text are not underlined';
47
- return await doTest(
48
- page, report, withItems, 'linkUl', 'body a', whats, 1, getBadWhat.toString()
49
- );
21
+ const reporter = async (page, report, _, withItems) => {
22
+ // The candidate selector yields rendered HTML link elements.
23
+ const getBadWhat = (element) => {
24
+ let { display, textDecorationLine } = window.getComputedStyle(element);
25
+ // If the element is not underlined:
26
+ if (!textDecorationLine.includes('underline')) {
27
+ let ancestor = element;
28
+ // Get its closest non-inline ancestor.
29
+ while (display === 'inline') {
30
+ ancestor = ancestor.parentElement;
31
+ display = ancestor ? window.getComputedStyle(ancestor).display : null;
32
+ }
33
+ // Removes superfluous whitespace from a string.
34
+ const compact = (string) => string?.replace(/\s+/g, ' ')?.trim();
35
+ // If the rendered compacted text of that ancestor includes more than that of the element:
36
+ if (compact(element.textContent) !== compact(ancestor?.textContent)
37
+ && compact(element.innerText) !== compact(ancestor?.innerText)) {
38
+ // Return a violation description.
39
+ return 'Element has adjacent text but is not underlined';
40
+ }
41
+ }
42
+ };
43
+ const whats = 'Links with adjacent text are not underlined';
44
+ return await (0, testaro_1.doTest)(page, report, withItems, 'linkUl', 'body a', whats, 1, getBadWhat.toString());
50
45
  };
46
+ exports.reporter = reporter;
@@ -0,0 +1,54 @@
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 https://opensource.org/license/mit/ for details.
7
+
8
+ SPDX-License-Identifier: MIT
9
+ */
10
+
11
+ // IMPORTS
12
+
13
+ import type {Page} from 'playwright';
14
+ import {doTest} from '../procs/testaro';
15
+ import type {BadWhat, Report} from '../types';
16
+
17
+ /*
18
+ linkUl
19
+ This test reports failures to underline links that have adjacent text. Underlining and color are the traditional style properties that identify links. A link whose text is the entire text of its block may be recognizable without underlining, but otherwise links are difficult or impossible to distinguish visually from surrounding text if not underlined. Underlining links only on hover provides an indicator valuable only to mouse users, and even they must traverse the text with a mouse merely to discover which passages are links.
20
+ Compiled to linkUl.js by tsc (issue #73); edit this file, not the emitted one.
21
+ */
22
+
23
+ // FUNCTIONS
24
+
25
+ // Runs the test and returns the result.
26
+ export const reporter = async (page: Page, report: Report, _: unknown, withItems: boolean) => {
27
+ // The candidate selector yields rendered HTML link elements.
28
+ const getBadWhat = (element: HTMLElement): BadWhat => {
29
+ let {display, textDecorationLine}: {display: string | null; textDecorationLine: string} = window.getComputedStyle(element);
30
+ // If the element is not underlined:
31
+ if (! textDecorationLine.includes('underline')) {
32
+ let ancestor: HTMLElement | null = element;
33
+ // Get its closest non-inline ancestor.
34
+ while (display === 'inline') {
35
+ ancestor = ancestor!.parentElement;
36
+ display = ancestor ? window.getComputedStyle(ancestor).display : null;
37
+ }
38
+ // Removes superfluous whitespace from a string.
39
+ const compact = (string: string | null | undefined) => string?.replace(/\s+/g, ' ')?.trim();
40
+ // If the rendered compacted text of that ancestor includes more than that of the element:
41
+ if (
42
+ compact(element.textContent) !== compact(ancestor?.textContent)
43
+ && compact(element.innerText) !== compact(ancestor?.innerText)
44
+ ) {
45
+ // Return a violation description.
46
+ return 'Element has adjacent text but is not underlined';
47
+ }
48
+ }
49
+ };
50
+ const whats = 'Links with adjacent text are not underlined';
51
+ return await doTest(
52
+ page, report, withItems, 'linkUl', 'body a', whats, 1, getBadWhat.toString()
53
+ );
54
+ };
@@ -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>;