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
@@ -1,1536 +0,0 @@
1
- /**
2
- * QA360 Phase 3 Runner
3
- * Orchestrates hooks, adapters, and proof generation
4
- * Supports both Pack v1 and Pack v2 configurations
5
- */
6
-
7
- import { existsSync, writeFileSync, mkdirSync } from 'fs';
8
- import { join, resolve } from 'path';
9
- import { createHash } from 'crypto';
10
- import chalk from 'chalk';
11
- import { PackConfigV1 } from '../types/pack-v1.js';
12
- import { PackConfigV2, AuthConfigV2, GateConfigV2 } from '../types/pack-v2.js';
13
- import { HooksRunner } from '../hooks/runner.js';
14
- import { PlaywrightNativeApiAdapter } from '../adapters/playwright-native-api.js';
15
- import { PlaywrightUiAdapter } from '../adapters/playwright-ui.js';
16
- import { K6PerfAdapter } from '../adapters/k6-perf.js';
17
- import { SemgrepSastAdapter } from '../adapters/semgrep-sast.js';
18
- // v2.2.0 Unit Test Adapters
19
- import { VitestAdapter } from '../adapters/vitest-adapter.js';
20
- import { JestAdapter } from '../adapters/jest-adapter.js';
21
- import { PytestAdapter } from '../adapters/pytest-adapter.js';
22
- // v2.2.0 Data Fixtures
23
- import { FixtureLoader } from '../fixtures/loader.js';
24
- import { FixtureResolver } from '../fixtures/resolver.js';
25
- import { PageObjectLoader } from '../pom/loader.js';
26
- import { SecurityRedactor } from '../security/redactor.js';
27
- import { initializeKeys, sign, KeyPair } from '../proof/signer.js';
28
- import { canonicalize } from '../proof/canonicalize.js';
29
- import { EvidenceVault, RunRecord, GateRecord, FindingRecord } from '../vault/index.js';
30
- import { AuthManager, AuthConfig, AuthCredentials } from '../auth/index.js';
31
- import {
32
- FlakinessDetector,
33
- TestResult as FlakyTestResult,
34
- FlakinessResult,
35
- FlakinessCategory,
36
- formatFlakinessScore,
37
- generateTestId,
38
- DEFAULT_FLAKINESS_OPTIONS
39
- } from '../flakiness/index.js';
40
-
41
- export type PackConfig = PackConfigV1 | PackConfigV2;
42
-
43
- export interface Phase3RunnerOptions {
44
- workingDir: string;
45
- pack: PackConfig;
46
- packDir?: string; // Directory containing the pack file (for resolving fixtures)
47
- outputDir?: string;
48
- /** Enable flakiness detection (runs tests N times consecutively) */
49
- flakyDetect?: boolean;
50
- /** Number of consecutive runs for flakiness detection (default: 3) */
51
- flakyRuns?: number;
52
- }
53
-
54
- export interface GateResult {
55
- gate: string;
56
- success: boolean;
57
- duration: number;
58
- adapter: string;
59
- results: any;
60
- junit?: string;
61
- error?: string;
62
- }
63
-
64
- export interface Phase3RunResult {
65
- success: boolean;
66
- pack: PackConfig;
67
- duration: number;
68
- gates: GateResult[];
69
- hooks: {
70
- beforeAll: any[];
71
- beforeEach: any[];
72
- afterEach: any[];
73
- afterAll: any[];
74
- };
75
- summary: {
76
- total: number;
77
- passed: number;
78
- failed: number;
79
- trustScore: number;
80
- };
81
- /** Flakiness analysis results (if enabled) */
82
- flakiness?: FlakinessResult[];
83
- proofPath?: string;
84
- /** Vault run ID for this execution */
85
- runId?: string;
86
- error?: string;
87
- }
88
-
89
- export class Phase3Runner {
90
- private workingDir: string;
91
- private pack: PackConfig;
92
- private packDir: string; // Directory containing the pack file
93
- private outputDir: string;
94
- private redactor: SecurityRedactor;
95
- private hooksRunner: HooksRunner;
96
- private keyPair?: KeyPair;
97
- private vault?: EvidenceVault;
98
- private authManager: AuthManager;
99
- private authCredentialsCache = new Map<string, AuthCredentials>();
100
- private flakyDetect: boolean;
101
- private flakyRuns: number;
102
- private flakinessDetector: FlakinessDetector;
103
- // v2.2.0 Data Fixtures & POM
104
- private fixtureLoader?: FixtureLoader;
105
- private fixtureResolver?: FixtureResolver;
106
- private pageObjectLoader?: PageObjectLoader;
107
-
108
- constructor(options: Phase3RunnerOptions) {
109
- this.workingDir = options.workingDir;
110
- this.pack = options.pack;
111
- this.packDir = options.packDir || options.workingDir;
112
- this.outputDir = options.outputDir || join(this.workingDir, '.qa360', 'runs');
113
- this.redactor = SecurityRedactor.forLogs();
114
- this.authManager = new AuthManager();
115
- this.flakyDetect = options.flakyDetect || false;
116
- this.flakyRuns = options.flakyRuns || DEFAULT_FLAKINESS_OPTIONS.consecutiveRuns;
117
- this.flakinessDetector = new FlakinessDetector({
118
- consecutiveRuns: this.flakyRuns,
119
- minRuns: 2,
120
- enablePatternDetection: true
121
- });
122
-
123
- // Initialize hooks runner (convert v2 hooks to v1 format if needed)
124
- const hooks = this.isPackV2(options.pack)
125
- ? this.convertV2HooksToV1(options.pack.hooks)
126
- : options.pack.hooks;
127
-
128
- this.hooksRunner = new HooksRunner({
129
- workingDir: this.workingDir,
130
- hooks: hooks || {},
131
- execution: this.isPackV2(options.pack) ? this.convertV2ExecutionToV1(options.pack.execution) : options.pack.execution,
132
- redactor: this.redactor
133
- });
134
-
135
- // Register auth profiles from pack v2
136
- if (this.isPackV2(options.pack) && options.pack.auth?.profiles) {
137
- this.registerAuthProfiles(options.pack.auth.profiles);
138
- }
139
-
140
- // Load data fixtures from pack v2
141
- if (this.isPackV2(options.pack) && options.pack.fixtures && options.pack.fixtures.length > 0) {
142
- this.initializeFixtures(options.pack.fixtures);
143
- }
144
-
145
- // Initialize Page Object Model from pack v2
146
- if (this.isPackV2(options.pack) && options.pack.pageObjects) {
147
- this.initializePageObjects(options.pack.pageObjects);
148
- }
149
- }
150
-
151
- /**
152
- * Initialize Page Object Model from the pack configuration
153
- */
154
- private initializePageObjects(config: { directory?: string; pattern?: string; baseUrl?: string }): void {
155
- try {
156
- const pomDir = config.directory ? resolve(this.packDir, config.directory) : this.packDir;
157
- this.pageObjectLoader = new PageObjectLoader({ cwd: pomDir });
158
- console.log(chalk.gray(` 📄 POM loader initialized for: ${pomDir}`));
159
- } catch (error) {
160
- console.log(chalk.yellow(`⚠️ Failed to initialize POM loader: ${error instanceof Error ? error.message : 'Unknown error'}`));
161
- }
162
- }
163
-
164
- /**
165
- * Load Page Objects before execution
166
- */
167
- private async loadPageObjects(): Promise<void> {
168
- if (!this.pageObjectLoader || !this.isPackV2(this.pack) || !this.pack.pageObjects) {
169
- return;
170
- }
171
-
172
- try {
173
- const pattern = this.pack.pageObjects.pattern || '**/*.page.{ts,js}';
174
- const result = await this.pageObjectLoader.loadFromDirectory(this.packDir, { pattern });
175
- console.log(chalk.green(` ✅ Page Objects loaded: ${result.pagesCount} pages`));
176
- } catch (error) {
177
- console.log(chalk.yellow(`⚠️ Failed to load page objects: ${error instanceof Error ? error.message : 'Unknown error'}`));
178
- }
179
- }
180
-
181
- /**
182
- * Initialize data fixtures from the pack configuration
183
- */
184
- private initializeFixtures(fixturePaths: string[]): void {
185
- try {
186
- this.fixtureLoader = new FixtureLoader(this.packDir);
187
- // Load fixtures synchronously - they're already validated
188
- // We'll load them before execution starts
189
- this.fixtureResolver = new FixtureResolver(this.fixtureLoader, this.packDir);
190
- } catch (error) {
191
- console.log(chalk.yellow(`⚠️ Failed to initialize fixtures: ${error instanceof Error ? error.message : 'Unknown error'}`));
192
- }
193
- }
194
-
195
- /**
196
- * Load fixtures before execution
197
- */
198
- private async loadFixtures(): Promise<void> {
199
- if (!this.fixtureLoader || !this.isPackV2(this.pack) || !this.pack.fixtures) {
200
- return;
201
- }
202
-
203
- try {
204
- await this.fixtureLoader.load(this.pack.fixtures);
205
- console.log(chalk.green(` ✅ Fixtures loaded: ${this.fixtureLoader.getFixtureNames().join(', ')}`));
206
- } catch (error) {
207
- console.log(chalk.yellow(`⚠️ Failed to load fixtures: ${error instanceof Error ? error.message : 'Unknown error'}`));
208
- }
209
- }
210
-
211
- /**
212
- * Resolve fixture references in a configuration object
213
- */
214
- private resolveFixturesInConfig(config: any): any {
215
- if (!this.fixtureResolver || !config) {
216
- return config;
217
- }
218
-
219
- try {
220
- const result = this.fixtureResolver.resolve(config, {
221
- baseDir: this.workingDir,
222
- keepUnresolved: false
223
- });
224
-
225
- if (result.hasFixtures) {
226
- console.log(chalk.gray(` 🔧 Fixtures resolved in config`));
227
- }
228
-
229
- return result.value;
230
- } catch (error) {
231
- console.log(chalk.yellow(`⚠️ Failed to resolve fixtures: ${error instanceof Error ? error.message : 'Unknown error'}`));
232
- return config;
233
- }
234
- }
235
-
236
- /**
237
- * Type guard to check if pack is v2
238
- */
239
- private isPackV2(pack: PackConfig): pack is PackConfigV2 {
240
- return (pack as PackConfigV2).version === 2;
241
- }
242
-
243
- /**
244
- * Register authentication profiles from pack config
245
- */
246
- private registerAuthProfiles(profiles: Record<string, any>): void {
247
- for (const [name, profile] of Object.entries(profiles)) {
248
- // Convert v2 auth profile to auth module format
249
- const authConfig: AuthConfig = {
250
- type: profile.type || 'none',
251
- ...profile.config
252
- };
253
- this.authManager.registerProfile(name, authConfig);
254
- }
255
- }
256
-
257
- /**
258
- * Get auth profile name for a specific gate
259
- */
260
- private getAuthProfileForGate(gateName: string): string | undefined {
261
- if (!this.isPackV2(this.pack) || !this.pack.auth) {
262
- return undefined;
263
- }
264
-
265
- const authConfig = this.pack.auth as AuthConfigV2;
266
-
267
- // Check if gate has specific auth override
268
- const gateConfig = (this.pack.gates as Record<string, GateConfigV2>)[gateName];
269
- if (gateConfig?.auth) {
270
- return gateConfig.auth;
271
- }
272
-
273
- // Use default based on gate type
274
- if (gateName === 'api_smoke' || gateName === 'api') {
275
- return authConfig.api;
276
- }
277
- if (gateName === 'ui' || gateName === 'a11y') {
278
- return authConfig.ui;
279
- }
280
-
281
- return undefined;
282
- }
283
-
284
- /**
285
- * Authenticate and get credentials for a gate
286
- */
287
- private async getCredentialsForGate(gateName: string): Promise<AuthCredentials | undefined> {
288
- const profileName = this.getAuthProfileForGate(gateName);
289
-
290
- if (!profileName) {
291
- return undefined;
292
- }
293
-
294
- // Check cache first
295
- if (this.authCredentialsCache.has(profileName)) {
296
- return this.authCredentialsCache.get(profileName);
297
- }
298
-
299
- // Authenticate
300
- const result = await this.authManager.authenticate(profileName);
301
-
302
- if (result.success && result.credentials) {
303
- this.authCredentialsCache.set(profileName, result.credentials);
304
- return result.credentials;
305
- }
306
-
307
- console.log(chalk.yellow(` ⚠️ Auth failed for profile '${profileName}': ${result.error}`));
308
- return undefined;
309
- }
310
-
311
- /**
312
- * Convert v2 hooks to v1 format
313
- */
314
- private convertV2HooksToV1(hooks?: any): any {
315
- if (!hooks) return undefined;
316
-
317
- // v2 hooks use { type, command, ... } format
318
- // v1 hooks use { run, timeout } format
319
- const converted: any = {
320
- beforeAll: [],
321
- afterAll: [],
322
- beforeEach: [],
323
- afterEach: []
324
- };
325
-
326
- for (const [phase, phaseHooks] of Object.entries(hooks)) {
327
- if (Array.isArray(phaseHooks)) {
328
- converted[phase] = (phaseHooks as any[]).map((h: any) => {
329
- if (h.type === 'run' || h.type === 'script') {
330
- return { run: h.command, timeout: h.timeout, cwd: h.cwd, env: h.env };
331
- }
332
- if (h.type === 'wait_on') {
333
- return { run: `npx wait-on ${h.wait_for?.resource || h.command}`, timeout: h.timeout };
334
- }
335
- if (h.type === 'docker') {
336
- return { run: `docker compose ${h.compose?.command || 'up -d'}`, timeout: h.timeout };
337
- }
338
- return h;
339
- });
340
- }
341
- }
342
-
343
- return converted;
344
- }
345
-
346
- /**
347
- * Convert v2 execution config to v1 format
348
- */
349
- private convertV2ExecutionToV1(execution?: any): any {
350
- if (!execution) return undefined;
351
-
352
- return {
353
- timeout: execution.default_timeout || execution.timeout,
354
- max_retries: execution.default_retries || execution.retries,
355
- on_failure: execution.on_failure || 'continue'
356
- };
357
- }
358
-
359
- /**
360
- * Get gates array from pack (handles v1 and v2)
361
- */
362
- private getGatesArray(): string[] {
363
- if (this.isPackV2(this.pack)) {
364
- return Object.keys(this.pack.gates).filter(gateName => {
365
- const gateConfig = (this.pack.gates as Record<string, GateConfigV2>)[gateName];
366
- return gateConfig?.enabled !== false;
367
- });
368
- }
369
- return (this.pack as PackConfigV1).gates || [];
370
- }
371
-
372
- /**
373
- * Execute complete Phase 3 workflow
374
- */
375
- async run(): Promise<Phase3RunResult> {
376
- const startTime = Date.now();
377
-
378
- const gatesArray = this.getGatesArray();
379
-
380
- console.log(chalk.bold.blue(`\n🚀 QA360 Phase 3 Runner - ${this.pack.name}`));
381
- console.log(chalk.gray(`Gates: ${gatesArray.join(', ')}`));
382
-
383
- try {
384
- // Ensure output directory exists
385
- this.ensureOutputDir();
386
-
387
- // Load data fixtures if configured
388
- await this.loadFixtures();
389
-
390
- // Load page objects if configured
391
- await this.loadPageObjects();
392
-
393
- // Initialize cryptographic keys
394
- console.log(chalk.blue('\n🔑 Initializing Ed25519 keys...'));
395
- this.keyPair = await initializeKeys();
396
- console.log(chalk.green(' ✅ Keys ready'));
397
-
398
- // Initialize Evidence Vault
399
- console.log(chalk.blue('\n🗄️ Initializing Evidence Vault...'));
400
- const vaultDir = join(this.workingDir, '.qa360');
401
- this.vault = await EvidenceVault.open(vaultDir);
402
- console.log(chalk.green(' ✅ Vault ready'));
403
-
404
- // Execute beforeAll hooks
405
- console.log(chalk.blue('\n🔗 Phase 1: Setup Hooks'));
406
- const beforeAllResults = await this.hooksRunner.executeHooks('beforeAll');
407
-
408
- // Check if setup failed and should stop
409
- const setupFailed = beforeAllResults.some(r => !r.success);
410
- if (setupFailed && this.pack.execution?.on_failure === 'stop') {
411
- throw new Error('Setup hooks failed, stopping execution');
412
- }
413
-
414
- // Execute gates
415
- console.log(chalk.blue('\n🎯 Phase 2: Quality Gates'));
416
- const gateResults: GateResult[] = [];
417
-
418
- for (const gate of gatesArray) {
419
- const gateResult = await this.executeGate(gate);
420
- gateResults.push(gateResult);
421
-
422
- // Check if gate failed and should stop
423
- if (!gateResult.success && this.pack.execution?.on_failure === 'stop') {
424
- console.log(chalk.yellow(`🛑 Gate ${gate} failed, stopping execution`));
425
- break;
426
- }
427
- }
428
-
429
- // Flakiness Detection Phase (Vision 2.0)
430
- let flakinessResults: FlakinessResult[] | undefined;
431
- if (this.flakyDetect) {
432
- console.log(chalk.blue(`\n🎲 Phase 2.5: Flakiness Detection (${this.flakyRuns} consecutive runs)`));
433
- flakinessResults = await this.detectFlakiness(gateResults);
434
-
435
- // Display flakiness summary
436
- const unstableCount = flakinessResults.filter(f =>
437
- f.category === FlakinessCategory.UNSTABLE || f.category === FlakinessCategory.SHAKY
438
- ).length;
439
-
440
- if (unstableCount > 0) {
441
- console.log(chalk.yellow(` ⚠️ ${unstableCount} test(s) show flaky behavior`));
442
- } else {
443
- console.log(chalk.green(' ✅ All tests stable - no flakiness detected'));
444
- }
445
- }
446
-
447
- // Execute afterAll hooks
448
- console.log(chalk.blue('\n🔗 Phase 3: Cleanup Hooks'));
449
- const afterAllResults = await this.hooksRunner.executeHooks('afterAll');
450
-
451
- // Calculate results
452
- const duration = Date.now() - startTime;
453
- const summary = this.calculateSummary(gateResults);
454
- const success = summary.failed === 0;
455
-
456
- // Generate proof
457
- console.log(chalk.blue('\n📋 Phase 4: Proof Generation'));
458
- const proofPath = await this.generateProof({
459
- success,
460
- pack: this.pack,
461
- duration,
462
- gates: gateResults,
463
- hooks: {
464
- beforeAll: beforeAllResults,
465
- beforeEach: [],
466
- afterEach: [],
467
- afterAll: afterAllResults
468
- },
469
- summary
470
- });
471
-
472
- // Save to Evidence Vault
473
- console.log(chalk.blue('\n💾 Phase 5: Evidence Storage'));
474
- const proofRunId = proofPath.split('/').pop()?.replace('-proof.json', '') || 'unknown';
475
- const vaultRunId = await this.saveToVault(proofRunId, {
476
- success,
477
- pack: this.pack,
478
- duration,
479
- gates: gateResults,
480
- hooks: {
481
- beforeAll: beforeAllResults,
482
- beforeEach: [],
483
- afterEach: [],
484
- afterAll: afterAllResults
485
- },
486
- summary,
487
- proofPath
488
- }, proofPath, flakinessResults, startTime);
489
-
490
- // Final summary
491
- console.log(chalk.blue('\n📊 Execution Summary'));
492
- console.log(` Duration: ${duration}ms`);
493
- console.log(` Gates: ${summary.passed}/${summary.total} passed`);
494
- console.log(` Trust Score: ${summary.trustScore}%`);
495
- console.log(` Proof: ${proofPath}`);
496
-
497
- // Display flakiness details if enabled
498
- if (flakinessResults && flakinessResults.length > 0) {
499
- console.log(chalk.blue('\n🎲 Flakiness Scores:'));
500
- for (const f of flakinessResults) {
501
- const scoreFormatted = formatFlakinessScore(f.score);
502
- const categoryMeta = {
503
- [FlakinessCategory.LEGENDARY]: { emoji: '🟢', color: chalk.green },
504
- [FlakinessCategory.SOLID]: { emoji: '🟢', color: chalk.green },
505
- [FlakinessCategory.GOOD]: { emoji: '🟡', color: chalk.yellow },
506
- [FlakinessCategory.SHAKY]: { emoji: '🟠', color: chalk.hex('#F97316') },
507
- [FlakinessCategory.UNSTABLE]: { emoji: '🔴', color: chalk.red }
508
- }[f.category];
509
-
510
- console.log(` ${categoryMeta.color(`${f.testName}: ${scoreFormatted}`)} (${f.successfulRuns}/${f.totalRuns} passes)`);
511
- if (f.suggestedFix) {
512
- console.log(chalk.gray(` 💡 ${f.suggestedFix}`));
513
- }
514
- }
515
- }
516
-
517
- if (success) {
518
- console.log(chalk.green('\n✅ All quality gates passed!'));
519
- } else {
520
- console.log(chalk.red(`\n❌ ${summary.failed} quality gate(s) failed`));
521
- }
522
-
523
- return {
524
- success,
525
- pack: this.pack,
526
- duration,
527
- gates: gateResults,
528
- hooks: {
529
- beforeAll: beforeAllResults,
530
- beforeEach: [],
531
- afterEach: [],
532
- afterAll: afterAllResults
533
- },
534
- summary,
535
- flakiness: flakinessResults,
536
- proofPath,
537
- runId: vaultRunId
538
- };
539
-
540
- } catch (error) {
541
- const duration = Date.now() - startTime;
542
-
543
- // Ensure cleanup even on error
544
- try {
545
- await this.hooksRunner.executeHooks('afterAll');
546
- } catch {
547
- // Ignore cleanup errors
548
- }
549
-
550
- return {
551
- success: false,
552
- pack: this.pack,
553
- duration,
554
- gates: [],
555
- hooks: { beforeAll: [], beforeEach: [], afterEach: [], afterAll: [] },
556
- summary: { total: 0, passed: 0, failed: 0, trustScore: 0 },
557
- error: this.redactor.redact(error instanceof Error ? error.message : 'Unknown error')
558
- };
559
- }
560
- }
561
-
562
- /**
563
- * Execute a single quality gate
564
- */
565
- private async executeGate(gate: string): Promise<GateResult> {
566
- const startTime = Date.now();
567
-
568
- console.log(chalk.cyan(`\n 🎯 Gate: ${gate}`));
569
-
570
- try {
571
- let result: any;
572
- let adapter: string;
573
-
574
- // Check if this is a v2 pack with dynamic gate configuration
575
- if (this.isPackV2(this.pack)) {
576
- const gateConfig = (this.pack.gates as Record<string, any>)[gate];
577
- if (gateConfig) {
578
- return await this.executeDynamicGate(gate, gateConfig);
579
- }
580
- }
581
-
582
- // Legacy v1 gates or predefined gates
583
- switch (gate) {
584
- case 'api_smoke':
585
- adapter = 'playwright-native-api';
586
- result = await this.runApiSmokeGate();
587
- break;
588
-
589
- case 'ui':
590
- adapter = 'playwright-ui';
591
- result = await this.runUiGate();
592
- break;
593
-
594
- case 'a11y':
595
- adapter = 'playwright-ui';
596
- result = await this.runA11yGate();
597
- break;
598
-
599
- case 'perf':
600
- adapter = 'k6';
601
- result = await this.runPerfGate();
602
- break;
603
-
604
- case 'sast':
605
- adapter = 'semgrep';
606
- result = await this.runSastGate();
607
- break;
608
-
609
- case 'dast':
610
- adapter = 'zap';
611
- result = await this.runDastGate();
612
- break;
613
-
614
- default:
615
- throw new Error(`Unknown gate: ${gate}`);
616
- }
617
-
618
- const duration = Date.now() - startTime;
619
-
620
- if (result.success) {
621
- console.log(chalk.green(` ✅ ${gate} passed (${duration}ms)`));
622
- } else {
623
- console.log(chalk.red(` ❌ ${gate} failed (${duration}ms)`));
624
- if (result.error) {
625
- console.log(chalk.red(` 🔍 ${result.error}`));
626
- }
627
- }
628
-
629
- return {
630
- gate,
631
- success: result.success,
632
- duration,
633
- adapter,
634
- results: result,
635
- junit: result.junit,
636
- error: result.error
637
- };
638
-
639
- } catch (error) {
640
- const duration = Date.now() - startTime;
641
- const errorMessage = this.redactor.redact(error instanceof Error ? error.message : 'Unknown error');
642
-
643
- console.log(chalk.red(` 💥 ${gate} crashed (${duration}ms): ${errorMessage}`));
644
-
645
- return {
646
- gate,
647
- success: false,
648
- duration,
649
- adapter: 'unknown',
650
- results: null,
651
- error: errorMessage
652
- };
653
- }
654
- }
655
-
656
- /**
657
- * Execute a dynamic v2 gate
658
- */
659
- private async executeDynamicGate(gateName: string, gateConfig: any): Promise<GateResult> {
660
- const startTime = Date.now();
661
- const adapterType = gateConfig.adapter || gateConfig.type;
662
-
663
- if (!adapterType) {
664
- throw new Error(`Gate '${gateName}' must specify an adapter`);
665
- }
666
-
667
- // Resolve fixtures in gate configuration
668
- const resolvedGateConfig = this.resolveFixturesInConfig(gateConfig);
669
-
670
- // Get auth credentials for this gate
671
- const credentials = await this.getCredentialsForGate(gateName);
672
-
673
- // Map adapter type to implementation
674
- let result: GateResult;
675
- switch (adapterType) {
676
- case 'playwright-api':
677
- result = await this.executePlaywrightApiGate(gateName, resolvedGateConfig, credentials);
678
- break;
679
-
680
- case 'playwright-ui':
681
- result = await this.executePlaywrightUiGate(gateName, resolvedGateConfig, credentials);
682
- break;
683
-
684
- case 'k6':
685
- case 'k6-perf':
686
- result = await this.executeK6PerfGate(gateName, resolvedGateConfig);
687
- break;
688
-
689
- case 'semgrep':
690
- case 'sast':
691
- result = await this.executeSemgrepSastGate(gateName, resolvedGateConfig);
692
- break;
693
-
694
- // v2.2.0 Unit Test Adapters
695
- case 'vitest':
696
- result = await this.executeVitestGate(gateName, resolvedGateConfig);
697
- break;
698
-
699
- case 'jest':
700
- result = await this.executeJestGate(gateName, resolvedGateConfig);
701
- break;
702
-
703
- case 'pytest':
704
- result = await this.executePytestGate(gateName, resolvedGateConfig);
705
- break;
706
-
707
- default:
708
- throw new Error(`Unsupported adapter: '${adapterType}' for gate '${gateName}'`);
709
- }
710
-
711
- // Set duration
712
- result.duration = Date.now() - startTime;
713
-
714
- // Log result
715
- if (result.success) {
716
- console.log(chalk.green(` ✅ ${gateName} passed (${result.duration}ms)`));
717
- } else {
718
- console.log(chalk.red(` ❌ ${gateName} failed (${result.duration}ms)`));
719
- if (result.error) {
720
- console.log(chalk.red(` 🔍 ${result.error}`));
721
- }
722
- }
723
-
724
- return result;
725
- }
726
-
727
- /**
728
- * Execute Playwright API gate with v2 config
729
- * Uses PlaywrightNativeApiAdapter for zero-overhead HTTP testing
730
- */
731
- private async executePlaywrightApiGate(gateName: string, gateConfig: any, credentials?: any): Promise<GateResult> {
732
- const { PlaywrightNativeApiAdapter } = await import('../adapters/playwright-native-api.js');
733
- const adapter = new PlaywrightNativeApiAdapter();
734
-
735
- // Transform v2 config to adapter format
736
- const gateConfigData = gateConfig.config || {};
737
- const gateOptions = gateConfig.options || {};
738
-
739
- const config = {
740
- target: {
741
- baseUrl: gateConfigData.baseUrl,
742
- smoke: gateConfigData.smoke
743
- },
744
- budgets: gateConfigData.budgets,
745
- timeout: gateOptions.timeout || gateConfigData.timeout,
746
- retries: gateOptions.retries || gateConfigData.retries,
747
- auth: credentials
748
- };
749
-
750
- const result = await adapter.runSmokeTests(config);
751
- return {
752
- gate: gateName,
753
- success: result.success,
754
- duration: 0, // Will be set by caller
755
- adapter: 'playwright-native-api',
756
- results: result,
757
- junit: result.junit
758
- };
759
- }
760
-
761
- /**
762
- * Execute Playwright UI gate with v2 config
763
- */
764
- private async executePlaywrightUiGate(gateName: string, gateConfig: any, credentials?: any): Promise<GateResult> {
765
- const { PlaywrightUiAdapter } = await import('../adapters/playwright-ui.js');
766
- const adapter = new PlaywrightUiAdapter();
767
-
768
- // Transform v2 config to adapter format
769
- // v2: { baseUrl, pages: [{ url: '/', expectedElements: [...] }] }
770
- // adapter expects: { target: { baseUrl, pages: ['https://.../'] } }
771
- const gateConfigData = gateConfig.config || {};
772
- const gateOptions = gateConfig.options || {};
773
-
774
- // Transform page objects to full URLs
775
- // v2 pages format: [{ url: '/', expectedElements: [...] }] or ['/', '/about']
776
- const rawPages = gateConfigData.pages;
777
- let pages: string[] | undefined;
778
- if (rawPages && Array.isArray(rawPages) && rawPages.length > 0) {
779
- const baseUrl = gateConfigData.baseUrl || '';
780
- pages = rawPages.map((p: any) => {
781
- if (typeof p === 'string') {
782
- // Already a URL string - make it absolute if relative
783
- return p.startsWith('http') ? p : `${baseUrl.replace(/\/$/, '')}${p}`;
784
- } else if (p && typeof p === 'object' && p.url) {
785
- // Page object { url: '/', ... } - convert to full URL
786
- const url = p.url;
787
- return url.startsWith('http') ? url : `${baseUrl.replace(/\/$/, '')}${url}`;
788
- }
789
- return p;
790
- });
791
- } else if (gateConfigData.baseUrl) {
792
- pages = [gateConfigData.baseUrl];
793
- }
794
-
795
- const config = {
796
- target: {
797
- baseUrl: gateConfigData.baseUrl,
798
- pages: pages
799
- },
800
- budgets: gateConfigData.budgets,
801
- timeout: gateOptions.timeout || gateConfigData.timeout,
802
- auth: credentials,
803
- // Playwright++ features
804
- artifacts: gateConfigData.artifacts,
805
- htmlReport: gateConfigData.htmlReport,
806
- bail: gateConfigData.bail
807
- };
808
-
809
- const result = await adapter.runSmokeTests(config);
810
- return {
811
- gate: gateName,
812
- success: result.success,
813
- duration: 0, // Will be set by caller
814
- adapter: 'playwright-ui',
815
- results: result,
816
- junit: result.junit
817
- };
818
- }
819
-
820
- /**
821
- * Execute K6 Performance gate with v2 config
822
- */
823
- private async executeK6PerfGate(gateName: string, gateConfig: any): Promise<GateResult> {
824
- const { K6PerfAdapter } = await import('../adapters/k6-perf.js');
825
- const adapter = new K6PerfAdapter(this.workingDir);
826
-
827
- const config = {
828
- baseUrl: gateConfig.config?.baseUrl,
829
- ...gateConfig.config
830
- };
831
-
832
- const result = await adapter.runPerfTest(config);
833
- return {
834
- gate: gateName,
835
- success: result.success,
836
- duration: 0,
837
- adapter: 'k6',
838
- results: result,
839
- junit: result.junit
840
- };
841
- }
842
-
843
- /**
844
- * Execute Semgrep SAST gate with v2 config
845
- */
846
- private async executeSemgrepSastGate(gateName: string, gateConfig: any): Promise<GateResult> {
847
- const { SemgrepSastAdapter } = await import('../adapters/semgrep-sast.js');
848
- const adapter = new SemgrepSastAdapter();
849
-
850
- const config = {
851
- workingDir: this.workingDir,
852
- ...gateConfig.config
853
- };
854
-
855
- const result = await adapter.runSastScan(config);
856
- return {
857
- gate: gateName,
858
- success: result.success,
859
- duration: 0,
860
- adapter: 'semgrep',
861
- results: result,
862
- junit: result.junit
863
- };
864
- }
865
-
866
- /**
867
- * Execute Vitest unit tests gate (v2.2.0)
868
- */
869
- private async executeVitestGate(gateName: string, gateConfig: any): Promise<GateResult> {
870
- const adapter = new VitestAdapter(this.workingDir);
871
-
872
- const config: any = {
873
- cwd: this.workingDir,
874
- ...gateConfig.config
875
- };
876
-
877
- const result = await adapter.execute(config);
878
-
879
- return {
880
- gate: gateName,
881
- success: result.success,
882
- duration: result.duration,
883
- adapter: 'vitest',
884
- results: {
885
- total: result.total,
886
- passed: result.passed,
887
- failed: result.failed,
888
- skipped: result.skipped,
889
- tests: result.tests.map(t => ({
890
- name: t.name,
891
- status: t.status,
892
- duration: t.duration,
893
- error: t.error
894
- }))
895
- },
896
- junit: this.buildJunitFromVitest(result)
897
- };
898
- }
899
-
900
- /**
901
- * Execute Jest unit tests gate (v2.2.0)
902
- */
903
- private async executeJestGate(gateName: string, gateConfig: any): Promise<GateResult> {
904
- const adapter = new JestAdapter(this.workingDir);
905
-
906
- const config: any = {
907
- cwd: this.workingDir,
908
- ...gateConfig.config
909
- };
910
-
911
- const result = await adapter.execute(config);
912
-
913
- return {
914
- gate: gateName,
915
- success: result.success,
916
- duration: result.duration,
917
- adapter: 'jest',
918
- results: {
919
- total: result.total,
920
- passed: result.passed,
921
- failed: result.failed,
922
- skipped: result.skipped + result.pending,
923
- tests: result.tests.map(t => ({
924
- name: t.name,
925
- status: t.status,
926
- duration: t.duration,
927
- error: t.error
928
- }))
929
- },
930
- junit: this.buildJunitFromJest(result)
931
- };
932
- }
933
-
934
- /**
935
- * Execute Pytest unit tests gate (v2.2.0)
936
- */
937
- private async executePytestGate(gateName: string, gateConfig: any): Promise<GateResult> {
938
- const adapter = new PytestAdapter(this.workingDir);
939
-
940
- const config: any = {
941
- cwd: this.workingDir,
942
- ...gateConfig.config
943
- };
944
-
945
- const result = await adapter.execute(config);
946
-
947
- return {
948
- gate: gateName,
949
- success: result.success,
950
- duration: result.duration,
951
- adapter: 'pytest',
952
- results: {
953
- total: result.total,
954
- passed: result.passed,
955
- failed: result.failed,
956
- skipped: result.skipped,
957
- tests: result.tests.map(t => ({
958
- name: t.name,
959
- status: t.status,
960
- duration: t.duration,
961
- error: t.error
962
- }))
963
- },
964
- junit: this.buildJunitFromPytest(result)
965
- };
966
- }
967
-
968
- /**
969
- * Build JUnit format from Vitest results
970
- */
971
- private buildJunitFromVitest(result: any): any {
972
- // Convert adapter result to JUnit-like format
973
- return {
974
- testsuites: [{
975
- name: 'vitest',
976
- tests: result.total,
977
- failures: result.failed,
978
- skipped: result.skipped,
979
- time: result.duration / 1000,
980
- testcases: result.tests.map((t: any) => ({
981
- name: t.name,
982
- classname: t.file,
983
- time: t.duration / 1000,
984
- failure: t.error ? { message: t.error } : undefined,
985
- skipped: t.status === 'skipped' ? { message: 'Skipped' } : undefined
986
- }))
987
- }]
988
- };
989
- }
990
-
991
- /**
992
- * Build JUnit format from Jest results
993
- */
994
- private buildJunitFromJest(result: any): any {
995
- return {
996
- testsuites: [{
997
- name: 'jest',
998
- tests: result.total,
999
- failures: result.failed,
1000
- skipped: result.pending,
1001
- time: result.duration / 1000,
1002
- testcases: result.tests.map((t: any) => ({
1003
- name: t.name,
1004
- time: t.duration / 1000,
1005
- failure: t.error ? { message: t.error } : undefined,
1006
- skipped: t.status === 'pending' || t.status === 'skipped' ? { message: 'Skipped' } : undefined
1007
- }))
1008
- }]
1009
- };
1010
- }
1011
-
1012
- /**
1013
- * Build JUnit format from Pytest results
1014
- */
1015
- private buildJunitFromPytest(result: any): any {
1016
- return {
1017
- testsuites: [{
1018
- name: 'pytest',
1019
- tests: result.total,
1020
- failures: result.failed,
1021
- skipped: result.skipped,
1022
- time: result.duration / 1000,
1023
- testcases: result.tests.map((t: any) => ({
1024
- name: t.name,
1025
- classname: t.file,
1026
- time: t.duration / 1000,
1027
- failure: t.error ? { message: t.error } : undefined,
1028
- skipped: t.status === 'skipped' ? { message: 'Skipped' } : undefined
1029
- }))
1030
- }]
1031
- };
1032
- }
1033
-
1034
- /**
1035
- * Run API smoke gate
1036
- * Uses PlaywrightNativeApiAdapter for zero-overhead HTTP testing
1037
- */
1038
- private async runApiSmokeGate() {
1039
- const target = this.getTargetApi();
1040
- if (!target) {
1041
- throw new Error('API smoke gate requires targets.api configuration or gate config with baseUrl');
1042
- }
1043
-
1044
- const credentials = await this.getCredentialsForGate('api_smoke');
1045
-
1046
- const adapter = new PlaywrightNativeApiAdapter();
1047
- return await adapter.runSmokeTests({
1048
- target,
1049
- budgets: this.getBudgets(),
1050
- timeout: this.getExecutionTimeout() || 10000,
1051
- retries: this.getExecutionRetries() || 1,
1052
- auth: credentials
1053
- });
1054
- }
1055
-
1056
- /**
1057
- * Run UI gate (includes basic accessibility)
1058
- */
1059
- private async runUiGate() {
1060
- const target = this.getTargetWeb();
1061
- if (!target) {
1062
- throw new Error('UI gate requires targets.web configuration or gate config with baseUrl');
1063
- }
1064
-
1065
- const credentials = await this.getCredentialsForGate('ui');
1066
-
1067
- const adapter = new PlaywrightUiAdapter();
1068
- return await adapter.runSmokeTests({
1069
- target,
1070
- budgets: this.getBudgets(),
1071
- timeout: this.getExecutionTimeout() || 30000,
1072
- auth: credentials
1073
- });
1074
- }
1075
-
1076
- /**
1077
- * Run A11y gate (focused accessibility testing)
1078
- */
1079
- private async runA11yGate() {
1080
- // Same as UI gate but focused on accessibility
1081
- return await this.runUiGate();
1082
- }
1083
-
1084
- /**
1085
- * Run performance gate
1086
- */
1087
- private async runPerfGate() {
1088
- const baseUrl = (this.pack as PackConfigV1).targets?.web?.baseUrl || (this.pack as PackConfigV1).targets?.api?.baseUrl;
1089
- if (!baseUrl) {
1090
- throw new Error('Performance gate requires web or api target');
1091
- }
1092
-
1093
- const adapter = new K6PerfAdapter(this.workingDir);
1094
- return await adapter.runPerfTest({
1095
- baseUrl,
1096
- budgets: (this.pack as PackConfigV1).budgets,
1097
- duration: '30s',
1098
- vus: 5,
1099
- timeout: 120000
1100
- });
1101
- }
1102
-
1103
- /**
1104
- * Run SAST gate
1105
- */
1106
- private async runSastGate() {
1107
- const adapter = new SemgrepSastAdapter();
1108
- return await adapter.runSastScan({
1109
- workingDir: this.workingDir,
1110
- security: (this.pack as PackConfigV1).security,
1111
- rules: ['auto'],
1112
- paths: ['src/', 'lib/', '.'],
1113
- timeout: 120000
1114
- });
1115
- }
1116
-
1117
- /**
1118
- * Run DAST gate (mock implementation)
1119
- */
1120
- private async runDastGate() {
1121
- // Mock DAST implementation for Phase 3
1122
- console.log(chalk.yellow(' ⚠️ DAST gate: Mock implementation (ZAP integration in Phase 4)'));
1123
-
1124
- return {
1125
- success: true,
1126
- findings: [],
1127
- summary: { total: 0, high: 0, medium: 0, low: 0 },
1128
- junit: `<?xml version="1.0" encoding="UTF-8"?>
1129
- <testsuite name="DAST Mock" tests="1" failures="0" time="0">
1130
- <testcase name="Mock DAST Scan" time="0"></testcase>
1131
- </testsuite>`
1132
- };
1133
- }
1134
-
1135
- /**
1136
- * Calculate execution summary
1137
- */
1138
- private calculateSummary(gateResults: GateResult[]): Phase3RunResult['summary'] {
1139
- const total = gateResults.length;
1140
- const passed = gateResults.filter(g => g.success).length;
1141
- const failed = total - passed;
1142
-
1143
- // Calculate trust score (weighted by gate importance)
1144
- const gateWeights: Record<string, number> = {
1145
- 'api_smoke': 20,
1146
- 'ui': 15,
1147
- 'perf': 15,
1148
- 'sast': 20,
1149
- 'dast': 20,
1150
- 'a11y': 10
1151
- };
1152
-
1153
- let totalWeight = 0;
1154
- let passedWeight = 0;
1155
-
1156
- for (const gate of gateResults) {
1157
- const weight = gateWeights[gate.gate] || 10;
1158
- totalWeight += weight;
1159
- if (gate.success) {
1160
- passedWeight += weight;
1161
- }
1162
- }
1163
-
1164
- const trustScore = totalWeight > 0 ? Math.round((passedWeight / totalWeight) * 100) : 0;
1165
-
1166
- return { total, passed, failed, trustScore };
1167
- }
1168
-
1169
- /**
1170
- * Generate cryptographically signed proof document
1171
- */
1172
- private async generateProof(result: Phase3RunResult): Promise<string> {
1173
- const timestamp = new Date().toISOString();
1174
- const runId = `run-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
1175
-
1176
- // Build proof payload (without signature)
1177
- const proofPayload = {
1178
- version: '3.0.0',
1179
- runId,
1180
- timestamp,
1181
- pack: {
1182
- name: result.pack.name,
1183
- version: result.pack.version,
1184
- gates: result.pack.gates
1185
- },
1186
- execution: {
1187
- duration: result.duration,
1188
- success: result.success,
1189
- trustScore: result.summary.trustScore
1190
- },
1191
- gates: result.gates.map(g => {
1192
- const gateObj: any = {
1193
- gate: g.gate,
1194
- adapter: g.adapter,
1195
- success: g.success,
1196
- duration: g.duration
1197
- };
1198
- // Only include error if it exists (avoid undefined fields)
1199
- if (g.error !== undefined) {
1200
- gateObj.error = g.error;
1201
- }
1202
- return gateObj;
1203
- }),
1204
- hooks: {
1205
- beforeAll: result.hooks.beforeAll.length,
1206
- afterAll: result.hooks.afterAll.length
1207
- }
1208
- };
1209
-
1210
- // Canonicalize the payload for signing (must match verification: canonical + newline)
1211
- const canonicalPayload = canonicalize(proofPayload) + '\n';
1212
-
1213
- // Sign with Ed25519
1214
- let signatureValue: string;
1215
- let algorithm: string;
1216
- let publicKeyB64: string;
1217
-
1218
- if (this.keyPair) {
1219
- signatureValue = sign(canonicalPayload, this.keyPair.secretKey);
1220
- algorithm = 'ed25519';
1221
- publicKeyB64 = Buffer.from(this.keyPair.publicKey).toString('base64');
1222
- console.log(chalk.green(' 🔏 Proof signed with Ed25519'));
1223
- } else {
1224
- signatureValue = `unsigned-${runId}`;
1225
- algorithm = 'none';
1226
- publicKeyB64 = '';
1227
- console.log(chalk.yellow(' ⚠️ Proof unsigned (no keys available)'));
1228
- }
1229
-
1230
- // Build complete proof with signature
1231
- const proof = {
1232
- ...proofPayload,
1233
- signature: {
1234
- algorithm,
1235
- publicKey: publicKeyB64,
1236
- value: signatureValue,
1237
- timestamp
1238
- }
1239
- };
1240
-
1241
- // Save proof
1242
- const proofPath = join(this.outputDir, `${runId}-proof.json`);
1243
- writeFileSync(proofPath, JSON.stringify(proof, null, 2));
1244
-
1245
- return proofPath;
1246
- }
1247
-
1248
- /**
1249
- * Save run results to Evidence Vault
1250
- * @returns The vault run ID
1251
- */
1252
- private async saveToVault(
1253
- runId: string,
1254
- result: Phase3RunResult,
1255
- proofPath: string,
1256
- flakinessResults?: FlakinessResult[],
1257
- startTime?: number
1258
- ): Promise<string | undefined> {
1259
- if (!this.vault) {
1260
- console.log(chalk.yellow(' ⚠️ Vault not initialized, skipping storage'));
1261
- return undefined;
1262
- }
1263
-
1264
- try {
1265
- // Begin run in vault (returns actual runId used)
1266
- // Use startTime if provided to correctly calculate duration
1267
- const { runId: vaultRunId } = await this.vault.beginRun({
1268
- pack_path: `${(this.pack as any).name || 'pack'}.yaml`,
1269
- pack_hash: this.hashPack(result.pack),
1270
- started_at: startTime // Use actual run start time for accurate duration
1271
- });
1272
-
1273
- // Finish run with final status
1274
- await this.vault.finishRun(vaultRunId, {
1275
- status: result.success ? 'passed' : 'failed',
1276
- trust_score: result.summary.trustScore,
1277
- signature: this.keyPair ? 'ed25519-signed' : undefined
1278
- });
1279
-
1280
- // Record gate executions
1281
- for (const gate of result.gates) {
1282
- await this.vault.recordGate(vaultRunId, {
1283
- name: gate.gate,
1284
- status: gate.success ? 'passed' : 'failed',
1285
- duration_ms: gate.duration,
1286
- metrics_json: JSON.stringify(gate.results?.summary || {})
1287
- });
1288
-
1289
- // Record finding if gate has error
1290
- if (gate.error) {
1291
- await this.vault.recordFinding(vaultRunId, {
1292
- gate: gate.gate,
1293
- severity: 'high',
1294
- rule: 'gate-failure',
1295
- message: gate.error
1296
- });
1297
- }
1298
- }
1299
-
1300
- // Record flakiness results if available
1301
- if (flakinessResults && flakinessResults.length > 0) {
1302
- for (const flaky of flakinessResults) {
1303
- // Record unstable/shaky tests as findings
1304
- if (flaky.category === FlakinessCategory.UNSTABLE || flaky.category === FlakinessCategory.SHAKY) {
1305
- await this.vault.recordFinding(vaultRunId, {
1306
- gate: flaky.gate,
1307
- severity: flaky.category === FlakinessCategory.UNSTABLE ? 'high' : 'medium',
1308
- rule: 'flaky-test-detected',
1309
- message: `Test "${flaky.testName}" is ${flaky.category}: ${flaky.score}% reliability (${flaky.successfulRuns}/${flaky.totalRuns} passes)`
1310
- });
1311
- }
1312
- }
1313
- console.log(chalk.green(` 💾 ${flakinessResults.length} flakiness analysis(es) saved`));
1314
- }
1315
-
1316
- console.log(chalk.green(' 💾 Run saved to Evidence Vault'));
1317
- return vaultRunId;
1318
-
1319
- } catch (error) {
1320
- console.log(chalk.yellow(` ⚠️ Failed to save to vault: ${error}`));
1321
- return undefined;
1322
- }
1323
- }
1324
-
1325
- /**
1326
- * Detect flakiness by running tests multiple times consecutively
1327
- * @param gateResults Original gate results from first run
1328
- * @returns Flakiness analysis results
1329
- */
1330
- private async detectFlakiness(gateResults: GateResult[]): Promise<FlakinessResult[]> {
1331
- const flakinessMap = new Map<string, FlakyTestResult[]>();
1332
- const timestamp = Date.now();
1333
-
1334
- // First, collect results from the initial run
1335
- for (const gateResult of gateResults) {
1336
- for (const [testId, testResult] of this.extractTestResults(gateResult, timestamp)) {
1337
- if (!flakinessMap.has(testId)) {
1338
- flakinessMap.set(testId, []);
1339
- }
1340
- flakinessMap.get(testId)!.push(testResult);
1341
- }
1342
- }
1343
-
1344
- // Run additional consecutive runs
1345
- for (let run = 1; run < this.flakyRuns; run++) {
1346
- console.log(chalk.gray(` 🔄 Consecutive run ${run + 1}/${this.flakyRuns}...`));
1347
-
1348
- for (const gateResult of gateResults) {
1349
- // Re-run all gates to detect flakiness
1350
- try {
1351
- const retryResult = await this.executeGate(gateResult.gate);
1352
-
1353
- // Extract and store test results
1354
- for (const [testId, testResult] of this.extractTestResults(retryResult, timestamp)) {
1355
- if (!flakinessMap.has(testId)) {
1356
- flakinessMap.set(testId, []);
1357
- }
1358
- flakinessMap.get(testId)!.push(testResult);
1359
- }
1360
- } catch (error) {
1361
- console.log(chalk.yellow(` ⚠️ Failed to re-run ${gateResult.gate}: ${error}`));
1362
- }
1363
- }
1364
- }
1365
-
1366
- // Analyze all collected results
1367
- return this.flakinessDetector.analyzeAll(flakinessMap);
1368
- }
1369
-
1370
- /**
1371
- * Extract test results from a gate result
1372
- * Returns a map of testId to TestResult for flakiness tracking
1373
- */
1374
- private extractTestResults(gateResult: GateResult, timestamp: number): Map<string, FlakyTestResult> {
1375
- const results = new Map<string, FlakyTestResult>();
1376
-
1377
- // Extract test results from adapter output
1378
- const adapterResults = gateResult.results;
1379
-
1380
- if (adapterResults?.results && Array.isArray(adapterResults.results)) {
1381
- // Check for Playwright Native API adapter format
1382
- const firstResult = adapterResults.results[0];
1383
-
1384
- if (firstResult && 'endpoint' in firstResult && 'method' in firstResult) {
1385
- // PlaywrightNativeApiAdapter format: { endpoint, method, status, success, error, ... }
1386
- for (const test of adapterResults.results as Array<{endpoint: string; method: string; status: number; success: boolean; error?: string; responseTime?: number}>) {
1387
- // Extract just the path from full URL for cleaner test names
1388
- const url = new URL(test.endpoint);
1389
- const path = url.pathname + url.search;
1390
- const testName = `${test.method} ${path} -> ${test.status}`;
1391
- const testId = generateTestId(testName, gateResult.gate);
1392
- results.set(testId, {
1393
- testId,
1394
- testName,
1395
- filePath: gateResult.gate,
1396
- gate: gateResult.gate,
1397
- success: test.success,
1398
- durationMs: test.responseTime || 0,
1399
- errorMessage: test.error,
1400
- timestamp: timestamp + Math.random(), // Small offset for ordering
1401
- environment: process.env.NODE_ENV || 'local'
1402
- });
1403
- }
1404
- } else {
1405
- // Generic adapter format with results array
1406
- for (const test of adapterResults.results as Array<{name?: string; passed?: boolean; status?: string; duration?: number; error?: {message?: string; type?: string}}>) {
1407
- const testName = test.name || gateResult.gate;
1408
- const testId = generateTestId(testName, gateResult.gate);
1409
- results.set(testId, {
1410
- testId,
1411
- testName,
1412
- filePath: gateResult.gate,
1413
- gate: gateResult.gate,
1414
- success: test.passed || test.status === 'passed',
1415
- durationMs: test.duration || 0,
1416
- errorType: test.error?.type,
1417
- errorMessage: test.error?.message,
1418
- timestamp: timestamp + Math.random(),
1419
- environment: process.env.NODE_ENV || 'local'
1420
- });
1421
- }
1422
- }
1423
- } else if (adapterResults?.summary) {
1424
- // Generic adapter with summary only (no detailed results)
1425
- const testId = generateTestId(gateResult.gate, gateResult.gate);
1426
- results.set(testId, {
1427
- testId,
1428
- testName: gateResult.gate,
1429
- filePath: gateResult.gate,
1430
- gate: gateResult.gate,
1431
- success: gateResult.success,
1432
- durationMs: gateResult.duration,
1433
- errorMessage: gateResult.error,
1434
- timestamp,
1435
- environment: process.env.NODE_ENV || 'local'
1436
- });
1437
- } else {
1438
- // Fallback: create single test result from gate
1439
- const testId = generateTestId(gateResult.gate, gateResult.gate);
1440
- results.set(testId, {
1441
- testId,
1442
- testName: gateResult.gate,
1443
- filePath: gateResult.gate,
1444
- gate: gateResult.gate,
1445
- success: gateResult.success,
1446
- durationMs: gateResult.duration,
1447
- errorMessage: gateResult.error,
1448
- timestamp,
1449
- environment: process.env.NODE_ENV || 'local'
1450
- });
1451
- }
1452
-
1453
- return results;
1454
- }
1455
-
1456
- /**
1457
- * Generate hash of pack configuration
1458
- */
1459
- private hashPack(pack: PackConfig): string {
1460
- return createHash('sha256')
1461
- .update(JSON.stringify(pack))
1462
- .digest('hex')
1463
- .substring(0, 16);
1464
- }
1465
-
1466
- /**
1467
- * Get API target (v1 or v2 format)
1468
- */
1469
- private getTargetApi(): any {
1470
- if (this.isPackV2(this.pack)) {
1471
- // In v2, target is in the gate config
1472
- const gateConfig = this.pack.gates['api_smoke'] || this.pack.gates['api'];
1473
- if (gateConfig && (gateConfig as any).config?.baseUrl) {
1474
- return (gateConfig as any).config;
1475
- }
1476
- return undefined;
1477
- }
1478
- return this.pack.targets?.api;
1479
- }
1480
-
1481
- /**
1482
- * Get Web target (v1 or v2 format)
1483
- */
1484
- private getTargetWeb(): any {
1485
- if (this.isPackV2(this.pack)) {
1486
- // In v2, target is in the gate config
1487
- const gateConfig = this.pack.gates['ui'] || this.pack.gates['a11y'];
1488
- if (gateConfig && (gateConfig as any).config?.baseUrl) {
1489
- return (gateConfig as any).config;
1490
- }
1491
- return undefined;
1492
- }
1493
- return this.pack.targets?.web;
1494
- }
1495
-
1496
- /**
1497
- * Get budgets (v1 or v2 format)
1498
- */
1499
- private getBudgets(): any {
1500
- if (this.isPackV2(this.pack)) {
1501
- // In v2, budgets can be in gate config or global
1502
- // For now, return undefined - budgets are gate-specific in v2
1503
- return undefined;
1504
- }
1505
- return this.pack.budgets;
1506
- }
1507
-
1508
- /**
1509
- * Get execution timeout (v1 or v2 format)
1510
- */
1511
- private getExecutionTimeout(): number | undefined {
1512
- if (this.isPackV2(this.pack)) {
1513
- return this.pack.execution?.default_timeout;
1514
- }
1515
- return this.pack.execution?.timeout;
1516
- }
1517
-
1518
- /**
1519
- * Get execution retries (v1 or v2 format)
1520
- */
1521
- private getExecutionRetries(): number | undefined {
1522
- if (this.isPackV2(this.pack)) {
1523
- return this.pack.execution?.default_retries;
1524
- }
1525
- return this.pack.execution?.max_retries;
1526
- }
1527
-
1528
- /**
1529
- * Ensure output directory exists
1530
- */
1531
- private ensureOutputDir(): void {
1532
- if (!existsSync(this.outputDir)) {
1533
- mkdirSync(this.outputDir, { recursive: true });
1534
- }
1535
- }
1536
- }