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
package/procs/xPath.ts ADDED
@@ -0,0 +1,106 @@
1
+ /*
2
+ © 2024 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 {Catalog, Report} from '../types';
15
+
16
+ /*
17
+ xPath
18
+ Processes element XPaths. Compiled to xPath.js by tsc (issue #73); edit this
19
+ file, not the emitted one.
20
+ */
21
+
22
+ // FUNCTIONS
23
+
24
+ // Normalizes an XPath.
25
+ export const getNormalizedXPath = (xPath: string | null | undefined): string => {
26
+ if (xPath) {
27
+ if (xPath === '/') {
28
+ xPath = '/html';
29
+ }
30
+ xPath = xPath.replace(/^\.\/\//, '/');
31
+ const segments = xPath.split('/');
32
+ // Initialize an array of normalized segments.
33
+ const normalizedSegments: string[] = [];
34
+ // For each segment of the XPath:
35
+ segments.forEach(segment => {
36
+ // If the segment is html[1] or body[1]:
37
+ if (/html\[1\]|body\[1\]/.test(segment)) {
38
+ // Add it without its subscript to the array.
39
+ normalizedSegments.push(segment.replace(/\[1\]/, ''));
40
+ }
41
+ // Otherwise, if the segment is empty or html or body or ends with a subscript:
42
+ else if (segment === '' || ['html', 'body'].includes(segment) || segment.endsWith(']')) {
43
+ // Add it to the array.
44
+ normalizedSegments.push(segment);
45
+ }
46
+ // Otherwise, i.e. if the segment is a tag name with no subscript:
47
+ else {
48
+ // Add it with a subscript 1 to the array.
49
+ normalizedSegments.push(`${segment}[1]`);
50
+ }
51
+ });
52
+ // If the final segment contains any nonstandard character:
53
+ if (/[[^\]A-Za-z0-9]/.test(segments[segments.length - 1])) {
54
+ // Remove it.
55
+ normalizedSegments.pop();
56
+ }
57
+ // Return the concatenated segments as the normalized XPath.
58
+ return normalizedSegments.join('/');
59
+ }
60
+ else {
61
+ return '/html';
62
+ }
63
+ };
64
+ // Gets an XPath from a data-xpath attribute in an HTML excerpt.
65
+ export const getAttributeXPath = (html: string | null | undefined): string => {
66
+ // If there is no excerpt (e.g. a Nu Html Checker message without an extract):
67
+ if (! html) {
68
+ // Return the fallback XPath, as for an excerpt without a data-xpath attribute.
69
+ return '/html';
70
+ }
71
+ const match = html.match(/ data-xpath="([^" ]+)"/);
72
+ return match ? match[1] : '/html';
73
+ };
74
+ // Gets a tag name from an XPath.
75
+ const getXPathTagName = (xPath: string): string => {
76
+ return (xPath.split('/').pop() as string).replace(/\[.+/, '').toUpperCase();
77
+ };
78
+ // Gets a catalog index as a string from an XPath, within a checkpoint (the active one by
79
+ // default). An XPath the checkpoint's catalog lacks gets a stub entry, keyed from the report's
80
+ // monotonic counter so that entries of different checkpoints never collide.
81
+ export const getXPathCatalogIndex = (
82
+ report: Report, xPath: string, checkpoint: number = report.activeCheckpoint ?? 0
83
+ ): string => {
84
+ // The catalog always exists by the time tests cite elements (getCatalog ran first).
85
+ const {catalog} = report as Report & {catalog: Catalog};
86
+ report.pathIDs ??= {};
87
+ const pathIDs = (report.pathIDs[checkpoint] ??= {});
88
+ // Get the index of the catalog item with the XPath.
89
+ const index = pathIDs[xPath];
90
+ // If no such item exists (an index of '0' is a match, so test for absence, not falsity):
91
+ if (index === undefined) {
92
+ // Add an item to the catalog, keyed by the counter (or, in a report without one, by the
93
+ // count of items already in it).
94
+ const newIndex = report.catalogNextIndex === undefined
95
+ ? `${Object.keys(catalog).length}`
96
+ : `${report.catalogNextIndex++}`;
97
+ catalog[newIndex] = {
98
+ pathID: xPath,
99
+ tagName: getXPathTagName(xPath),
100
+ checkpoint
101
+ };
102
+ pathIDs[xPath] = newIndex;
103
+ return newIndex;
104
+ }
105
+ return index;
106
+ };
@@ -0,0 +1,6 @@
1
+ import type {Page} from 'playwright';
2
+
3
+ // The in-page script defining window.getXPath, as source text.
4
+ export const getXPathSource: string;
5
+ // Defines window.getXPath on a live page if it is not already defined.
6
+ export function defineGetXPath(page: Page): Promise<void>;
@@ -0,0 +1,70 @@
1
+ /*
2
+ © 2026 Jeff Witt.
3
+
4
+ Licensed under the MIT License. See LICENSE file at the project root or
5
+ https://opensource.org/license/mit/ for details.
6
+
7
+ SPDX-License-Identifier: MIT
8
+ */
9
+
10
+ /*
11
+ xPathScript
12
+ The in-page script that defines window.getXPath, shared by the launcher (which adds it as an
13
+ init script to every page it creates) and the checkpoint cataloguer (which defines it on a live
14
+ page that was launched without it).
15
+ */
16
+
17
+ // FUNCTIONS
18
+
19
+ // Defines window.getXPath in the page. Runs inside the page, so it must be closure-free.
20
+ const installGetXPath = () => {
21
+ window.getXPath = element => {
22
+ if (! element || element.nodeType !== Node.ELEMENT_NODE) {
23
+ return '';
24
+ }
25
+ const segments = [];
26
+ // As long as the current node is an element:
27
+ while (element && element.nodeType === Node.ELEMENT_NODE) {
28
+ const tag = element.tagName.toLowerCase();
29
+ // If it is the html element:
30
+ if (element === document.documentElement) {
31
+ // Prepend it to the segment array
32
+ segments.unshift('html');
33
+ // Stop traversing.
34
+ break;
35
+ }
36
+ // Otherwise, get its parent node.
37
+ const parent = element.parentNode;
38
+ // If (abnormally) the parent node is not an element:
39
+ if (! parent || parent.nodeType !== Node.ELEMENT_NODE) {
40
+ // Prepend the element (not the parent) to the segment array.
41
+ segments.unshift(tag);
42
+ // Stop traversing, leaving the segment array partial.
43
+ break;
44
+ }
45
+ // Get the subscript of the element if it is not the body element.
46
+ const cohort = Array
47
+ .from(parent.childNodes)
48
+ .filter(
49
+ childNode => childNode.nodeType === Node.ELEMENT_NODE
50
+ && childNode.tagName === element.tagName
51
+ );
52
+ const subscript = tag === 'body' ? '' : `[${cohort.indexOf(element) + 1}]`;
53
+ // Prepend the element identifier to the segment array.
54
+ segments.unshift(`${tag}${subscript}`);
55
+ // Continue the traversal with the parent of the current element.
56
+ element = parent;
57
+ }
58
+ // Return the XPath.
59
+ return `/${segments.join('/')}`;
60
+ };
61
+ };
62
+ // The script as source text, for addInitScript and evaluate.
63
+ const getXPathSource = exports.getXPathSource = `(${installGetXPath.toString()})();`;
64
+ // Defines window.getXPath on a live page if it is not already defined.
65
+ exports.defineGetXPath = async page => {
66
+ const isDefined = await page.evaluate(() => typeof window.getXPath === 'function');
67
+ if (! isDefined) {
68
+ await page.evaluate(getXPathSource);
69
+ }
70
+ };
package/run.js CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  const {doActs} = require('./procs/doActs');
20
20
  require('dotenv').config({quiet: true});
21
- const {isValidJob} = require('./procs/job');
21
+ const {getIsolation, isValidJob} = require('./procs/job');
22
22
  const {getCatalog} = require('./procs/catalog');
23
23
  const {nowString} = require('./procs/dateTime');
24
24
  const {chromium} = require('playwright-extra');
@@ -131,7 +131,8 @@ exports.doJob = async (job, opts = {}) => {
131
131
  presses: 0,
132
132
  amountRead: 0,
133
133
  toolTimes: {},
134
- preventions: {}
134
+ preventions: {},
135
+ isolation: getIsolation(job)
135
136
  };
136
137
  process.on('message', message => {
137
138
  if (message === 'interrupt') {
@@ -0,0 +1,44 @@
1
+ # Vendored SureA11y core bundle
2
+
3
+ Upstream: [SureA11y/core](https://github.com/SureA11y/core) (`@surea11y/core` on npm,
4
+ **MPL-2.0** — file-level copyleft: modifications to the vendored file itself must remain
5
+ MPL-2.0; the rest of this repo is unaffected. The bundle is vendored verbatim, unmodified).
6
+
7
+ ## Vendoring
8
+
9
+ No build step: upstream publishes a self-contained standalone browser bundle. To vendor or
10
+ update:
11
+
12
+ ```sh
13
+ npm pack @surea11y/core@<version>
14
+ tar xzf surea11y-core-<version>.tgz
15
+ cp package/surea11y.browser.js surea11y/surea11y.browser.js
16
+ ```
17
+
18
+ The bundle defines one global, `a11ycore`, exposing `runa11yCoreInPage(pageUrl,
19
+ contextSelector, engineOptions, runOnly)`; `tests/surea11y.js` reports the act as `prevented`
20
+ if the file is missing or the global is absent. English-only by design (locale side files
21
+ exist upstream; not vendored).
22
+
23
+ ## Result shape (verified against 1.7.0, schemaVersion 1.0.0)
24
+
25
+ `runa11yCoreInPage()` returns `{engine: {tag: 'a11ycore', schemaVersion, wcagVersion},
26
+ checksResults, rulesResults, ...}`. Each `checksResults` entry:
27
+ `{ruleId, outcome: pass|fail|cantTell|notApplicable, severity: minor|moderate|serious|critical,
28
+ confidence, type: automatic|manual, occurrences, title, meta: {normativeMappings:
29
+ [{standard, version, requirement, ...}], ...}}`. Occurrences carry `{selector, html, summary,
30
+ occurrenceOutcome?: fail|cantTell, uncertainty?}` — a `fail`-outcome rule may grade individual
31
+ occurrences into `cantTell` tier via `occurrenceOutcome`, which the adapter honors
32
+ per-occurrence, and the adapter forwards the occurrence's (else the check's) `uncertainty.code`
33
+ and `uncertainty.needed` as the standard instance's `uncertainty` and `needed`. `pass` results serialize no occurrences; `notApplicable` may carry one
34
+ scan-describing occurrence (empty selector) which the adapter must not count. Full contract:
35
+ upstream `docs/OUTPUT_SCHEMA.md` (pinned to `schemaVersion` — the adapter reports `prevented`
36
+ on a major schema change is NOT automatic; re-verify at each vendor bump).
37
+
38
+ ## Pinned version
39
+
40
+ - **Vendored:** 2026-09-01
41
+ - **Upstream:** `@surea11y/core` 1.7.0 (npm tarball, published bundle used verbatim)
42
+ - **Bundle:** 749 KB standalone browser IIFE, global `a11ycore`
43
+ - **Smoke-tested:** see yra-monitor `docs/plans/engine-candidacy-pipeline.md` candidate
44
+ register for Stage-1 results.