qa360 2.2.1 → 2.2.13

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 (912) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +79 -0
  3. package/cli/dist/cli-minimal.d.ts +6 -0
  4. package/cli/dist/cli-minimal.js +36 -0
  5. package/cli/dist/commands/ai.d.ts +43 -0
  6. package/cli/dist/commands/ai.js +616 -0
  7. package/cli/dist/commands/ask.d.ts +94 -0
  8. package/cli/dist/commands/ask.js +582 -0
  9. package/cli/dist/commands/coverage.d.ts +8 -0
  10. package/cli/dist/commands/coverage.js +252 -0
  11. package/cli/dist/commands/crawl.d.ts +24 -0
  12. package/cli/dist/commands/crawl.js +121 -0
  13. package/cli/dist/commands/doctor.d.ts +54 -0
  14. package/cli/dist/commands/doctor.js +513 -0
  15. package/cli/dist/commands/examples.d.ts +33 -0
  16. package/cli/dist/commands/examples.js +193 -0
  17. package/cli/dist/commands/explain.d.ts +27 -0
  18. package/cli/dist/commands/explain.js +630 -0
  19. package/cli/dist/commands/flakiness.d.ts +73 -0
  20. package/cli/dist/commands/flakiness.js +435 -0
  21. package/cli/dist/commands/generate.d.ts +66 -0
  22. package/cli/dist/commands/generate.js +438 -0
  23. package/cli/dist/commands/history.d.ts +76 -0
  24. package/cli/dist/commands/history.js +755 -0
  25. package/cli/dist/commands/init.d.ts +106 -0
  26. package/cli/dist/commands/init.js +616 -0
  27. package/cli/dist/commands/monitor.d.ts +27 -0
  28. package/cli/dist/commands/monitor.js +225 -0
  29. package/cli/dist/commands/ollama.d.ts +40 -0
  30. package/cli/dist/commands/ollama.js +346 -0
  31. package/cli/dist/commands/pack.d.ts +70 -0
  32. package/cli/dist/commands/pack.js +413 -0
  33. package/cli/dist/commands/regression.d.ts +8 -0
  34. package/cli/dist/commands/regression.js +340 -0
  35. package/cli/dist/commands/repair.d.ts +26 -0
  36. package/cli/dist/commands/repair.js +307 -0
  37. package/cli/dist/commands/report.d.ts +62 -0
  38. package/cli/dist/commands/report.js +378 -0
  39. package/cli/dist/commands/retry.d.ts +43 -0
  40. package/cli/dist/commands/retry.js +275 -0
  41. package/cli/dist/commands/run.d.ts +41 -0
  42. package/cli/dist/commands/run.js +171 -0
  43. package/cli/dist/commands/scan.d.ts +5 -0
  44. package/cli/dist/commands/scan.js +155 -0
  45. package/cli/dist/commands/secrets.d.ts +58 -0
  46. package/cli/dist/commands/secrets.js +289 -0
  47. package/cli/dist/commands/serve.d.ts +13 -0
  48. package/cli/dist/commands/serve.js +156 -0
  49. package/cli/dist/commands/slo.d.ts +8 -0
  50. package/cli/dist/commands/slo.js +327 -0
  51. package/cli/dist/commands/verify.d.ts +32 -0
  52. package/cli/dist/commands/verify.js +278 -0
  53. package/cli/dist/core/adapters/gitleaks-secrets.d.ts +114 -0
  54. package/cli/dist/core/adapters/gitleaks-secrets.js +410 -0
  55. package/cli/dist/core/adapters/jest-adapter.d.ts +44 -0
  56. package/cli/dist/core/adapters/jest-adapter.js +261 -0
  57. package/cli/dist/core/adapters/k6-perf.d.ts +85 -0
  58. package/cli/dist/core/adapters/k6-perf.js +398 -0
  59. package/cli/dist/core/adapters/osv-deps.d.ts +123 -0
  60. package/cli/dist/core/adapters/osv-deps.js +372 -0
  61. package/cli/dist/core/adapters/playwright-native-adapter.d.ts +121 -0
  62. package/cli/dist/core/adapters/playwright-native-adapter.js +339 -0
  63. package/cli/dist/core/adapters/playwright-native-api.d.ts +183 -0
  64. package/cli/dist/core/adapters/playwright-native-api.js +465 -0
  65. package/cli/dist/core/adapters/playwright-ui.d.ts +197 -0
  66. package/cli/dist/core/adapters/playwright-ui.js +864 -0
  67. package/cli/dist/core/adapters/pytest-adapter.d.ts +49 -0
  68. package/cli/dist/core/adapters/pytest-adapter.js +324 -0
  69. package/cli/dist/core/adapters/semgrep-sast.d.ts +99 -0
  70. package/cli/dist/core/adapters/semgrep-sast.js +322 -0
  71. package/cli/dist/core/adapters/unit-test-types.d.ts +119 -0
  72. package/cli/dist/core/adapters/unit-test-types.js +6 -0
  73. package/cli/dist/core/adapters/vitest-adapter.d.ts +46 -0
  74. package/cli/dist/core/adapters/vitest-adapter.js +272 -0
  75. package/cli/dist/core/adapters/zap-dast.d.ts +133 -0
  76. package/cli/dist/core/adapters/zap-dast.js +424 -0
  77. package/cli/dist/core/ai/anthropic-provider.d.ts +50 -0
  78. package/cli/dist/core/ai/anthropic-provider.js +223 -0
  79. package/cli/dist/core/ai/deepseek-provider.d.ts +81 -0
  80. package/cli/dist/core/ai/deepseek-provider.js +266 -0
  81. package/cli/dist/core/ai/index.d.ts +60 -0
  82. package/cli/dist/core/ai/index.js +18 -0
  83. package/cli/dist/core/ai/llm-client.d.ts +45 -0
  84. package/cli/dist/core/ai/llm-client.js +7 -0
  85. package/cli/dist/core/ai/mock-provider.d.ts +49 -0
  86. package/cli/dist/core/ai/mock-provider.js +121 -0
  87. package/cli/dist/core/ai/ollama-provider.d.ts +78 -0
  88. package/cli/dist/core/ai/ollama-provider.js +216 -0
  89. package/cli/dist/core/ai/openai-provider.d.ts +48 -0
  90. package/cli/dist/core/ai/openai-provider.js +200 -0
  91. package/cli/dist/core/ai/provider-factory.d.ts +160 -0
  92. package/cli/dist/core/ai/provider-factory.js +269 -0
  93. package/cli/dist/core/artifacts/index.d.ts +6 -0
  94. package/cli/dist/core/artifacts/index.js +6 -0
  95. package/cli/dist/core/artifacts/ui-artifacts.d.ts +133 -0
  96. package/cli/dist/core/artifacts/ui-artifacts.js +304 -0
  97. package/cli/dist/core/assertions/engine.d.ts +51 -0
  98. package/cli/dist/core/assertions/engine.js +530 -0
  99. package/cli/dist/core/assertions/index.d.ts +11 -0
  100. package/cli/dist/core/assertions/index.js +11 -0
  101. package/cli/dist/core/assertions/types.d.ts +121 -0
  102. package/cli/dist/core/assertions/types.js +37 -0
  103. package/cli/dist/core/auth/api-key-provider.d.ts +16 -0
  104. package/cli/dist/core/auth/api-key-provider.js +63 -0
  105. package/cli/dist/core/auth/aws-iam-provider.d.ts +35 -0
  106. package/cli/dist/core/auth/aws-iam-provider.js +177 -0
  107. package/cli/dist/core/auth/azure-ad-provider.d.ts +15 -0
  108. package/cli/dist/core/auth/azure-ad-provider.js +99 -0
  109. package/cli/dist/core/auth/basic-auth-provider.d.ts +26 -0
  110. package/cli/dist/core/auth/basic-auth-provider.js +111 -0
  111. package/cli/dist/core/auth/gcp-adc-provider.d.ts +27 -0
  112. package/cli/dist/core/auth/gcp-adc-provider.js +126 -0
  113. package/cli/dist/core/auth/index.d.ts +238 -0
  114. package/cli/dist/core/auth/index.js +82 -0
  115. package/cli/dist/core/auth/jwt-provider.d.ts +19 -0
  116. package/cli/dist/core/auth/jwt-provider.js +160 -0
  117. package/cli/dist/core/auth/manager.d.ts +84 -0
  118. package/cli/dist/core/auth/manager.js +230 -0
  119. package/cli/dist/core/auth/oauth2-provider.d.ts +17 -0
  120. package/cli/dist/core/auth/oauth2-provider.js +114 -0
  121. package/cli/dist/core/auth/totp-provider.d.ts +31 -0
  122. package/cli/dist/core/auth/totp-provider.js +134 -0
  123. package/cli/dist/core/auth/ui-login-provider.d.ts +26 -0
  124. package/cli/dist/core/auth/ui-login-provider.js +198 -0
  125. package/cli/dist/core/cache/index.d.ts +7 -0
  126. package/cli/dist/core/cache/index.js +6 -0
  127. package/cli/dist/core/cache/lru-cache.d.ts +203 -0
  128. package/cli/dist/core/cache/lru-cache.js +397 -0
  129. package/cli/dist/core/coverage/analyzer.d.ts +101 -0
  130. package/cli/dist/core/coverage/analyzer.js +415 -0
  131. package/cli/dist/core/coverage/collector.d.ts +74 -0
  132. package/cli/dist/core/coverage/collector.js +459 -0
  133. package/cli/dist/core/coverage/config.d.ts +37 -0
  134. package/cli/dist/core/coverage/config.js +156 -0
  135. package/cli/dist/core/coverage/index.d.ts +11 -0
  136. package/cli/dist/core/coverage/index.js +15 -0
  137. package/cli/dist/core/coverage/types.d.ts +267 -0
  138. package/cli/dist/core/coverage/types.js +6 -0
  139. package/cli/dist/core/coverage/vault.d.ts +95 -0
  140. package/cli/dist/core/coverage/vault.js +405 -0
  141. package/cli/dist/core/crawler/index.d.ts +57 -0
  142. package/cli/dist/core/crawler/index.js +281 -0
  143. package/cli/dist/core/crawler/journey-generator.d.ts +49 -0
  144. package/cli/dist/core/crawler/journey-generator.js +412 -0
  145. package/cli/dist/core/crawler/page-analyzer.d.ts +88 -0
  146. package/cli/dist/core/crawler/page-analyzer.js +709 -0
  147. package/cli/dist/core/crawler/selector-generator.d.ts +34 -0
  148. package/cli/dist/core/crawler/selector-generator.js +309 -0
  149. package/cli/dist/core/crawler/types.d.ts +353 -0
  150. package/cli/dist/core/crawler/types.js +6 -0
  151. package/cli/dist/core/dashboard/assets.d.ts +6 -0
  152. package/cli/dist/core/dashboard/assets.js +690 -0
  153. package/cli/dist/core/dashboard/index.d.ts +6 -0
  154. package/cli/dist/core/dashboard/index.js +5 -0
  155. package/cli/dist/core/dashboard/server.d.ts +72 -0
  156. package/cli/dist/core/dashboard/server.js +354 -0
  157. package/cli/dist/core/dashboard/types.d.ts +70 -0
  158. package/cli/dist/core/dashboard/types.js +5 -0
  159. package/cli/dist/core/discoverer/index.d.ts +115 -0
  160. package/cli/dist/core/discoverer/index.js +250 -0
  161. package/cli/dist/core/fixtures/index.d.ts +8 -0
  162. package/cli/dist/core/fixtures/index.js +8 -0
  163. package/cli/dist/core/fixtures/loader.d.ts +65 -0
  164. package/cli/dist/core/fixtures/loader.js +161 -0
  165. package/cli/dist/core/fixtures/resolver.d.ts +79 -0
  166. package/cli/dist/core/fixtures/resolver.js +181 -0
  167. package/cli/dist/core/fixtures/types.d.ts +75 -0
  168. package/cli/dist/core/fixtures/types.js +30 -0
  169. package/cli/dist/core/flakiness/index.d.ts +228 -0
  170. package/cli/dist/core/flakiness/index.js +384 -0
  171. package/cli/dist/core/generation/code-formatter.d.ts +111 -0
  172. package/cli/dist/core/generation/code-formatter.js +307 -0
  173. package/cli/dist/core/generation/code-generator.d.ts +144 -0
  174. package/cli/dist/core/generation/code-generator.js +293 -0
  175. package/cli/dist/core/generation/crawler-pack-generator.d.ts +44 -0
  176. package/cli/dist/core/generation/crawler-pack-generator.js +245 -0
  177. package/cli/dist/core/generation/generator.d.ts +40 -0
  178. package/cli/dist/core/generation/generator.js +76 -0
  179. package/cli/dist/core/generation/index.d.ts +32 -0
  180. package/cli/dist/core/generation/index.js +30 -0
  181. package/cli/dist/core/generation/pack-generator.d.ts +107 -0
  182. package/cli/dist/core/generation/pack-generator.js +416 -0
  183. package/cli/dist/core/generation/prompt-builder.d.ts +132 -0
  184. package/cli/dist/core/generation/prompt-builder.js +672 -0
  185. package/cli/dist/core/generation/source-analyzer.d.ts +213 -0
  186. package/cli/dist/core/generation/source-analyzer.js +657 -0
  187. package/cli/dist/core/generation/test-optimizer.d.ts +117 -0
  188. package/cli/dist/core/generation/test-optimizer.js +328 -0
  189. package/cli/dist/core/generation/types.d.ts +214 -0
  190. package/cli/dist/core/generation/types.js +4 -0
  191. package/cli/dist/core/hooks/compose.d.ts +61 -0
  192. package/cli/dist/core/hooks/compose.js +225 -0
  193. package/cli/dist/core/hooks/runner.d.ts +68 -0
  194. package/cli/dist/core/hooks/runner.js +303 -0
  195. package/cli/dist/core/index.d.ts +110 -0
  196. package/cli/dist/core/index.js +99 -0
  197. package/cli/dist/core/pack/migrator.d.ts +51 -0
  198. package/cli/dist/core/pack/migrator.js +304 -0
  199. package/cli/dist/core/pack/validator.d.ts +42 -0
  200. package/cli/dist/core/pack/validator.js +330 -0
  201. package/cli/dist/core/pack-v2/index.d.ts +9 -0
  202. package/cli/dist/core/pack-v2/index.js +8 -0
  203. package/cli/dist/core/pack-v2/loader.d.ts +63 -0
  204. package/cli/dist/core/pack-v2/loader.js +292 -0
  205. package/cli/dist/core/pack-v2/migrator.d.ts +62 -0
  206. package/cli/dist/core/pack-v2/migrator.js +505 -0
  207. package/cli/dist/core/pack-v2/validator.d.ts +65 -0
  208. package/cli/dist/core/pack-v2/validator.js +629 -0
  209. package/cli/dist/core/parallel/index.d.ts +6 -0
  210. package/cli/dist/core/parallel/index.js +6 -0
  211. package/cli/dist/core/parallel/parallel-runner.d.ts +107 -0
  212. package/cli/dist/core/parallel/parallel-runner.js +192 -0
  213. package/cli/dist/core/pom/base-page.d.ts +237 -0
  214. package/cli/dist/core/pom/base-page.js +354 -0
  215. package/cli/dist/core/pom/index.d.ts +22 -0
  216. package/cli/dist/core/pom/index.js +23 -0
  217. package/cli/dist/core/pom/loader.d.ts +118 -0
  218. package/cli/dist/core/pom/loader.js +382 -0
  219. package/cli/dist/core/pom/types.d.ts +112 -0
  220. package/cli/dist/core/pom/types.js +9 -0
  221. package/cli/dist/core/proof/bundle.d.ts +137 -0
  222. package/cli/dist/core/proof/bundle.js +160 -0
  223. package/cli/dist/core/proof/canonicalize.d.ts +47 -0
  224. package/cli/dist/core/proof/canonicalize.js +105 -0
  225. package/cli/dist/core/proof/index.d.ts +13 -0
  226. package/cli/dist/core/proof/index.js +18 -0
  227. package/cli/dist/core/proof/schema.d.ts +217 -0
  228. package/cli/dist/core/proof/schema.js +263 -0
  229. package/cli/dist/core/proof/signer.d.ts +111 -0
  230. package/cli/dist/core/proof/signer.js +226 -0
  231. package/cli/dist/core/proof/verifier.d.ts +97 -0
  232. package/cli/dist/core/proof/verifier.js +308 -0
  233. package/cli/dist/core/regression/detector.d.ts +107 -0
  234. package/cli/dist/core/regression/detector.js +497 -0
  235. package/cli/dist/core/regression/index.d.ts +9 -0
  236. package/cli/dist/core/regression/index.js +11 -0
  237. package/cli/dist/core/regression/trend-analyzer.d.ts +102 -0
  238. package/cli/dist/core/regression/trend-analyzer.js +345 -0
  239. package/cli/dist/core/regression/types.d.ts +222 -0
  240. package/cli/dist/core/regression/types.js +7 -0
  241. package/cli/dist/core/regression/vault.d.ts +87 -0
  242. package/cli/dist/core/regression/vault.js +289 -0
  243. package/cli/dist/core/repair/engine/fixer.d.ts +24 -0
  244. package/cli/dist/core/repair/engine/fixer.js +226 -0
  245. package/cli/dist/core/repair/engine/suggestion-engine.d.ts +18 -0
  246. package/cli/dist/core/repair/engine/suggestion-engine.js +187 -0
  247. package/cli/dist/core/repair/index.d.ts +10 -0
  248. package/cli/dist/core/repair/index.js +13 -0
  249. package/cli/dist/core/repair/repairer.d.ts +90 -0
  250. package/cli/dist/core/repair/repairer.js +284 -0
  251. package/cli/dist/core/repair/types.d.ts +91 -0
  252. package/cli/dist/core/repair/types.js +6 -0
  253. package/cli/dist/core/repair/utils/error-analyzer.d.ts +28 -0
  254. package/cli/dist/core/repair/utils/error-analyzer.js +264 -0
  255. package/cli/dist/core/reporting/html-reporter.d.ts +119 -0
  256. package/cli/dist/core/reporting/html-reporter.js +737 -0
  257. package/cli/dist/core/reporting/index.d.ts +6 -0
  258. package/cli/dist/core/reporting/index.js +6 -0
  259. package/cli/dist/core/retry/flakiness-integration.d.ts +60 -0
  260. package/cli/dist/core/retry/flakiness-integration.js +228 -0
  261. package/cli/dist/core/retry/index.d.ts +14 -0
  262. package/cli/dist/core/retry/index.js +16 -0
  263. package/cli/dist/core/retry/retry-engine.d.ts +80 -0
  264. package/cli/dist/core/retry/retry-engine.js +296 -0
  265. package/cli/dist/core/retry/types.d.ts +178 -0
  266. package/cli/dist/core/retry/types.js +52 -0
  267. package/cli/dist/core/retry/vault.d.ts +77 -0
  268. package/cli/dist/core/retry/vault.js +304 -0
  269. package/cli/dist/core/runner/e2e-helpers.d.ts +102 -0
  270. package/cli/dist/core/runner/e2e-helpers.js +153 -0
  271. package/cli/dist/core/runner/phase3-runner.d.ts +249 -0
  272. package/cli/dist/core/runner/phase3-runner.js +1323 -0
  273. package/cli/dist/core/schemas/pack.schema.json +236 -0
  274. package/cli/dist/core/secrets/crypto.d.ts +75 -0
  275. package/cli/dist/core/secrets/crypto.js +223 -0
  276. package/cli/dist/core/secrets/manager.d.ts +76 -0
  277. package/cli/dist/core/secrets/manager.js +219 -0
  278. package/cli/dist/core/security/redaction-patterns-extended.d.ts +27 -0
  279. package/cli/dist/core/security/redaction-patterns-extended.js +247 -0
  280. package/cli/dist/core/security/redactor.d.ts +71 -0
  281. package/cli/dist/core/security/redactor.js +279 -0
  282. package/cli/dist/core/self-healing/assertion-healer.d.ts +97 -0
  283. package/cli/dist/core/self-healing/assertion-healer.js +371 -0
  284. package/cli/dist/core/self-healing/engine.d.ts +122 -0
  285. package/cli/dist/core/self-healing/engine.js +538 -0
  286. package/cli/dist/core/self-healing/index.d.ts +10 -0
  287. package/cli/dist/core/self-healing/index.js +11 -0
  288. package/cli/dist/core/self-healing/selector-healer.d.ts +103 -0
  289. package/cli/dist/core/self-healing/selector-healer.js +372 -0
  290. package/cli/dist/core/self-healing/types.d.ts +152 -0
  291. package/cli/dist/core/self-healing/types.js +6 -0
  292. package/cli/dist/core/serve/diagnostics-collector.d.ts +32 -0
  293. package/cli/dist/core/serve/diagnostics-collector.js +149 -0
  294. package/cli/dist/core/serve/health-checker.d.ts +44 -0
  295. package/cli/dist/core/serve/health-checker.js +219 -0
  296. package/cli/dist/core/serve/index.d.ts +8 -0
  297. package/cli/dist/core/serve/index.js +8 -0
  298. package/cli/dist/core/serve/metrics-collector.d.ts +24 -0
  299. package/cli/dist/core/serve/metrics-collector.js +322 -0
  300. package/cli/dist/core/serve/process-manager.d.ts +36 -0
  301. package/cli/dist/core/serve/process-manager.js +213 -0
  302. package/cli/dist/core/serve/server.d.ts +36 -0
  303. package/cli/dist/core/serve/server.js +191 -0
  304. package/cli/dist/core/slo/config.d.ts +107 -0
  305. package/cli/dist/core/slo/config.js +360 -0
  306. package/cli/dist/core/slo/index.d.ts +11 -0
  307. package/cli/dist/core/slo/index.js +15 -0
  308. package/cli/dist/core/slo/sli-calculator.d.ts +92 -0
  309. package/cli/dist/core/slo/sli-calculator.js +364 -0
  310. package/cli/dist/core/slo/slo-tracker.d.ts +148 -0
  311. package/cli/dist/core/slo/slo-tracker.js +379 -0
  312. package/cli/dist/core/slo/types.d.ts +281 -0
  313. package/cli/dist/core/slo/types.js +7 -0
  314. package/cli/dist/core/slo/vault.d.ts +102 -0
  315. package/cli/dist/core/slo/vault.js +427 -0
  316. package/cli/dist/core/tui/index.d.ts +7 -0
  317. package/cli/dist/core/tui/index.js +6 -0
  318. package/cli/dist/core/tui/monitor.d.ts +92 -0
  319. package/cli/dist/core/tui/monitor.js +271 -0
  320. package/cli/dist/core/tui/renderer.d.ts +33 -0
  321. package/cli/dist/core/tui/renderer.js +218 -0
  322. package/cli/dist/core/tui/types.d.ts +63 -0
  323. package/cli/dist/core/tui/types.js +5 -0
  324. package/cli/dist/core/types/pack-v1.d.ts +251 -0
  325. package/cli/dist/core/types/pack-v1.js +5 -0
  326. package/cli/dist/core/types/pack-v2.d.ts +456 -0
  327. package/cli/dist/core/types/pack-v2.js +8 -0
  328. package/cli/dist/core/types/trust-score.d.ts +69 -0
  329. package/cli/dist/core/types/trust-score.js +191 -0
  330. package/cli/dist/core/vault/cas.d.ts +90 -0
  331. package/cli/dist/core/vault/cas.js +261 -0
  332. package/cli/dist/core/vault/index.d.ts +326 -0
  333. package/cli/dist/core/vault/index.js +1042 -0
  334. package/cli/dist/core/visual/index.d.ts +6 -0
  335. package/cli/dist/core/visual/index.js +6 -0
  336. package/cli/dist/core/visual/visual-regression.d.ts +113 -0
  337. package/cli/dist/core/visual/visual-regression.js +236 -0
  338. package/cli/dist/core/watch/index.d.ts +7 -0
  339. package/cli/dist/core/watch/index.js +6 -0
  340. package/cli/dist/core/watch/watch-mode.d.ts +213 -0
  341. package/cli/dist/core/watch/watch-mode.js +389 -0
  342. package/cli/dist/generators/index.d.ts +5 -0
  343. package/cli/dist/generators/index.js +5 -0
  344. package/cli/dist/generators/json-reporter.d.ts +10 -0
  345. package/cli/dist/generators/json-reporter.js +12 -0
  346. package/cli/dist/generators/test-generator.d.ts +18 -0
  347. package/cli/dist/generators/test-generator.js +78 -0
  348. package/cli/dist/index.d.ts +8 -0
  349. package/cli/dist/index.js +262 -0
  350. package/cli/dist/scanners/dom-scanner.d.ts +52 -0
  351. package/cli/dist/scanners/dom-scanner.js +296 -0
  352. package/cli/dist/scanners/index.d.ts +4 -0
  353. package/cli/dist/scanners/index.js +4 -0
  354. package/cli/dist/schemas/pack.schema.json +236 -0
  355. package/cli/dist/types/scan.d.ts +68 -0
  356. package/cli/dist/types/scan.js +4 -0
  357. package/cli/dist/utils/config.d.ts +35 -0
  358. package/cli/dist/utils/config.js +196 -0
  359. package/cli/package.json +1 -1
  360. package/package.json +26 -2
  361. package/.BETA_TESTING_FEEDBACK.md +0 -256
  362. package/.claude/settings.local.json +0 -154
  363. package/.editorconfig +0 -21
  364. package/.github/CODEOWNERS +0 -23
  365. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -108
  366. package/.github/ISSUE_TEMPLATE/feedback_dx.yml +0 -121
  367. package/.github/dependabot.yml +0 -35
  368. package/.github/workflows/mcp-dx.yml +0 -106
  369. package/.github/workflows/release.yml +0 -26
  370. package/.github/workflows/test.yml +0 -93
  371. package/.nvmrc +0 -1
  372. package/.qa360/vault.db +0 -0
  373. package/.qa360/vault.db-shm +0 -0
  374. package/.qa360/vault.db-wal +0 -0
  375. package/.qa360-artifacts/.gitkeep +0 -0
  376. package/.qa360-artifacts/baselines/.gitkeep +0 -0
  377. package/.qa360-artifacts/cache/.gitkeep +0 -0
  378. package/.qa360-artifacts/reports/.gitkeep +0 -0
  379. package/.qa360-artifacts/screenshots/.gitkeep +0 -0
  380. package/.qa360-baselines/www_xyqo_ai.baseline.json +0 -33
  381. package/CODEOWNERS +0 -43
  382. package/NOVICE_USER_GUIDE.md +0 -272
  383. package/adapters/README.md +0 -46
  384. package/check-branches.sh +0 -32
  385. package/cli/.qa360/keys/ed25519.key +0 -1
  386. package/cli/.qa360/keys/ed25519.pub +0 -1
  387. package/cli/examples/README.md +0 -160
  388. package/cli/examples/accessibility.yml +0 -48
  389. package/cli/examples/api-basic.yml +0 -27
  390. package/cli/examples/complete.yml +0 -146
  391. package/cli/examples/crawler.yml +0 -38
  392. package/cli/examples/fullstack.yml +0 -78
  393. package/cli/examples/security.yml +0 -58
  394. package/cli/examples/ui-advanced.yml +0 -49
  395. package/cli/examples/ui-basic.yml +0 -24
  396. package/cli/scripts/bundle-for-npm.sh +0 -51
  397. package/cli/scripts/validate-package.js +0 -116
  398. package/cli/src/__tests__/commands/doctor.test.ts +0 -108
  399. package/cli/src/__tests__/index.test.ts +0 -15
  400. package/cli/src/cli-minimal.ts +0 -44
  401. package/cli/src/commands/__tests__/crawl.test.ts +0 -412
  402. package/cli/src/commands/__tests__/doctor-qa360-home.test.ts +0 -156
  403. package/cli/src/commands/__tests__/e2e-ui-tests.test.ts +0 -494
  404. package/cli/src/commands/__tests__/e2e.test.ts +0 -187
  405. package/cli/src/commands/__tests__/flakiness.test.ts +0 -528
  406. package/cli/src/commands/__tests__/generate.test.ts +0 -507
  407. package/cli/src/commands/__tests__/history.integration.test.ts +0 -358
  408. package/cli/src/commands/__tests__/history.test.ts +0 -433
  409. package/cli/src/commands/__tests__/monitor-realworld.test.ts +0 -199
  410. package/cli/src/commands/__tests__/monitor.test.ts +0 -81
  411. package/cli/src/commands/__tests__/ollama.test.ts +0 -529
  412. package/cli/src/commands/__tests__/repair.test.ts +0 -225
  413. package/cli/src/commands/__tests__/report.integration.test.ts +0 -167
  414. package/cli/src/commands/__tests__/report.test.ts +0 -294
  415. package/cli/src/commands/__tests__/report.vitest.ts +0 -288
  416. package/cli/src/commands/__tests__/retry.test.ts +0 -78
  417. package/cli/src/commands/__tests__/run.integration.test.ts +0 -240
  418. package/cli/src/commands/__tests__/run.test.ts +0 -346
  419. package/cli/src/commands/__tests__/run.vitest.ts +0 -301
  420. package/cli/src/commands/__tests__/secrets.test.ts +0 -114
  421. package/cli/src/commands/__tests__/serve.test.ts +0 -80
  422. package/cli/src/commands/__tests__/verify.test.ts +0 -103
  423. package/cli/src/commands/ai.ts +0 -702
  424. package/cli/src/commands/ask.ts +0 -678
  425. package/cli/src/commands/coverage.ts +0 -305
  426. package/cli/src/commands/crawl.ts +0 -155
  427. package/cli/src/commands/doctor.ts +0 -610
  428. package/cli/src/commands/examples.ts +0 -248
  429. package/cli/src/commands/explain.ts +0 -710
  430. package/cli/src/commands/flakiness.ts +0 -560
  431. package/cli/src/commands/generate.ts +0 -566
  432. package/cli/src/commands/history.ts +0 -914
  433. package/cli/src/commands/init.ts +0 -777
  434. package/cli/src/commands/monitor.ts +0 -270
  435. package/cli/src/commands/ollama.ts +0 -337
  436. package/cli/src/commands/pack.ts +0 -497
  437. package/cli/src/commands/regression.ts +0 -400
  438. package/cli/src/commands/repair.ts +0 -356
  439. package/cli/src/commands/report.ts +0 -463
  440. package/cli/src/commands/retry.ts +0 -380
  441. package/cli/src/commands/run.ts +0 -220
  442. package/cli/src/commands/scan.ts +0 -177
  443. package/cli/src/commands/secrets.ts +0 -340
  444. package/cli/src/commands/serve.ts +0 -194
  445. package/cli/src/commands/slo.ts +0 -387
  446. package/cli/src/commands/verify-temp-note.md +0 -11
  447. package/cli/src/commands/verify.ts +0 -322
  448. package/cli/src/generators/index.ts +0 -6
  449. package/cli/src/generators/json-reporter.ts +0 -15
  450. package/cli/src/generators/test-generator.ts +0 -90
  451. package/cli/src/index.ts +0 -289
  452. package/cli/src/scanners/dom-scanner.ts +0 -360
  453. package/cli/src/scanners/index.ts +0 -5
  454. package/cli/src/types/scan.ts +0 -84
  455. package/cli/src/utils/config.ts +0 -145
  456. package/cli/tsconfig.bundle.json +0 -12
  457. package/cli/tsconfig.json +0 -23
  458. package/cli/vitest.config.ts +0 -59
  459. package/core/src/__tests__/adapters-contract/adapters-contract.test.md +0 -156
  460. package/core/src/__tests__/index.test.ts +0 -31
  461. package/core/src/__tests__/integration/phase3.test.ts +0 -405
  462. package/core/src/__tests__/pack/validator.test.ts +0 -312
  463. package/core/src/__tests__/secrets/crypto.test.ts +0 -190
  464. package/core/src/__tests__/secrets/manager.test.ts +0 -316
  465. package/core/src/__tests__/security/redactor-phase3.test.ts +0 -233
  466. package/core/src/__tests__/serve/health-checker.test.ts +0 -155
  467. package/core/src/__tests__/serve/process-manager.test.ts +0 -213
  468. package/core/src/__tests__/serve/server.test.ts +0 -103
  469. package/core/src/__tests__/vault/cas.test.ts +0 -178
  470. package/core/src/__tests__/vault/vault.test.ts +0 -296
  471. package/core/src/adapters/__tests__/fixtures/jest-coverage.json +0 -8
  472. package/core/src/adapters/__tests__/fixtures/jest-results.json +0 -41
  473. package/core/src/adapters/__tests__/fixtures/pytest-junit.xml +0 -16
  474. package/core/src/adapters/__tests__/fixtures/vitest-coverage.json +0 -8
  475. package/core/src/adapters/__tests__/fixtures/vitest-results.json +0 -50
  476. package/core/src/adapters/__tests__/gitleaks-secrets.test.ts +0 -452
  477. package/core/src/adapters/__tests__/jest-adapter.test.ts +0 -276
  478. package/core/src/adapters/__tests__/k6-perf.test.ts +0 -538
  479. package/core/src/adapters/__tests__/osv-deps.test.ts +0 -471
  480. package/core/src/adapters/__tests__/playwright-native-api.test.ts +0 -792
  481. package/core/src/adapters/__tests__/playwright-ui-e2e.test.ts +0 -431
  482. package/core/src/adapters/__tests__/playwright-ui.test.ts +0 -1073
  483. package/core/src/adapters/__tests__/pytest-adapter.test.ts +0 -207
  484. package/core/src/adapters/__tests__/semgrep-sast.test.ts +0 -436
  485. package/core/src/adapters/__tests__/vitest-adapter.test.ts +0 -208
  486. package/core/src/adapters/__tests__/zap-dast.test.ts +0 -453
  487. package/core/src/adapters/gitleaks-secrets.ts +0 -521
  488. package/core/src/adapters/jest-adapter.ts +0 -306
  489. package/core/src/adapters/k6-perf.ts +0 -479
  490. package/core/src/adapters/osv-deps.ts +0 -467
  491. package/core/src/adapters/playwright-native-adapter.ts +0 -472
  492. package/core/src/adapters/playwright-native-api.ts +0 -619
  493. package/core/src/adapters/playwright-ui.ts +0 -1088
  494. package/core/src/adapters/pytest-adapter.ts +0 -472
  495. package/core/src/adapters/semgrep-sast.ts +0 -410
  496. package/core/src/adapters/unit-test-types.ts +0 -106
  497. package/core/src/adapters/vitest-adapter.ts +0 -295
  498. package/core/src/adapters/zap-dast.ts +0 -551
  499. package/core/src/ai/__tests__/deepseek-provider.test.ts +0 -586
  500. package/core/src/ai/__tests__/ollama-provider.test.ts +0 -641
  501. package/core/src/ai/anthropic-provider.ts +0 -262
  502. package/core/src/ai/deepseek-provider.ts +0 -315
  503. package/core/src/ai/index.ts +0 -87
  504. package/core/src/ai/llm-client.ts +0 -52
  505. package/core/src/ai/mock-provider.ts +0 -146
  506. package/core/src/ai/ollama-provider.ts +0 -269
  507. package/core/src/ai/openai-provider.ts +0 -240
  508. package/core/src/ai/provider-factory.ts +0 -408
  509. package/core/src/artifacts/README.md +0 -78
  510. package/core/src/artifacts/index.ts +0 -16
  511. package/core/src/artifacts/ui-artifacts.ts +0 -412
  512. package/core/src/assertions/__tests__/engine.test.ts +0 -360
  513. package/core/src/assertions/engine.ts +0 -577
  514. package/core/src/assertions/index.ts +0 -13
  515. package/core/src/assertions/types.ts +0 -229
  516. package/core/src/auth/__tests__/api-key-provider.test.ts +0 -282
  517. package/core/src/auth/__tests__/auth-manager.test.ts +0 -430
  518. package/core/src/auth/__tests__/basic-auth-provider.test.ts +0 -364
  519. package/core/src/auth/__tests__/cloud-providers.test.ts +0 -751
  520. package/core/src/auth/__tests__/jwt-provider.test.ts +0 -400
  521. package/core/src/auth/__tests__/oauth2-provider.test.ts +0 -383
  522. package/core/src/auth/__tests__/totp-provider.test.ts +0 -294
  523. package/core/src/auth/__tests__/ui-login-provider.test.ts +0 -323
  524. package/core/src/auth/api-key-provider.ts +0 -75
  525. package/core/src/auth/aws-iam-provider.ts +0 -212
  526. package/core/src/auth/azure-ad-provider.ts +0 -126
  527. package/core/src/auth/basic-auth-provider.ts +0 -133
  528. package/core/src/auth/gcp-adc-provider.ts +0 -146
  529. package/core/src/auth/index.ts +0 -342
  530. package/core/src/auth/jwt-provider.ts +0 -193
  531. package/core/src/auth/manager.ts +0 -281
  532. package/core/src/auth/oauth2-provider.ts +0 -141
  533. package/core/src/auth/totp-provider.ts +0 -163
  534. package/core/src/auth/ui-login-provider.ts +0 -242
  535. package/core/src/cache/__tests__/lru-cache.test.ts +0 -564
  536. package/core/src/cache/index.ts +0 -13
  537. package/core/src/cache/lru-cache.ts +0 -536
  538. package/core/src/crawler/__tests__/journey-generator.test.ts +0 -344
  539. package/core/src/crawler/__tests__/selector-generator.test.ts +0 -211
  540. package/core/src/crawler/index.ts +0 -335
  541. package/core/src/crawler/journey-generator.ts +0 -471
  542. package/core/src/crawler/page-analyzer.ts +0 -857
  543. package/core/src/crawler/selector-generator.ts +0 -280
  544. package/core/src/crawler/types.ts +0 -475
  545. package/core/src/dashboard/__tests__/real-world.test.ts +0 -430
  546. package/core/src/dashboard/__tests__/server.test.ts +0 -283
  547. package/core/src/dashboard/__tests__/types.test.ts +0 -208
  548. package/core/src/dashboard/assets.ts +0 -692
  549. package/core/src/dashboard/index.ts +0 -17
  550. package/core/src/dashboard/server.ts +0 -401
  551. package/core/src/dashboard/types.ts +0 -78
  552. package/core/src/discoverer/__tests__/test-discoverer.test.ts +0 -444
  553. package/core/src/discoverer/index.ts +0 -374
  554. package/core/src/fixtures/__tests__/loader.test.ts +0 -246
  555. package/core/src/fixtures/__tests__/resolver.test.ts +0 -334
  556. package/core/src/fixtures/index.ts +0 -9
  557. package/core/src/fixtures/loader.ts +0 -200
  558. package/core/src/fixtures/resolver.ts +0 -221
  559. package/core/src/fixtures/types.ts +0 -86
  560. package/core/src/flakiness/__tests__/flakiness.test.ts +0 -554
  561. package/core/src/flakiness/index.ts +0 -536
  562. package/core/src/generation/__tests__/code-formatter.test.ts +0 -170
  563. package/core/src/generation/__tests__/code-generator-contract.test.ts +0 -207
  564. package/core/src/generation/__tests__/code-generator.test.ts +0 -586
  565. package/core/src/generation/__tests__/crawler-pack-generator.test.ts +0 -479
  566. package/core/src/generation/__tests__/generation-e2e-b2bshop.test.ts +0 -718
  567. package/core/src/generation/__tests__/generation-integration.test.ts +0 -655
  568. package/core/src/generation/__tests__/pack-generator.test.ts +0 -408
  569. package/core/src/generation/__tests__/prompt-builder.test.ts +0 -200
  570. package/core/src/generation/__tests__/real-provider-integration.test.ts +0 -414
  571. package/core/src/generation/__tests__/source-analyzer.test.ts +0 -774
  572. package/core/src/generation/__tests__/test-optimizer.test.ts +0 -255
  573. package/core/src/generation/code-formatter.ts +0 -408
  574. package/core/src/generation/code-generator.ts +0 -470
  575. package/core/src/generation/crawler-pack-generator.ts +0 -289
  576. package/core/src/generation/generator.ts +0 -113
  577. package/core/src/generation/index.ts +0 -59
  578. package/core/src/generation/pack-generator.ts +0 -527
  579. package/core/src/generation/prompt-builder.ts +0 -772
  580. package/core/src/generation/source-analyzer.ts +0 -830
  581. package/core/src/generation/test-optimizer.ts +0 -474
  582. package/core/src/generation/types.ts +0 -217
  583. package/core/src/hooks/__tests__/compose.test.ts +0 -636
  584. package/core/src/hooks/__tests__/runner.test.ts +0 -478
  585. package/core/src/hooks/compose.ts +0 -268
  586. package/core/src/hooks/runner.ts +0 -364
  587. package/core/src/index.ts +0 -255
  588. package/core/src/pack/__tests__/migrator.test.ts +0 -594
  589. package/core/src/pack/__tests__/validator.test.ts +0 -759
  590. package/core/src/pack/migrator.ts +0 -353
  591. package/core/src/pack/validator.ts +0 -359
  592. package/core/src/pack-v2/__tests__/loader.test.ts +0 -533
  593. package/core/src/pack-v2/__tests__/migrator.test.ts +0 -455
  594. package/core/src/pack-v2/__tests__/validator.test.ts +0 -609
  595. package/core/src/pack-v2/index.ts +0 -41
  596. package/core/src/pack-v2/loader.ts +0 -358
  597. package/core/src/pack-v2/migrator.ts +0 -540
  598. package/core/src/pack-v2/validator.ts +0 -731
  599. package/core/src/parallel/README.md +0 -143
  600. package/core/src/parallel/index.ts +0 -16
  601. package/core/src/parallel/parallel-runner.ts +0 -282
  602. package/core/src/pom/__tests__/loader.test.ts +0 -378
  603. package/core/src/pom/base-page.ts +0 -425
  604. package/core/src/pom/index.ts +0 -45
  605. package/core/src/pom/loader.ts +0 -480
  606. package/core/src/pom/types.ts +0 -146
  607. package/core/src/proof/__tests__/proof-roundtrip.test.ts +0 -149
  608. package/core/src/proof/__tests__/schema-validation-manual.mjs +0 -211
  609. package/core/src/proof/__tests__/schema-validation.test.ts +0 -336
  610. package/core/src/proof/__tests__/signer.test.ts +0 -486
  611. package/core/src/proof/__tests__/temporal-regression.test.ts +0 -537
  612. package/core/src/proof/__tests__/verifier-advanced.test.ts +0 -588
  613. package/core/src/proof/__tests__/verifier.test.ts +0 -413
  614. package/core/src/proof/bundle.ts +0 -290
  615. package/core/src/proof/canonicalize.ts +0 -116
  616. package/core/src/proof/index.ts +0 -74
  617. package/core/src/proof/schema.ts +0 -285
  618. package/core/src/proof/signer.ts +0 -293
  619. package/core/src/proof/verifier.ts +0 -380
  620. package/core/src/regression/__tests__/detector.test.ts +0 -396
  621. package/core/src/regression/__tests__/trend-analyzer.test.ts +0 -300
  622. package/core/src/regression/detector.ts +0 -629
  623. package/core/src/regression/index.ts +0 -34
  624. package/core/src/regression/trend-analyzer.ts +0 -468
  625. package/core/src/regression/types.ts +0 -295
  626. package/core/src/regression/vault.ts +0 -419
  627. package/core/src/repair/__tests__/repairer.test.ts +0 -572
  628. package/core/src/repair/__tests__/types.test.ts +0 -302
  629. package/core/src/repair/engine/__tests__/fixer.test.ts +0 -482
  630. package/core/src/repair/engine/__tests__/suggestion-engine.test.ts +0 -395
  631. package/core/src/repair/engine/fixer.ts +0 -271
  632. package/core/src/repair/engine/suggestion-engine.ts +0 -234
  633. package/core/src/repair/index.ts +0 -53
  634. package/core/src/repair/repairer.ts +0 -376
  635. package/core/src/repair/types.ts +0 -119
  636. package/core/src/repair/utils/__tests__/error-analyzer.test.ts +0 -454
  637. package/core/src/repair/utils/error-analyzer.ts +0 -308
  638. package/core/src/reporting/README.md +0 -144
  639. package/core/src/reporting/html-reporter.ts +0 -835
  640. package/core/src/reporting/index.ts +0 -16
  641. package/core/src/retry/README.md +0 -192
  642. package/core/src/retry/__tests__/flakiness-integration.test.ts +0 -475
  643. package/core/src/retry/__tests__/retry-engine.test.ts +0 -424
  644. package/core/src/retry/flakiness-integration.ts +0 -267
  645. package/core/src/retry/index.ts +0 -48
  646. package/core/src/retry/retry-engine.ts +0 -368
  647. package/core/src/retry/types.ts +0 -208
  648. package/core/src/retry/vault.ts +0 -413
  649. package/core/src/runner/__tests__/flakiness-integration.test.ts +0 -566
  650. package/core/src/runner/__tests__/phase3-e2e-b2bshop.test.ts +0 -218
  651. package/core/src/runner/__tests__/phase3-e2e-reqres.test.ts +0 -199
  652. package/core/src/runner/__tests__/phase3-runner.test.ts +0 -1118
  653. package/core/src/runner/e2e-helpers.ts +0 -216
  654. package/core/src/runner/phase3-runner.ts +0 -1536
  655. package/core/src/schemas/gherkin-report.json +0 -122
  656. package/core/src/secrets/__tests__/crypto.test.ts +0 -180
  657. package/core/src/secrets/crypto.ts +0 -289
  658. package/core/src/secrets/manager.ts +0 -272
  659. package/core/src/security/__tests__/hardening.test.ts +0 -480
  660. package/core/src/security/redaction-patterns-extended.ts +0 -278
  661. package/core/src/security/redactor.ts +0 -326
  662. package/core/src/self-healing/assertion-healer.ts +0 -485
  663. package/core/src/self-healing/engine.ts +0 -626
  664. package/core/src/self-healing/index.ts +0 -33
  665. package/core/src/self-healing/selector-healer.ts +0 -488
  666. package/core/src/self-healing/types.ts +0 -193
  667. package/core/src/serve/diagnostics-collector.ts +0 -201
  668. package/core/src/serve/health-checker.ts +0 -274
  669. package/core/src/serve/index.ts +0 -9
  670. package/core/src/serve/metrics-collector.ts +0 -386
  671. package/core/src/serve/process-manager.ts +0 -265
  672. package/core/src/serve/server.ts +0 -230
  673. package/core/src/slo/config.ts +0 -408
  674. package/core/src/slo/index.ts +0 -68
  675. package/core/src/slo/sli-calculator.ts +0 -474
  676. package/core/src/slo/slo-tracker.ts +0 -481
  677. package/core/src/slo/types.ts +0 -408
  678. package/core/src/slo/vault.ts +0 -600
  679. package/core/src/tui/__tests__/monitor.test.ts +0 -336
  680. package/core/src/tui/__tests__/real-world.test.ts +0 -376
  681. package/core/src/tui/__tests__/renderer.test.ts +0 -201
  682. package/core/src/tui/__tests__/types.test.ts +0 -295
  683. package/core/src/tui/index.ts +0 -19
  684. package/core/src/tui/monitor.ts +0 -331
  685. package/core/src/tui/renderer.ts +0 -269
  686. package/core/src/tui/types.ts +0 -68
  687. package/core/src/types/pack-v1.ts +0 -305
  688. package/core/src/types/pack-v2.ts +0 -525
  689. package/core/src/types/trust-score.ts +0 -258
  690. package/core/src/vault/__tests__/flakiness-vault.test.ts +0 -562
  691. package/core/src/vault/__tests__/vault.test.ts +0 -259
  692. package/core/src/vault/cas.ts +0 -323
  693. package/core/src/vault/index.ts +0 -1361
  694. package/core/src/vault/schema.sql +0 -168
  695. package/core/src/visual/README.md +0 -185
  696. package/core/src/visual/index.ts +0 -14
  697. package/core/src/visual/visual-regression.ts +0 -347
  698. package/core/src/watch/__tests__/watch-mode.test.ts +0 -192
  699. package/core/src/watch/index.ts +0 -14
  700. package/core/src/watch/watch-mode.ts +0 -565
  701. package/core/tsconfig.json +0 -12
  702. package/core/vitest.config.ts +0 -52
  703. package/docs/ARCHITECTURE.md +0 -901
  704. package/docs/AUDIT-GLOBAL-DEC2025.md +0 -271
  705. package/docs/BETA_TESTING.md +0 -257
  706. package/docs/BETA_TESTING_PLAN.md +0 -727
  707. package/docs/CERTIFICATION-REPORT.md +0 -142
  708. package/docs/COMPLETE_AUDIT_REFACTORING.md +0 -965
  709. package/docs/DEVELOPMENT.md +0 -545
  710. package/docs/DEVELOPMENT_HISTORY.md +0 -345
  711. package/docs/LIMITATIONS.md +0 -176
  712. package/docs/MIGRATION.md +0 -303
  713. package/docs/OPTION_3_4_EXPLORATION.md +0 -1257
  714. package/docs/PHASE1_PERFORMANCE.md +0 -144
  715. package/docs/QA360_Cloud.postman_collection.json +0 -89
  716. package/docs/QA360_TESTING_PHILOSOPHY.md +0 -769
  717. package/docs/QA_TEST_PLAN.md +0 -727
  718. package/docs/README.md +0 -50
  719. package/docs/STATUS.md +0 -198
  720. package/docs/STRATEGIC_STUDY_GOOSE_INTEGRATION.md +0 -615
  721. package/docs/USER_GUIDE.md +0 -687
  722. package/docs/WORK-DONE-ADAPTER-TESTS.md +0 -136
  723. package/docs/adapters-security.md +0 -485
  724. package/docs/architecture-diagram.mmd +0 -168
  725. package/docs/archive/ARCH-01-DAY6-BUILD-FIXES.md +0 -396
  726. package/docs/archive/ARCH-01-DAY6-FINAL-STATUS.md +0 -324
  727. package/docs/archive/ARCH-01_MCP_MERGE_ANALYSIS.md +0 -644
  728. package/docs/archive/ARCH-01_NEXT_STEPS.md +0 -60
  729. package/docs/archive/BRANCH_PROTECTION.md +0 -183
  730. package/docs/archive/CI_LOCKDOWN_CHECKLIST.md +0 -222
  731. package/docs/archive/HANDOFF_TEST-01.md +0 -669
  732. package/docs/archive/LEGAL_READY_PLACEHOLDERS.md +0 -372
  733. package/docs/archive/NODE_UPGRADE_GUIDE.md +0 -188
  734. package/docs/archive/PHASE1_COMPLETION.md +0 -386
  735. package/docs/archive/PHASE2_COMPLETION.md +0 -404
  736. package/docs/archive/PHASE3_AND_4_FINAL.md +0 -360
  737. package/docs/archive/PHASE3_COMPLETE.md +0 -301
  738. package/docs/archive/PHASE3_STATUS.md +0 -255
  739. package/docs/archive/PRE-WEEK2-AUDIT.md +0 -364
  740. package/docs/archive/README.md +0 -16
  741. package/docs/archive/SCHEMA_AJV_2020_FIX.md +0 -245
  742. package/docs/archive/TEST-01_AUDIT_REPORT.md +0 -240
  743. package/docs/archive/TEST-01_COVERAGE_PLAN.md +0 -423
  744. package/docs/archive/obsolete-proposals/dom-element-discovery-mode.md +0 -250
  745. package/docs/archive/obsolete-proposals/qa360-comprehensive-test-plan.md +0 -1249
  746. package/docs/archive/obsolete-proposals/qa360-quick-start-guide.md +0 -298
  747. package/docs/archive/obsolete-proposals/technical-plan-dom-discovery.md +0 -870
  748. package/docs/budgets-advanced.md +0 -308
  749. package/docs/examples/history-export-gc.md +0 -285
  750. package/docs/examples/pack-v2-complete.yaml +0 -158
  751. package/docs/examples/pack-v2-quickstart.yaml +0 -24
  752. package/docs/examples/pack-v2-ui-login.yaml +0 -81
  753. package/docs/examples/qa360-report.json +0 -50
  754. package/docs/history.md +0 -565
  755. package/docs/hooks.md +0 -304
  756. package/docs/llm-providers.md +0 -512
  757. package/docs/mcp-server.md +0 -651
  758. package/docs/mcp-tools.md +0 -1131
  759. package/docs/pack-v1.md +0 -383
  760. package/docs/pack-v2.md +0 -558
  761. package/docs/page-objects.md +0 -366
  762. package/docs/proofs.md +0 -670
  763. package/docs/quickstart-5min.md +0 -257
  764. package/docs/readiness-ci.md +0 -654
  765. package/docs/rfc/README.md +0 -20
  766. package/docs/rfc/proof-bundle-v1.md +0 -787
  767. package/docs/secrets.md +0 -392
  768. package/docs/serve.md +0 -494
  769. package/docs/unit-test-adapters.md +0 -168
  770. package/docs/vault.md +0 -491
  771. package/e2e/qa360-e2e.test.ts +0 -696
  772. package/e2e/vitest.config.ts +0 -18
  773. package/examples/README.md +0 -50
  774. package/examples/ci/docker-compose-serve.yml +0 -375
  775. package/examples/ci/github-actions-serve.yml +0 -345
  776. package/examples/ci/gitlab-ci-serve.yml +0 -407
  777. package/examples/datasets/README.md +0 -101
  778. package/examples/datasets/b2bshop.ts +0 -155
  779. package/examples/datasets/index.ts +0 -57
  780. package/examples/datasets/reqres.ts +0 -195
  781. package/examples/fixtures-demo/fixtures/users.yml +0 -39
  782. package/examples/fixtures-demo/pack.yml +0 -71
  783. package/examples/future-api/README.md +0 -16
  784. package/examples/future-api/diag.js +0 -7
  785. package/examples/future-api/health.js +0 -4
  786. package/examples/future-api/packs.js +0 -13
  787. package/examples/future-api/runpack.js +0 -10
  788. package/examples/generation/README.md +0 -148
  789. package/examples/generation/pack-generator-example.js +0 -115
  790. package/examples/generation/source-analyzer-example.js +0 -115
  791. package/examples/httpbin/pack.yml +0 -59
  792. package/examples/load-testing/mcp-load.yml +0 -115
  793. package/examples/load-testing/mcp-stdio.yml +0 -95
  794. package/examples/mcp/claude-desktop-config.json +0 -33
  795. package/examples/mcp/claude-desktop.json +0 -16
  796. package/examples/mcp/conversation-sample.md +0 -131
  797. package/examples/mcp/demo-60s.md +0 -330
  798. package/examples/mcp/sample-conversation.jsonl +0 -21
  799. package/examples/mcp/vscode-settings.json +0 -22
  800. package/examples/pack-v2-complete.yml +0 -242
  801. package/examples/pack-v2-examples.md +0 -244
  802. package/examples/pack-v2-quickstart.yml +0 -55
  803. package/examples/packs-business/ecommerce-api.yml +0 -121
  804. package/examples/packs-business/saas-dashboard-ui.yml +0 -133
  805. package/examples/packs-conformance/compose-multi.yml +0 -174
  806. package/examples/packs-conformance/full.yml +0 -152
  807. package/examples/packs-conformance/heavy-artifacts.yml +0 -152
  808. package/examples/packs-conformance/minimal.yml +0 -71
  809. package/examples/packs-conformance/secrets-missing.yml +0 -97
  810. package/examples/packs-conformance/timeouts.yml +0 -77
  811. package/examples/pom-demo/README.md +0 -104
  812. package/examples/pom-demo/pack.yml +0 -60
  813. package/examples/pom-demo/pages/DashboardPage.page.ts +0 -73
  814. package/examples/pom-demo/pages/LoginPage.page.ts +0 -76
  815. package/examples/proofs/e2e-playwright-proof.json +0 -75
  816. package/examples/proofs/httpbin-proof.json +0 -69
  817. package/examples/proofs/multi-adapter-proof.json +0 -117
  818. package/examples/proofs/test-proof.json +0 -26
  819. package/examples/restful-api-dev/README.md +0 -102
  820. package/examples/restful-api-dev/restful-api-advanced.yml +0 -29
  821. package/examples/restful-api-dev/restful-api-basic.yml +0 -29
  822. package/examples/web-lite/.github/workflows/qa360-phase3.yml +0 -73
  823. package/examples/web-lite/api-mock/server.js +0 -258
  824. package/examples/web-lite/pack.yml +0 -71
  825. package/examples/web-lite/services.yml +0 -43
  826. package/examples/web-lite/web-content/healthz +0 -1
  827. package/examples/web-lite/web-content/index.html +0 -259
  828. package/packages/mcp/CHANGELOG.md +0 -109
  829. package/packages/mcp/IMPLEMENTATION_SUMMARY.md +0 -350
  830. package/packages/mcp/LICENSE +0 -21
  831. package/packages/mcp/QUICK_START.md +0 -291
  832. package/packages/mcp/README.md +0 -294
  833. package/packages/mcp/TELEMETRY.md +0 -220
  834. package/packages/mcp/package.json +0 -91
  835. package/packages/mcp/scripts/generate-sbom-fallback.cjs +0 -84
  836. package/packages/mcp/scripts/safe-postinstall.cjs +0 -32
  837. package/packages/mcp/src/__tests__/contract.test.ts +0 -902
  838. package/packages/mcp/src/cli/cli.ts +0 -137
  839. package/packages/mcp/src/cli/doctor.ts +0 -286
  840. package/packages/mcp/src/cli/fix.ts +0 -99
  841. package/packages/mcp/src/cli/init.ts +0 -233
  842. package/packages/mcp/src/cli/postinstall.ts +0 -14
  843. package/packages/mcp/src/cli/reset.ts +0 -44
  844. package/packages/mcp/src/cli/telemetry.ts +0 -166
  845. package/packages/mcp/src/cli/test-dx.ts +0 -94
  846. package/packages/mcp/src/cli/uninstall.ts +0 -80
  847. package/packages/mcp/src/cli/up.ts +0 -178
  848. package/packages/mcp/src/index.ts +0 -12
  849. package/packages/mcp/src/scripts/e2e-local.ts +0 -337
  850. package/packages/mcp/src/scripts/verify-settings.ts +0 -242
  851. package/packages/mcp/src/security/audit.ts +0 -244
  852. package/packages/mcp/src/security/manager.ts +0 -242
  853. package/packages/mcp/src/server/full-server.ts +0 -212
  854. package/packages/mcp/src/server/minimal-server.ts +0 -134
  855. package/packages/mcp/src/tools/history.ts +0 -388
  856. package/packages/mcp/src/tools/pack.ts +0 -449
  857. package/packages/mcp/src/tools/registry.ts +0 -638
  858. package/packages/mcp/src/tools/report.ts +0 -100
  859. package/packages/mcp/src/tools/run.ts +0 -268
  860. package/packages/mcp/src/tools/secrets.ts +0 -198
  861. package/packages/mcp/src/tools/serve.ts +0 -221
  862. package/packages/mcp/src/tools/triage.ts +0 -532
  863. package/packages/mcp/src/tools/types.ts +0 -26
  864. package/packages/mcp/src/tools/vault.ts +0 -164
  865. package/packages/mcp/src/tools/verify.ts +0 -166
  866. package/packages/mcp/src/types/index.ts +0 -311
  867. package/packages/mcp/src/types/mcp-stubs.ts +0 -83
  868. package/packages/mcp/tsconfig.json +0 -16
  869. package/playwright.config.ts +0 -20
  870. package/pnpm-workspace.yaml +0 -4
  871. package/run-test-and-push.sh +0 -20
  872. package/scripts/build-proof-cli.sh +0 -110
  873. package/scripts/ci/check-windows-paths.js +0 -92
  874. package/scripts/ci/invariants.sh +0 -124
  875. package/scripts/ci/make-final-bundle.js +0 -106
  876. package/scripts/ci/mcp-run-multipack.js +0 -305
  877. package/scripts/ci/run-pack-suite.sh +0 -103
  878. package/scripts/ci/run-phase7-final.sh +0 -190
  879. package/scripts/ci/slo-assert.js +0 -158
  880. package/scripts/ci/test-fault-tolerance.sh +0 -301
  881. package/scripts/install-mcp.sh +0 -66
  882. package/scripts/mcp-smoke.mjs +0 -27
  883. package/scripts/smoke.sh +0 -26
  884. package/scripts/stress-test.js +0 -288
  885. package/scripts/sync-version.mjs +0 -50
  886. package/scripts/validate-examples.mjs +0 -404
  887. package/scripts/validation/simple-pack-check.sh +0 -51
  888. package/scripts/validation/validate-universal-pack.mjs +0 -77
  889. package/scripts/verify-persistence.js +0 -127
  890. package/test-pack.yaml +0 -43
  891. package/test-results/.last-run.json +0 -4
  892. package/test-runner.mjs +0 -87
  893. package/tests/artifacts.spec.js +0 -147
  894. package/tests/contracts.spec.js +0 -239
  895. package/tests/e2e/assertions.test.mjs +0 -370
  896. package/tests/e2e/crawler.test.mjs +0 -451
  897. package/tests/e2e/playwright-plus-plus.test.mjs +0 -604
  898. package/tests/e2e/proof-bundle.test.mjs +0 -258
  899. package/tests/e2e/real-world/saucedemo.test.mjs +0 -714
  900. package/tests/e2e/real-world/the-internet-herokuapp.test.mjs +0 -760
  901. package/tests/e2e/ui-actions.test.mjs +0 -546
  902. package/tests/gherkin.e2e.spec.ts +0 -310
  903. package/tests/no-console-errors.spec.js +0 -136
  904. package/tests/pdf.spec.ts +0 -252
  905. package/tests/run-pack.spec.ts +0 -58
  906. package/tsconfig.base.json +0 -15
  907. package/tsconfig.build.json +0 -8
  908. package/tsconfig.json +0 -37
  909. package/tsconfig.test.json +0 -18
  910. package/typedoc.json +0 -37
  911. package/ui/README.md +0 -50
  912. package/verify-proof.mjs +0 -60
@@ -0,0 +1,1323 @@
1
+ /**
2
+ * QA360 Phase 3 Runner
3
+ * Orchestrates hooks, adapters, and proof generation
4
+ * Supports both Pack v1 and Pack v2 configurations
5
+ */
6
+ import { existsSync, writeFileSync, mkdirSync } from 'fs';
7
+ import { join, resolve } from 'path';
8
+ import { createHash } from 'crypto';
9
+ import chalk from 'chalk';
10
+ import { HooksRunner } from '../hooks/runner.js';
11
+ import { PlaywrightNativeApiAdapter } from '../adapters/playwright-native-api.js';
12
+ import { PlaywrightUiAdapter } from '../adapters/playwright-ui.js';
13
+ import { K6PerfAdapter } from '../adapters/k6-perf.js';
14
+ import { SemgrepSastAdapter } from '../adapters/semgrep-sast.js';
15
+ // v2.2.0 Unit Test Adapters
16
+ import { VitestAdapter } from '../adapters/vitest-adapter.js';
17
+ import { JestAdapter } from '../adapters/jest-adapter.js';
18
+ import { PytestAdapter } from '../adapters/pytest-adapter.js';
19
+ // v2.2.0 Data Fixtures
20
+ import { FixtureLoader } from '../fixtures/loader.js';
21
+ import { FixtureResolver } from '../fixtures/resolver.js';
22
+ import { PageObjectLoader } from '../pom/loader.js';
23
+ import { SecurityRedactor } from '../security/redactor.js';
24
+ import { initializeKeys, sign } from '../proof/signer.js';
25
+ import { canonicalize } from '../proof/canonicalize.js';
26
+ import { EvidenceVault } from '../vault/index.js';
27
+ import { AuthManager } from '../auth/index.js';
28
+ import { FlakinessDetector, FlakinessCategory, formatFlakinessScore, generateTestId, DEFAULT_FLAKINESS_OPTIONS } from '../flakiness/index.js';
29
+ export class Phase3Runner {
30
+ workingDir;
31
+ pack;
32
+ packDir; // Directory containing the pack file
33
+ outputDir;
34
+ redactor;
35
+ hooksRunner;
36
+ keyPair;
37
+ vault;
38
+ authManager;
39
+ authCredentialsCache = new Map();
40
+ flakyDetect;
41
+ flakyRuns;
42
+ flakinessDetector;
43
+ // v2.2.0 Data Fixtures & POM
44
+ fixtureLoader;
45
+ fixtureResolver;
46
+ pageObjectLoader;
47
+ constructor(options) {
48
+ this.workingDir = options.workingDir;
49
+ this.pack = options.pack;
50
+ this.packDir = options.packDir || options.workingDir;
51
+ this.outputDir = options.outputDir || join(this.workingDir, '.qa360', 'runs');
52
+ this.redactor = SecurityRedactor.forLogs();
53
+ this.authManager = new AuthManager();
54
+ this.flakyDetect = options.flakyDetect || false;
55
+ this.flakyRuns = options.flakyRuns || DEFAULT_FLAKINESS_OPTIONS.consecutiveRuns;
56
+ this.flakinessDetector = new FlakinessDetector({
57
+ consecutiveRuns: this.flakyRuns,
58
+ minRuns: 2,
59
+ enablePatternDetection: true
60
+ });
61
+ // Initialize hooks runner (convert v2 hooks to v1 format if needed)
62
+ const hooks = this.isPackV2(options.pack)
63
+ ? this.convertV2HooksToV1(options.pack.hooks)
64
+ : options.pack.hooks;
65
+ this.hooksRunner = new HooksRunner({
66
+ workingDir: this.workingDir,
67
+ hooks: hooks || {},
68
+ execution: this.isPackV2(options.pack) ? this.convertV2ExecutionToV1(options.pack.execution) : options.pack.execution,
69
+ redactor: this.redactor
70
+ });
71
+ // Register auth profiles from pack v2
72
+ if (this.isPackV2(options.pack) && options.pack.auth?.profiles) {
73
+ this.registerAuthProfiles(options.pack.auth.profiles);
74
+ }
75
+ // Load data fixtures from pack v2
76
+ if (this.isPackV2(options.pack) && options.pack.fixtures && options.pack.fixtures.length > 0) {
77
+ this.initializeFixtures(options.pack.fixtures);
78
+ }
79
+ // Initialize Page Object Model from pack v2
80
+ if (this.isPackV2(options.pack) && options.pack.pageObjects) {
81
+ this.initializePageObjects(options.pack.pageObjects);
82
+ }
83
+ }
84
+ /**
85
+ * Initialize Page Object Model from the pack configuration
86
+ */
87
+ initializePageObjects(config) {
88
+ try {
89
+ const pomDir = config.directory ? resolve(this.packDir, config.directory) : this.packDir;
90
+ this.pageObjectLoader = new PageObjectLoader({ cwd: pomDir });
91
+ console.log(chalk.gray(` 📄 POM loader initialized for: ${pomDir}`));
92
+ }
93
+ catch (error) {
94
+ console.log(chalk.yellow(`⚠️ Failed to initialize POM loader: ${error instanceof Error ? error.message : 'Unknown error'}`));
95
+ }
96
+ }
97
+ /**
98
+ * Load Page Objects before execution
99
+ */
100
+ async loadPageObjects() {
101
+ if (!this.pageObjectLoader || !this.isPackV2(this.pack) || !this.pack.pageObjects) {
102
+ return;
103
+ }
104
+ try {
105
+ const pattern = this.pack.pageObjects.pattern || '**/*.page.{ts,js}';
106
+ const result = await this.pageObjectLoader.loadFromDirectory(this.packDir, { pattern });
107
+ console.log(chalk.green(` ✅ Page Objects loaded: ${result.pagesCount} pages`));
108
+ }
109
+ catch (error) {
110
+ console.log(chalk.yellow(`⚠️ Failed to load page objects: ${error instanceof Error ? error.message : 'Unknown error'}`));
111
+ }
112
+ }
113
+ /**
114
+ * Initialize data fixtures from the pack configuration
115
+ */
116
+ initializeFixtures(fixturePaths) {
117
+ try {
118
+ this.fixtureLoader = new FixtureLoader(this.packDir);
119
+ // Load fixtures synchronously - they're already validated
120
+ // We'll load them before execution starts
121
+ this.fixtureResolver = new FixtureResolver(this.fixtureLoader, this.packDir);
122
+ }
123
+ catch (error) {
124
+ console.log(chalk.yellow(`⚠️ Failed to initialize fixtures: ${error instanceof Error ? error.message : 'Unknown error'}`));
125
+ }
126
+ }
127
+ /**
128
+ * Load fixtures before execution
129
+ */
130
+ async loadFixtures() {
131
+ if (!this.fixtureLoader || !this.isPackV2(this.pack) || !this.pack.fixtures) {
132
+ return;
133
+ }
134
+ try {
135
+ await this.fixtureLoader.load(this.pack.fixtures);
136
+ console.log(chalk.green(` ✅ Fixtures loaded: ${this.fixtureLoader.getFixtureNames().join(', ')}`));
137
+ }
138
+ catch (error) {
139
+ console.log(chalk.yellow(`⚠️ Failed to load fixtures: ${error instanceof Error ? error.message : 'Unknown error'}`));
140
+ }
141
+ }
142
+ /**
143
+ * Resolve fixture references in a configuration object
144
+ */
145
+ resolveFixturesInConfig(config) {
146
+ if (!this.fixtureResolver || !config) {
147
+ return config;
148
+ }
149
+ try {
150
+ const result = this.fixtureResolver.resolve(config, {
151
+ baseDir: this.workingDir,
152
+ keepUnresolved: false
153
+ });
154
+ if (result.hasFixtures) {
155
+ console.log(chalk.gray(` 🔧 Fixtures resolved in config`));
156
+ }
157
+ return result.value;
158
+ }
159
+ catch (error) {
160
+ console.log(chalk.yellow(`⚠️ Failed to resolve fixtures: ${error instanceof Error ? error.message : 'Unknown error'}`));
161
+ return config;
162
+ }
163
+ }
164
+ /**
165
+ * Type guard to check if pack is v2
166
+ */
167
+ isPackV2(pack) {
168
+ return pack.version === 2;
169
+ }
170
+ /**
171
+ * Register authentication profiles from pack config
172
+ */
173
+ registerAuthProfiles(profiles) {
174
+ for (const [name, profile] of Object.entries(profiles)) {
175
+ // Convert v2 auth profile to auth module format
176
+ const authConfig = {
177
+ type: profile.type || 'none',
178
+ ...profile.config
179
+ };
180
+ this.authManager.registerProfile(name, authConfig);
181
+ }
182
+ }
183
+ /**
184
+ * Get auth profile name for a specific gate
185
+ */
186
+ getAuthProfileForGate(gateName) {
187
+ if (!this.isPackV2(this.pack) || !this.pack.auth) {
188
+ return undefined;
189
+ }
190
+ const authConfig = this.pack.auth;
191
+ // Check if gate has specific auth override
192
+ const gateConfig = this.pack.gates[gateName];
193
+ if (gateConfig?.auth) {
194
+ return gateConfig.auth;
195
+ }
196
+ // Use default based on gate type
197
+ if (gateName === 'api_smoke' || gateName === 'api') {
198
+ return authConfig.api;
199
+ }
200
+ if (gateName === 'ui' || gateName === 'a11y') {
201
+ return authConfig.ui;
202
+ }
203
+ return undefined;
204
+ }
205
+ /**
206
+ * Authenticate and get credentials for a gate
207
+ */
208
+ async getCredentialsForGate(gateName) {
209
+ const profileName = this.getAuthProfileForGate(gateName);
210
+ if (!profileName) {
211
+ return undefined;
212
+ }
213
+ // Check cache first
214
+ if (this.authCredentialsCache.has(profileName)) {
215
+ return this.authCredentialsCache.get(profileName);
216
+ }
217
+ // Authenticate
218
+ const result = await this.authManager.authenticate(profileName);
219
+ if (result.success && result.credentials) {
220
+ this.authCredentialsCache.set(profileName, result.credentials);
221
+ return result.credentials;
222
+ }
223
+ console.log(chalk.yellow(` ⚠️ Auth failed for profile '${profileName}': ${result.error}`));
224
+ return undefined;
225
+ }
226
+ /**
227
+ * Convert v2 hooks to v1 format
228
+ */
229
+ convertV2HooksToV1(hooks) {
230
+ if (!hooks)
231
+ return undefined;
232
+ // v2 hooks use { type, command, ... } format
233
+ // v1 hooks use { run, timeout } format
234
+ const converted = {
235
+ beforeAll: [],
236
+ afterAll: [],
237
+ beforeEach: [],
238
+ afterEach: []
239
+ };
240
+ for (const [phase, phaseHooks] of Object.entries(hooks)) {
241
+ if (Array.isArray(phaseHooks)) {
242
+ converted[phase] = phaseHooks.map((h) => {
243
+ if (h.type === 'run' || h.type === 'script') {
244
+ return { run: h.command, timeout: h.timeout, cwd: h.cwd, env: h.env };
245
+ }
246
+ if (h.type === 'wait_on') {
247
+ return { run: `npx wait-on ${h.wait_for?.resource || h.command}`, timeout: h.timeout };
248
+ }
249
+ if (h.type === 'docker') {
250
+ return { run: `docker compose ${h.compose?.command || 'up -d'}`, timeout: h.timeout };
251
+ }
252
+ return h;
253
+ });
254
+ }
255
+ }
256
+ return converted;
257
+ }
258
+ /**
259
+ * Convert v2 execution config to v1 format
260
+ */
261
+ convertV2ExecutionToV1(execution) {
262
+ if (!execution)
263
+ return undefined;
264
+ return {
265
+ timeout: execution.default_timeout || execution.timeout,
266
+ max_retries: execution.default_retries || execution.retries,
267
+ on_failure: execution.on_failure || 'continue'
268
+ };
269
+ }
270
+ /**
271
+ * Get gates array from pack (handles v1 and v2)
272
+ */
273
+ getGatesArray() {
274
+ if (this.isPackV2(this.pack)) {
275
+ return Object.keys(this.pack.gates).filter(gateName => {
276
+ const gateConfig = this.pack.gates[gateName];
277
+ return gateConfig?.enabled !== false;
278
+ });
279
+ }
280
+ return this.pack.gates || [];
281
+ }
282
+ /**
283
+ * Execute complete Phase 3 workflow
284
+ */
285
+ async run() {
286
+ const startTime = Date.now();
287
+ const gatesArray = this.getGatesArray();
288
+ console.log(chalk.bold.blue(`\n🚀 QA360 Phase 3 Runner - ${this.pack.name}`));
289
+ console.log(chalk.gray(`Gates: ${gatesArray.join(', ')}`));
290
+ try {
291
+ // Ensure output directory exists
292
+ this.ensureOutputDir();
293
+ // Load data fixtures if configured
294
+ await this.loadFixtures();
295
+ // Load page objects if configured
296
+ await this.loadPageObjects();
297
+ // Initialize cryptographic keys
298
+ console.log(chalk.blue('\n🔑 Initializing Ed25519 keys...'));
299
+ this.keyPair = await initializeKeys();
300
+ console.log(chalk.green(' ✅ Keys ready'));
301
+ // Initialize Evidence Vault
302
+ console.log(chalk.blue('\n🗄️ Initializing Evidence Vault...'));
303
+ const vaultDir = join(this.workingDir, '.qa360');
304
+ this.vault = await EvidenceVault.open(vaultDir);
305
+ console.log(chalk.green(' ✅ Vault ready'));
306
+ // Execute beforeAll hooks
307
+ console.log(chalk.blue('\n🔗 Phase 1: Setup Hooks'));
308
+ const beforeAllResults = await this.hooksRunner.executeHooks('beforeAll');
309
+ // Check if setup failed and should stop
310
+ const setupFailed = beforeAllResults.some(r => !r.success);
311
+ if (setupFailed && this.pack.execution?.on_failure === 'stop') {
312
+ throw new Error('Setup hooks failed, stopping execution');
313
+ }
314
+ // Execute gates
315
+ console.log(chalk.blue('\n🎯 Phase 2: Quality Gates'));
316
+ const gateResults = [];
317
+ for (const gate of gatesArray) {
318
+ const gateResult = await this.executeGate(gate);
319
+ gateResults.push(gateResult);
320
+ // Check if gate failed and should stop
321
+ if (!gateResult.success && this.pack.execution?.on_failure === 'stop') {
322
+ console.log(chalk.yellow(`🛑 Gate ${gate} failed, stopping execution`));
323
+ break;
324
+ }
325
+ }
326
+ // Flakiness Detection Phase (Vision 2.0)
327
+ let flakinessResults;
328
+ if (this.flakyDetect) {
329
+ console.log(chalk.blue(`\n🎲 Phase 2.5: Flakiness Detection (${this.flakyRuns} consecutive runs)`));
330
+ flakinessResults = await this.detectFlakiness(gateResults);
331
+ // Display flakiness summary
332
+ const unstableCount = flakinessResults.filter(f => f.category === FlakinessCategory.UNSTABLE || f.category === FlakinessCategory.SHAKY).length;
333
+ if (unstableCount > 0) {
334
+ console.log(chalk.yellow(` ⚠️ ${unstableCount} test(s) show flaky behavior`));
335
+ }
336
+ else {
337
+ console.log(chalk.green(' ✅ All tests stable - no flakiness detected'));
338
+ }
339
+ }
340
+ // Execute afterAll hooks
341
+ console.log(chalk.blue('\n🔗 Phase 3: Cleanup Hooks'));
342
+ const afterAllResults = await this.hooksRunner.executeHooks('afterAll');
343
+ // Calculate results
344
+ const duration = Date.now() - startTime;
345
+ const summary = this.calculateSummary(gateResults);
346
+ const success = summary.failed === 0;
347
+ // Generate proof
348
+ console.log(chalk.blue('\n📋 Phase 4: Proof Generation'));
349
+ const proofPath = await this.generateProof({
350
+ success,
351
+ pack: this.pack,
352
+ duration,
353
+ gates: gateResults,
354
+ hooks: {
355
+ beforeAll: beforeAllResults,
356
+ beforeEach: [],
357
+ afterEach: [],
358
+ afterAll: afterAllResults
359
+ },
360
+ summary
361
+ });
362
+ // Save to Evidence Vault
363
+ console.log(chalk.blue('\n💾 Phase 5: Evidence Storage'));
364
+ const proofRunId = proofPath.split('/').pop()?.replace('-proof.json', '') || 'unknown';
365
+ const vaultRunId = await this.saveToVault(proofRunId, {
366
+ success,
367
+ pack: this.pack,
368
+ duration,
369
+ gates: gateResults,
370
+ hooks: {
371
+ beforeAll: beforeAllResults,
372
+ beforeEach: [],
373
+ afterEach: [],
374
+ afterAll: afterAllResults
375
+ },
376
+ summary,
377
+ proofPath
378
+ }, proofPath, flakinessResults, startTime);
379
+ // Final summary
380
+ console.log(chalk.blue('\n📊 Execution Summary'));
381
+ console.log(` Duration: ${duration}ms`);
382
+ console.log(` Gates: ${summary.passed}/${summary.total} passed`);
383
+ console.log(` Trust Score: ${summary.trustScore}%`);
384
+ console.log(` Proof: ${proofPath}`);
385
+ // Display flakiness details if enabled
386
+ if (flakinessResults && flakinessResults.length > 0) {
387
+ console.log(chalk.blue('\n🎲 Flakiness Scores:'));
388
+ for (const f of flakinessResults) {
389
+ const scoreFormatted = formatFlakinessScore(f.score);
390
+ const categoryMeta = {
391
+ [FlakinessCategory.LEGENDARY]: { emoji: '🟢', color: chalk.green },
392
+ [FlakinessCategory.SOLID]: { emoji: '🟢', color: chalk.green },
393
+ [FlakinessCategory.GOOD]: { emoji: '🟡', color: chalk.yellow },
394
+ [FlakinessCategory.SHAKY]: { emoji: '🟠', color: chalk.hex('#F97316') },
395
+ [FlakinessCategory.UNSTABLE]: { emoji: '🔴', color: chalk.red }
396
+ }[f.category];
397
+ console.log(` ${categoryMeta.color(`${f.testName}: ${scoreFormatted}`)} (${f.successfulRuns}/${f.totalRuns} passes)`);
398
+ if (f.suggestedFix) {
399
+ console.log(chalk.gray(` 💡 ${f.suggestedFix}`));
400
+ }
401
+ }
402
+ }
403
+ if (success) {
404
+ console.log(chalk.green('\n✅ All quality gates passed!'));
405
+ }
406
+ else {
407
+ console.log(chalk.red(`\n❌ ${summary.failed} quality gate(s) failed`));
408
+ }
409
+ return {
410
+ success,
411
+ pack: this.pack,
412
+ duration,
413
+ gates: gateResults,
414
+ hooks: {
415
+ beforeAll: beforeAllResults,
416
+ beforeEach: [],
417
+ afterEach: [],
418
+ afterAll: afterAllResults
419
+ },
420
+ summary,
421
+ flakiness: flakinessResults,
422
+ proofPath,
423
+ runId: vaultRunId
424
+ };
425
+ }
426
+ catch (error) {
427
+ const duration = Date.now() - startTime;
428
+ // Ensure cleanup even on error
429
+ try {
430
+ await this.hooksRunner.executeHooks('afterAll');
431
+ }
432
+ catch {
433
+ // Ignore cleanup errors
434
+ }
435
+ return {
436
+ success: false,
437
+ pack: this.pack,
438
+ duration,
439
+ gates: [],
440
+ hooks: { beforeAll: [], beforeEach: [], afterEach: [], afterAll: [] },
441
+ summary: { total: 0, passed: 0, failed: 0, trustScore: 0 },
442
+ error: this.redactor.redact(error instanceof Error ? error.message : 'Unknown error')
443
+ };
444
+ }
445
+ }
446
+ /**
447
+ * Execute a single quality gate
448
+ */
449
+ async executeGate(gate) {
450
+ const startTime = Date.now();
451
+ console.log(chalk.cyan(`\n 🎯 Gate: ${gate}`));
452
+ try {
453
+ let result;
454
+ let adapter;
455
+ // Check if this is a v2 pack with dynamic gate configuration
456
+ if (this.isPackV2(this.pack)) {
457
+ const gateConfig = this.pack.gates[gate];
458
+ if (gateConfig) {
459
+ return await this.executeDynamicGate(gate, gateConfig);
460
+ }
461
+ }
462
+ // Legacy v1 gates or predefined gates
463
+ switch (gate) {
464
+ case 'api_smoke':
465
+ adapter = 'playwright-native-api';
466
+ result = await this.runApiSmokeGate();
467
+ break;
468
+ case 'ui':
469
+ adapter = 'playwright-ui';
470
+ result = await this.runUiGate();
471
+ break;
472
+ case 'a11y':
473
+ adapter = 'playwright-ui';
474
+ result = await this.runA11yGate();
475
+ break;
476
+ case 'perf':
477
+ adapter = 'k6';
478
+ result = await this.runPerfGate();
479
+ break;
480
+ case 'sast':
481
+ adapter = 'semgrep';
482
+ result = await this.runSastGate();
483
+ break;
484
+ case 'dast':
485
+ adapter = 'zap';
486
+ result = await this.runDastGate();
487
+ break;
488
+ default:
489
+ throw new Error(`Unknown gate: ${gate}`);
490
+ }
491
+ const duration = Date.now() - startTime;
492
+ if (result.success) {
493
+ console.log(chalk.green(` ✅ ${gate} passed (${duration}ms)`));
494
+ }
495
+ else {
496
+ console.log(chalk.red(` ❌ ${gate} failed (${duration}ms)`));
497
+ if (result.error) {
498
+ console.log(chalk.red(` 🔍 ${result.error}`));
499
+ }
500
+ }
501
+ return {
502
+ gate,
503
+ success: result.success,
504
+ duration,
505
+ adapter,
506
+ results: result,
507
+ junit: result.junit,
508
+ error: result.error
509
+ };
510
+ }
511
+ catch (error) {
512
+ const duration = Date.now() - startTime;
513
+ const errorMessage = this.redactor.redact(error instanceof Error ? error.message : 'Unknown error');
514
+ console.log(chalk.red(` 💥 ${gate} crashed (${duration}ms): ${errorMessage}`));
515
+ return {
516
+ gate,
517
+ success: false,
518
+ duration,
519
+ adapter: 'unknown',
520
+ results: null,
521
+ error: errorMessage
522
+ };
523
+ }
524
+ }
525
+ /**
526
+ * Execute a dynamic v2 gate
527
+ */
528
+ async executeDynamicGate(gateName, gateConfig) {
529
+ const startTime = Date.now();
530
+ const adapterType = gateConfig.adapter || gateConfig.type;
531
+ if (!adapterType) {
532
+ throw new Error(`Gate '${gateName}' must specify an adapter`);
533
+ }
534
+ // Resolve fixtures in gate configuration
535
+ const resolvedGateConfig = this.resolveFixturesInConfig(gateConfig);
536
+ // Get auth credentials for this gate
537
+ const credentials = await this.getCredentialsForGate(gateName);
538
+ // Map adapter type to implementation
539
+ let result;
540
+ switch (adapterType) {
541
+ case 'playwright-api':
542
+ result = await this.executePlaywrightApiGate(gateName, resolvedGateConfig, credentials);
543
+ break;
544
+ case 'playwright-ui':
545
+ result = await this.executePlaywrightUiGate(gateName, resolvedGateConfig, credentials);
546
+ break;
547
+ case 'k6':
548
+ case 'k6-perf':
549
+ result = await this.executeK6PerfGate(gateName, resolvedGateConfig);
550
+ break;
551
+ case 'semgrep':
552
+ case 'sast':
553
+ result = await this.executeSemgrepSastGate(gateName, resolvedGateConfig);
554
+ break;
555
+ // v2.2.0 Unit Test Adapters
556
+ case 'vitest':
557
+ result = await this.executeVitestGate(gateName, resolvedGateConfig);
558
+ break;
559
+ case 'jest':
560
+ result = await this.executeJestGate(gateName, resolvedGateConfig);
561
+ break;
562
+ case 'pytest':
563
+ result = await this.executePytestGate(gateName, resolvedGateConfig);
564
+ break;
565
+ default:
566
+ throw new Error(`Unsupported adapter: '${adapterType}' for gate '${gateName}'`);
567
+ }
568
+ // Set duration
569
+ result.duration = Date.now() - startTime;
570
+ // Log result
571
+ if (result.success) {
572
+ console.log(chalk.green(` ✅ ${gateName} passed (${result.duration}ms)`));
573
+ }
574
+ else {
575
+ console.log(chalk.red(` ❌ ${gateName} failed (${result.duration}ms)`));
576
+ if (result.error) {
577
+ console.log(chalk.red(` 🔍 ${result.error}`));
578
+ }
579
+ }
580
+ return result;
581
+ }
582
+ /**
583
+ * Execute Playwright API gate with v2 config
584
+ * Uses PlaywrightNativeApiAdapter for zero-overhead HTTP testing
585
+ */
586
+ async executePlaywrightApiGate(gateName, gateConfig, credentials) {
587
+ const { PlaywrightNativeApiAdapter } = await import('../adapters/playwright-native-api.js');
588
+ const adapter = new PlaywrightNativeApiAdapter();
589
+ // Transform v2 config to adapter format
590
+ const gateConfigData = gateConfig.config || {};
591
+ const gateOptions = gateConfig.options || {};
592
+ const config = {
593
+ target: {
594
+ baseUrl: gateConfigData.baseUrl,
595
+ smoke: gateConfigData.smoke
596
+ },
597
+ budgets: gateConfigData.budgets,
598
+ timeout: gateOptions.timeout || gateConfigData.timeout,
599
+ retries: gateOptions.retries || gateConfigData.retries,
600
+ auth: credentials
601
+ };
602
+ const result = await adapter.runSmokeTests(config);
603
+ return {
604
+ gate: gateName,
605
+ success: result.success,
606
+ duration: 0, // Will be set by caller
607
+ adapter: 'playwright-native-api',
608
+ results: result,
609
+ junit: result.junit
610
+ };
611
+ }
612
+ /**
613
+ * Execute Playwright UI gate with v2 config
614
+ */
615
+ async executePlaywrightUiGate(gateName, gateConfig, credentials) {
616
+ const { PlaywrightUiAdapter } = await import('../adapters/playwright-ui.js');
617
+ const adapter = new PlaywrightUiAdapter();
618
+ // Transform v2 config to adapter format
619
+ // v2: { baseUrl, pages: [{ url: '/', expectedElements: [...] }] }
620
+ // adapter expects: { target: { baseUrl, pages: ['https://.../'] } }
621
+ const gateConfigData = gateConfig.config || {};
622
+ const gateOptions = gateConfig.options || {};
623
+ // Transform page objects to full URLs
624
+ // v2 pages format: [{ url: '/', expectedElements: [...] }] or ['/', '/about']
625
+ const rawPages = gateConfigData.pages;
626
+ let pages;
627
+ if (rawPages && Array.isArray(rawPages) && rawPages.length > 0) {
628
+ const baseUrl = gateConfigData.baseUrl || '';
629
+ pages = rawPages.map((p) => {
630
+ if (typeof p === 'string') {
631
+ // Already a URL string - make it absolute if relative
632
+ return p.startsWith('http') ? p : `${baseUrl.replace(/\/$/, '')}${p}`;
633
+ }
634
+ else if (p && typeof p === 'object' && p.url) {
635
+ // Page object { url: '/', ... } - convert to full URL
636
+ const url = p.url;
637
+ return url.startsWith('http') ? url : `${baseUrl.replace(/\/$/, '')}${url}`;
638
+ }
639
+ return p;
640
+ });
641
+ }
642
+ else if (gateConfigData.baseUrl) {
643
+ pages = [gateConfigData.baseUrl];
644
+ }
645
+ const config = {
646
+ target: {
647
+ baseUrl: gateConfigData.baseUrl,
648
+ pages: pages
649
+ },
650
+ budgets: gateConfigData.budgets,
651
+ timeout: gateOptions.timeout || gateConfigData.timeout,
652
+ auth: credentials,
653
+ // Playwright++ features
654
+ artifacts: gateConfigData.artifacts,
655
+ htmlReport: gateConfigData.htmlReport,
656
+ bail: gateConfigData.bail
657
+ };
658
+ const result = await adapter.runSmokeTests(config);
659
+ return {
660
+ gate: gateName,
661
+ success: result.success,
662
+ duration: 0, // Will be set by caller
663
+ adapter: 'playwright-ui',
664
+ results: result,
665
+ junit: result.junit
666
+ };
667
+ }
668
+ /**
669
+ * Execute K6 Performance gate with v2 config
670
+ */
671
+ async executeK6PerfGate(gateName, gateConfig) {
672
+ const { K6PerfAdapter } = await import('../adapters/k6-perf.js');
673
+ const adapter = new K6PerfAdapter(this.workingDir);
674
+ const config = {
675
+ baseUrl: gateConfig.config?.baseUrl,
676
+ ...gateConfig.config
677
+ };
678
+ const result = await adapter.runPerfTest(config);
679
+ return {
680
+ gate: gateName,
681
+ success: result.success,
682
+ duration: 0,
683
+ adapter: 'k6',
684
+ results: result,
685
+ junit: result.junit
686
+ };
687
+ }
688
+ /**
689
+ * Execute Semgrep SAST gate with v2 config
690
+ */
691
+ async executeSemgrepSastGate(gateName, gateConfig) {
692
+ const { SemgrepSastAdapter } = await import('../adapters/semgrep-sast.js');
693
+ const adapter = new SemgrepSastAdapter();
694
+ const config = {
695
+ workingDir: this.workingDir,
696
+ ...gateConfig.config
697
+ };
698
+ const result = await adapter.runSastScan(config);
699
+ return {
700
+ gate: gateName,
701
+ success: result.success,
702
+ duration: 0,
703
+ adapter: 'semgrep',
704
+ results: result,
705
+ junit: result.junit
706
+ };
707
+ }
708
+ /**
709
+ * Execute Vitest unit tests gate (v2.2.0)
710
+ */
711
+ async executeVitestGate(gateName, gateConfig) {
712
+ const adapter = new VitestAdapter(this.workingDir);
713
+ const config = {
714
+ cwd: this.workingDir,
715
+ ...gateConfig.config
716
+ };
717
+ const result = await adapter.execute(config);
718
+ return {
719
+ gate: gateName,
720
+ success: result.success,
721
+ duration: result.duration,
722
+ adapter: 'vitest',
723
+ results: {
724
+ total: result.total,
725
+ passed: result.passed,
726
+ failed: result.failed,
727
+ skipped: result.skipped,
728
+ tests: result.tests.map(t => ({
729
+ name: t.name,
730
+ status: t.status,
731
+ duration: t.duration,
732
+ error: t.error
733
+ }))
734
+ },
735
+ junit: this.buildJunitFromVitest(result)
736
+ };
737
+ }
738
+ /**
739
+ * Execute Jest unit tests gate (v2.2.0)
740
+ */
741
+ async executeJestGate(gateName, gateConfig) {
742
+ const adapter = new JestAdapter(this.workingDir);
743
+ const config = {
744
+ cwd: this.workingDir,
745
+ ...gateConfig.config
746
+ };
747
+ const result = await adapter.execute(config);
748
+ return {
749
+ gate: gateName,
750
+ success: result.success,
751
+ duration: result.duration,
752
+ adapter: 'jest',
753
+ results: {
754
+ total: result.total,
755
+ passed: result.passed,
756
+ failed: result.failed,
757
+ skipped: result.skipped + result.pending,
758
+ tests: result.tests.map(t => ({
759
+ name: t.name,
760
+ status: t.status,
761
+ duration: t.duration,
762
+ error: t.error
763
+ }))
764
+ },
765
+ junit: this.buildJunitFromJest(result)
766
+ };
767
+ }
768
+ /**
769
+ * Execute Pytest unit tests gate (v2.2.0)
770
+ */
771
+ async executePytestGate(gateName, gateConfig) {
772
+ const adapter = new PytestAdapter(this.workingDir);
773
+ const config = {
774
+ cwd: this.workingDir,
775
+ ...gateConfig.config
776
+ };
777
+ const result = await adapter.execute(config);
778
+ return {
779
+ gate: gateName,
780
+ success: result.success,
781
+ duration: result.duration,
782
+ adapter: 'pytest',
783
+ results: {
784
+ total: result.total,
785
+ passed: result.passed,
786
+ failed: result.failed,
787
+ skipped: result.skipped,
788
+ tests: result.tests.map(t => ({
789
+ name: t.name,
790
+ status: t.status,
791
+ duration: t.duration,
792
+ error: t.error
793
+ }))
794
+ },
795
+ junit: this.buildJunitFromPytest(result)
796
+ };
797
+ }
798
+ /**
799
+ * Build JUnit format from Vitest results
800
+ */
801
+ buildJunitFromVitest(result) {
802
+ // Convert adapter result to JUnit-like format
803
+ return {
804
+ testsuites: [{
805
+ name: 'vitest',
806
+ tests: result.total,
807
+ failures: result.failed,
808
+ skipped: result.skipped,
809
+ time: result.duration / 1000,
810
+ testcases: result.tests.map((t) => ({
811
+ name: t.name,
812
+ classname: t.file,
813
+ time: t.duration / 1000,
814
+ failure: t.error ? { message: t.error } : undefined,
815
+ skipped: t.status === 'skipped' ? { message: 'Skipped' } : undefined
816
+ }))
817
+ }]
818
+ };
819
+ }
820
+ /**
821
+ * Build JUnit format from Jest results
822
+ */
823
+ buildJunitFromJest(result) {
824
+ return {
825
+ testsuites: [{
826
+ name: 'jest',
827
+ tests: result.total,
828
+ failures: result.failed,
829
+ skipped: result.pending,
830
+ time: result.duration / 1000,
831
+ testcases: result.tests.map((t) => ({
832
+ name: t.name,
833
+ time: t.duration / 1000,
834
+ failure: t.error ? { message: t.error } : undefined,
835
+ skipped: t.status === 'pending' || t.status === 'skipped' ? { message: 'Skipped' } : undefined
836
+ }))
837
+ }]
838
+ };
839
+ }
840
+ /**
841
+ * Build JUnit format from Pytest results
842
+ */
843
+ buildJunitFromPytest(result) {
844
+ return {
845
+ testsuites: [{
846
+ name: 'pytest',
847
+ tests: result.total,
848
+ failures: result.failed,
849
+ skipped: result.skipped,
850
+ time: result.duration / 1000,
851
+ testcases: result.tests.map((t) => ({
852
+ name: t.name,
853
+ classname: t.file,
854
+ time: t.duration / 1000,
855
+ failure: t.error ? { message: t.error } : undefined,
856
+ skipped: t.status === 'skipped' ? { message: 'Skipped' } : undefined
857
+ }))
858
+ }]
859
+ };
860
+ }
861
+ /**
862
+ * Run API smoke gate
863
+ * Uses PlaywrightNativeApiAdapter for zero-overhead HTTP testing
864
+ */
865
+ async runApiSmokeGate() {
866
+ const target = this.getTargetApi();
867
+ if (!target) {
868
+ throw new Error('API smoke gate requires targets.api configuration or gate config with baseUrl');
869
+ }
870
+ const credentials = await this.getCredentialsForGate('api_smoke');
871
+ const adapter = new PlaywrightNativeApiAdapter();
872
+ return await adapter.runSmokeTests({
873
+ target,
874
+ budgets: this.getBudgets(),
875
+ timeout: this.getExecutionTimeout() || 10000,
876
+ retries: this.getExecutionRetries() || 1,
877
+ auth: credentials
878
+ });
879
+ }
880
+ /**
881
+ * Run UI gate (includes basic accessibility)
882
+ */
883
+ async runUiGate() {
884
+ let target = this.getTargetWeb();
885
+ if (!target) {
886
+ throw new Error('UI gate requires targets.web configuration or gate config with baseUrl');
887
+ }
888
+ // Transform relative pages to full URLs for v1 packs
889
+ if (target.pages && target.baseUrl && !this.isPackV2(this.pack)) {
890
+ const baseUrl = target.baseUrl.replace(/\/$/, '');
891
+ target.pages = target.pages.map((p) => {
892
+ const pageStr = typeof p === 'object' && p.url ? p.url : p;
893
+ if (typeof pageStr === 'string' && !pageStr.startsWith('http')) {
894
+ return `${baseUrl}${pageStr.startsWith('/') ? '' : '/'}${pageStr}`;
895
+ }
896
+ return p;
897
+ });
898
+ }
899
+ const credentials = await this.getCredentialsForGate('ui');
900
+ const adapter = new PlaywrightUiAdapter();
901
+ return await adapter.runSmokeTests({
902
+ target,
903
+ budgets: this.getBudgets(),
904
+ timeout: this.getExecutionTimeout() || 30000,
905
+ auth: credentials
906
+ });
907
+ }
908
+ /**
909
+ * Run A11y gate (focused accessibility testing)
910
+ */
911
+ async runA11yGate() {
912
+ // Same as UI gate but focused on accessibility
913
+ return await this.runUiGate();
914
+ }
915
+ /**
916
+ * Run performance gate
917
+ */
918
+ async runPerfGate() {
919
+ const baseUrl = this.pack.targets?.web?.baseUrl || this.pack.targets?.api?.baseUrl;
920
+ if (!baseUrl) {
921
+ throw new Error('Performance gate requires web or api target');
922
+ }
923
+ const adapter = new K6PerfAdapter(this.workingDir);
924
+ return await adapter.runPerfTest({
925
+ baseUrl,
926
+ budgets: this.pack.budgets,
927
+ duration: '30s',
928
+ vus: 5,
929
+ timeout: 120000
930
+ });
931
+ }
932
+ /**
933
+ * Run SAST gate
934
+ */
935
+ async runSastGate() {
936
+ const adapter = new SemgrepSastAdapter();
937
+ return await adapter.runSastScan({
938
+ workingDir: this.workingDir,
939
+ security: this.pack.security,
940
+ rules: ['auto'],
941
+ paths: ['src/', 'lib/', '.'],
942
+ timeout: 120000
943
+ });
944
+ }
945
+ /**
946
+ * Run DAST gate (mock implementation)
947
+ */
948
+ async runDastGate() {
949
+ // Mock DAST implementation for Phase 3
950
+ console.log(chalk.yellow(' ⚠️ DAST gate: Mock implementation (ZAP integration in Phase 4)'));
951
+ return {
952
+ success: true,
953
+ findings: [],
954
+ summary: { total: 0, high: 0, medium: 0, low: 0 },
955
+ junit: `<?xml version="1.0" encoding="UTF-8"?>
956
+ <testsuite name="DAST Mock" tests="1" failures="0" time="0">
957
+ <testcase name="Mock DAST Scan" time="0"></testcase>
958
+ </testsuite>`
959
+ };
960
+ }
961
+ /**
962
+ * Calculate execution summary
963
+ */
964
+ calculateSummary(gateResults) {
965
+ const total = gateResults.length;
966
+ const passed = gateResults.filter(g => g.success).length;
967
+ const failed = total - passed;
968
+ // Calculate trust score (weighted by gate importance)
969
+ const gateWeights = {
970
+ 'api_smoke': 20,
971
+ 'ui': 15,
972
+ 'perf': 15,
973
+ 'sast': 20,
974
+ 'dast': 20,
975
+ 'a11y': 10
976
+ };
977
+ let totalWeight = 0;
978
+ let passedWeight = 0;
979
+ for (const gate of gateResults) {
980
+ const weight = gateWeights[gate.gate] || 10;
981
+ totalWeight += weight;
982
+ if (gate.success) {
983
+ passedWeight += weight;
984
+ }
985
+ }
986
+ const trustScore = totalWeight > 0 ? Math.round((passedWeight / totalWeight) * 100) : 0;
987
+ return { total, passed, failed, trustScore };
988
+ }
989
+ /**
990
+ * Generate cryptographically signed proof document
991
+ */
992
+ async generateProof(result) {
993
+ const timestamp = new Date().toISOString();
994
+ const runId = `run-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
995
+ // Build proof payload (without signature)
996
+ const proofPayload = {
997
+ version: '3.0.0',
998
+ runId,
999
+ timestamp,
1000
+ pack: {
1001
+ name: result.pack.name,
1002
+ version: result.pack.version,
1003
+ gates: result.pack.gates
1004
+ },
1005
+ execution: {
1006
+ duration: result.duration,
1007
+ success: result.success,
1008
+ trustScore: result.summary.trustScore
1009
+ },
1010
+ gates: result.gates.map(g => {
1011
+ const gateObj = {
1012
+ gate: g.gate,
1013
+ adapter: g.adapter,
1014
+ success: g.success,
1015
+ duration: g.duration
1016
+ };
1017
+ // Only include error if it exists (avoid undefined fields)
1018
+ if (g.error !== undefined) {
1019
+ gateObj.error = g.error;
1020
+ }
1021
+ return gateObj;
1022
+ }),
1023
+ hooks: {
1024
+ beforeAll: result.hooks.beforeAll.length,
1025
+ afterAll: result.hooks.afterAll.length
1026
+ }
1027
+ };
1028
+ // Canonicalize the payload for signing (must match verification: canonical + newline)
1029
+ const canonicalPayload = canonicalize(proofPayload) + '\n';
1030
+ // Sign with Ed25519
1031
+ let signatureValue;
1032
+ let algorithm;
1033
+ let publicKeyB64;
1034
+ if (this.keyPair) {
1035
+ signatureValue = sign(canonicalPayload, this.keyPair.secretKey);
1036
+ algorithm = 'ed25519';
1037
+ publicKeyB64 = Buffer.from(this.keyPair.publicKey).toString('base64');
1038
+ console.log(chalk.green(' 🔏 Proof signed with Ed25519'));
1039
+ }
1040
+ else {
1041
+ signatureValue = `unsigned-${runId}`;
1042
+ algorithm = 'none';
1043
+ publicKeyB64 = '';
1044
+ console.log(chalk.yellow(' ⚠️ Proof unsigned (no keys available)'));
1045
+ }
1046
+ // Build complete proof with signature
1047
+ const proof = {
1048
+ ...proofPayload,
1049
+ signature: {
1050
+ algorithm,
1051
+ publicKey: publicKeyB64,
1052
+ value: signatureValue,
1053
+ timestamp
1054
+ }
1055
+ };
1056
+ // Save proof
1057
+ const proofPath = join(this.outputDir, `${runId}-proof.json`);
1058
+ writeFileSync(proofPath, JSON.stringify(proof, null, 2));
1059
+ return proofPath;
1060
+ }
1061
+ /**
1062
+ * Save run results to Evidence Vault
1063
+ * @returns The vault run ID
1064
+ */
1065
+ async saveToVault(runId, result, proofPath, flakinessResults, startTime) {
1066
+ if (!this.vault) {
1067
+ console.log(chalk.yellow(' ⚠️ Vault not initialized, skipping storage'));
1068
+ return undefined;
1069
+ }
1070
+ try {
1071
+ // Begin run in vault (returns actual runId used)
1072
+ // Use startTime if provided to correctly calculate duration
1073
+ const { runId: vaultRunId } = await this.vault.beginRun({
1074
+ pack_path: `${this.pack.name || 'pack'}.yaml`,
1075
+ pack_hash: this.hashPack(result.pack),
1076
+ started_at: startTime // Use actual run start time for accurate duration
1077
+ });
1078
+ // Finish run with final status
1079
+ await this.vault.finishRun(vaultRunId, {
1080
+ status: result.success ? 'passed' : 'failed',
1081
+ trust_score: result.summary.trustScore,
1082
+ signature: this.keyPair ? 'ed25519-signed' : undefined
1083
+ });
1084
+ // Record gate executions
1085
+ for (const gate of result.gates) {
1086
+ await this.vault.recordGate(vaultRunId, {
1087
+ name: gate.gate,
1088
+ status: gate.success ? 'passed' : 'failed',
1089
+ duration_ms: gate.duration,
1090
+ metrics_json: JSON.stringify(gate.results?.summary || {})
1091
+ });
1092
+ // Record finding if gate has error
1093
+ if (gate.error) {
1094
+ await this.vault.recordFinding(vaultRunId, {
1095
+ gate: gate.gate,
1096
+ severity: 'high',
1097
+ rule: 'gate-failure',
1098
+ message: gate.error
1099
+ });
1100
+ }
1101
+ }
1102
+ // Record flakiness results if available
1103
+ if (flakinessResults && flakinessResults.length > 0) {
1104
+ for (const flaky of flakinessResults) {
1105
+ // Record unstable/shaky tests as findings
1106
+ if (flaky.category === FlakinessCategory.UNSTABLE || flaky.category === FlakinessCategory.SHAKY) {
1107
+ await this.vault.recordFinding(vaultRunId, {
1108
+ gate: flaky.gate,
1109
+ severity: flaky.category === FlakinessCategory.UNSTABLE ? 'high' : 'medium',
1110
+ rule: 'flaky-test-detected',
1111
+ message: `Test "${flaky.testName}" is ${flaky.category}: ${flaky.score}% reliability (${flaky.successfulRuns}/${flaky.totalRuns} passes)`
1112
+ });
1113
+ }
1114
+ }
1115
+ console.log(chalk.green(` 💾 ${flakinessResults.length} flakiness analysis(es) saved`));
1116
+ }
1117
+ console.log(chalk.green(' 💾 Run saved to Evidence Vault'));
1118
+ return vaultRunId;
1119
+ }
1120
+ catch (error) {
1121
+ console.log(chalk.yellow(` ⚠️ Failed to save to vault: ${error}`));
1122
+ return undefined;
1123
+ }
1124
+ }
1125
+ /**
1126
+ * Detect flakiness by running tests multiple times consecutively
1127
+ * @param gateResults Original gate results from first run
1128
+ * @returns Flakiness analysis results
1129
+ */
1130
+ async detectFlakiness(gateResults) {
1131
+ const flakinessMap = new Map();
1132
+ const timestamp = Date.now();
1133
+ // First, collect results from the initial run
1134
+ for (const gateResult of gateResults) {
1135
+ for (const [testId, testResult] of this.extractTestResults(gateResult, timestamp)) {
1136
+ if (!flakinessMap.has(testId)) {
1137
+ flakinessMap.set(testId, []);
1138
+ }
1139
+ flakinessMap.get(testId).push(testResult);
1140
+ }
1141
+ }
1142
+ // Run additional consecutive runs
1143
+ for (let run = 1; run < this.flakyRuns; run++) {
1144
+ console.log(chalk.gray(` 🔄 Consecutive run ${run + 1}/${this.flakyRuns}...`));
1145
+ for (const gateResult of gateResults) {
1146
+ // Re-run all gates to detect flakiness
1147
+ try {
1148
+ const retryResult = await this.executeGate(gateResult.gate);
1149
+ // Extract and store test results
1150
+ for (const [testId, testResult] of this.extractTestResults(retryResult, timestamp)) {
1151
+ if (!flakinessMap.has(testId)) {
1152
+ flakinessMap.set(testId, []);
1153
+ }
1154
+ flakinessMap.get(testId).push(testResult);
1155
+ }
1156
+ }
1157
+ catch (error) {
1158
+ console.log(chalk.yellow(` ⚠️ Failed to re-run ${gateResult.gate}: ${error}`));
1159
+ }
1160
+ }
1161
+ }
1162
+ // Analyze all collected results
1163
+ return this.flakinessDetector.analyzeAll(flakinessMap);
1164
+ }
1165
+ /**
1166
+ * Extract test results from a gate result
1167
+ * Returns a map of testId to TestResult for flakiness tracking
1168
+ */
1169
+ extractTestResults(gateResult, timestamp) {
1170
+ const results = new Map();
1171
+ // Extract test results from adapter output
1172
+ const adapterResults = gateResult.results;
1173
+ if (adapterResults?.results && Array.isArray(adapterResults.results)) {
1174
+ // Check for Playwright Native API adapter format
1175
+ const firstResult = adapterResults.results[0];
1176
+ if (firstResult && 'endpoint' in firstResult && 'method' in firstResult) {
1177
+ // PlaywrightNativeApiAdapter format: { endpoint, method, status, success, error, ... }
1178
+ for (const test of adapterResults.results) {
1179
+ // Extract just the path from full URL for cleaner test names
1180
+ const url = new URL(test.endpoint);
1181
+ const path = url.pathname + url.search;
1182
+ const testName = `${test.method} ${path} -> ${test.status}`;
1183
+ const testId = generateTestId(testName, gateResult.gate);
1184
+ results.set(testId, {
1185
+ testId,
1186
+ testName,
1187
+ filePath: gateResult.gate,
1188
+ gate: gateResult.gate,
1189
+ success: test.success,
1190
+ durationMs: test.responseTime || 0,
1191
+ errorMessage: test.error,
1192
+ timestamp: timestamp + Math.random(), // Small offset for ordering
1193
+ environment: process.env.NODE_ENV || 'local'
1194
+ });
1195
+ }
1196
+ }
1197
+ else {
1198
+ // Generic adapter format with results array
1199
+ for (const test of adapterResults.results) {
1200
+ const testName = test.name || gateResult.gate;
1201
+ const testId = generateTestId(testName, gateResult.gate);
1202
+ results.set(testId, {
1203
+ testId,
1204
+ testName,
1205
+ filePath: gateResult.gate,
1206
+ gate: gateResult.gate,
1207
+ success: test.passed || test.status === 'passed',
1208
+ durationMs: test.duration || 0,
1209
+ errorType: test.error?.type,
1210
+ errorMessage: test.error?.message,
1211
+ timestamp: timestamp + Math.random(),
1212
+ environment: process.env.NODE_ENV || 'local'
1213
+ });
1214
+ }
1215
+ }
1216
+ }
1217
+ else if (adapterResults?.summary) {
1218
+ // Generic adapter with summary only (no detailed results)
1219
+ const testId = generateTestId(gateResult.gate, gateResult.gate);
1220
+ results.set(testId, {
1221
+ testId,
1222
+ testName: gateResult.gate,
1223
+ filePath: gateResult.gate,
1224
+ gate: gateResult.gate,
1225
+ success: gateResult.success,
1226
+ durationMs: gateResult.duration,
1227
+ errorMessage: gateResult.error,
1228
+ timestamp,
1229
+ environment: process.env.NODE_ENV || 'local'
1230
+ });
1231
+ }
1232
+ else {
1233
+ // Fallback: create single test result from gate
1234
+ const testId = generateTestId(gateResult.gate, gateResult.gate);
1235
+ results.set(testId, {
1236
+ testId,
1237
+ testName: gateResult.gate,
1238
+ filePath: gateResult.gate,
1239
+ gate: gateResult.gate,
1240
+ success: gateResult.success,
1241
+ durationMs: gateResult.duration,
1242
+ errorMessage: gateResult.error,
1243
+ timestamp,
1244
+ environment: process.env.NODE_ENV || 'local'
1245
+ });
1246
+ }
1247
+ return results;
1248
+ }
1249
+ /**
1250
+ * Generate hash of pack configuration
1251
+ */
1252
+ hashPack(pack) {
1253
+ return createHash('sha256')
1254
+ .update(JSON.stringify(pack))
1255
+ .digest('hex')
1256
+ .substring(0, 16);
1257
+ }
1258
+ /**
1259
+ * Get API target (v1 or v2 format)
1260
+ */
1261
+ getTargetApi() {
1262
+ if (this.isPackV2(this.pack)) {
1263
+ // In v2, target is in the gate config
1264
+ const gateConfig = this.pack.gates['api_smoke'] || this.pack.gates['api'];
1265
+ if (gateConfig && gateConfig.config?.baseUrl) {
1266
+ return gateConfig.config;
1267
+ }
1268
+ return undefined;
1269
+ }
1270
+ return this.pack.targets?.api;
1271
+ }
1272
+ /**
1273
+ * Get Web target (v1 or v2 format)
1274
+ */
1275
+ getTargetWeb() {
1276
+ if (this.isPackV2(this.pack)) {
1277
+ // In v2, target is in the gate config
1278
+ const gateConfig = this.pack.gates['ui'] || this.pack.gates['a11y'];
1279
+ if (gateConfig && gateConfig.config?.baseUrl) {
1280
+ return gateConfig.config;
1281
+ }
1282
+ return undefined;
1283
+ }
1284
+ return this.pack.targets?.web;
1285
+ }
1286
+ /**
1287
+ * Get budgets (v1 or v2 format)
1288
+ */
1289
+ getBudgets() {
1290
+ if (this.isPackV2(this.pack)) {
1291
+ // In v2, budgets can be in gate config or global
1292
+ // For now, return undefined - budgets are gate-specific in v2
1293
+ return undefined;
1294
+ }
1295
+ return this.pack.budgets;
1296
+ }
1297
+ /**
1298
+ * Get execution timeout (v1 or v2 format)
1299
+ */
1300
+ getExecutionTimeout() {
1301
+ if (this.isPackV2(this.pack)) {
1302
+ return this.pack.execution?.default_timeout;
1303
+ }
1304
+ return this.pack.execution?.timeout;
1305
+ }
1306
+ /**
1307
+ * Get execution retries (v1 or v2 format)
1308
+ */
1309
+ getExecutionRetries() {
1310
+ if (this.isPackV2(this.pack)) {
1311
+ return this.pack.execution?.default_retries;
1312
+ }
1313
+ return this.pack.execution?.max_retries;
1314
+ }
1315
+ /**
1316
+ * Ensure output directory exists
1317
+ */
1318
+ ensureOutputDir() {
1319
+ if (!existsSync(this.outputDir)) {
1320
+ mkdirSync(this.outputDir, { recursive: true });
1321
+ }
1322
+ }
1323
+ }