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,370 @@
1
+ /**
2
+ * Download Handler
3
+ *
4
+ * P1 - File download management
5
+ *
6
+ * Supports:
7
+ * - Click and wait for download
8
+ * - Download verification
9
+ * - Multiple downloads handling
10
+ * - Download timeout
11
+ * - File size validation
12
+ *
13
+ * @see https://playwright.dev/docs/downloads
14
+ */
15
+ import { promises as fs } from 'fs';
16
+ import { join } from 'path';
17
+ /**
18
+ * Download Handler class
19
+ */
20
+ export class DownloadHandler {
21
+ downloads = new Map();
22
+ downloadDir;
23
+ defaultTimeout;
24
+ saveFiles;
25
+ stats = {
26
+ totalDownloads: 0,
27
+ successfulDownloads: 0,
28
+ failedDownloads: 0,
29
+ totalSize: 0,
30
+ };
31
+ constructor(config = {}) {
32
+ this.downloadDir = config.downloadDir || '/tmp/qa360-downloads';
33
+ this.defaultTimeout = config.timeout || 30000;
34
+ this.saveFiles = config.saveFiles !== false;
35
+ // Ensure download directory exists
36
+ this.ensureDownloadDir();
37
+ }
38
+ async ensureDownloadDir() {
39
+ try {
40
+ await fs.mkdir(this.downloadDir, { recursive: true });
41
+ }
42
+ catch {
43
+ // Directory might already exist
44
+ }
45
+ }
46
+ /**
47
+ * Setup download handling for a page
48
+ */
49
+ setupDownloadHandler(page) {
50
+ page.on('download', async (download) => {
51
+ const filename = download.suggestedFilename();
52
+ const path = join(this.downloadDir, filename);
53
+ const info = {
54
+ filename,
55
+ path,
56
+ url: download.url(),
57
+ mimeType: download.contentType(),
58
+ timestamp: Date.now(),
59
+ };
60
+ if (this.saveFiles) {
61
+ try {
62
+ await download.saveAs(path);
63
+ const stats = await fs.stat(path);
64
+ info.size = stats.size;
65
+ }
66
+ catch (e) {
67
+ console.error(`Failed to save download: ${e}`);
68
+ }
69
+ }
70
+ this.downloads.set(filename, info);
71
+ console.log(`📥 Download: ${filename} (${info.size ? info.size + ' bytes' : 'size unknown'})`);
72
+ });
73
+ }
74
+ /**
75
+ * Click element and wait for download
76
+ */
77
+ async clickAndWaitForDownload(page, selector, options = {}) {
78
+ const timeout = options.timeout || this.defaultTimeout;
79
+ const action = options.action || 'click';
80
+ this.stats.totalDownloads++;
81
+ this.setupDownloadHandler(page);
82
+ try {
83
+ // Start waiting for download before clicking
84
+ const downloadPromise = page.waitForEvent('download', { timeout });
85
+ // Perform the action
86
+ const element = page.locator(selector).first();
87
+ await element.waitFor({ state: 'visible', timeout: 5000 });
88
+ switch (action) {
89
+ case 'click':
90
+ await element.click();
91
+ break;
92
+ case 'dblclick':
93
+ await element.dblclick();
94
+ break;
95
+ case 'hover':
96
+ await element.hover();
97
+ break;
98
+ }
99
+ // Wait for download to start
100
+ const download = await downloadPromise;
101
+ const filename = download.suggestedFilename();
102
+ const path = join(this.downloadDir, filename);
103
+ const info = {
104
+ filename,
105
+ path,
106
+ url: download.url(),
107
+ mimeType: download.contentType(),
108
+ timestamp: Date.now(),
109
+ };
110
+ if (this.saveFiles && options.waitForCompletion !== false) {
111
+ await download.saveAs(path);
112
+ const stats = await fs.stat(path);
113
+ info.size = stats.size;
114
+ this.stats.totalSize += stats.size;
115
+ }
116
+ this.downloads.set(filename, info);
117
+ this.stats.successfulDownloads++;
118
+ // Return both the info and the raw download object for tests
119
+ return {
120
+ success: true,
121
+ download: info,
122
+ // Include raw download object for tests that expect download.suggestedFilename()
123
+ rawDownload: download,
124
+ };
125
+ }
126
+ catch (e) {
127
+ this.stats.failedDownloads++;
128
+ return {
129
+ success: false,
130
+ error: e instanceof Error ? e.message : String(e),
131
+ };
132
+ }
133
+ }
134
+ /**
135
+ * Click multiple elements and wait for downloads
136
+ */
137
+ async clickAndWaitForDownloads(page, selectors, options = {}) {
138
+ const results = [];
139
+ for (const selector of selectors) {
140
+ const result = await this.clickAndWaitForDownload(page, selector, options);
141
+ results.push(result);
142
+ }
143
+ return results;
144
+ }
145
+ /**
146
+ * Wait for download by filename pattern
147
+ */
148
+ async waitForDownload(page, filenamePattern, timeout = this.defaultTimeout) {
149
+ const startTime = Date.now();
150
+ return new Promise((resolve) => {
151
+ const checkInterval = setInterval(() => {
152
+ const downloads = Array.from(this.downloads.values());
153
+ for (const download of downloads) {
154
+ const matches = typeof filenamePattern === 'string'
155
+ ? download.filename.includes(filenamePattern)
156
+ : filenamePattern.test(download.filename);
157
+ if (matches) {
158
+ clearInterval(checkInterval);
159
+ resolve({ success: true, download });
160
+ return;
161
+ }
162
+ }
163
+ if (Date.now() - startTime > timeout) {
164
+ clearInterval(checkInterval);
165
+ resolve({ success: false, error: `Timeout waiting for download matching: ${filenamePattern}` });
166
+ }
167
+ }, 100);
168
+ });
169
+ }
170
+ /**
171
+ * Verify a download
172
+ */
173
+ async verifyDownload(download, verification) {
174
+ // Handle both raw Download object and DownloadInfo
175
+ const filename = download.suggestedFilename ? download.suggestedFilename() : download.filename;
176
+ const size = download.size || (download._failure ? undefined : download.size);
177
+ const errors = [];
178
+ let filenameMatch = true;
179
+ let sizeMatch = true;
180
+ let mimeTypeMatch = true;
181
+ let contentMatch = true;
182
+ // Filename verification
183
+ if (verification.filename) {
184
+ const matches = typeof verification.filename === 'string'
185
+ ? filename === verification.filename
186
+ : verification.filename.test(filename);
187
+ filenameMatch = matches;
188
+ if (!matches) {
189
+ errors.push('Filename mismatch');
190
+ }
191
+ }
192
+ else if (verification.filenamePattern) {
193
+ const pattern = verification.filenamePattern;
194
+ const matches = typeof pattern === 'string'
195
+ ? filename.includes(pattern)
196
+ : pattern.test(filename);
197
+ if (!matches) {
198
+ errors.push('Filename mismatch');
199
+ }
200
+ }
201
+ // Size verification
202
+ if (verification.minSize && size !== undefined && size < verification.minSize) {
203
+ sizeMatch = false;
204
+ errors.push('File size mismatch');
205
+ }
206
+ if (verification.maxSize && size !== undefined && size > verification.maxSize) {
207
+ sizeMatch = false;
208
+ errors.push('File size mismatch');
209
+ }
210
+ // MIME type verification
211
+ if (verification.mimeType) {
212
+ const mimeType = download.contentType ? download.contentType() : download.mimeType;
213
+ const matches = typeof verification.mimeType === 'string'
214
+ ? mimeType === verification.mimeType
215
+ : (verification.mimeType instanceof RegExp
216
+ ? verification.mimeType.test(mimeType)
217
+ : mimeType.includes(verification.mimeType.replace('*', '')));
218
+ mimeTypeMatch = matches;
219
+ if (!matches) {
220
+ errors.push('MIME type mismatch');
221
+ }
222
+ }
223
+ // Content verification (requires reading file)
224
+ if (verification.content || verification.contentPattern) {
225
+ if (download.path) {
226
+ try {
227
+ const fileContent = await fs.readFile(download.path, 'utf-8');
228
+ if (verification.content) {
229
+ contentMatch = fileContent.includes(verification.content);
230
+ }
231
+ else if (verification.contentPattern) {
232
+ contentMatch = verification.contentPattern.test(fileContent);
233
+ }
234
+ if (!contentMatch) {
235
+ errors.push('Content mismatch');
236
+ }
237
+ }
238
+ catch {
239
+ contentMatch = false;
240
+ errors.push('Content mismatch');
241
+ }
242
+ }
243
+ }
244
+ return {
245
+ valid: filenameMatch && sizeMatch && mimeTypeMatch && contentMatch,
246
+ filenameMatch,
247
+ sizeMatch,
248
+ mimeTypeMatch,
249
+ contentMatch,
250
+ actualSize: size,
251
+ errors,
252
+ };
253
+ }
254
+ /**
255
+ * Get all downloads
256
+ */
257
+ getAllDownloads() {
258
+ return Array.from(this.downloads.values());
259
+ }
260
+ /**
261
+ * Get download by filename
262
+ */
263
+ getDownload(filename) {
264
+ return this.downloads.get(filename);
265
+ }
266
+ /**
267
+ * Get last download
268
+ */
269
+ getLastDownload() {
270
+ const downloads = Array.from(this.downloads.values());
271
+ if (downloads.length === 0)
272
+ return undefined;
273
+ return downloads.sort((a, b) => b.timestamp - a.timestamp)[0];
274
+ }
275
+ /**
276
+ * Clear all downloads
277
+ */
278
+ clearDownloads() {
279
+ this.downloads.clear();
280
+ }
281
+ /**
282
+ * Delete downloaded files
283
+ */
284
+ async clearDownloadFiles() {
285
+ const files = await fs.readdir(this.downloadDir).catch(() => []);
286
+ for (const file of files) {
287
+ const path = join(this.downloadDir, file);
288
+ await fs.unlink(path).catch(() => {
289
+ // File might not exist or be deletable
290
+ });
291
+ }
292
+ }
293
+ /**
294
+ * Get download directory
295
+ */
296
+ getDownloadDir() {
297
+ return this.downloadDir;
298
+ }
299
+ /**
300
+ * Set download directory
301
+ */
302
+ setDownloadDir(dir) {
303
+ this.downloadDir = dir;
304
+ this.ensureDownloadDir();
305
+ }
306
+ /**
307
+ * Get download count
308
+ */
309
+ get downloadCount() {
310
+ return this.downloads.size;
311
+ }
312
+ /**
313
+ * Assert download exists
314
+ */
315
+ assertDownloadExists(filenamePattern) {
316
+ const downloads = Array.from(this.downloads.values());
317
+ for (const download of downloads) {
318
+ const matches = typeof filenamePattern === 'string'
319
+ ? download.filename.includes(filenamePattern)
320
+ : filenamePattern.test(download.filename);
321
+ if (matches) {
322
+ return { success: true, download };
323
+ }
324
+ }
325
+ return {
326
+ success: false,
327
+ error: `No download found matching pattern: ${filenamePattern}`,
328
+ };
329
+ }
330
+ /**
331
+ * Get download statistics
332
+ */
333
+ getStats() {
334
+ const downloads = this.getAllDownloads();
335
+ const averageSize = this.stats.totalDownloads > 0
336
+ ? this.stats.totalSize / this.stats.successfulDownloads
337
+ : 0;
338
+ return {
339
+ totalDownloads: this.stats.totalDownloads,
340
+ successfulDownloads: this.stats.successfulDownloads,
341
+ failedDownloads: this.stats.failedDownloads,
342
+ totalSize: this.stats.totalSize,
343
+ averageSize,
344
+ };
345
+ }
346
+ /**
347
+ * Get download history
348
+ */
349
+ getHistory() {
350
+ return this.getAllDownloads();
351
+ }
352
+ /**
353
+ * Reset statistics
354
+ */
355
+ resetStats() {
356
+ this.stats = {
357
+ totalDownloads: 0,
358
+ successfulDownloads: 0,
359
+ failedDownloads: 0,
360
+ totalSize: 0,
361
+ };
362
+ }
363
+ }
364
+ /**
365
+ * Factory function to create Download Handler
366
+ */
367
+ export function createDownloadHandler(config) {
368
+ return new DownloadHandler(config);
369
+ }
370
+ export default DownloadHandler;
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Email Testing Handler
3
+ *
4
+ * P1 - Email testing for applications that send emails
5
+ *
6
+ * Supports:
7
+ * - Mailhog integration
8
+ * - Mailtrap integration
9
+ * - Mailgun API
10
+ * - SendGrid API
11
+ * - Generic IMAP/POP3 access
12
+ * - Email parsing and validation
13
+ * - Link extraction from emails
14
+ * - Attachment handling
15
+ *
16
+ * @see https://github.com/mailhog/MailHog
17
+ */
18
+ export interface EmailConfig {
19
+ /** Mailhog API base URL (e.g., http://localhost:8025) */
20
+ mailhogUrl?: string;
21
+ /** Mailtrap API token */
22
+ mailtrapToken?: string;
23
+ /** Mailgun API key */
24
+ mailgunApiKey?: string;
25
+ /** SendGrid API key */
26
+ sendgridApiKey?: string;
27
+ /** Default timeout for email operations (ms) */
28
+ timeout?: number;
29
+ }
30
+ export interface EmailMessage {
31
+ /** Message ID */
32
+ id: string;
33
+ /** From address */
34
+ from: string;
35
+ /** To addresses */
36
+ to: string[];
37
+ /** CC addresses */
38
+ cc?: string[];
39
+ /** Subject */
40
+ subject: string;
41
+ /** Plain text body */
42
+ text?: string;
43
+ /** HTML body */
44
+ html?: string;
45
+ /** Received timestamp */
46
+ received: Date;
47
+ /** Attachments */
48
+ attachments?: EmailAttachment[];
49
+ /** Custom headers */
50
+ headers?: Record<string, string>;
51
+ }
52
+ export interface EmailAttachment {
53
+ /** Filename */
54
+ filename: string;
55
+ /** Content type */
56
+ contentType: string;
57
+ /** Size in bytes */
58
+ size: number;
59
+ /** Download URL (if available) */
60
+ downloadUrl?: string;
61
+ }
62
+ export interface EmailSearchOptions {
63
+ /** Filter by recipient */
64
+ to?: string;
65
+ /** Filter by sender */
66
+ from?: string;
67
+ /** Filter by subject (partial match) */
68
+ subject?: string;
69
+ /** Filter by content (partial match) */
70
+ contains?: string;
71
+ /** Minimum received date */
72
+ after?: Date;
73
+ /** Maximum received date */
74
+ before?: Date;
75
+ }
76
+ /**
77
+ * Email Testing Handler class
78
+ */
79
+ export declare class EmailTestingHandler {
80
+ private mailhogUrl;
81
+ private timeout;
82
+ private mailtrapToken?;
83
+ private mailgunApiKey?;
84
+ private sendgridApiKey?;
85
+ constructor(config?: EmailConfig);
86
+ /**
87
+ * Fetch all messages from Mailhog
88
+ */
89
+ fetchMessages(): Promise<EmailMessage[]>;
90
+ /**
91
+ * Delete all messages from Mailhog
92
+ */
93
+ deleteAllMessages(): Promise<void>;
94
+ /**
95
+ * Get a specific message by ID
96
+ */
97
+ getMessage(id: string): Promise<EmailMessage | null>;
98
+ /**
99
+ * Wait for a new email matching criteria
100
+ */
101
+ waitForEmail(options?: EmailSearchOptions, timeout?: number): Promise<EmailMessage | null>;
102
+ /**
103
+ * Search for messages matching criteria
104
+ */
105
+ searchMessages(options: EmailSearchOptions): Promise<EmailMessage[]>;
106
+ /**
107
+ * Get the most recent email matching criteria
108
+ */
109
+ getLatestEmail(options?: EmailSearchOptions): Promise<EmailMessage | null>;
110
+ /**
111
+ * Extract all links from an email
112
+ */
113
+ extractLinks(message: EmailMessage): {
114
+ textLinks: string[];
115
+ htmlLinks: string[];
116
+ allLinks: string[];
117
+ };
118
+ /**
119
+ * Extract verification links (common patterns)
120
+ */
121
+ extractVerificationLinks(message: EmailMessage): {
122
+ verifyEmail: string[];
123
+ resetPassword: string[];
124
+ unsubscribe: string[];
125
+ other: string[];
126
+ };
127
+ /**
128
+ * Extract OTP/code from email
129
+ */
130
+ extractCode(message: EmailMessage): {
131
+ code?: string;
132
+ type?: 'numeric' | 'alphanumeric';
133
+ confidence: number;
134
+ };
135
+ /**
136
+ * Parse a Mailhog message
137
+ */
138
+ private parseMailhogMessage;
139
+ /**
140
+ * Parse email address from string
141
+ */
142
+ private parseEmailAddress;
143
+ /**
144
+ * Parse attachments from Mailhog format
145
+ */
146
+ private parseAttachments;
147
+ /**
148
+ * Check if message matches search criteria
149
+ */
150
+ private matchesCriteria;
151
+ /**
152
+ * Assert email was received
153
+ */
154
+ assertEmailReceived(options: EmailSearchOptions, timeout?: number): Promise<{
155
+ received: boolean;
156
+ email?: EmailMessage;
157
+ error?: string;
158
+ }>;
159
+ /**
160
+ * Assert email contains link
161
+ */
162
+ assertEmailContainsLink(message: EmailMessage, linkPattern: string | RegExp): {
163
+ contains: boolean;
164
+ foundLinks: string[];
165
+ };
166
+ /**
167
+ * Get Mailhog status
168
+ */
169
+ getMailhogStatus(): Promise<{
170
+ available: boolean;
171
+ error?: string;
172
+ }>;
173
+ private sleep;
174
+ /**
175
+ * Fetch messages from Mailtrap (alternative to Mailhog)
176
+ */
177
+ fetchMailtrapMessages(inboxId?: string): Promise<EmailMessage[]>;
178
+ /**
179
+ * Parse Mailtrap message
180
+ */
181
+ private parseMailtrapMessage;
182
+ /**
183
+ * Create email testing utilities for test helpers
184
+ */
185
+ createTestHelpers(): {
186
+ waitForEmail: (options?: EmailSearchOptions, timeout?: number) => Promise<EmailMessage | null>;
187
+ getLatestEmail: (options?: EmailSearchOptions) => Promise<EmailMessage | null>;
188
+ extractLinks: (message: EmailMessage) => {
189
+ textLinks: string[];
190
+ htmlLinks: string[];
191
+ allLinks: string[];
192
+ };
193
+ extractCode: (message: EmailMessage) => {
194
+ code?: string;
195
+ type?: "numeric" | "alphanumeric";
196
+ confidence: number;
197
+ };
198
+ deleteAll: () => Promise<void>;
199
+ assertEmailReceived: (options: EmailSearchOptions, timeout?: number) => Promise<{
200
+ received: boolean;
201
+ email?: EmailMessage;
202
+ error?: string;
203
+ }>;
204
+ };
205
+ }
206
+ /**
207
+ * Factory function to create Email Testing Handler
208
+ */
209
+ export declare function createEmailTestingHandler(config?: EmailConfig): EmailTestingHandler;
210
+ /**
211
+ * Quick function to wait for email
212
+ */
213
+ export declare function waitForEmail(config: EmailConfig, options: EmailSearchOptions, timeout?: number): Promise<EmailMessage | null>;
214
+ export default EmailTestingHandler;