qa360 2.2.20 → 2.3.1

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 (507) hide show
  1. package/README.md +155 -262
  2. package/{cli/dist → dist}/commands/ai.js +1 -1
  3. package/{cli/dist → dist}/commands/coverage.js +1 -1
  4. package/{cli/dist → dist}/commands/crawl.d.ts +12 -1
  5. package/{cli/dist → dist}/commands/crawl.js +70 -9
  6. package/{cli/dist → dist}/commands/doctor.js +2 -2
  7. package/{cli/dist → dist}/commands/explain.js +2 -2
  8. package/{cli/dist → dist}/commands/flakiness.js +1 -1
  9. package/{cli/dist → dist}/commands/generate.js +1 -1
  10. package/{cli/dist → dist}/commands/history.js +1 -1
  11. package/{cli/dist → dist}/commands/monitor.js +3 -3
  12. package/{cli/dist → dist}/commands/ollama.js +1 -1
  13. package/{cli/dist → dist}/commands/pack.js +2 -2
  14. package/{cli/dist → dist}/commands/regression.js +1 -1
  15. package/{cli/dist → dist}/commands/repair.js +1 -1
  16. package/{cli/dist → dist}/commands/retry.js +1 -1
  17. package/{cli/dist → dist}/commands/run.d.ts +1 -1
  18. package/{cli/dist → dist}/commands/run.js +1 -1
  19. package/{cli/dist → dist}/commands/secrets.js +1 -1
  20. package/{cli/dist → dist}/commands/serve.js +1 -1
  21. package/{cli/dist → dist}/commands/slo.js +1 -1
  22. package/{cli/dist → dist}/commands/verify.js +1 -1
  23. package/{cli/dist → dist}/core/adapters/playwright-native-api.d.ts +2 -0
  24. package/{cli/dist → dist}/core/adapters/playwright-native-api.js +20 -1
  25. package/{cli/dist → dist}/core/adapters/playwright-ui.d.ts +21 -0
  26. package/dist/core/adapters/playwright-ui.js +2050 -0
  27. package/{cli/dist → dist}/core/ai/ollama-provider.js +15 -3
  28. package/{cli/dist → dist}/core/artifacts/ui-artifacts.js +24 -4
  29. package/dist/core/auth/backup-codes-provider.d.ts +91 -0
  30. package/dist/core/auth/backup-codes-provider.js +215 -0
  31. package/{cli/dist → dist}/core/auth/basic-auth-provider.d.ts +6 -0
  32. package/{cli/dist → dist}/core/auth/basic-auth-provider.js +24 -6
  33. package/dist/core/auth/digest-auth-provider.d.ts +116 -0
  34. package/dist/core/auth/digest-auth-provider.js +244 -0
  35. package/dist/core/auth/hcaptcha-handler.d.ts +103 -0
  36. package/dist/core/auth/hcaptcha-handler.js +288 -0
  37. package/{cli/dist → dist}/core/auth/index.d.ts +81 -4
  38. package/{cli/dist → dist}/core/auth/index.js +15 -1
  39. package/dist/core/auth/oauth-handler.d.ts +408 -0
  40. package/dist/core/auth/oauth-handler.js +636 -0
  41. package/{cli/dist → dist}/core/auth/oauth2-provider.d.ts +9 -0
  42. package/dist/core/auth/oauth2-provider.js +227 -0
  43. package/dist/core/auth/otp-provider.d.ts +93 -0
  44. package/dist/core/auth/otp-provider.js +288 -0
  45. package/dist/core/auth/recaptcha-handler.d.ts +119 -0
  46. package/dist/core/auth/recaptcha-handler.js +301 -0
  47. package/dist/core/auth/remember-me-handler.d.ts +142 -0
  48. package/dist/core/auth/remember-me-handler.js +255 -0
  49. package/dist/core/auth/saml-handler.d.ts +173 -0
  50. package/dist/core/auth/saml-handler.js +364 -0
  51. package/dist/core/auth/webauthn-handler.d.ts +182 -0
  52. package/dist/core/auth/webauthn-handler.js +310 -0
  53. package/dist/core/crawler/advanced-interactions.d.ts +342 -0
  54. package/dist/core/crawler/advanced-interactions.js +1069 -0
  55. package/dist/core/crawler/blob-url-download-handler.d.ts +145 -0
  56. package/dist/core/crawler/blob-url-download-handler.js +392 -0
  57. package/dist/core/crawler/consent-handler.d.ts +49 -0
  58. package/dist/core/crawler/consent-handler.js +258 -0
  59. package/dist/core/crawler/cookie-manager.d.ts +166 -0
  60. package/dist/core/crawler/cookie-manager.js +353 -0
  61. package/dist/core/crawler/coop-coep-handler.d.ts +136 -0
  62. package/dist/core/crawler/coop-coep-handler.js +338 -0
  63. package/dist/core/crawler/csp-handler.d.ts +151 -0
  64. package/dist/core/crawler/csp-handler.js +415 -0
  65. package/dist/core/crawler/download-handler.d.ts +155 -0
  66. package/dist/core/crawler/download-handler.js +370 -0
  67. package/dist/core/crawler/email-testing-handler.d.ts +214 -0
  68. package/dist/core/crawler/email-testing-handler.js +398 -0
  69. package/dist/core/crawler/error-tracking-handler.d.ts +177 -0
  70. package/dist/core/crawler/error-tracking-handler.js +378 -0
  71. package/dist/core/crawler/form-handler.d.ts +100 -0
  72. package/dist/core/crawler/form-handler.js +465 -0
  73. package/dist/core/crawler/framework-wait-handler.d.ts +96 -0
  74. package/dist/core/crawler/framework-wait-handler.js +464 -0
  75. package/dist/core/crawler/geolocation-handler.d.ts +112 -0
  76. package/dist/core/crawler/geolocation-handler.js +276 -0
  77. package/dist/core/crawler/index.d.ts +78 -0
  78. package/{cli/dist → dist}/core/crawler/index.js +74 -1
  79. package/dist/core/crawler/intelligent-selector-generator.d.ts +164 -0
  80. package/dist/core/crawler/intelligent-selector-generator.js +612 -0
  81. package/{cli/dist → dist}/core/crawler/journey-generator.js +44 -1
  82. package/{cli/dist → dist}/core/crawler/page-analyzer.d.ts +16 -1
  83. package/{cli/dist → dist}/core/crawler/page-analyzer.js +469 -17
  84. package/dist/core/crawler/permissions-handler.d.ts +112 -0
  85. package/dist/core/crawler/permissions-handler.js +236 -0
  86. package/dist/core/crawler/permissions-policy-handler.d.ts +113 -0
  87. package/dist/core/crawler/permissions-policy-handler.js +402 -0
  88. package/dist/core/crawler/presets.d.ts +100 -0
  89. package/dist/core/crawler/presets.js +887 -0
  90. package/dist/core/crawler/repl-debug-handler.d.ts +105 -0
  91. package/dist/core/crawler/repl-debug-handler.js +552 -0
  92. package/dist/core/crawler/reporting-api-handler.d.ts +212 -0
  93. package/dist/core/crawler/reporting-api-handler.js +344 -0
  94. package/{cli/dist → dist}/core/crawler/selector-generator.d.ts +9 -0
  95. package/{cli/dist → dist}/core/crawler/selector-generator.js +99 -23
  96. package/dist/core/crawler/site-profiler.d.ts +89 -0
  97. package/dist/core/crawler/site-profiler.js +290 -0
  98. package/dist/core/crawler/sourcemaps-handler.d.ts +144 -0
  99. package/dist/core/crawler/sourcemaps-handler.js +420 -0
  100. package/dist/core/crawler/stacked-modals-handler.d.ts +118 -0
  101. package/dist/core/crawler/stacked-modals-handler.js +429 -0
  102. package/dist/core/crawler/trusted-types-handler.d.ts +149 -0
  103. package/dist/core/crawler/trusted-types-handler.js +413 -0
  104. package/{cli/dist → dist}/core/crawler/types.d.ts +68 -2
  105. package/dist/core/crawler/wait-strategies.d.ts +108 -0
  106. package/dist/core/crawler/wait-strategies.js +399 -0
  107. package/dist/core/fixtures/factories.d.ts +180 -0
  108. package/dist/core/fixtures/factories.js +279 -0
  109. package/dist/core/fixtures/index.d.ts +6 -0
  110. package/dist/core/fixtures/index.js +6 -0
  111. package/{cli/dist → dist}/core/generation/crawler-pack-generator.d.ts +13 -3
  112. package/dist/core/generation/crawler-pack-generator.js +232 -0
  113. package/{cli/dist → dist}/core/generation/index.d.ts +2 -0
  114. package/{cli/dist → dist}/core/generation/index.js +2 -0
  115. package/{cli/dist → dist}/core/index.d.ts +2 -0
  116. package/{cli/dist → dist}/core/index.js +4 -0
  117. package/dist/core/network/index.d.ts +7 -0
  118. package/dist/core/network/index.js +7 -0
  119. package/dist/core/network/network-manager.d.ts +237 -0
  120. package/dist/core/network/network-manager.js +343 -0
  121. package/dist/core/network/network-simulator.d.ts +158 -0
  122. package/dist/core/network/network-simulator.js +261 -0
  123. package/{cli/dist → dist}/core/pack/validator.js +2 -2
  124. package/{cli/dist → dist}/core/pack-v2/migrator.d.ts +5 -0
  125. package/{cli/dist → dist}/core/pack-v2/migrator.js +81 -6
  126. package/{cli/dist → dist}/core/pack-v2/validator.js +4 -3
  127. package/{cli/dist → dist}/core/pom/base-page.js +1 -1
  128. package/{cli/dist → dist}/core/pom/loader.js +1 -1
  129. package/dist/core/reporting/index.d.ts +9 -0
  130. package/dist/core/reporting/index.js +10 -0
  131. package/dist/core/reporting/junit-reporter.d.ts +114 -0
  132. package/dist/core/reporting/junit-reporter.js +306 -0
  133. package/{cli/dist → dist}/core/runner/e2e-helpers.d.ts +1 -1
  134. package/{cli/dist → dist}/core/runner/e2e-helpers.js +2 -2
  135. package/{cli/dist → dist}/core/runner/phase3-runner.d.ts +3 -0
  136. package/{cli/dist → dist}/core/runner/phase3-runner.js +45 -14
  137. package/dist/core/sharding/test-sharding.d.ts +137 -0
  138. package/dist/core/sharding/test-sharding.js +233 -0
  139. package/dist/core/storage/cookie-manager.d.ts +160 -0
  140. package/dist/core/storage/cookie-manager.js +268 -0
  141. package/dist/core/storage/index.d.ts +7 -0
  142. package/dist/core/storage/index.js +7 -0
  143. package/dist/core/storage/storage-helpers.d.ts +138 -0
  144. package/dist/core/storage/storage-helpers.js +315 -0
  145. package/dist/core/test-helpers/index.d.ts +6 -0
  146. package/dist/core/test-helpers/index.js +6 -0
  147. package/dist/core/test-helpers/state-reset.d.ts +119 -0
  148. package/dist/core/test-helpers/state-reset.js +234 -0
  149. package/{cli/dist → dist}/core/types/pack-v1.d.ts +15 -2
  150. package/{cli/dist → dist}/core/types/pack-v2.d.ts +1 -1
  151. package/dist/core/upload/chunked-uploader.d.ts +150 -0
  152. package/dist/core/upload/chunked-uploader.js +289 -0
  153. package/dist/core/upload/index.d.ts +11 -0
  154. package/dist/core/upload/index.js +8 -0
  155. package/dist/core/upload/mime-validator.d.ts +119 -0
  156. package/dist/core/upload/mime-validator.js +373 -0
  157. package/dist/core/upload/presigned-uploader.d.ts +118 -0
  158. package/dist/core/upload/presigned-uploader.js +274 -0
  159. package/dist/core/utils/device-emulation.d.ts +194 -0
  160. package/dist/core/utils/device-emulation.js +380 -0
  161. package/dist/core/utils/index.d.ts +8 -0
  162. package/dist/core/utils/index.js +8 -0
  163. package/dist/core/utils/retry.d.ts +145 -0
  164. package/dist/core/utils/retry.js +242 -0
  165. package/dist/core/utils/smart-wait.d.ts +133 -0
  166. package/dist/core/utils/smart-wait.js +417 -0
  167. package/dist/core/visual/index.d.ts +7 -0
  168. package/dist/core/visual/index.js +7 -0
  169. package/dist/core/visual/pixel-diff.d.ts +87 -0
  170. package/dist/core/visual/pixel-diff.js +213 -0
  171. package/dist/core/visual/screenshot-helper.d.ts +130 -0
  172. package/dist/core/visual/screenshot-helper.js +223 -0
  173. package/{cli/dist → dist}/utils/config.d.ts +1 -1
  174. package/examples/README.md +160 -0
  175. package/examples/accessibility.yml +48 -0
  176. package/examples/api-basic.yml +27 -0
  177. package/examples/complete.yml +146 -0
  178. package/examples/crawler.yml +38 -0
  179. package/examples/fullstack.yml +78 -0
  180. package/examples/security.yml +58 -0
  181. package/examples/ui-advanced.yml +49 -0
  182. package/examples/ui-basic.yml +24 -0
  183. package/package.json +33 -67
  184. package/CHANGELOG.md +0 -262
  185. package/CONTRIBUTING.md +0 -273
  186. package/QUICK_START.md +0 -191
  187. package/cli/CHANGELOG.md +0 -84
  188. package/cli/LICENSE +0 -24
  189. package/cli/README.md +0 -222
  190. package/cli/dist/core/adapters/playwright-ui.js +0 -864
  191. package/cli/dist/core/auth/oauth2-provider.js +0 -114
  192. package/cli/dist/core/coverage/analyzer.d.ts +0 -101
  193. package/cli/dist/core/coverage/analyzer.js +0 -415
  194. package/cli/dist/core/coverage/collector.d.ts +0 -74
  195. package/cli/dist/core/coverage/collector.js +0 -459
  196. package/cli/dist/core/coverage/config.d.ts +0 -37
  197. package/cli/dist/core/coverage/config.js +0 -156
  198. package/cli/dist/core/coverage/index.d.ts +0 -11
  199. package/cli/dist/core/coverage/index.js +0 -15
  200. package/cli/dist/core/coverage/types.d.ts +0 -267
  201. package/cli/dist/core/coverage/types.js +0 -6
  202. package/cli/dist/core/coverage/vault.d.ts +0 -95
  203. package/cli/dist/core/coverage/vault.js +0 -405
  204. package/cli/dist/core/crawler/index.d.ts +0 -57
  205. package/cli/dist/core/fixtures/index.d.ts +0 -8
  206. package/cli/dist/core/fixtures/index.js +0 -8
  207. package/cli/dist/core/generation/crawler-pack-generator.js +0 -231
  208. package/cli/dist/core/reporting/index.d.ts +0 -6
  209. package/cli/dist/core/reporting/index.js +0 -6
  210. package/cli/dist/core/visual/index.d.ts +0 -6
  211. package/cli/dist/core/visual/index.js +0 -6
  212. package/cli/package.json +0 -76
  213. package/core/LICENSE +0 -24
  214. package/core/README.md +0 -64
  215. package/core/package.json +0 -81
  216. package/core/schemas/pack.schema.json +0 -236
  217. /package/{cli/bin → bin}/qa360.js +0 -0
  218. /package/{cli/dist → dist}/cli-minimal.d.ts +0 -0
  219. /package/{cli/dist → dist}/cli-minimal.js +0 -0
  220. /package/{cli/dist → dist}/commands/ai.d.ts +0 -0
  221. /package/{cli/dist → dist}/commands/ask.d.ts +0 -0
  222. /package/{cli/dist → dist}/commands/ask.js +0 -0
  223. /package/{cli/dist → dist}/commands/coverage.d.ts +0 -0
  224. /package/{cli/dist → dist}/commands/doctor.d.ts +0 -0
  225. /package/{cli/dist → dist}/commands/examples.d.ts +0 -0
  226. /package/{cli/dist → dist}/commands/examples.js +0 -0
  227. /package/{cli/dist → dist}/commands/explain.d.ts +0 -0
  228. /package/{cli/dist → dist}/commands/flakiness.d.ts +0 -0
  229. /package/{cli/dist → dist}/commands/generate.d.ts +0 -0
  230. /package/{cli/dist → dist}/commands/history.d.ts +0 -0
  231. /package/{cli/dist → dist}/commands/init.d.ts +0 -0
  232. /package/{cli/dist → dist}/commands/init.js +0 -0
  233. /package/{cli/dist → dist}/commands/monitor.d.ts +0 -0
  234. /package/{cli/dist → dist}/commands/ollama.d.ts +0 -0
  235. /package/{cli/dist → dist}/commands/pack.d.ts +0 -0
  236. /package/{cli/dist → dist}/commands/regression.d.ts +0 -0
  237. /package/{cli/dist → dist}/commands/repair.d.ts +0 -0
  238. /package/{cli/dist → dist}/commands/report.d.ts +0 -0
  239. /package/{cli/dist → dist}/commands/report.js +0 -0
  240. /package/{cli/dist → dist}/commands/retry.d.ts +0 -0
  241. /package/{cli/dist → dist}/commands/scan.d.ts +0 -0
  242. /package/{cli/dist → dist}/commands/scan.js +0 -0
  243. /package/{cli/dist → dist}/commands/secrets.d.ts +0 -0
  244. /package/{cli/dist → dist}/commands/serve.d.ts +0 -0
  245. /package/{cli/dist → dist}/commands/slo.d.ts +0 -0
  246. /package/{cli/dist → dist}/commands/verify.d.ts +0 -0
  247. /package/{cli/dist → dist}/core/adapters/gitleaks-secrets.d.ts +0 -0
  248. /package/{cli/dist → dist}/core/adapters/gitleaks-secrets.js +0 -0
  249. /package/{cli/dist → dist}/core/adapters/jest-adapter.d.ts +0 -0
  250. /package/{cli/dist → dist}/core/adapters/jest-adapter.js +0 -0
  251. /package/{cli/dist → dist}/core/adapters/k6-perf.d.ts +0 -0
  252. /package/{cli/dist → dist}/core/adapters/k6-perf.js +0 -0
  253. /package/{cli/dist → dist}/core/adapters/osv-deps.d.ts +0 -0
  254. /package/{cli/dist → dist}/core/adapters/osv-deps.js +0 -0
  255. /package/{cli/dist → dist}/core/adapters/playwright-native-adapter.d.ts +0 -0
  256. /package/{cli/dist → dist}/core/adapters/playwright-native-adapter.js +0 -0
  257. /package/{cli/dist → dist}/core/adapters/pytest-adapter.d.ts +0 -0
  258. /package/{cli/dist → dist}/core/adapters/pytest-adapter.js +0 -0
  259. /package/{cli/dist → dist}/core/adapters/semgrep-sast.d.ts +0 -0
  260. /package/{cli/dist → dist}/core/adapters/semgrep-sast.js +0 -0
  261. /package/{cli/dist → dist}/core/adapters/unit-test-types.d.ts +0 -0
  262. /package/{cli/dist → dist}/core/adapters/unit-test-types.js +0 -0
  263. /package/{cli/dist → dist}/core/adapters/vitest-adapter.d.ts +0 -0
  264. /package/{cli/dist → dist}/core/adapters/vitest-adapter.js +0 -0
  265. /package/{cli/dist → dist}/core/adapters/zap-dast.d.ts +0 -0
  266. /package/{cli/dist → dist}/core/adapters/zap-dast.js +0 -0
  267. /package/{cli/dist → dist}/core/ai/anthropic-provider.d.ts +0 -0
  268. /package/{cli/dist → dist}/core/ai/anthropic-provider.js +0 -0
  269. /package/{cli/dist → dist}/core/ai/deepseek-provider.d.ts +0 -0
  270. /package/{cli/dist → dist}/core/ai/deepseek-provider.js +0 -0
  271. /package/{cli/dist → dist}/core/ai/index.d.ts +0 -0
  272. /package/{cli/dist → dist}/core/ai/index.js +0 -0
  273. /package/{cli/dist → dist}/core/ai/llm-client.d.ts +0 -0
  274. /package/{cli/dist → dist}/core/ai/llm-client.js +0 -0
  275. /package/{cli/dist → dist}/core/ai/mock-provider.d.ts +0 -0
  276. /package/{cli/dist → dist}/core/ai/mock-provider.js +0 -0
  277. /package/{cli/dist → dist}/core/ai/ollama-provider.d.ts +0 -0
  278. /package/{cli/dist → dist}/core/ai/openai-provider.d.ts +0 -0
  279. /package/{cli/dist → dist}/core/ai/openai-provider.js +0 -0
  280. /package/{cli/dist → dist}/core/ai/provider-factory.d.ts +0 -0
  281. /package/{cli/dist → dist}/core/ai/provider-factory.js +0 -0
  282. /package/{cli/dist → dist}/core/artifacts/index.d.ts +0 -0
  283. /package/{cli/dist → dist}/core/artifacts/index.js +0 -0
  284. /package/{cli/dist → dist}/core/artifacts/ui-artifacts.d.ts +0 -0
  285. /package/{cli/dist → dist}/core/assertions/engine.d.ts +0 -0
  286. /package/{cli/dist → dist}/core/assertions/engine.js +0 -0
  287. /package/{cli/dist → dist}/core/assertions/index.d.ts +0 -0
  288. /package/{cli/dist → dist}/core/assertions/index.js +0 -0
  289. /package/{cli/dist → dist}/core/assertions/types.d.ts +0 -0
  290. /package/{cli/dist → dist}/core/assertions/types.js +0 -0
  291. /package/{cli/dist → dist}/core/auth/api-key-provider.d.ts +0 -0
  292. /package/{cli/dist → dist}/core/auth/api-key-provider.js +0 -0
  293. /package/{cli/dist → dist}/core/auth/aws-iam-provider.d.ts +0 -0
  294. /package/{cli/dist → dist}/core/auth/aws-iam-provider.js +0 -0
  295. /package/{cli/dist → dist}/core/auth/azure-ad-provider.d.ts +0 -0
  296. /package/{cli/dist → dist}/core/auth/azure-ad-provider.js +0 -0
  297. /package/{cli/dist → dist}/core/auth/gcp-adc-provider.d.ts +0 -0
  298. /package/{cli/dist → dist}/core/auth/gcp-adc-provider.js +0 -0
  299. /package/{cli/dist → dist}/core/auth/jwt-provider.d.ts +0 -0
  300. /package/{cli/dist → dist}/core/auth/jwt-provider.js +0 -0
  301. /package/{cli/dist → dist}/core/auth/manager.d.ts +0 -0
  302. /package/{cli/dist → dist}/core/auth/manager.js +0 -0
  303. /package/{cli/dist → dist}/core/auth/totp-provider.d.ts +0 -0
  304. /package/{cli/dist → dist}/core/auth/totp-provider.js +0 -0
  305. /package/{cli/dist → dist}/core/auth/ui-login-provider.d.ts +0 -0
  306. /package/{cli/dist → dist}/core/auth/ui-login-provider.js +0 -0
  307. /package/{cli/dist → dist}/core/cache/index.d.ts +0 -0
  308. /package/{cli/dist → dist}/core/cache/index.js +0 -0
  309. /package/{cli/dist → dist}/core/cache/lru-cache.d.ts +0 -0
  310. /package/{cli/dist → dist}/core/cache/lru-cache.js +0 -0
  311. /package/{cli/dist/core → dist}/core/coverage/analyzer.d.ts +0 -0
  312. /package/{cli/dist/core → dist}/core/coverage/analyzer.js +0 -0
  313. /package/{cli/dist/core → dist}/core/coverage/collector.d.ts +0 -0
  314. /package/{cli/dist/core → dist}/core/coverage/collector.js +0 -0
  315. /package/{cli/dist/core → dist}/core/coverage/config.d.ts +0 -0
  316. /package/{cli/dist/core → dist}/core/coverage/config.js +0 -0
  317. /package/{cli/dist/core → dist}/core/coverage/index.d.ts +0 -0
  318. /package/{cli/dist/core → dist}/core/coverage/index.js +0 -0
  319. /package/{cli/dist/core → dist}/core/coverage/types.d.ts +0 -0
  320. /package/{cli/dist/core → dist}/core/coverage/types.js +0 -0
  321. /package/{cli/dist/core → dist}/core/coverage/vault.d.ts +0 -0
  322. /package/{cli/dist/core → dist}/core/coverage/vault.js +0 -0
  323. /package/{cli/dist → dist}/core/crawler/journey-generator.d.ts +0 -0
  324. /package/{cli/dist → dist}/core/crawler/types.js +0 -0
  325. /package/{cli/dist → dist}/core/dashboard/assets.d.ts +0 -0
  326. /package/{cli/dist → dist}/core/dashboard/assets.js +0 -0
  327. /package/{cli/dist → dist}/core/dashboard/index.d.ts +0 -0
  328. /package/{cli/dist → dist}/core/dashboard/index.js +0 -0
  329. /package/{cli/dist → dist}/core/dashboard/server.d.ts +0 -0
  330. /package/{cli/dist → dist}/core/dashboard/server.js +0 -0
  331. /package/{cli/dist → dist}/core/dashboard/types.d.ts +0 -0
  332. /package/{cli/dist → dist}/core/dashboard/types.js +0 -0
  333. /package/{cli/dist → dist}/core/discoverer/index.d.ts +0 -0
  334. /package/{cli/dist → dist}/core/discoverer/index.js +0 -0
  335. /package/{cli/dist → dist}/core/fixtures/loader.d.ts +0 -0
  336. /package/{cli/dist → dist}/core/fixtures/loader.js +0 -0
  337. /package/{cli/dist → dist}/core/fixtures/resolver.d.ts +0 -0
  338. /package/{cli/dist → dist}/core/fixtures/resolver.js +0 -0
  339. /package/{cli/dist → dist}/core/fixtures/types.d.ts +0 -0
  340. /package/{cli/dist → dist}/core/fixtures/types.js +0 -0
  341. /package/{cli/dist → dist}/core/flakiness/index.d.ts +0 -0
  342. /package/{cli/dist → dist}/core/flakiness/index.js +0 -0
  343. /package/{cli/dist → dist}/core/generation/code-formatter.d.ts +0 -0
  344. /package/{cli/dist → dist}/core/generation/code-formatter.js +0 -0
  345. /package/{cli/dist → dist}/core/generation/code-generator.d.ts +0 -0
  346. /package/{cli/dist → dist}/core/generation/code-generator.js +0 -0
  347. /package/{cli/dist → dist}/core/generation/generator.d.ts +0 -0
  348. /package/{cli/dist → dist}/core/generation/generator.js +0 -0
  349. /package/{cli/dist → dist}/core/generation/pack-generator.d.ts +0 -0
  350. /package/{cli/dist → dist}/core/generation/pack-generator.js +0 -0
  351. /package/{cli/dist → dist}/core/generation/prompt-builder.d.ts +0 -0
  352. /package/{cli/dist → dist}/core/generation/prompt-builder.js +0 -0
  353. /package/{cli/dist → dist}/core/generation/source-analyzer.d.ts +0 -0
  354. /package/{cli/dist → dist}/core/generation/source-analyzer.js +0 -0
  355. /package/{cli/dist → dist}/core/generation/test-optimizer.d.ts +0 -0
  356. /package/{cli/dist → dist}/core/generation/test-optimizer.js +0 -0
  357. /package/{cli/dist → dist}/core/generation/types.d.ts +0 -0
  358. /package/{cli/dist → dist}/core/generation/types.js +0 -0
  359. /package/{cli/dist → dist}/core/hooks/compose.d.ts +0 -0
  360. /package/{cli/dist → dist}/core/hooks/compose.js +0 -0
  361. /package/{cli/dist → dist}/core/hooks/runner.d.ts +0 -0
  362. /package/{cli/dist → dist}/core/hooks/runner.js +0 -0
  363. /package/{cli/dist → dist}/core/pack/migrator.d.ts +0 -0
  364. /package/{cli/dist → dist}/core/pack/migrator.js +0 -0
  365. /package/{cli/dist → dist}/core/pack/validator.d.ts +0 -0
  366. /package/{cli/dist → dist}/core/pack-v2/index.d.ts +0 -0
  367. /package/{cli/dist → dist}/core/pack-v2/index.js +0 -0
  368. /package/{cli/dist → dist}/core/pack-v2/loader.d.ts +0 -0
  369. /package/{cli/dist → dist}/core/pack-v2/loader.js +0 -0
  370. /package/{cli/dist → dist}/core/pack-v2/validator.d.ts +0 -0
  371. /package/{cli/dist → dist}/core/parallel/index.d.ts +0 -0
  372. /package/{cli/dist → dist}/core/parallel/index.js +0 -0
  373. /package/{cli/dist → dist}/core/parallel/parallel-runner.d.ts +0 -0
  374. /package/{cli/dist → dist}/core/parallel/parallel-runner.js +0 -0
  375. /package/{cli/dist → dist}/core/pom/base-page.d.ts +0 -0
  376. /package/{cli/dist → dist}/core/pom/index.d.ts +0 -0
  377. /package/{cli/dist → dist}/core/pom/index.js +0 -0
  378. /package/{cli/dist → dist}/core/pom/loader.d.ts +0 -0
  379. /package/{cli/dist → dist}/core/pom/types.d.ts +0 -0
  380. /package/{cli/dist → dist}/core/pom/types.js +0 -0
  381. /package/{cli/dist → dist}/core/proof/bundle.d.ts +0 -0
  382. /package/{cli/dist → dist}/core/proof/bundle.js +0 -0
  383. /package/{cli/dist → dist}/core/proof/canonicalize.d.ts +0 -0
  384. /package/{cli/dist → dist}/core/proof/canonicalize.js +0 -0
  385. /package/{cli/dist → dist}/core/proof/index.d.ts +0 -0
  386. /package/{cli/dist → dist}/core/proof/index.js +0 -0
  387. /package/{cli/dist → dist}/core/proof/schema.d.ts +0 -0
  388. /package/{cli/dist → dist}/core/proof/schema.js +0 -0
  389. /package/{cli/dist → dist}/core/proof/signer.d.ts +0 -0
  390. /package/{cli/dist → dist}/core/proof/signer.js +0 -0
  391. /package/{cli/dist → dist}/core/proof/verifier.d.ts +0 -0
  392. /package/{cli/dist → dist}/core/proof/verifier.js +0 -0
  393. /package/{cli/dist → dist}/core/regression/detector.d.ts +0 -0
  394. /package/{cli/dist → dist}/core/regression/detector.js +0 -0
  395. /package/{cli/dist → dist}/core/regression/index.d.ts +0 -0
  396. /package/{cli/dist → dist}/core/regression/index.js +0 -0
  397. /package/{cli/dist → dist}/core/regression/trend-analyzer.d.ts +0 -0
  398. /package/{cli/dist → dist}/core/regression/trend-analyzer.js +0 -0
  399. /package/{cli/dist → dist}/core/regression/types.d.ts +0 -0
  400. /package/{cli/dist → dist}/core/regression/types.js +0 -0
  401. /package/{cli/dist → dist}/core/regression/vault.d.ts +0 -0
  402. /package/{cli/dist → dist}/core/regression/vault.js +0 -0
  403. /package/{cli/dist → dist}/core/repair/engine/fixer.d.ts +0 -0
  404. /package/{cli/dist → dist}/core/repair/engine/fixer.js +0 -0
  405. /package/{cli/dist → dist}/core/repair/engine/suggestion-engine.d.ts +0 -0
  406. /package/{cli/dist → dist}/core/repair/engine/suggestion-engine.js +0 -0
  407. /package/{cli/dist → dist}/core/repair/index.d.ts +0 -0
  408. /package/{cli/dist → dist}/core/repair/index.js +0 -0
  409. /package/{cli/dist → dist}/core/repair/repairer.d.ts +0 -0
  410. /package/{cli/dist → dist}/core/repair/repairer.js +0 -0
  411. /package/{cli/dist → dist}/core/repair/types.d.ts +0 -0
  412. /package/{cli/dist → dist}/core/repair/types.js +0 -0
  413. /package/{cli/dist → dist}/core/repair/utils/error-analyzer.d.ts +0 -0
  414. /package/{cli/dist → dist}/core/repair/utils/error-analyzer.js +0 -0
  415. /package/{cli/dist → dist}/core/reporting/html-reporter.d.ts +0 -0
  416. /package/{cli/dist → dist}/core/reporting/html-reporter.js +0 -0
  417. /package/{cli/dist → dist}/core/retry/flakiness-integration.d.ts +0 -0
  418. /package/{cli/dist → dist}/core/retry/flakiness-integration.js +0 -0
  419. /package/{cli/dist → dist}/core/retry/index.d.ts +0 -0
  420. /package/{cli/dist → dist}/core/retry/index.js +0 -0
  421. /package/{cli/dist → dist}/core/retry/retry-engine.d.ts +0 -0
  422. /package/{cli/dist → dist}/core/retry/retry-engine.js +0 -0
  423. /package/{cli/dist → dist}/core/retry/types.d.ts +0 -0
  424. /package/{cli/dist → dist}/core/retry/types.js +0 -0
  425. /package/{cli/dist → dist}/core/retry/vault.d.ts +0 -0
  426. /package/{cli/dist → dist}/core/retry/vault.js +0 -0
  427. /package/{cli/dist → dist}/core/schemas/pack.schema.json +0 -0
  428. /package/{cli/dist → dist}/core/secrets/crypto.d.ts +0 -0
  429. /package/{cli/dist → dist}/core/secrets/crypto.js +0 -0
  430. /package/{cli/dist → dist}/core/secrets/manager.d.ts +0 -0
  431. /package/{cli/dist → dist}/core/secrets/manager.js +0 -0
  432. /package/{cli/dist → dist}/core/security/redaction-patterns-extended.d.ts +0 -0
  433. /package/{cli/dist → dist}/core/security/redaction-patterns-extended.js +0 -0
  434. /package/{cli/dist → dist}/core/security/redactor.d.ts +0 -0
  435. /package/{cli/dist → dist}/core/security/redactor.js +0 -0
  436. /package/{cli/dist → dist}/core/self-healing/assertion-healer.d.ts +0 -0
  437. /package/{cli/dist → dist}/core/self-healing/assertion-healer.js +0 -0
  438. /package/{cli/dist → dist}/core/self-healing/engine.d.ts +0 -0
  439. /package/{cli/dist → dist}/core/self-healing/engine.js +0 -0
  440. /package/{cli/dist → dist}/core/self-healing/index.d.ts +0 -0
  441. /package/{cli/dist → dist}/core/self-healing/index.js +0 -0
  442. /package/{cli/dist → dist}/core/self-healing/selector-healer.d.ts +0 -0
  443. /package/{cli/dist → dist}/core/self-healing/selector-healer.js +0 -0
  444. /package/{cli/dist → dist}/core/self-healing/types.d.ts +0 -0
  445. /package/{cli/dist → dist}/core/self-healing/types.js +0 -0
  446. /package/{cli/dist → dist}/core/serve/diagnostics-collector.d.ts +0 -0
  447. /package/{cli/dist → dist}/core/serve/diagnostics-collector.js +0 -0
  448. /package/{cli/dist → dist}/core/serve/health-checker.d.ts +0 -0
  449. /package/{cli/dist → dist}/core/serve/health-checker.js +0 -0
  450. /package/{cli/dist → dist}/core/serve/index.d.ts +0 -0
  451. /package/{cli/dist → dist}/core/serve/index.js +0 -0
  452. /package/{cli/dist → dist}/core/serve/metrics-collector.d.ts +0 -0
  453. /package/{cli/dist → dist}/core/serve/metrics-collector.js +0 -0
  454. /package/{cli/dist → dist}/core/serve/process-manager.d.ts +0 -0
  455. /package/{cli/dist → dist}/core/serve/process-manager.js +0 -0
  456. /package/{cli/dist → dist}/core/serve/server.d.ts +0 -0
  457. /package/{cli/dist → dist}/core/serve/server.js +0 -0
  458. /package/{cli/dist → dist}/core/slo/config.d.ts +0 -0
  459. /package/{cli/dist → dist}/core/slo/config.js +0 -0
  460. /package/{cli/dist → dist}/core/slo/index.d.ts +0 -0
  461. /package/{cli/dist → dist}/core/slo/index.js +0 -0
  462. /package/{cli/dist → dist}/core/slo/sli-calculator.d.ts +0 -0
  463. /package/{cli/dist → dist}/core/slo/sli-calculator.js +0 -0
  464. /package/{cli/dist → dist}/core/slo/slo-tracker.d.ts +0 -0
  465. /package/{cli/dist → dist}/core/slo/slo-tracker.js +0 -0
  466. /package/{cli/dist → dist}/core/slo/types.d.ts +0 -0
  467. /package/{cli/dist → dist}/core/slo/types.js +0 -0
  468. /package/{cli/dist → dist}/core/slo/vault.d.ts +0 -0
  469. /package/{cli/dist → dist}/core/slo/vault.js +0 -0
  470. /package/{cli/dist → dist}/core/tui/index.d.ts +0 -0
  471. /package/{cli/dist → dist}/core/tui/index.js +0 -0
  472. /package/{cli/dist → dist}/core/tui/monitor.d.ts +0 -0
  473. /package/{cli/dist → dist}/core/tui/monitor.js +0 -0
  474. /package/{cli/dist → dist}/core/tui/renderer.d.ts +0 -0
  475. /package/{cli/dist → dist}/core/tui/renderer.js +0 -0
  476. /package/{cli/dist → dist}/core/tui/types.d.ts +0 -0
  477. /package/{cli/dist → dist}/core/tui/types.js +0 -0
  478. /package/{cli/dist → dist}/core/types/pack-v1.js +0 -0
  479. /package/{cli/dist → dist}/core/types/pack-v2.js +0 -0
  480. /package/{cli/dist → dist}/core/types/trust-score.d.ts +0 -0
  481. /package/{cli/dist → dist}/core/types/trust-score.js +0 -0
  482. /package/{cli/dist → dist}/core/vault/cas.d.ts +0 -0
  483. /package/{cli/dist → dist}/core/vault/cas.js +0 -0
  484. /package/{cli/dist → dist}/core/vault/index.d.ts +0 -0
  485. /package/{cli/dist → dist}/core/vault/index.js +0 -0
  486. /package/{cli/dist → dist}/core/visual/visual-regression.d.ts +0 -0
  487. /package/{cli/dist → dist}/core/visual/visual-regression.js +0 -0
  488. /package/{cli/dist → dist}/core/watch/index.d.ts +0 -0
  489. /package/{cli/dist → dist}/core/watch/index.js +0 -0
  490. /package/{cli/dist → dist}/core/watch/watch-mode.d.ts +0 -0
  491. /package/{cli/dist → dist}/core/watch/watch-mode.js +0 -0
  492. /package/{cli/dist → dist}/generators/index.d.ts +0 -0
  493. /package/{cli/dist → dist}/generators/index.js +0 -0
  494. /package/{cli/dist → dist}/generators/json-reporter.d.ts +0 -0
  495. /package/{cli/dist → dist}/generators/json-reporter.js +0 -0
  496. /package/{cli/dist → dist}/generators/test-generator.d.ts +0 -0
  497. /package/{cli/dist → dist}/generators/test-generator.js +0 -0
  498. /package/{cli/dist → dist}/index.d.ts +0 -0
  499. /package/{cli/dist → dist}/index.js +0 -0
  500. /package/{cli/dist → dist}/scanners/dom-scanner.d.ts +0 -0
  501. /package/{cli/dist → dist}/scanners/dom-scanner.js +0 -0
  502. /package/{cli/dist → dist}/scanners/index.d.ts +0 -0
  503. /package/{cli/dist → dist}/scanners/index.js +0 -0
  504. /package/{cli/dist → dist}/schemas/pack.schema.json +0 -0
  505. /package/{cli/dist → dist}/types/scan.d.ts +0 -0
  506. /package/{cli/dist → dist}/types/scan.js +0 -0
  507. /package/{cli/dist → dist}/utils/config.js +0 -0
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Blob URL Download Handler
3
+ *
4
+ * P1 - Handle downloads initiated via createObjectURL / URL.createObjectURL
5
+ *
6
+ * Supports:
7
+ * - Detection of blob URL downloads
8
+ * - Intercepting blob URL creation
9
+ * - Capturing blob content
10
+ * - Validating blob downloads
11
+ * - Converting blobs to files
12
+ *
13
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
14
+ */
15
+ export interface BlobDownloadConfig {
16
+ /** Directory to save blob downloads */
17
+ downloadDir?: string;
18
+ /** Whether to capture blob content automatically */
19
+ captureContent?: boolean;
20
+ /** Maximum blob size to capture (bytes) */
21
+ maxCaptureSize?: number;
22
+ }
23
+ export interface BlobDownloadInfo {
24
+ /** Blob URL */
25
+ url: string;
26
+ /** Blob ID (internal) */
27
+ blobId: string;
28
+ /** MIME type */
29
+ mimeType: string;
30
+ /** Size in bytes */
31
+ size: number;
32
+ /** Content (if captured) */
33
+ content?: Buffer;
34
+ /** Timestamp */
35
+ timestamp: number;
36
+ /** Source element that triggered download */
37
+ source?: string;
38
+ }
39
+ export interface BlobDownloadResult {
40
+ success: boolean;
41
+ blob?: BlobDownloadInfo;
42
+ error?: string;
43
+ }
44
+ /**
45
+ * Blob URL Download Handler class
46
+ */
47
+ export declare class BlobURLDownloadHandler {
48
+ private downloads;
49
+ private downloadDir;
50
+ private captureContent;
51
+ private maxCaptureSize;
52
+ private stats;
53
+ constructor(config?: BlobDownloadConfig);
54
+ private ensureDownloadDir;
55
+ /**
56
+ * Setup blob URL interception on a page
57
+ * Overrides URL.createObjectURL to capture blob creation
58
+ */
59
+ setupBlobInterception(page: any): Promise<void>;
60
+ /**
61
+ * Wait for blob URL creation matching a pattern
62
+ */
63
+ waitForBlob(page: any, options?: {
64
+ /** MIME type to match */
65
+ mimeType?: string | RegExp;
66
+ /** Minimum size */
67
+ minSize?: number;
68
+ /** Maximum size */
69
+ maxSize?: number;
70
+ /** Timeout in ms */
71
+ timeout?: number;
72
+ }): Promise<BlobDownloadResult>;
73
+ /**
74
+ * Trigger a blob download by clicking an element
75
+ */
76
+ clickAndWaitForBlob(page: any, selector: string, options?: {
77
+ mimeType?: string | RegExp;
78
+ timeout?: number;
79
+ action?: 'click' | 'dblclick';
80
+ }): Promise<BlobDownloadResult>;
81
+ /**
82
+ * Save a blob to a file
83
+ */
84
+ saveBlob(blob: BlobDownloadInfo, filename?: string): Promise<string>;
85
+ /**
86
+ * Get all captured blobs
87
+ */
88
+ getAllBlobs(): BlobDownloadInfo[];
89
+ /**
90
+ * Get blob by ID
91
+ */
92
+ getBlob(blobId: string): BlobDownloadInfo | undefined;
93
+ /**
94
+ * Get the last blob
95
+ */
96
+ getLastBlob(): BlobDownloadInfo | undefined;
97
+ /**
98
+ * Get all blobs by MIME type
99
+ */
100
+ getBlobsByMimeType(mimeType: string | RegExp): BlobDownloadInfo[];
101
+ /**
102
+ * Clear all captured blobs
103
+ */
104
+ clearBlobs(): void;
105
+ /**
106
+ * Get file extension from MIME type
107
+ */
108
+ private getExtension;
109
+ /**
110
+ * Get statistics
111
+ */
112
+ getStats(): {
113
+ totalBlobs: number;
114
+ capturedBlobs: number;
115
+ totalSize: number;
116
+ averageSize: number;
117
+ };
118
+ /**
119
+ * Reset statistics
120
+ */
121
+ resetStats(): void;
122
+ /**
123
+ * Get download directory
124
+ */
125
+ getDownloadDir(): string;
126
+ /**
127
+ * Verify blob content
128
+ */
129
+ verifyBlob(blob: BlobDownloadInfo, verification: {
130
+ /** Expected content pattern */
131
+ contentPattern?: string | RegExp;
132
+ /** Minimum size */
133
+ minSize?: number;
134
+ /** Maximum size */
135
+ maxSize?: number;
136
+ }): Promise<{
137
+ valid: boolean;
138
+ errors: string[];
139
+ }>;
140
+ }
141
+ /**
142
+ * Factory function to create Blob URL Download Handler
143
+ */
144
+ export declare function createBlobURLDownloadHandler(config?: BlobDownloadConfig): BlobURLDownloadHandler;
145
+ export default BlobURLDownloadHandler;
@@ -0,0 +1,392 @@
1
+ /**
2
+ * Blob URL Download Handler
3
+ *
4
+ * P1 - Handle downloads initiated via createObjectURL / URL.createObjectURL
5
+ *
6
+ * Supports:
7
+ * - Detection of blob URL downloads
8
+ * - Intercepting blob URL creation
9
+ * - Capturing blob content
10
+ * - Validating blob downloads
11
+ * - Converting blobs to files
12
+ *
13
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
14
+ */
15
+ import { promises as fs } from 'fs';
16
+ import { join } from 'path';
17
+ /**
18
+ * Blob URL Download Handler class
19
+ */
20
+ export class BlobURLDownloadHandler {
21
+ downloads = new Map();
22
+ downloadDir;
23
+ captureContent;
24
+ maxCaptureSize;
25
+ stats = {
26
+ totalBlobs: 0,
27
+ capturedBlobs: 0,
28
+ totalSize: 0,
29
+ };
30
+ constructor(config = {}) {
31
+ this.downloadDir = config.downloadDir || '/tmp/qa360-blob-downloads';
32
+ this.captureContent = config.captureContent !== false;
33
+ this.maxCaptureSize = config.maxCaptureSize || 10 * 1024 * 1024; // 10MB default
34
+ this.ensureDownloadDir();
35
+ }
36
+ async ensureDownloadDir() {
37
+ try {
38
+ await fs.mkdir(this.downloadDir, { recursive: true });
39
+ }
40
+ catch {
41
+ // Directory might already exist
42
+ }
43
+ }
44
+ /**
45
+ * Setup blob URL interception on a page
46
+ * Overrides URL.createObjectURL to capture blob creation
47
+ */
48
+ async setupBlobInterception(page) {
49
+ await page.evaluate((config) => {
50
+ // Store original createObjectURL
51
+ const originalCreateObjectURL = URL.createObjectURL;
52
+ // Initialize blob storage on window
53
+ if (!window.__qa360Blobs) {
54
+ window.__qa360Blobs = [];
55
+ }
56
+ // Override URL.createObjectURL
57
+ URL.createObjectURL = function (blob) {
58
+ const url = originalCreateObjectURL.call(URL, blob);
59
+ // Capture blob info
60
+ const blobInfo = {
61
+ url,
62
+ id: `blob-${Date.now()}-${Math.random().toString(36).substring(7)}`,
63
+ mimeType: blob.type || 'application/octet-stream',
64
+ size: blob.size || 0,
65
+ timestamp: Date.now(),
66
+ };
67
+ // Capture content if enabled and size is reasonable
68
+ if (config.capture && blob.size <= config.maxSize) {
69
+ const reader = new FileReader();
70
+ reader.onload = () => {
71
+ blobInfo.content = reader.result;
72
+ };
73
+ reader.readAsDataURL(blob);
74
+ }
75
+ window.__qa360Blobs.push(blobInfo);
76
+ console.log(`📦 Blob created: ${blobInfo.mimeType} (${blobInfo.size} bytes)`);
77
+ return url;
78
+ };
79
+ // Also override URL.revokeObjectURL to track cleanup
80
+ const originalRevokeObjectURL = URL.revokeObjectURL;
81
+ URL.revokeObjectURL = function (url) {
82
+ originalRevokeObjectURL.call(URL, url);
83
+ const blobs = window.__qa360Blobs || [];
84
+ const index = blobs.findIndex((b) => b.url === url);
85
+ if (index !== -1) {
86
+ blobs[index].revoked = true;
87
+ blobs[index].revokedAt = Date.now();
88
+ }
89
+ };
90
+ // Track blob downloads via download attribute on links
91
+ document.addEventListener('click', (e) => {
92
+ const target = e.target;
93
+ if (target.tagName === 'A' && target instanceof HTMLAnchorElement) {
94
+ const href = target.href;
95
+ if (href && href.startsWith('blob:')) {
96
+ const blobs = window.__qa360Blobs || [];
97
+ const blob = blobs.find((b) => b.url === href);
98
+ if (blob) {
99
+ blob.downloaded = true;
100
+ blob.downloadSource = {
101
+ tagName: target.tagName,
102
+ id: target.id,
103
+ className: target.className,
104
+ textContent: target.textContent?.substring(0, 50),
105
+ };
106
+ }
107
+ }
108
+ }
109
+ }, true);
110
+ }, {
111
+ capture: this.captureContent,
112
+ maxSize: this.maxCaptureSize,
113
+ });
114
+ }
115
+ /**
116
+ * Wait for blob URL creation matching a pattern
117
+ */
118
+ async waitForBlob(page, options = {}) {
119
+ const timeout = options.timeout || 30000;
120
+ const startTime = Date.now();
121
+ return new Promise((resolve) => {
122
+ const checkInterval = setInterval(async () => {
123
+ try {
124
+ const blobs = await page.evaluate(() => {
125
+ return window.__qa360Blobs || [];
126
+ });
127
+ for (const blob of blobs) {
128
+ // Check MIME type filter
129
+ if (options.mimeType) {
130
+ const matches = typeof options.mimeType === 'string'
131
+ ? blob.mimeType.includes(options.mimeType)
132
+ : options.mimeType.test(blob.mimeType);
133
+ if (!matches)
134
+ continue;
135
+ }
136
+ // Check size filters
137
+ if (options.minSize && blob.size < options.minSize)
138
+ continue;
139
+ if (options.maxSize && blob.size > options.maxSize)
140
+ continue;
141
+ clearInterval(checkInterval);
142
+ // Fetch blob content
143
+ let content;
144
+ if (this.captureContent) {
145
+ try {
146
+ const contentDataUrl = await page.evaluate((blobUrl) => {
147
+ const blobs = window.__qa360Blobs || [];
148
+ const blob = blobs.find((b) => b.url === blobUrl);
149
+ return blob?.content;
150
+ }, blob.url);
151
+ if (contentDataUrl) {
152
+ const base64 = contentDataUrl.split(',')[1];
153
+ content = Buffer.from(base64, 'base64');
154
+ }
155
+ }
156
+ catch {
157
+ // Content not available
158
+ }
159
+ }
160
+ const downloadInfo = {
161
+ url: blob.url,
162
+ blobId: blob.id,
163
+ mimeType: blob.mimeType,
164
+ size: blob.size,
165
+ content,
166
+ timestamp: blob.timestamp,
167
+ source: blob.downloadSource?.textContent,
168
+ };
169
+ this.downloads.set(blob.id, downloadInfo);
170
+ this.stats.totalBlobs++;
171
+ if (content) {
172
+ this.stats.capturedBlobs++;
173
+ this.stats.totalSize += content.length;
174
+ }
175
+ resolve({
176
+ success: true,
177
+ blob: downloadInfo,
178
+ });
179
+ return;
180
+ }
181
+ if (Date.now() - startTime > timeout) {
182
+ clearInterval(checkInterval);
183
+ resolve({
184
+ success: false,
185
+ error: `Timeout waiting for blob URL creation`,
186
+ });
187
+ }
188
+ }
189
+ catch (e) {
190
+ clearInterval(checkInterval);
191
+ resolve({
192
+ success: false,
193
+ error: e instanceof Error ? e.message : String(e),
194
+ });
195
+ }
196
+ }, 100);
197
+ });
198
+ }
199
+ /**
200
+ * Trigger a blob download by clicking an element
201
+ */
202
+ async clickAndWaitForBlob(page, selector, options = {}) {
203
+ await this.setupBlobInterception(page);
204
+ const timeout = options.timeout || 30000;
205
+ const startTime = Date.now();
206
+ // Start waiting for blob before clicking
207
+ const blobPromise = this.waitForBlob(page, {
208
+ mimeType: options.mimeType,
209
+ timeout,
210
+ });
211
+ // Perform the click
212
+ try {
213
+ const element = page.locator(selector).first();
214
+ await element.waitFor({ state: 'visible', timeout: 5000 });
215
+ if (options.action === 'dblclick') {
216
+ await element.dblclick();
217
+ }
218
+ else {
219
+ await element.click();
220
+ }
221
+ const result = await blobPromise;
222
+ // Add source info
223
+ if (result.blob) {
224
+ const sourceInfo = await page.evaluate((sel) => {
225
+ const el = document.querySelector(sel);
226
+ if (!el)
227
+ return null;
228
+ return {
229
+ tagName: el.tagName,
230
+ id: el.id,
231
+ className: el.className,
232
+ textContent: el.textContent?.substring(0, 50),
233
+ };
234
+ }, selector);
235
+ result.blob.source = sourceInfo?.textContent || selector;
236
+ }
237
+ return result;
238
+ }
239
+ catch (e) {
240
+ return {
241
+ success: false,
242
+ error: e instanceof Error ? e.message : String(e),
243
+ };
244
+ }
245
+ }
246
+ /**
247
+ * Save a blob to a file
248
+ */
249
+ async saveBlob(blob, filename) {
250
+ const finalFilename = filename || `blob-${blob.blobId}.${this.getExtension(blob.mimeType)}`;
251
+ const path = join(this.downloadDir, finalFilename);
252
+ if (blob.content) {
253
+ await fs.writeFile(path, blob.content);
254
+ return path;
255
+ }
256
+ // If content wasn't captured, try to fetch it from the page context
257
+ throw new Error('Blob content not available for saving');
258
+ }
259
+ /**
260
+ * Get all captured blobs
261
+ */
262
+ getAllBlobs() {
263
+ return Array.from(this.downloads.values());
264
+ }
265
+ /**
266
+ * Get blob by ID
267
+ */
268
+ getBlob(blobId) {
269
+ return this.downloads.get(blobId);
270
+ }
271
+ /**
272
+ * Get the last blob
273
+ */
274
+ getLastBlob() {
275
+ const blobs = Array.from(this.downloads.values());
276
+ if (blobs.length === 0)
277
+ return undefined;
278
+ return blobs.sort((a, b) => b.timestamp - a.timestamp)[0];
279
+ }
280
+ /**
281
+ * Get all blobs by MIME type
282
+ */
283
+ getBlobsByMimeType(mimeType) {
284
+ const blobs = this.getAllBlobs();
285
+ return blobs.filter(blob => {
286
+ if (typeof mimeType === 'string') {
287
+ return blob.mimeType.includes(mimeType);
288
+ }
289
+ return mimeType.test(blob.mimeType);
290
+ });
291
+ }
292
+ /**
293
+ * Clear all captured blobs
294
+ */
295
+ clearBlobs() {
296
+ this.downloads.clear();
297
+ }
298
+ /**
299
+ * Get file extension from MIME type
300
+ */
301
+ getExtension(mimeType) {
302
+ const extensions = {
303
+ 'application/pdf': 'pdf',
304
+ 'application/json': 'json',
305
+ 'application/xml': 'xml',
306
+ 'text/xml': 'xml',
307
+ 'text/html': 'html',
308
+ 'text/plain': 'txt',
309
+ 'text/csv': 'csv',
310
+ 'image/jpeg': 'jpg',
311
+ 'image/png': 'png',
312
+ 'image/gif': 'gif',
313
+ 'image/webp': 'webp',
314
+ 'image/svg+xml': 'svg',
315
+ 'video/mp4': 'mp4',
316
+ 'video/webm': 'webm',
317
+ 'audio/mpeg': 'mp3',
318
+ 'audio/wav': 'wav',
319
+ 'application/zip': 'zip',
320
+ 'application/x-zip-compressed': 'zip',
321
+ };
322
+ for (const [type, ext] of Object.entries(extensions)) {
323
+ if (mimeType.startsWith(type)) {
324
+ return ext;
325
+ }
326
+ }
327
+ return 'bin';
328
+ }
329
+ /**
330
+ * Get statistics
331
+ */
332
+ getStats() {
333
+ return {
334
+ ...this.stats,
335
+ averageSize: this.stats.capturedBlobs > 0
336
+ ? this.stats.totalSize / this.stats.capturedBlobs
337
+ : 0,
338
+ };
339
+ }
340
+ /**
341
+ * Reset statistics
342
+ */
343
+ resetStats() {
344
+ this.stats = {
345
+ totalBlobs: 0,
346
+ capturedBlobs: 0,
347
+ totalSize: 0,
348
+ };
349
+ }
350
+ /**
351
+ * Get download directory
352
+ */
353
+ getDownloadDir() {
354
+ return this.downloadDir;
355
+ }
356
+ /**
357
+ * Verify blob content
358
+ */
359
+ async verifyBlob(blob, verification) {
360
+ const errors = [];
361
+ if (verification.minSize && blob.size < verification.minSize) {
362
+ errors.push(`Size ${blob.size} is below minimum ${verification.minSize}`);
363
+ }
364
+ if (verification.maxSize && blob.size > verification.maxSize) {
365
+ errors.push(`Size ${blob.size} exceeds maximum ${verification.maxSize}`);
366
+ }
367
+ if (verification.contentPattern && blob.content) {
368
+ const content = blob.content.toString('utf-8');
369
+ if (typeof verification.contentPattern === 'string') {
370
+ if (!content.includes(verification.contentPattern)) {
371
+ errors.push(`Content does not include "${verification.contentPattern}"`);
372
+ }
373
+ }
374
+ else {
375
+ if (!verification.contentPattern.test(content)) {
376
+ errors.push('Content does not match expected pattern');
377
+ }
378
+ }
379
+ }
380
+ return {
381
+ valid: errors.length === 0,
382
+ errors,
383
+ };
384
+ }
385
+ }
386
+ /**
387
+ * Factory function to create Blob URL Download Handler
388
+ */
389
+ export function createBlobURLDownloadHandler(config) {
390
+ return new BlobURLDownloadHandler(config);
391
+ }
392
+ export default BlobURLDownloadHandler;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * QA360 Consent Handler
3
+ *
4
+ * Automatically detects and dismisses GDPR/CCPA cookie consent banners.
5
+ * Supports all major Consent Management Platforms (CMPs).
6
+ *
7
+ * Philosophy: "80% of EU sites block interaction with consent banners"
8
+ */
9
+ import type { Page } from '@playwright/test';
10
+ /**
11
+ * Consent handling options
12
+ */
13
+ export interface ConsentOptions {
14
+ /** Action to take: 'accept', 'reject', or 'ignore' */
15
+ action?: 'accept' | 'reject' | 'ignore';
16
+ /** Timeout for banner detection (ms) */
17
+ timeout?: number;
18
+ /** Custom selector override */
19
+ customSelector?: string;
20
+ }
21
+ /**
22
+ * Consent Handler - Auto-detects and handles GDPR/CCPA banners
23
+ */
24
+ export declare class ConsentHandler {
25
+ /**
26
+ * Handle consent banners on the page
27
+ *
28
+ * @param page - Playwright Page instance
29
+ * @param options - Consent handling options
30
+ * @returns true if a banner was found and handled, false otherwise
31
+ */
32
+ static handleConsent(page: Page, options?: ConsentOptions): Promise<boolean>;
33
+ /**
34
+ * Try a specific CMP
35
+ */
36
+ private static tryCMP;
37
+ /**
38
+ * Handle custom consent selector
39
+ */
40
+ private static handleCustom;
41
+ /**
42
+ * Get all supported CMP names
43
+ */
44
+ static getSupportedCMPs(): string[];
45
+ }
46
+ /**
47
+ * Quick function to handle consent (convenience wrapper)
48
+ */
49
+ export declare function handleConsent(page: Page, options?: ConsentOptions): Promise<boolean>;