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,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>;