@taodigital/crawler 0.0.0-stage → 1.2.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 (494) hide show
  1. package/Dockerfile +82 -0
  2. package/README.md +10 -2
  3. package/dist/accessibility-auditor.d.ts +29 -0
  4. package/dist/accessibility-auditor.js +57 -0
  5. package/dist/accessibility-auditor.js.map +7 -0
  6. package/dist/accessibility-tree-crawler.d.ts +44 -0
  7. package/dist/accessibility-tree-crawler.js +156 -0
  8. package/dist/accessibility-tree-crawler.js.map +7 -0
  9. package/dist/advanced-ui-probes.d.ts +47 -0
  10. package/dist/advanced-ui-probes.js +310 -0
  11. package/dist/advanced-ui-probes.js.map +7 -0
  12. package/dist/ai-login.d.ts +32 -0
  13. package/dist/ai-login.js +250 -0
  14. package/dist/ai-login.js.map +7 -0
  15. package/dist/auth-token-rotator.d.ts +47 -0
  16. package/dist/auth-token-rotator.js +58 -0
  17. package/dist/auth-token-rotator.js.map +7 -0
  18. package/dist/auth.d.ts +20 -0
  19. package/dist/auth.js +348 -0
  20. package/dist/auth.js.map +7 -0
  21. package/dist/browser-extension.d.ts +37 -0
  22. package/dist/browser-extension.js +113 -0
  23. package/dist/browser-extension.js.map +7 -0
  24. package/dist/captcha-solver.d.ts +16 -0
  25. package/dist/captcha-solver.js +105 -0
  26. package/dist/captcha-solver.js.map +7 -0
  27. package/dist/color-contrast.d.ts +30 -0
  28. package/dist/color-contrast.js +78 -0
  29. package/dist/color-contrast.js.map +7 -0
  30. package/dist/content-chunker.d.ts +18 -0
  31. package/dist/content-chunker.js +152 -0
  32. package/dist/content-chunker.js.map +7 -0
  33. package/dist/content-dedup.d.ts +23 -0
  34. package/dist/content-dedup.js +60 -0
  35. package/dist/content-dedup.js.map +7 -0
  36. package/dist/cookie-consent.d.ts +25 -0
  37. package/dist/cookie-consent.js +78 -0
  38. package/dist/cookie-consent.js.map +7 -0
  39. package/dist/cookie-jar.d.ts +20 -0
  40. package/dist/cookie-jar.js +61 -0
  41. package/dist/cookie-jar.js.map +7 -0
  42. package/dist/crawl-session-manager.d.ts +44 -0
  43. package/dist/crawl-session-manager.js +145 -0
  44. package/dist/crawl-session-manager.js.map +7 -0
  45. package/dist/crawler.d.ts +233 -0
  46. package/dist/crawler.js +6239 -0
  47. package/dist/crawler.js.map +7 -0
  48. package/dist/crud-interaction.d.ts +31 -0
  49. package/dist/crud-interaction.js +264 -0
  50. package/dist/crud-interaction.js.map +7 -0
  51. package/dist/custom-js-injector.d.ts +42 -0
  52. package/dist/custom-js-injector.js +50 -0
  53. package/dist/custom-js-injector.js.map +7 -0
  54. package/dist/dark-mode-capture.d.ts +23 -0
  55. package/dist/dark-mode-capture.js +75 -0
  56. package/dist/dark-mode-capture.js.map +7 -0
  57. package/dist/dead-link-detector.d.ts +37 -0
  58. package/dist/dead-link-detector.js +50 -0
  59. package/dist/dead-link-detector.js.map +7 -0
  60. package/dist/dropdown-enumerator.d.ts +20 -0
  61. package/dist/dropdown-enumerator.js +230 -0
  62. package/dist/dropdown-enumerator.js.map +7 -0
  63. package/dist/element-hash.d.ts +9 -0
  64. package/dist/element-hash.js +9 -0
  65. package/dist/element-hash.js.map +7 -0
  66. package/dist/email-otp.d.ts +42 -0
  67. package/dist/email-otp.js +177 -0
  68. package/dist/email-otp.js.map +7 -0
  69. package/dist/engine-router.d.ts +47 -0
  70. package/dist/engine-router.js +94 -0
  71. package/dist/engine-router.js.map +7 -0
  72. package/dist/export/bulk-export.d.ts +26 -0
  73. package/dist/export/bulk-export.js +76 -0
  74. package/dist/export/bulk-export.js.map +7 -0
  75. package/dist/export/vector-export.d.ts +76 -0
  76. package/dist/export/vector-export.js +85 -0
  77. package/dist/export/vector-export.js.map +7 -0
  78. package/dist/extractors/advanced.d.ts +64 -0
  79. package/dist/extractors/advanced.js +265 -0
  80. package/dist/extractors/advanced.js.map +7 -0
  81. package/dist/extractors/artifact-envelope.d.ts +63 -0
  82. package/dist/extractors/artifact-envelope.js +63 -0
  83. package/dist/extractors/artifact-envelope.js.map +7 -0
  84. package/dist/extractors/branding-extractor.d.ts +46 -0
  85. package/dist/extractors/branding-extractor.js +104 -0
  86. package/dist/extractors/branding-extractor.js.map +7 -0
  87. package/dist/extractors/summary-extractor.d.ts +10 -0
  88. package/dist/extractors/summary-extractor.js +36 -0
  89. package/dist/extractors/summary-extractor.js.map +7 -0
  90. package/dist/failure-analysis-agent.d.ts +16 -0
  91. package/dist/failure-analysis-agent.js +42 -0
  92. package/dist/failure-analysis-agent.js.map +7 -0
  93. package/dist/feature-flag-detector.d.ts +30 -0
  94. package/dist/feature-flag-detector.js +55 -0
  95. package/dist/feature-flag-detector.js.map +7 -0
  96. package/dist/filter-pagination-crawler.d.ts +52 -0
  97. package/dist/filter-pagination-crawler.js +299 -0
  98. package/dist/filter-pagination-crawler.js.map +7 -0
  99. package/dist/form-detector.d.ts +34 -0
  100. package/dist/form-detector.js +58 -0
  101. package/dist/form-detector.js.map +7 -0
  102. package/dist/frontier.d.ts +40 -0
  103. package/dist/frontier.js +103 -0
  104. package/dist/frontier.js.map +7 -0
  105. package/dist/gap-pass.d.ts +36 -0
  106. package/dist/gap-pass.js +115 -0
  107. package/dist/gap-pass.js.map +7 -0
  108. package/dist/graphql-detector.d.ts +39 -0
  109. package/dist/graphql-detector.js +86 -0
  110. package/dist/graphql-detector.js.map +7 -0
  111. package/dist/http-engine.d.ts +80 -0
  112. package/dist/http-engine.js +318 -0
  113. package/dist/http-engine.js.map +7 -0
  114. package/dist/incremental-diff.d.ts +116 -0
  115. package/dist/incremental-diff.js +137 -0
  116. package/dist/incremental-diff.js.map +7 -0
  117. package/dist/index.d.ts +52 -0
  118. package/dist/index.js +83 -0
  119. package/dist/index.js.map +7 -0
  120. package/dist/input-fuzzer.d.ts +30 -0
  121. package/dist/input-fuzzer.js +105 -0
  122. package/dist/input-fuzzer.js.map +7 -0
  123. package/dist/interactive-probe.d.ts +144 -0
  124. package/dist/interactive-probe.js +865 -0
  125. package/dist/interactive-probe.js.map +7 -0
  126. package/dist/job-queue.d.ts +297 -0
  127. package/dist/job-queue.js +3812 -0
  128. package/dist/job-queue.js.map +7 -0
  129. package/dist/js-coverage.d.ts +29 -0
  130. package/dist/js-coverage.js +56 -0
  131. package/dist/js-coverage.js.map +7 -0
  132. package/dist/js-router-detector.d.ts +17 -0
  133. package/dist/js-router-detector.js +90 -0
  134. package/dist/js-router-detector.js.map +7 -0
  135. package/dist/language-detector.d.ts +22 -0
  136. package/dist/language-detector.js +57 -0
  137. package/dist/language-detector.js.map +7 -0
  138. package/dist/link-classifier.d.ts +23 -0
  139. package/dist/link-classifier.js +40 -0
  140. package/dist/link-classifier.js.map +7 -0
  141. package/dist/live-view.d.ts +36 -0
  142. package/dist/live-view.js +105 -0
  143. package/dist/live-view.js.map +7 -0
  144. package/dist/locator-extractor.d.ts +46 -0
  145. package/dist/locator-extractor.js +220 -0
  146. package/dist/locator-extractor.js.map +7 -0
  147. package/dist/logger.d.ts +2 -0
  148. package/dist/logger.js +10 -0
  149. package/dist/logger.js.map +7 -0
  150. package/dist/markdown-extract.d.ts +8 -0
  151. package/dist/markdown-extract.js +54 -0
  152. package/dist/markdown-extract.js.map +7 -0
  153. package/dist/multi-context-handler.d.ts +55 -0
  154. package/dist/multi-context-handler.js +182 -0
  155. package/dist/multi-context-handler.js.map +7 -0
  156. package/dist/native-crawler.d.ts +69 -0
  157. package/dist/native-crawler.js +839 -0
  158. package/dist/native-crawler.js.map +7 -0
  159. package/dist/nested-window-crawler.d.ts +41 -0
  160. package/dist/nested-window-crawler.js +172 -0
  161. package/dist/nested-window-crawler.js.map +7 -0
  162. package/dist/network-action-correlator.d.ts +47 -0
  163. package/dist/network-action-correlator.js +209 -0
  164. package/dist/network-action-correlator.js.map +7 -0
  165. package/dist/network-observer.d.ts +49 -0
  166. package/dist/network-observer.js +149 -0
  167. package/dist/network-observer.js.map +7 -0
  168. package/dist/network-throttle.d.ts +25 -0
  169. package/dist/network-throttle.js +34 -0
  170. package/dist/network-throttle.js.map +7 -0
  171. package/dist/openapi-generator.d.ts +49 -0
  172. package/dist/openapi-generator.js +89 -0
  173. package/dist/openapi-generator.js.map +7 -0
  174. package/dist/pdf-extractor.d.ts +28 -0
  175. package/dist/pdf-extractor.js +81 -0
  176. package/dist/pdf-extractor.js.map +7 -0
  177. package/dist/performance-metrics-collector.d.ts +50 -0
  178. package/dist/performance-metrics-collector.js +155 -0
  179. package/dist/performance-metrics-collector.js.map +7 -0
  180. package/dist/performance-metrics.d.ts +52 -0
  181. package/dist/performance-metrics.js +83 -0
  182. package/dist/performance-metrics.js.map +7 -0
  183. package/dist/phash.d.ts +50 -0
  184. package/dist/phash.js +136 -0
  185. package/dist/phash.js.map +7 -0
  186. package/dist/pii-scrubber.d.ts +21 -0
  187. package/dist/pii-scrubber.js +75 -0
  188. package/dist/pii-scrubber.js.map +7 -0
  189. package/dist/playwright-recorder.d.ts +39 -0
  190. package/dist/playwright-recorder.js +123 -0
  191. package/dist/playwright-recorder.js.map +7 -0
  192. package/dist/policies/crawl-safety.d.ts +9 -0
  193. package/dist/policies/crawl-safety.js +41 -0
  194. package/dist/policies/crawl-safety.js.map +7 -0
  195. package/dist/profiles/domain-profile.d.ts +19 -0
  196. package/dist/profiles/domain-profile.js +160 -0
  197. package/dist/profiles/domain-profile.js.map +7 -0
  198. package/dist/proxy.d.ts +50 -0
  199. package/dist/proxy.js +165 -0
  200. package/dist/proxy.js.map +7 -0
  201. package/dist/rate-limiter.d.ts +31 -0
  202. package/dist/rate-limiter.js +64 -0
  203. package/dist/rate-limiter.js.map +7 -0
  204. package/dist/redirect-tracker.d.ts +37 -0
  205. package/dist/redirect-tracker.js +65 -0
  206. package/dist/redirect-tracker.js.map +7 -0
  207. package/dist/redis-frontier.d.ts +48 -0
  208. package/dist/redis-frontier.js +126 -0
  209. package/dist/redis-frontier.js.map +7 -0
  210. package/dist/redis-queue.d.ts +48 -0
  211. package/dist/redis-queue.js +165 -0
  212. package/dist/redis-queue.js.map +7 -0
  213. package/dist/response-cache.d.ts +38 -0
  214. package/dist/response-cache.js +140 -0
  215. package/dist/response-cache.js.map +7 -0
  216. package/dist/responsive-detector.d.ts +29 -0
  217. package/dist/responsive-detector.js +46 -0
  218. package/dist/responsive-detector.js.map +7 -0
  219. package/dist/retry-policy.d.ts +20 -0
  220. package/dist/retry-policy.js +54 -0
  221. package/dist/retry-policy.js.map +7 -0
  222. package/dist/robots-txt.d.ts +9 -0
  223. package/dist/robots-txt.js +77 -0
  224. package/dist/robots-txt.js.map +7 -0
  225. package/dist/screen-reader.d.ts +15 -0
  226. package/dist/screen-reader.js +48 -0
  227. package/dist/screen-reader.js.map +7 -0
  228. package/dist/screenshot-masker.d.ts +28 -0
  229. package/dist/screenshot-masker.js +62 -0
  230. package/dist/screenshot-masker.js.map +7 -0
  231. package/dist/seo-checker.d.ts +33 -0
  232. package/dist/seo-checker.js +91 -0
  233. package/dist/seo-checker.js.map +7 -0
  234. package/dist/service-worker-interceptor.d.ts +36 -0
  235. package/dist/service-worker-interceptor.js +136 -0
  236. package/dist/service-worker-interceptor.js.map +7 -0
  237. package/dist/session-capture.d.ts +39 -0
  238. package/dist/session-capture.js +274 -0
  239. package/dist/session-capture.js.map +7 -0
  240. package/dist/session-export.d.ts +49 -0
  241. package/dist/session-export.js +117 -0
  242. package/dist/session-export.js.map +7 -0
  243. package/dist/shadow-dom-crawler.d.ts +35 -0
  244. package/dist/shadow-dom-crawler.js +132 -0
  245. package/dist/shadow-dom-crawler.js.map +7 -0
  246. package/dist/sitemap-writer.d.ts +21 -0
  247. package/dist/sitemap-writer.js +47 -0
  248. package/dist/sitemap-writer.js.map +7 -0
  249. package/dist/sitemap.d.ts +51 -0
  250. package/dist/sitemap.js +160 -0
  251. package/dist/sitemap.js.map +7 -0
  252. package/dist/skyvern.d.ts +56 -0
  253. package/dist/skyvern.js +129 -0
  254. package/dist/skyvern.js.map +7 -0
  255. package/dist/sqs-queue.d.ts +13 -0
  256. package/dist/sqs-queue.js +115 -0
  257. package/dist/sqs-queue.js.map +7 -0
  258. package/dist/sso-token.d.ts +29 -0
  259. package/dist/sso-token.js +76 -0
  260. package/dist/sso-token.js.map +7 -0
  261. package/dist/state-graph.d.ts +59 -0
  262. package/dist/state-graph.js +193 -0
  263. package/dist/state-graph.js.map +7 -0
  264. package/dist/stealth/human-behavior.d.ts +20 -0
  265. package/dist/stealth/human-behavior.js +202 -0
  266. package/dist/stealth/human-behavior.js.map +7 -0
  267. package/dist/telemetry.d.ts +34 -0
  268. package/dist/telemetry.js +77 -0
  269. package/dist/telemetry.js.map +7 -0
  270. package/dist/test-executor.d.ts +81 -0
  271. package/dist/test-executor.js +443 -0
  272. package/dist/test-executor.js.map +7 -0
  273. package/dist/tls-fingerprint.d.ts +50 -0
  274. package/dist/tls-fingerprint.js +81 -0
  275. package/dist/tls-fingerprint.js.map +7 -0
  276. package/dist/url-pattern-completer.d.ts +28 -0
  277. package/dist/url-pattern-completer.js +122 -0
  278. package/dist/url-pattern-completer.js.map +7 -0
  279. package/dist/visual-diff-verdict.d.ts +40 -0
  280. package/dist/visual-diff-verdict.js +27 -0
  281. package/dist/visual-diff-verdict.js.map +7 -0
  282. package/dist/webhook-notifier.d.ts +30 -0
  283. package/dist/webhook-notifier.js +76 -0
  284. package/dist/webhook-notifier.js.map +7 -0
  285. package/dist/websocket-detector.d.ts +24 -0
  286. package/dist/websocket-detector.js +60 -0
  287. package/dist/websocket-detector.js.map +7 -0
  288. package/dist/worker.d.ts +1 -0
  289. package/dist/worker.js +33 -0
  290. package/dist/worker.js.map +7 -0
  291. package/package.json +49 -4
  292. package/src/accessibility-auditor.ts +102 -0
  293. package/src/accessibility-tree-crawler.ts +246 -0
  294. package/src/advanced-ui-probes.ts +470 -0
  295. package/src/ai-login.ts +298 -0
  296. package/src/auth-token-rotator.ts +89 -0
  297. package/src/auth.ts +418 -0
  298. package/src/browser-extension.ts +186 -0
  299. package/src/captcha-solver.ts +143 -0
  300. package/src/color-contrast.ts +116 -0
  301. package/src/content-chunker.ts +170 -0
  302. package/src/content-dedup.ts +99 -0
  303. package/src/cookie-consent.ts +106 -0
  304. package/src/cookie-jar.ts +91 -0
  305. package/src/crawl-session-manager.ts +231 -0
  306. package/src/crawler.ts +7123 -0
  307. package/src/crawler.ts.rej +12 -0
  308. package/src/crud-interaction.ts +386 -0
  309. package/src/custom-js-injector.ts +93 -0
  310. package/src/dark-mode-capture.ts +110 -0
  311. package/src/dead-link-detector.ts +76 -0
  312. package/src/dropdown-enumerator.ts +312 -0
  313. package/src/element-hash.ts +16 -0
  314. package/src/email-otp.ts +252 -0
  315. package/src/engine-router.ts +141 -0
  316. package/src/export/bulk-export.ts +85 -0
  317. package/src/export/vector-export.ts +160 -0
  318. package/src/extractors/advanced.ts +309 -0
  319. package/src/extractors/artifact-envelope.ts +111 -0
  320. package/src/extractors/branding-extractor.ts +159 -0
  321. package/src/extractors/summary-extractor.ts +49 -0
  322. package/src/failure-analysis-agent.ts +51 -0
  323. package/src/feature-flag-detector.ts +97 -0
  324. package/src/filter-pagination-crawler.ts +500 -0
  325. package/src/form-detector.ts +103 -0
  326. package/src/frontier.test.ts +64 -0
  327. package/src/frontier.ts +144 -0
  328. package/src/gap-pass.ts +165 -0
  329. package/src/graphql-detector.ts +129 -0
  330. package/src/http-engine.ts +453 -0
  331. package/src/incremental-diff.ts +259 -0
  332. package/src/index.ts +52 -0
  333. package/src/input-fuzzer.ts +129 -0
  334. package/src/interactive-probe.ts +1136 -0
  335. package/src/job-queue.test.ts +187 -0
  336. package/src/job-queue.ts +4504 -0
  337. package/src/js-coverage.ts +87 -0
  338. package/src/js-router-detector.ts +112 -0
  339. package/src/language-detector.ts +82 -0
  340. package/src/link-classifier.ts +65 -0
  341. package/src/live-view.ts +146 -0
  342. package/src/locator-extractor.ts +309 -0
  343. package/src/logger.ts +9 -0
  344. package/src/markdown-extract.test.ts +73 -0
  345. package/src/markdown-extract.ts +76 -0
  346. package/src/multi-context-handler.ts +296 -0
  347. package/src/native-crawler.ts +1108 -0
  348. package/src/nested-window-crawler.ts +310 -0
  349. package/src/network-action-correlator.ts +320 -0
  350. package/src/network-observer.ts +204 -0
  351. package/src/network-throttle.ts +69 -0
  352. package/src/openapi-generator.ts +135 -0
  353. package/src/pdf-extractor.ts +123 -0
  354. package/src/performance-metrics-collector.ts +243 -0
  355. package/src/performance-metrics.ts +134 -0
  356. package/src/phash.ts +184 -0
  357. package/src/pii-scrubber.ts +99 -0
  358. package/src/playwright-recorder.ts +170 -0
  359. package/src/policies/crawl-safety.ts +52 -0
  360. package/src/profiles/domain-profile.ts +190 -0
  361. package/src/proxy.ts +238 -0
  362. package/src/rate-limiter.ts +87 -0
  363. package/src/redirect-tracker.ts +97 -0
  364. package/src/redis-frontier.ts +143 -0
  365. package/src/redis-queue.ts +208 -0
  366. package/src/response-cache.ts +150 -0
  367. package/src/responsive-detector.ts +92 -0
  368. package/src/retry-policy.ts +87 -0
  369. package/src/robots-txt.ts +96 -0
  370. package/src/screen-reader.ts +98 -0
  371. package/src/screenshot-masker.ts +98 -0
  372. package/src/seo-checker.ts +134 -0
  373. package/src/service-worker-interceptor.ts +185 -0
  374. package/src/session-capture.ts +335 -0
  375. package/src/session-export.test.ts +75 -0
  376. package/src/session-export.ts +172 -0
  377. package/src/shadow-dom-crawler.ts +198 -0
  378. package/src/sitemap-writer.ts +65 -0
  379. package/src/sitemap.test.ts +127 -0
  380. package/src/sitemap.ts +233 -0
  381. package/src/skyvern.ts +199 -0
  382. package/src/sqs-queue.ts +129 -0
  383. package/src/sso-token.ts +120 -0
  384. package/src/state-graph.ts +280 -0
  385. package/src/stealth/human-behavior.ts +227 -0
  386. package/src/telemetry.ts +122 -0
  387. package/src/test-executor.test.ts +72 -0
  388. package/src/test-executor.ts +578 -0
  389. package/src/tls-fingerprint.ts +111 -0
  390. package/src/url-pattern-completer.ts +161 -0
  391. package/src/vendor.d.ts +20 -0
  392. package/src/visual-diff-verdict.test.ts +80 -0
  393. package/src/visual-diff-verdict.ts +59 -0
  394. package/src/webhook-notifier.ts +109 -0
  395. package/src/websocket-detector.ts +83 -0
  396. package/src/worker.ts +50 -0
  397. package/tsconfig.json +13 -0
  398. package/types/accessibility-auditor.d.ts +29 -0
  399. package/types/accessibility-tree-crawler.d.ts +44 -0
  400. package/types/advanced-ui-probes.d.ts +47 -0
  401. package/types/ai-login.d.ts +32 -0
  402. package/types/auth-token-rotator.d.ts +47 -0
  403. package/types/auth.d.ts +20 -0
  404. package/types/browser-extension.d.ts +37 -0
  405. package/types/bull-worker.d.ts +6 -0
  406. package/types/captcha-solver.d.ts +16 -0
  407. package/types/color-contrast.d.ts +30 -0
  408. package/types/content-chunker.d.ts +18 -0
  409. package/types/content-dedup.d.ts +23 -0
  410. package/types/cookie-consent.d.ts +25 -0
  411. package/types/cookie-jar.d.ts +20 -0
  412. package/types/crawl-session-manager.d.ts +44 -0
  413. package/types/crawler.d.ts +233 -0
  414. package/types/crud-interaction.d.ts +31 -0
  415. package/types/custom-js-injector.d.ts +42 -0
  416. package/types/dark-mode-capture.d.ts +23 -0
  417. package/types/dead-link-detector.d.ts +37 -0
  418. package/types/dropdown-enumerator.d.ts +20 -0
  419. package/types/element-hash.d.ts +9 -0
  420. package/types/email-otp.d.ts +42 -0
  421. package/types/engine-router.d.ts +47 -0
  422. package/types/export/bulk-export.d.ts +26 -0
  423. package/types/export/vector-export.d.ts +76 -0
  424. package/types/extractors/advanced.d.ts +64 -0
  425. package/types/extractors/artifact-envelope.d.ts +63 -0
  426. package/types/extractors/branding-extractor.d.ts +46 -0
  427. package/types/extractors/summary-extractor.d.ts +10 -0
  428. package/types/failure-analysis-agent.d.ts +16 -0
  429. package/types/feature-flag-detector.d.ts +30 -0
  430. package/types/filter-pagination-crawler.d.ts +52 -0
  431. package/types/form-detector.d.ts +34 -0
  432. package/types/frontier.d.ts +40 -0
  433. package/types/gap-pass.d.ts +36 -0
  434. package/types/graphql-detector.d.ts +39 -0
  435. package/types/http-engine.d.ts +80 -0
  436. package/types/incremental-diff.d.ts +116 -0
  437. package/types/index.d.ts +52 -0
  438. package/types/input-fuzzer.d.ts +30 -0
  439. package/types/interactive-probe.d.ts +144 -0
  440. package/types/job-queue.d.ts +308 -0
  441. package/types/js-coverage.d.ts +29 -0
  442. package/types/js-router-detector.d.ts +17 -0
  443. package/types/language-detector.d.ts +22 -0
  444. package/types/link-classifier.d.ts +23 -0
  445. package/types/live-view.d.ts +36 -0
  446. package/types/locator-extractor.d.ts +46 -0
  447. package/types/logger.d.ts +2 -0
  448. package/types/markdown-extract.d.ts +8 -0
  449. package/types/multi-context-handler.d.ts +55 -0
  450. package/types/native-crawler.d.ts +69 -0
  451. package/types/nested-window-crawler.d.ts +41 -0
  452. package/types/network-action-correlator.d.ts +47 -0
  453. package/types/network-observer.d.ts +49 -0
  454. package/types/network-throttle.d.ts +25 -0
  455. package/types/openapi-generator.d.ts +49 -0
  456. package/types/pdf-extractor.d.ts +28 -0
  457. package/types/performance-metrics-collector.d.ts +50 -0
  458. package/types/performance-metrics.d.ts +52 -0
  459. package/types/phash.d.ts +50 -0
  460. package/types/pii-scrubber.d.ts +21 -0
  461. package/types/playwright-recorder.d.ts +39 -0
  462. package/types/policies/crawl-safety.d.ts +9 -0
  463. package/types/profiles/domain-profile.d.ts +19 -0
  464. package/types/proxy.d.ts +50 -0
  465. package/types/rate-limiter.d.ts +31 -0
  466. package/types/redirect-tracker.d.ts +37 -0
  467. package/types/redis-frontier.d.ts +48 -0
  468. package/types/redis-queue.d.ts +48 -0
  469. package/types/response-cache.d.ts +38 -0
  470. package/types/responsive-detector.d.ts +29 -0
  471. package/types/retry-policy.d.ts +20 -0
  472. package/types/robots-txt.d.ts +9 -0
  473. package/types/screen-reader.d.ts +15 -0
  474. package/types/screenshot-masker.d.ts +28 -0
  475. package/types/seo-checker.d.ts +33 -0
  476. package/types/service-worker-interceptor.d.ts +36 -0
  477. package/types/session-capture.d.ts +39 -0
  478. package/types/session-export.d.ts +49 -0
  479. package/types/shadow-dom-crawler.d.ts +35 -0
  480. package/types/sitemap-writer.d.ts +21 -0
  481. package/types/sitemap.d.ts +51 -0
  482. package/types/skyvern.d.ts +56 -0
  483. package/types/sqs-queue.d.ts +13 -0
  484. package/types/sso-token.d.ts +29 -0
  485. package/types/state-graph.d.ts +59 -0
  486. package/types/stealth/human-behavior.d.ts +20 -0
  487. package/types/telemetry.d.ts +34 -0
  488. package/types/test-executor.d.ts +84 -0
  489. package/types/tls-fingerprint.d.ts +50 -0
  490. package/types/url-pattern-completer.d.ts +28 -0
  491. package/types/visual-diff-verdict.d.ts +40 -0
  492. package/types/webhook-notifier.d.ts +30 -0
  493. package/types/websocket-detector.d.ts +24 -0
  494. package/types/worker.d.ts +1 -0
package/Dockerfile ADDED
@@ -0,0 +1,82 @@
1
+ # ZeTa-AI Crawler — includes Playwright + Chromium
2
+ # Playwright needs a real Linux environment with system deps.
3
+ # This service CANNOT run on Vercel serverless — use Railway/Render.
4
+ # IMPORTANT: ECS Fargate task definition must set sharedMemorySize: 2048 (MB) for Chromium stability
5
+ FROM mcr.microsoft.com/playwright:v1.55.0-jammy AS runner
6
+ WORKDIR /app
7
+ ENV NODE_ENV=production
8
+ # Install browsers to a fixed path — base image ships browsers here and
9
+ # we override after npm ci to match the exact installed playwright revision.
10
+ ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
11
+
12
+ # Install Node.js 20 (Playwright base image ships with 18)
13
+ RUN apt-get update && apt-get install -y curl build-essential python3 && \
14
+ curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
15
+ apt-get install -y nodejs && \
16
+ apt-get clean && rm -rf /var/lib/apt/lists/*
17
+
18
+ # Workspace manifests (layer cache)
19
+ # Copy all workspace package.json files so npm ci can resolve the full lockfile.
20
+ # Packages not used by the crawler (api, web, etc.) are stubs; their source is not copied later.
21
+ COPY package.json package-lock.json ./
22
+ COPY packages/agent-cli/package.json packages/agent-cli/
23
+ COPY packages/agents/package.json packages/agents/
24
+ COPY packages/api/package.json packages/api/
25
+ COPY packages/app-brain/package.json packages/app-brain/
26
+ COPY packages/chrome-extension/package.json packages/chrome-extension/
27
+ COPY packages/connectors/package.json packages/connectors/
28
+ COPY packages/core/package.json packages/core/
29
+ COPY packages/crawler/package.json packages/crawler/
30
+ COPY packages/database/package.json packages/database/
31
+ COPY packages/github-action/package.json packages/github-action/
32
+ COPY packages/reranker/package.json packages/reranker/
33
+ COPY packages/sdk/package.json packages/sdk/
34
+ COPY packages/session-receiver/package.json packages/session-receiver/
35
+ COPY packages/vscode-extension/package.json packages/vscode-extension/
36
+ COPY packages/web/package.json packages/web/
37
+ RUN npm ci --include=dev
38
+
39
+ # Patch Stagehand's act() schema to add `additionalProperties: false` on the
40
+ # inner anyOf[0] object. OpenAI strict mode (v1/responses) requires it on every
41
+ # nested object; Stagehand ≤3.6 omits it, causing a 400 "invalid_json_schema".
42
+ RUN node -e "const fs=require('fs');['packages/crawler/node_modules/@browserbasehq/stagehand/dist/cjs/lib/inference.js','packages/crawler/node_modules/@browserbasehq/stagehand/dist/esm/lib/inference.js'].forEach(f=>{if(!fs.existsSync(f)){console.log('skip',f);return;}let c=fs.readFileSync(f,'utf8');if(c.includes('.strict()')){console.log('already patched',f);return;}c=c.replace(/\\.nullable\\(\\)\\n(\\s+)\\.describe\\(\"The element to act on/g,'\.strict()\n\$1.nullable()\n\$1.describe(\"The element to act on');fs.writeFileSync(f,c);console.log('patched',f);});"
43
+
44
+ # Re-install chromium after npm ci so the browser revision matches the
45
+ # exact playwright version resolved by the lockfile (not the base image's
46
+ # bundled version, which may differ if the lockfile was updated).
47
+ RUN npx playwright install chromium
48
+
49
+ # Source
50
+ COPY tsconfig.base.json ./
51
+ COPY packages/database packages/database
52
+ COPY packages/reranker packages/reranker
53
+ COPY packages/core packages/core
54
+ COPY packages/connectors packages/connectors
55
+ COPY packages/app-brain packages/app-brain
56
+ COPY packages/agents packages/agents
57
+ COPY packages/crawler packages/crawler
58
+
59
+ # Build order: database → reranker → core → connectors → app-brain → agents → crawler
60
+ RUN npx prisma generate --schema packages/database/prisma/schema.prisma && \
61
+ npm run -w @detiq/database build && \
62
+ npm run -w @detiq/reranker build && \
63
+ npm run -w @detiq/core build && \
64
+ npm run -w @detiq/connectors build && \
65
+ npm run -w @detiq/app-brain build && \
66
+ npm run -w @detiq/agents build && \
67
+ npm run -w @detiq/crawler build
68
+
69
+ # Screenshot cache dir
70
+ RUN mkdir -p /app/.screenshots-cache
71
+
72
+ RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser
73
+ RUN chown -R appuser:appgroup /app
74
+ USER appuser
75
+
76
+ EXPOSE 4001
77
+ # index.js is a side-effect-free library barrel (also imported by @detiq/api) — it holds
78
+ # no listener/timer, so running it directly starts the process, finishes its imports,
79
+ # and exits immediately with nothing ever consuming the job queue. worker.js is the
80
+ # actual long-running entrypoint: it starts the durable job-poll loop (and the SQS
81
+ # consumer when JOB_QUEUE_BACKEND=sqs) and keeps the process alive.
82
+ CMD ["node", "packages/crawler/dist/worker.js"]
package/README.md CHANGED
@@ -1,3 +1,11 @@
1
- # Temporary Holding Version
1
+ # @detiq/crawler — The Explorer
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Crawls an app, **gets past the login** (the star of Phase 1), discovers
4
+ screens, captures screenshots, and reads each page's elements into the App
5
+ Brain.
6
+
7
+ - `auth.ts` — login handling. **Invest here**; it's the competitive edge.
8
+ - `screen-reader.ts` — reads pages as a cheap structured outline (accessibility
9
+ tree), not pixels. Vision is a later fallback.
10
+ - `crawler.ts` — the discovery loop. Swap in an AI navigation library
11
+ (Stagehand / Browser Use) to explore more intelligently.
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Accessibility auditor — lightweight a11y checks using Playwright's aria snapshot
3
+ * and manual DOM queries. No axe-core dependency needed.
4
+ *
5
+ * Checks:
6
+ * 1. Images without alt text
7
+ * 2. Form inputs without associated labels
8
+ * 3. Buttons/links with no accessible name
9
+ * 4. Missing lang attribute on html element
10
+ * 5. Missing page title
11
+ * 6. Empty headings
12
+ * 7. Color contrast (limited — detects text with inline style color only)
13
+ * 8. Keyboard-unfocusable interactive elements (tabIndex=-1 on buttons)
14
+ */
15
+ import type { Page } from 'playwright';
16
+ export interface A11yViolation {
17
+ rule: string;
18
+ severity: 'critical' | 'serious' | 'moderate' | 'minor';
19
+ count: number;
20
+ examples: string[];
21
+ }
22
+ export interface A11yAuditResult {
23
+ url: string;
24
+ violations: A11yViolation[];
25
+ passCount: number;
26
+ score: number;
27
+ auditedAt: string;
28
+ }
29
+ export declare function auditAccessibility(page: Page, url: string): Promise<A11yAuditResult>;
@@ -0,0 +1,57 @@
1
+ async function queryAll(page, selector) {
2
+ try {
3
+ return await page.$$eval(selector, (els) => els.map((el) => ({
4
+ outerHTML: el.outerHTML?.slice(0, 200) ?? "",
5
+ textContent: (el.textContent ?? "").trim().slice(0, 100),
6
+ tabIndex: el.tabIndex,
7
+ getAttribute: (a) => el.getAttribute(a)
8
+ })));
9
+ } catch {
10
+ return [];
11
+ }
12
+ }
13
+ async function auditAccessibility(page, url) {
14
+ const violations = [];
15
+ let passCount = 0;
16
+ const auditedAt = (/* @__PURE__ */ new Date()).toISOString();
17
+ const imgs = await page.$$eval("img:not([alt])", (els) => els.map((e) => e.outerHTML?.slice(0, 120) ?? ""));
18
+ if (imgs.length > 0) violations.push({ rule: "image-alt", severity: "critical", count: imgs.length, examples: imgs.slice(0, 3) });
19
+ else passCount++;
20
+ const unlabeledInputs = await page.$$eval(
21
+ 'input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not([aria-label]):not([aria-labelledby]):not([id])',
22
+ (els) => els.map((e) => e.outerHTML?.slice(0, 120) ?? "")
23
+ );
24
+ if (unlabeledInputs.length > 0) violations.push({ rule: "label", severity: "serious", count: unlabeledInputs.length, examples: unlabeledInputs.slice(0, 3) });
25
+ else passCount++;
26
+ const emptyButtons = await page.$$eval(
27
+ "button:not([aria-label]):not([aria-labelledby])",
28
+ (els) => els.filter((e) => !(e.textContent ?? "").trim()).map((e) => e.outerHTML?.slice(0, 120) ?? "")
29
+ );
30
+ if (emptyButtons.length > 0) violations.push({ rule: "button-name", severity: "critical", count: emptyButtons.length, examples: emptyButtons.slice(0, 3) });
31
+ else passCount++;
32
+ const htmlLang = await page.$eval("html", (el) => el.getAttribute("lang") ?? "").catch(() => "");
33
+ if (!htmlLang) violations.push({ rule: "html-has-lang", severity: "serious", count: 1, examples: ["<html> missing lang attribute"] });
34
+ else passCount++;
35
+ const title = await page.title().catch(() => "");
36
+ if (!title) violations.push({ rule: "document-title", severity: "serious", count: 1, examples: ["Page has no <title>"] });
37
+ else passCount++;
38
+ const emptyHeadings = await page.$$eval(
39
+ "h1,h2,h3,h4,h5,h6",
40
+ (els) => els.filter((e) => !(e.textContent ?? "").trim()).map((e) => e.tagName.toLowerCase())
41
+ );
42
+ if (emptyHeadings.length > 0) violations.push({ rule: "empty-heading", severity: "moderate", count: emptyHeadings.length, examples: emptyHeadings.slice(0, 3) });
43
+ else passCount++;
44
+ const emptyLinks = await page.$$eval(
45
+ "a[href]:not([aria-label]):not([aria-labelledby])",
46
+ (els) => els.filter((e) => !(e.textContent ?? "").trim() && !e.querySelector("img[alt]")).map((e) => e.outerHTML?.slice(0, 120) ?? "")
47
+ );
48
+ if (emptyLinks.length > 0) violations.push({ rule: "link-name", severity: "serious", count: emptyLinks.length, examples: emptyLinks.slice(0, 3) });
49
+ else passCount++;
50
+ const totalChecks = passCount + violations.length;
51
+ const score = totalChecks > 0 ? Math.round(passCount / totalChecks * 100) : 100;
52
+ return { url, violations, passCount, score, auditedAt };
53
+ }
54
+ export {
55
+ auditAccessibility
56
+ };
57
+ //# sourceMappingURL=accessibility-auditor.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/accessibility-auditor.ts"],
4
+ "sourcesContent": ["/**\n * Accessibility auditor \u2014 lightweight a11y checks using Playwright's aria snapshot\n * and manual DOM queries. No axe-core dependency needed.\n *\n * Checks:\n * 1. Images without alt text\n * 2. Form inputs without associated labels\n * 3. Buttons/links with no accessible name\n * 4. Missing lang attribute on html element\n * 5. Missing page title\n * 6. Empty headings\n * 7. Color contrast (limited \u2014 detects text with inline style color only)\n * 8. Keyboard-unfocusable interactive elements (tabIndex=-1 on buttons)\n */\n\nimport type { Page } from 'playwright';\n\nexport interface A11yViolation {\n rule: string;\n severity: 'critical' | 'serious' | 'moderate' | 'minor';\n count: number;\n examples: string[];\n}\n\nexport interface A11yAuditResult {\n url: string;\n violations: A11yViolation[];\n passCount: number;\n score: number; // 0-100\n auditedAt: string;\n}\n\nasync function queryAll(page: Page, selector: string): Promise<any[]> {\n try {\n return await page.$$eval(selector, els => els.map((el: any) => ({\n outerHTML: el.outerHTML?.slice(0, 200) ?? '',\n textContent: (el.textContent ?? '').trim().slice(0, 100),\n tabIndex: el.tabIndex,\n getAttribute: (a: string) => el.getAttribute(a),\n })));\n } catch {\n return [];\n }\n}\n\nexport async function auditAccessibility(page: Page, url: string): Promise<A11yAuditResult> {\n const violations: A11yViolation[] = [];\n let passCount = 0;\n const auditedAt = new Date().toISOString();\n\n // 1. Images without alt\n const imgs = await page.$$eval('img:not([alt])', els => els.map((e: any) => e.outerHTML?.slice(0, 120) ?? ''));\n if (imgs.length > 0) violations.push({ rule: 'image-alt', severity: 'critical', count: imgs.length, examples: imgs.slice(0, 3) });\n else passCount++;\n\n // 2. Inputs without labels\n const unlabeledInputs = await page.$$eval(\n 'input:not([type=\"hidden\"]):not([type=\"submit\"]):not([type=\"button\"]):not([aria-label]):not([aria-labelledby]):not([id])',\n els => els.map((e: any) => e.outerHTML?.slice(0, 120) ?? ''),\n );\n if (unlabeledInputs.length > 0) violations.push({ rule: 'label', severity: 'serious', count: unlabeledInputs.length, examples: unlabeledInputs.slice(0, 3) });\n else passCount++;\n\n // 3. Buttons with no text\n const emptyButtons = await page.$$eval(\n 'button:not([aria-label]):not([aria-labelledby])',\n els => els.filter((e: any) => !(e.textContent ?? '').trim()).map((e: any) => e.outerHTML?.slice(0, 120) ?? ''),\n );\n if (emptyButtons.length > 0) violations.push({ rule: 'button-name', severity: 'critical', count: emptyButtons.length, examples: emptyButtons.slice(0, 3) });\n else passCount++;\n\n // 4. Missing html lang\n const htmlLang = await page.$eval('html', (el: any) => el.getAttribute('lang') ?? '').catch(() => '');\n if (!htmlLang) violations.push({ rule: 'html-has-lang', severity: 'serious', count: 1, examples: ['<html> missing lang attribute'] });\n else passCount++;\n\n // 5. Missing page title\n const title = await page.title().catch(() => '');\n if (!title) violations.push({ rule: 'document-title', severity: 'serious', count: 1, examples: ['Page has no <title>'] });\n else passCount++;\n\n // 6. Empty headings\n const emptyHeadings = await page.$$eval(\n 'h1,h2,h3,h4,h5,h6',\n els => els.filter((e: any) => !(e.textContent ?? '').trim()).map((e: any) => e.tagName.toLowerCase()),\n );\n if (emptyHeadings.length > 0) violations.push({ rule: 'empty-heading', severity: 'moderate', count: emptyHeadings.length, examples: emptyHeadings.slice(0, 3) });\n else passCount++;\n\n // 7. Links with no accessible name\n const emptyLinks = await page.$$eval(\n 'a[href]:not([aria-label]):not([aria-labelledby])',\n els => els.filter((e: any) => !(e.textContent ?? '').trim() && !e.querySelector('img[alt]')).map((e: any) => e.outerHTML?.slice(0, 120) ?? ''),\n );\n if (emptyLinks.length > 0) violations.push({ rule: 'link-name', severity: 'serious', count: emptyLinks.length, examples: emptyLinks.slice(0, 3) });\n else passCount++;\n\n const totalChecks = passCount + violations.length;\n const score = totalChecks > 0 ? Math.round((passCount / totalChecks) * 100) : 100;\n\n return { url, violations, passCount, score, auditedAt };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Accessibility tree crawler — extract landmark, heading, and ARIA metadata from crawled pages.
3
+ *
4
+ * Captures: landmarks with interactive counts, heading hierarchy with violation detection,
5
+ * interactive elements missing accessible names, live regions, and skip-link presence.
6
+ *
7
+ * This data feeds ZeTa's accessibility test generator to surface WCAG 2.1 Level A/AA
8
+ * failures (missing names, heading skips, absent skip links, unlabeled live regions).
9
+ */
10
+ export interface LandmarkInfo {
11
+ role: string;
12
+ label: string;
13
+ elementId: string;
14
+ interactiveCount: number;
15
+ }
16
+ export interface HeadingInfo {
17
+ level: number;
18
+ text: string;
19
+ elementId: string;
20
+ }
21
+ export interface MissingNameEl {
22
+ tagName: string;
23
+ role: string;
24
+ elementId: string;
25
+ htmlSnippet: string;
26
+ }
27
+ export interface LiveRegionInfo {
28
+ role: string;
29
+ ariaLive: string;
30
+ ariaAtomic: string;
31
+ currentText: string;
32
+ }
33
+ export interface AccessibilityTreeResult {
34
+ landmarkCount: number;
35
+ landmarks: LandmarkInfo[];
36
+ headings: HeadingInfo[];
37
+ headingHierarchyViolations: string[];
38
+ missingNameElements: MissingNameEl[];
39
+ missingNameCount: number;
40
+ liveRegions: LiveRegionInfo[];
41
+ totalInteractiveCount: number;
42
+ hasSkipLink: boolean;
43
+ }
44
+ export declare function crawlAccessibilityTree(page: any): Promise<AccessibilityTreeResult>;
@@ -0,0 +1,156 @@
1
+ async function extractLandmarks(page) {
2
+ try {
3
+ const raw = await page.evaluate(() => {
4
+ const LANDMARK_SELECTORS = [
5
+ { role: "banner", selector: 'header,[role="banner"]' },
6
+ { role: "navigation", selector: 'nav,[role="navigation"]' },
7
+ { role: "main", selector: 'main,[role="main"]' },
8
+ { role: "complementary", selector: 'aside,[role="complementary"]' },
9
+ { role: "contentinfo", selector: 'footer,[role="contentinfo"]' },
10
+ { role: "search", selector: '[role="search"]' },
11
+ { role: "form", selector: 'form[aria-label],[role="form"]' },
12
+ { role: "region", selector: '[role="region"][aria-label]' }
13
+ ];
14
+ return LANDMARK_SELECTORS.flatMap(
15
+ ({ role, selector }) => [...document.querySelectorAll(selector)].slice(0, 10).map((el) => ({
16
+ role,
17
+ label: el.getAttribute("aria-label") || el.getAttribute("aria-labelledby") || "",
18
+ elementId: el.id || "",
19
+ interactiveCount: el.querySelectorAll(
20
+ 'button,a[href],input,select,textarea,[role="button"],[tabindex="0"]'
21
+ ).length
22
+ }))
23
+ );
24
+ });
25
+ return raw.slice(0, 50);
26
+ } catch {
27
+ return [];
28
+ }
29
+ }
30
+ async function extractHeadings(page) {
31
+ try {
32
+ const raw = await page.evaluate(() => {
33
+ const headingEls = [...document.querySelectorAll('h1,h2,h3,h4,h5,h6,[role="heading"]')];
34
+ return headingEls.map((el) => ({
35
+ level: parseInt(el.tagName.slice(1)) || parseInt(el.getAttribute("aria-level") || "0") || 0,
36
+ text: el.textContent?.trim().slice(0, 100) || "",
37
+ elementId: el.id || ""
38
+ })).filter((h) => h.level >= 1 && h.level <= 6);
39
+ });
40
+ return raw.slice(0, 100);
41
+ } catch {
42
+ return [];
43
+ }
44
+ }
45
+ function detectHeadingViolations(headings) {
46
+ const violations = [];
47
+ if (headings.length === 0) return violations;
48
+ const h1s = headings.filter((h) => h.level === 1);
49
+ if (h1s.length === 0) {
50
+ violations.push("Missing h1 landmark");
51
+ } else if (h1s.length > 1) {
52
+ violations.push("Multiple h1 elements found");
53
+ }
54
+ let prevLevel = 0;
55
+ for (const heading of headings) {
56
+ if (prevLevel > 0 && heading.level > prevLevel + 1) {
57
+ violations.push(
58
+ `Heading level skip: h${prevLevel} to h${heading.level}`
59
+ );
60
+ }
61
+ prevLevel = heading.level;
62
+ }
63
+ return violations;
64
+ }
65
+ async function findMissingNames(page) {
66
+ try {
67
+ return await page.evaluate(() => {
68
+ const INTERACTIVE_SELECTOR = 'button,a[href],input:not([type="hidden"]),select,textarea,[role="button"],[role="link"],[role="checkbox"],[role="radio"],[role="switch"],[role="menuitem"],[role="tab"]';
69
+ return [...document.querySelectorAll(INTERACTIVE_SELECTOR)].filter((el) => {
70
+ const labelledById = el.getAttribute("aria-labelledby") || "";
71
+ const name = (el.getAttribute("aria-label") || "").trim() || (labelledById ? document.getElementById(labelledById)?.textContent?.trim() ?? "" : "") || (el.textContent || "").trim() || (el.placeholder || "").trim() || (el.title || "").trim() || (el.alt || "").trim();
72
+ return !name || name.length === 0;
73
+ }).slice(0, 30).map((el) => ({
74
+ tagName: el.tagName.toLowerCase(),
75
+ role: el.getAttribute("role") || "",
76
+ elementId: el.id || "",
77
+ htmlSnippet: el.outerHTML.slice(0, 120)
78
+ }));
79
+ });
80
+ } catch {
81
+ return [];
82
+ }
83
+ }
84
+ async function extractLiveRegions(page) {
85
+ try {
86
+ return await page.evaluate(() => {
87
+ const els = [
88
+ ...document.querySelectorAll(
89
+ '[aria-live],[role="alert"],[role="status"],[role="log"]'
90
+ )
91
+ ];
92
+ return els.slice(0, 20).map((el) => ({
93
+ role: el.getAttribute("role") || "",
94
+ ariaLive: el.getAttribute("aria-live") || "",
95
+ ariaAtomic: el.getAttribute("aria-atomic") || "",
96
+ currentText: (el.textContent || "").trim().slice(0, 200)
97
+ }));
98
+ });
99
+ } catch {
100
+ return [];
101
+ }
102
+ }
103
+ async function checkSkipLink(page) {
104
+ try {
105
+ return await page.evaluate(() => {
106
+ const firstFocusable = document.querySelector('a[href^="#"],a:first-of-type');
107
+ return !!(firstFocusable && /skip/i.test(
108
+ (firstFocusable.textContent || "") + (firstFocusable.getAttribute("href") || "")
109
+ ));
110
+ });
111
+ } catch {
112
+ return false;
113
+ }
114
+ }
115
+ async function crawlAccessibilityTree(page) {
116
+ const [
117
+ landmarksResult,
118
+ headingsResult,
119
+ missingNamesResult,
120
+ liveRegionsResult,
121
+ skipLinkResult,
122
+ interactiveCountResult
123
+ ] = await Promise.allSettled([
124
+ extractLandmarks(page),
125
+ extractHeadings(page),
126
+ findMissingNames(page),
127
+ extractLiveRegions(page),
128
+ checkSkipLink(page),
129
+ page.evaluate(() => {
130
+ const INTERACTIVE_SELECTOR = 'button,a[href],input:not([type="hidden"]),select,textarea,[role="button"],[role="link"],[role="checkbox"],[role="radio"],[role="switch"],[role="menuitem"],[role="tab"]';
131
+ return document.querySelectorAll(INTERACTIVE_SELECTOR).length;
132
+ }).catch(() => 0)
133
+ ]);
134
+ const landmarks = landmarksResult.status === "fulfilled" ? landmarksResult.value : [];
135
+ const headings = headingsResult.status === "fulfilled" ? headingsResult.value : [];
136
+ const missingNameElements = missingNamesResult.status === "fulfilled" ? missingNamesResult.value : [];
137
+ const liveRegions = liveRegionsResult.status === "fulfilled" ? liveRegionsResult.value : [];
138
+ const hasSkipLink = skipLinkResult.status === "fulfilled" ? skipLinkResult.value : false;
139
+ const totalInteractiveCount = interactiveCountResult.status === "fulfilled" ? interactiveCountResult.value : 0;
140
+ const headingHierarchyViolations = detectHeadingViolations(headings);
141
+ return {
142
+ landmarkCount: landmarks.length,
143
+ landmarks,
144
+ headings,
145
+ headingHierarchyViolations,
146
+ missingNameElements,
147
+ missingNameCount: missingNameElements.length,
148
+ liveRegions,
149
+ totalInteractiveCount,
150
+ hasSkipLink
151
+ };
152
+ }
153
+ export {
154
+ crawlAccessibilityTree
155
+ };
156
+ //# sourceMappingURL=accessibility-tree-crawler.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/accessibility-tree-crawler.ts"],
4
+ "sourcesContent": ["/**\n * Accessibility tree crawler \u2014 extract landmark, heading, and ARIA metadata from crawled pages.\n *\n * Captures: landmarks with interactive counts, heading hierarchy with violation detection,\n * interactive elements missing accessible names, live regions, and skip-link presence.\n *\n * This data feeds ZeTa's accessibility test generator to surface WCAG 2.1 Level A/AA\n * failures (missing names, heading skips, absent skip links, unlabeled live regions).\n */\n\nimport type { Page } from 'playwright';\n\nexport interface LandmarkInfo {\n role: string;\n label: string;\n elementId: string;\n interactiveCount: number;\n}\n\nexport interface HeadingInfo {\n level: number;\n text: string;\n elementId: string;\n}\n\nexport interface MissingNameEl {\n tagName: string;\n role: string;\n elementId: string;\n htmlSnippet: string;\n}\n\nexport interface LiveRegionInfo {\n role: string;\n ariaLive: string;\n ariaAtomic: string;\n currentText: string;\n}\n\nexport interface AccessibilityTreeResult {\n landmarkCount: number;\n landmarks: LandmarkInfo[];\n headings: HeadingInfo[];\n headingHierarchyViolations: string[];\n missingNameElements: MissingNameEl[];\n missingNameCount: number;\n liveRegions: LiveRegionInfo[];\n totalInteractiveCount: number;\n hasSkipLink: boolean;\n}\n\nasync function extractLandmarks(page: any): Promise<LandmarkInfo[]> {\n try {\n const raw = await page.evaluate(() => {\n const LANDMARK_SELECTORS = [\n { role: 'banner', selector: 'header,[role=\"banner\"]' },\n { role: 'navigation', selector: 'nav,[role=\"navigation\"]' },\n { role: 'main', selector: 'main,[role=\"main\"]' },\n { role: 'complementary', selector: 'aside,[role=\"complementary\"]' },\n { role: 'contentinfo', selector: 'footer,[role=\"contentinfo\"]' },\n { role: 'search', selector: '[role=\"search\"]' },\n { role: 'form', selector: 'form[aria-label],[role=\"form\"]' },\n { role: 'region', selector: '[role=\"region\"][aria-label]' },\n ];\n return LANDMARK_SELECTORS.flatMap(({ role, selector }) =>\n [...document.querySelectorAll(selector)].slice(0, 10).map(el => ({\n role,\n label: el.getAttribute('aria-label') || el.getAttribute('aria-labelledby') || '',\n elementId: el.id || '',\n interactiveCount: el.querySelectorAll(\n 'button,a[href],input,select,textarea,[role=\"button\"],[tabindex=\"0\"]'\n ).length,\n }))\n );\n });\n return raw.slice(0, 50);\n } catch {\n return [];\n }\n}\n\nasync function extractHeadings(page: any): Promise<HeadingInfo[]> {\n try {\n const raw = await page.evaluate(() => {\n const headingEls = [...document.querySelectorAll('h1,h2,h3,h4,h5,h6,[role=\"heading\"]')];\n return headingEls\n .map(el => ({\n level:\n parseInt(el.tagName.slice(1)) ||\n parseInt(el.getAttribute('aria-level') || '0') ||\n 0,\n text: el.textContent?.trim().slice(0, 100) || '',\n elementId: el.id || '',\n }))\n .filter(h => h.level >= 1 && h.level <= 6);\n });\n return raw.slice(0, 100);\n } catch {\n return [];\n }\n}\n\nfunction detectHeadingViolations(headings: HeadingInfo[]): string[] {\n const violations: string[] = [];\n if (headings.length === 0) return violations;\n\n const h1s = headings.filter(h => h.level === 1);\n if (h1s.length === 0) {\n violations.push('Missing h1 landmark');\n } else if (h1s.length > 1) {\n violations.push('Multiple h1 elements found');\n }\n\n let prevLevel = 0;\n for (const heading of headings) {\n if (prevLevel > 0 && heading.level > prevLevel + 1) {\n violations.push(\n `Heading level skip: h${prevLevel} to h${heading.level}`\n );\n }\n prevLevel = heading.level;\n }\n\n return violations;\n}\n\nasync function findMissingNames(page: any): Promise<MissingNameEl[]> {\n try {\n return await page.evaluate(() => {\n const INTERACTIVE_SELECTOR =\n 'button,a[href],input:not([type=\"hidden\"]),select,textarea,' +\n '[role=\"button\"],[role=\"link\"],[role=\"checkbox\"],[role=\"radio\"],' +\n '[role=\"switch\"],[role=\"menuitem\"],[role=\"tab\"]';\n return [...document.querySelectorAll(INTERACTIVE_SELECTOR)]\n .filter(el => {\n const labelledById = el.getAttribute('aria-labelledby') || '';\n const name =\n (el.getAttribute('aria-label') || '').trim() ||\n (labelledById\n ? document.getElementById(labelledById)?.textContent?.trim() ?? ''\n : '') ||\n (el.textContent || '').trim() ||\n ((el as HTMLInputElement).placeholder || '').trim() ||\n ((el as HTMLElement).title || '').trim() ||\n ((el as HTMLImageElement).alt || '').trim();\n return !name || name.length === 0;\n })\n .slice(0, 30)\n .map(el => ({\n tagName: el.tagName.toLowerCase(),\n role: el.getAttribute('role') || '',\n elementId: el.id || '',\n htmlSnippet: el.outerHTML.slice(0, 120),\n }));\n });\n } catch {\n return [];\n }\n}\n\nasync function extractLiveRegions(page: any): Promise<LiveRegionInfo[]> {\n try {\n return await page.evaluate(() => {\n const els = [\n ...document.querySelectorAll(\n '[aria-live],[role=\"alert\"],[role=\"status\"],[role=\"log\"]'\n ),\n ];\n return els.slice(0, 20).map(el => ({\n role: el.getAttribute('role') || '',\n ariaLive: el.getAttribute('aria-live') || '',\n ariaAtomic: el.getAttribute('aria-atomic') || '',\n currentText: (el.textContent || '').trim().slice(0, 200),\n }));\n });\n } catch {\n return [];\n }\n}\n\nasync function checkSkipLink(page: any): Promise<boolean> {\n try {\n return await page.evaluate(() => {\n const firstFocusable = document.querySelector('a[href^=\"#\"],a:first-of-type');\n return !!(\n firstFocusable &&\n /skip/i.test(\n (firstFocusable.textContent || '') + (firstFocusable.getAttribute('href') || '')\n )\n );\n });\n } catch {\n return false;\n }\n}\n\nexport async function crawlAccessibilityTree(page: any): Promise<AccessibilityTreeResult> {\n const [\n landmarksResult,\n headingsResult,\n missingNamesResult,\n liveRegionsResult,\n skipLinkResult,\n interactiveCountResult,\n ] = await Promise.allSettled([\n extractLandmarks(page),\n extractHeadings(page),\n findMissingNames(page),\n extractLiveRegions(page),\n checkSkipLink(page),\n page.evaluate(() => {\n const INTERACTIVE_SELECTOR =\n 'button,a[href],input:not([type=\"hidden\"]),select,textarea,' +\n '[role=\"button\"],[role=\"link\"],[role=\"checkbox\"],[role=\"radio\"],' +\n '[role=\"switch\"],[role=\"menuitem\"],[role=\"tab\"]';\n return document.querySelectorAll(INTERACTIVE_SELECTOR).length;\n }).catch(() => 0),\n ]);\n\n const landmarks =\n landmarksResult.status === 'fulfilled' ? landmarksResult.value : [];\n const headings =\n headingsResult.status === 'fulfilled' ? headingsResult.value : [];\n const missingNameElements =\n missingNamesResult.status === 'fulfilled' ? missingNamesResult.value : [];\n const liveRegions =\n liveRegionsResult.status === 'fulfilled' ? liveRegionsResult.value : [];\n const hasSkipLink =\n skipLinkResult.status === 'fulfilled' ? skipLinkResult.value : false;\n const totalInteractiveCount =\n interactiveCountResult.status === 'fulfilled' ? interactiveCountResult.value : 0;\n\n const headingHierarchyViolations = detectHeadingViolations(headings);\n\n return {\n landmarkCount: landmarks.length,\n landmarks,\n headings,\n headingHierarchyViolations,\n missingNameElements,\n missingNameCount: missingNameElements.length,\n liveRegions,\n totalInteractiveCount,\n hasSkipLink,\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Advanced UI probes — detect and exercise drag-drop, date pickers, sliders,
3
+ * and typeahead/autocomplete widgets on a crawled page.
4
+ *
5
+ * Results feed ZeTa's test generator so it can emit interaction-level test
6
+ * cases for these widget families instead of falling back to generic clicks.
7
+ *
8
+ * Each probe is independently try/caught so a broken widget does not abort
9
+ * the others. All browser-side code runs inside page.evaluate / page.$$eval
10
+ * to avoid serialisation issues with DOM handles.
11
+ */
12
+ import type { Page } from 'playwright';
13
+ export interface DragDropCapture {
14
+ library: 'html5' | 'dnd-kit' | 'react-beautiful-dnd' | 'sortablejs' | 'pointer-event' | 'none';
15
+ draggableCount: number;
16
+ dropZoneCount: number;
17
+ testAttempted: boolean;
18
+ testCompleted: boolean;
19
+ }
20
+ export interface DatePickerCapture {
21
+ fieldLabel: string;
22
+ pickerType: 'calendar-popup' | 'native-date' | 'native-datetime' | 'none';
23
+ minDate?: string;
24
+ maxDate?: string;
25
+ disabledDatesFound: boolean;
26
+ sampleSelectedValue?: string;
27
+ }
28
+ export interface SliderCapture {
29
+ label: string;
30
+ min: number;
31
+ max: number;
32
+ step: number;
33
+ currentValue: number;
34
+ }
35
+ export interface TypeaheadCapture {
36
+ label: string;
37
+ minCharsToTrigger: number;
38
+ sampleSuggestions: string[];
39
+ noResultsText: string | null;
40
+ }
41
+ export interface AdvancedProbeResult {
42
+ dragDrop: DragDropCapture;
43
+ datePickers: DatePickerCapture[];
44
+ sliders: SliderCapture[];
45
+ typeaheads: TypeaheadCapture[];
46
+ }
47
+ export declare function probeAdvancedUI(page: Page): Promise<AdvancedProbeResult>;