swipium 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (387) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +295 -0
  3. package/dist/appMap/automationLink.js +74 -0
  4. package/dist/appMap/automationLink.js.map +1 -0
  5. package/dist/appMap/build.js +193 -0
  6. package/dist/appMap/build.js.map +1 -0
  7. package/dist/appMap/codeIndex.js +73 -0
  8. package/dist/appMap/codeIndex.js.map +1 -0
  9. package/dist/appMap/featureModel.js +83 -0
  10. package/dist/appMap/featureModel.js.map +1 -0
  11. package/dist/appMap/firstRunApply.js +131 -0
  12. package/dist/appMap/firstRunApply.js.map +1 -0
  13. package/dist/appMap/fsWalk.js +75 -0
  14. package/dist/appMap/fsWalk.js.map +1 -0
  15. package/dist/appMap/issues.js +227 -0
  16. package/dist/appMap/issues.js.map +1 -0
  17. package/dist/appMap/migrations.js +87 -0
  18. package/dist/appMap/migrations.js.map +1 -0
  19. package/dist/appMap/prelaunch.js +66 -0
  20. package/dist/appMap/prelaunch.js.map +1 -0
  21. package/dist/appMap/projectRegistry.js +70 -0
  22. package/dist/appMap/projectRegistry.js.map +1 -0
  23. package/dist/appMap/provenance.js +52 -0
  24. package/dist/appMap/provenance.js.map +1 -0
  25. package/dist/appMap/query.js +118 -0
  26. package/dist/appMap/query.js.map +1 -0
  27. package/dist/appMap/runtimeMerge.js +207 -0
  28. package/dist/appMap/runtimeMerge.js.map +1 -0
  29. package/dist/appMap/schema.js +65 -0
  30. package/dist/appMap/schema.js.map +1 -0
  31. package/dist/appMap/screenMatch.js +75 -0
  32. package/dist/appMap/screenMatch.js.map +1 -0
  33. package/dist/appMap/staticScan.js +614 -0
  34. package/dist/appMap/staticScan.js.map +1 -0
  35. package/dist/appMap/store.js +173 -0
  36. package/dist/appMap/store.js.map +1 -0
  37. package/dist/appMap/tsAstScan.js +184 -0
  38. package/dist/appMap/tsAstScan.js.map +1 -0
  39. package/dist/artifacts/bundletool.js +199 -0
  40. package/dist/artifacts/bundletool.js.map +1 -0
  41. package/dist/artifacts/resolve.js +388 -0
  42. package/dist/artifacts/resolve.js.map +1 -0
  43. package/dist/automationGen/appiumModel.js +129 -0
  44. package/dist/automationGen/appiumModel.js.map +1 -0
  45. package/dist/automationGen/ciEmitter.js +80 -0
  46. package/dist/automationGen/ciEmitter.js.map +1 -0
  47. package/dist/automationGen/jsEmitter.js +440 -0
  48. package/dist/automationGen/jsEmitter.js.map +1 -0
  49. package/dist/automationGen/packagePatch.js +56 -0
  50. package/dist/automationGen/packagePatch.js.map +1 -0
  51. package/dist/automationGen/projectProfile.js +317 -0
  52. package/dist/automationGen/projectProfile.js.map +1 -0
  53. package/dist/automationGen/pythonEmitter.js +386 -0
  54. package/dist/automationGen/pythonEmitter.js.map +1 -0
  55. package/dist/automationGen/readmeEmitter.js +66 -0
  56. package/dist/automationGen/readmeEmitter.js.map +1 -0
  57. package/dist/automationGen/suitePlan.js +94 -0
  58. package/dist/automationGen/suitePlan.js.map +1 -0
  59. package/dist/automationGen/validation.js +150 -0
  60. package/dist/automationGen/validation.js.map +1 -0
  61. package/dist/build/parseBuildLog.js +119 -0
  62. package/dist/build/parseBuildLog.js.map +1 -0
  63. package/dist/build/plan.js +150 -0
  64. package/dist/build/plan.js.map +1 -0
  65. package/dist/ci/preflight.js +85 -0
  66. package/dist/ci/preflight.js.map +1 -0
  67. package/dist/cli/init.js +105 -0
  68. package/dist/cli/init.js.map +1 -0
  69. package/dist/cli/scan.js +85 -0
  70. package/dist/cli/scan.js.map +1 -0
  71. package/dist/cli/suite.js +85 -0
  72. package/dist/cli/suite.js.map +1 -0
  73. package/dist/cli/verify.js +62 -0
  74. package/dist/cli/verify.js.map +1 -0
  75. package/dist/consent/consent.js +43 -0
  76. package/dist/consent/consent.js.map +1 -0
  77. package/dist/context/detect.js +156 -0
  78. package/dist/context/detect.js.map +1 -0
  79. package/dist/context/findApps.js +198 -0
  80. package/dist/context/findApps.js.map +1 -0
  81. package/dist/context/projectRoot.js +41 -0
  82. package/dist/context/projectRoot.js.map +1 -0
  83. package/dist/context/scan.js +167 -0
  84. package/dist/context/scan.js.map +1 -0
  85. package/dist/core/target.js +115 -0
  86. package/dist/core/target.js.map +1 -0
  87. package/dist/core/targetPlan.js +140 -0
  88. package/dist/core/targetPlan.js.map +1 -0
  89. package/dist/drivers/DirectDriver.js +228 -0
  90. package/dist/drivers/DirectDriver.js.map +1 -0
  91. package/dist/drivers/Driver.js +4 -0
  92. package/dist/drivers/Driver.js.map +1 -0
  93. package/dist/drivers/SimctlDriver.js +127 -0
  94. package/dist/drivers/SimctlDriver.js.map +1 -0
  95. package/dist/drivers/WdaDriver.js +250 -0
  96. package/dist/drivers/WdaDriver.js.map +1 -0
  97. package/dist/explore/candidates.js +93 -0
  98. package/dist/explore/candidates.js.map +1 -0
  99. package/dist/explore/graph.js +116 -0
  100. package/dist/explore/graph.js.map +1 -0
  101. package/dist/explore/memory.js +35 -0
  102. package/dist/explore/memory.js.map +1 -0
  103. package/dist/explore/planner.js +105 -0
  104. package/dist/explore/planner.js.map +1 -0
  105. package/dist/explore/policy.js +85 -0
  106. package/dist/explore/policy.js.map +1 -0
  107. package/dist/explore/runner.js +475 -0
  108. package/dist/explore/runner.js.map +1 -0
  109. package/dist/explore/signatures.js +35 -0
  110. package/dist/explore/signatures.js.map +1 -0
  111. package/dist/explore/suite.js +55 -0
  112. package/dist/explore/suite.js.map +1 -0
  113. package/dist/featureTesting/executionBootstrap.js +140 -0
  114. package/dist/featureTesting/executionBootstrap.js.map +1 -0
  115. package/dist/firstRun/authStateMachine.js +83 -0
  116. package/dist/firstRun/authStateMachine.js.map +1 -0
  117. package/dist/firstRun/classifyScreen.js +201 -0
  118. package/dist/firstRun/classifyScreen.js.map +1 -0
  119. package/dist/firstRun/firstRunPlanner.js +207 -0
  120. package/dist/firstRun/firstRunPlanner.js.map +1 -0
  121. package/dist/firstRun/firstRunRunner.js +331 -0
  122. package/dist/firstRun/firstRunRunner.js.map +1 -0
  123. package/dist/firstRun/generatedDataPolicy.js +215 -0
  124. package/dist/firstRun/generatedDataPolicy.js.map +1 -0
  125. package/dist/firstRun/inputPlanner.js +67 -0
  126. package/dist/firstRun/inputPlanner.js.map +1 -0
  127. package/dist/firstRun/onboardingStateMachine.js +46 -0
  128. package/dist/firstRun/onboardingStateMachine.js.map +1 -0
  129. package/dist/firstRun/paywallPolicy.js +54 -0
  130. package/dist/firstRun/paywallPolicy.js.map +1 -0
  131. package/dist/firstRun/types.js +7 -0
  132. package/dist/firstRun/types.js.map +1 -0
  133. package/dist/fixtures/catalog.js +131 -0
  134. package/dist/fixtures/catalog.js.map +1 -0
  135. package/dist/flows/discover.js +18 -0
  136. package/dist/flows/discover.js.map +1 -0
  137. package/dist/flows/generate.js +211 -0
  138. package/dist/flows/generate.js.map +1 -0
  139. package/dist/flows/lint.js +97 -0
  140. package/dist/flows/lint.js.map +1 -0
  141. package/dist/flows/pack.js +68 -0
  142. package/dist/flows/pack.js.map +1 -0
  143. package/dist/flows/run.js +738 -0
  144. package/dist/flows/run.js.map +1 -0
  145. package/dist/flows/schema.js +240 -0
  146. package/dist/flows/schema.js.map +1 -0
  147. package/dist/flows/seedExec.js +108 -0
  148. package/dist/flows/seedExec.js.map +1 -0
  149. package/dist/flows/templates.js +155 -0
  150. package/dist/flows/templates.js.map +1 -0
  151. package/dist/flows/waitGuards.js +12 -0
  152. package/dist/flows/waitGuards.js.map +1 -0
  153. package/dist/index.js +33 -0
  154. package/dist/index.js.map +1 -0
  155. package/dist/ios/signing.js +182 -0
  156. package/dist/ios/signing.js.map +1 -0
  157. package/dist/issues/classify.js +186 -0
  158. package/dist/issues/classify.js.map +1 -0
  159. package/dist/issues/fingerprint.js +130 -0
  160. package/dist/issues/fingerprint.js.map +1 -0
  161. package/dist/issues/index.js +240 -0
  162. package/dist/issues/index.js.map +1 -0
  163. package/dist/issues/metrics.js +155 -0
  164. package/dist/issues/metrics.js.map +1 -0
  165. package/dist/issues/recurrence.js +193 -0
  166. package/dist/issues/recurrence.js.map +1 -0
  167. package/dist/issues/report.js +110 -0
  168. package/dist/issues/report.js.map +1 -0
  169. package/dist/issues/reportBridge.js +119 -0
  170. package/dist/issues/reportBridge.js.map +1 -0
  171. package/dist/issues/schema.js +90 -0
  172. package/dist/issues/schema.js.map +1 -0
  173. package/dist/issues/sourceRevision.js +108 -0
  174. package/dist/issues/sourceRevision.js.map +1 -0
  175. package/dist/issues/store.js +155 -0
  176. package/dist/issues/store.js.map +1 -0
  177. package/dist/lib/android.js +278 -0
  178. package/dist/lib/android.js.map +1 -0
  179. package/dist/lib/commandTemplate.js +55 -0
  180. package/dist/lib/commandTemplate.js.map +1 -0
  181. package/dist/lib/coordSpace.js +23 -0
  182. package/dist/lib/coordSpace.js.map +1 -0
  183. package/dist/lib/device.js +87 -0
  184. package/dist/lib/device.js.map +1 -0
  185. package/dist/lib/gitignore.js +22 -0
  186. package/dist/lib/gitignore.js.map +1 -0
  187. package/dist/lib/image.js +97 -0
  188. package/dist/lib/image.js.map +1 -0
  189. package/dist/lib/logger.js +8 -0
  190. package/dist/lib/logger.js.map +1 -0
  191. package/dist/lib/metroState.js +45 -0
  192. package/dist/lib/metroState.js.map +1 -0
  193. package/dist/lib/needsInput.js +201 -0
  194. package/dist/lib/needsInput.js.map +1 -0
  195. package/dist/lib/png.js +103 -0
  196. package/dist/lib/png.js.map +1 -0
  197. package/dist/lib/redact.js +21 -0
  198. package/dist/lib/redact.js.map +1 -0
  199. package/dist/lib/result.js +87 -0
  200. package/dist/lib/result.js.map +1 -0
  201. package/dist/lib/schemaHash.js +65 -0
  202. package/dist/lib/schemaHash.js.map +1 -0
  203. package/dist/lib/sensitive.js +13 -0
  204. package/dist/lib/sensitive.js.map +1 -0
  205. package/dist/lib/simctl.js +149 -0
  206. package/dist/lib/simctl.js.map +1 -0
  207. package/dist/lib/spawn.js +144 -0
  208. package/dist/lib/spawn.js.map +1 -0
  209. package/dist/lib/wda.js +347 -0
  210. package/dist/lib/wda.js.map +1 -0
  211. package/dist/lib/wdaConfig.js +69 -0
  212. package/dist/lib/wdaConfig.js.map +1 -0
  213. package/dist/lib/wdaTune.js +58 -0
  214. package/dist/lib/wdaTune.js.map +1 -0
  215. package/dist/oracle/auth.js +22 -0
  216. package/dist/oracle/auth.js.map +1 -0
  217. package/dist/oracle/failures.js +193 -0
  218. package/dist/oracle/failures.js.map +1 -0
  219. package/dist/oracle/health.js +123 -0
  220. package/dist/oracle/health.js.map +1 -0
  221. package/dist/oracle/record.js +36 -0
  222. package/dist/oracle/record.js.map +1 -0
  223. package/dist/orchestration/envelope.js +52 -0
  224. package/dist/orchestration/envelope.js.map +1 -0
  225. package/dist/orchestration/goal.js +98 -0
  226. package/dist/orchestration/goal.js.map +1 -0
  227. package/dist/plan/plan.js +124 -0
  228. package/dist/plan/plan.js.map +1 -0
  229. package/dist/prompts/index.js +63 -0
  230. package/dist/prompts/index.js.map +1 -0
  231. package/dist/report/artifactManifest.js +44 -0
  232. package/dist/report/artifactManifest.js.map +1 -0
  233. package/dist/report/coverage.js +60 -0
  234. package/dist/report/coverage.js.map +1 -0
  235. package/dist/report/evidence.js +84 -0
  236. package/dist/report/evidence.js.map +1 -0
  237. package/dist/report/export.js +447 -0
  238. package/dist/report/export.js.map +1 -0
  239. package/dist/report/flake.js +61 -0
  240. package/dist/report/flake.js.map +1 -0
  241. package/dist/report/history.js +564 -0
  242. package/dist/report/history.js.map +1 -0
  243. package/dist/report/policy.js +98 -0
  244. package/dist/report/policy.js.map +1 -0
  245. package/dist/report/qaLevel.js +96 -0
  246. package/dist/report/qaLevel.js.map +1 -0
  247. package/dist/report/readiness.js +213 -0
  248. package/dist/report/readiness.js.map +1 -0
  249. package/dist/report/summary.js +42 -0
  250. package/dist/report/summary.js.map +1 -0
  251. package/dist/report/testCatalog.js +93 -0
  252. package/dist/report/testCatalog.js.map +1 -0
  253. package/dist/report/timing.js +37 -0
  254. package/dist/report/timing.js.map +1 -0
  255. package/dist/server.js +180 -0
  256. package/dist/server.js.map +1 -0
  257. package/dist/services/automationGenerate.js +60 -0
  258. package/dist/services/automationGenerate.js.map +1 -0
  259. package/dist/services/build.js +66 -0
  260. package/dist/services/build.js.map +1 -0
  261. package/dist/services/preflight.js +51 -0
  262. package/dist/services/preflight.js.map +1 -0
  263. package/dist/services/prepareAndroid.js +183 -0
  264. package/dist/services/prepareAndroid.js.map +1 -0
  265. package/dist/services/prepareIos.js +162 -0
  266. package/dist/services/prepareIos.js.map +1 -0
  267. package/dist/services/report.js +537 -0
  268. package/dist/services/report.js.map +1 -0
  269. package/dist/services/smoke.js +120 -0
  270. package/dist/services/smoke.js.map +1 -0
  271. package/dist/services/suiteGenerate.js +123 -0
  272. package/dist/services/suiteGenerate.js.map +1 -0
  273. package/dist/services/testSuiteKnowledge.js +150 -0
  274. package/dist/services/testSuiteKnowledge.js.map +1 -0
  275. package/dist/session/attach.js +47 -0
  276. package/dist/session/attach.js.map +1 -0
  277. package/dist/session/progress.js +56 -0
  278. package/dist/session/progress.js.map +1 -0
  279. package/dist/session/store.js +329 -0
  280. package/dist/session/store.js.map +1 -0
  281. package/dist/snapshot/overlays.js +132 -0
  282. package/dist/snapshot/overlays.js.map +1 -0
  283. package/dist/snapshot/parse.js +204 -0
  284. package/dist/snapshot/parse.js.map +1 -0
  285. package/dist/snapshot/present.js +12 -0
  286. package/dist/snapshot/present.js.map +1 -0
  287. package/dist/snapshot/settle.js +36 -0
  288. package/dist/snapshot/settle.js.map +1 -0
  289. package/dist/state/profile.js +318 -0
  290. package/dist/state/profile.js.map +1 -0
  291. package/dist/suite/compile.js +176 -0
  292. package/dist/suite/compile.js.map +1 -0
  293. package/dist/suite/lint.js +45 -0
  294. package/dist/suite/lint.js.map +1 -0
  295. package/dist/suite/pom.js +285 -0
  296. package/dist/suite/pom.js.map +1 -0
  297. package/dist/suite/testcase.js +87 -0
  298. package/dist/suite/testcase.js.map +1 -0
  299. package/dist/testSuite/generator.js +222 -0
  300. package/dist/testSuite/generator.js.map +1 -0
  301. package/dist/testSuite/history.js +44 -0
  302. package/dist/testSuite/history.js.map +1 -0
  303. package/dist/testSuite/issueLinks.js +96 -0
  304. package/dist/testSuite/issueLinks.js.map +1 -0
  305. package/dist/testSuite/merge.js +190 -0
  306. package/dist/testSuite/merge.js.map +1 -0
  307. package/dist/testSuite/schema.js +86 -0
  308. package/dist/testSuite/schema.js.map +1 -0
  309. package/dist/testSuite/store.js +116 -0
  310. package/dist/testSuite/store.js.map +1 -0
  311. package/dist/testSuite/traceability.js +55 -0
  312. package/dist/testSuite/traceability.js.map +1 -0
  313. package/dist/tools/act.js +457 -0
  314. package/dist/tools/act.js.map +1 -0
  315. package/dist/tools/agent.js +225 -0
  316. package/dist/tools/agent.js.map +1 -0
  317. package/dist/tools/appMap.js +317 -0
  318. package/dist/tools/appMap.js.map +1 -0
  319. package/dist/tools/assertVisual.js +74 -0
  320. package/dist/tools/assertVisual.js.map +1 -0
  321. package/dist/tools/automationGenerate.js +394 -0
  322. package/dist/tools/automationGenerate.js.map +1 -0
  323. package/dist/tools/capabilities.js +114 -0
  324. package/dist/tools/capabilities.js.map +1 -0
  325. package/dist/tools/clearOverlay.js +150 -0
  326. package/dist/tools/clearOverlay.js.map +1 -0
  327. package/dist/tools/detectContext.js +41 -0
  328. package/dist/tools/detectContext.js.map +1 -0
  329. package/dist/tools/doctor.js +116 -0
  330. package/dist/tools/doctor.js.map +1 -0
  331. package/dist/tools/explore.js +289 -0
  332. package/dist/tools/explore.js.map +1 -0
  333. package/dist/tools/firstRun.js +136 -0
  334. package/dist/tools/firstRun.js.map +1 -0
  335. package/dist/tools/flow.js +331 -0
  336. package/dist/tools/flow.js.map +1 -0
  337. package/dist/tools/flowGenerate.js +55 -0
  338. package/dist/tools/flowGenerate.js.map +1 -0
  339. package/dist/tools/getArtifact.js +39 -0
  340. package/dist/tools/getArtifact.js.map +1 -0
  341. package/dist/tools/health.js +41 -0
  342. package/dist/tools/health.js.map +1 -0
  343. package/dist/tools/ios.js +492 -0
  344. package/dist/tools/ios.js.map +1 -0
  345. package/dist/tools/jobs.js +20 -0
  346. package/dist/tools/jobs.js.map +1 -0
  347. package/dist/tools/network.js +50 -0
  348. package/dist/tools/network.js.map +1 -0
  349. package/dist/tools/note.js +69 -0
  350. package/dist/tools/note.js.map +1 -0
  351. package/dist/tools/plan.js +49 -0
  352. package/dist/tools/plan.js.map +1 -0
  353. package/dist/tools/prepareIosTarget.js +99 -0
  354. package/dist/tools/prepareIosTarget.js.map +1 -0
  355. package/dist/tools/prepareTarget.js +257 -0
  356. package/dist/tools/prepareTarget.js.map +1 -0
  357. package/dist/tools/report.js +42 -0
  358. package/dist/tools/report.js.map +1 -0
  359. package/dist/tools/screenRecord.js +24 -0
  360. package/dist/tools/screenRecord.js.map +1 -0
  361. package/dist/tools/screenshot.js +63 -0
  362. package/dist/tools/screenshot.js.map +1 -0
  363. package/dist/tools/smoke.js +39 -0
  364. package/dist/tools/smoke.js.map +1 -0
  365. package/dist/tools/snapshot.js +129 -0
  366. package/dist/tools/snapshot.js.map +1 -0
  367. package/dist/tools/startSession.js +169 -0
  368. package/dist/tools/startSession.js.map +1 -0
  369. package/dist/tools/state.js +87 -0
  370. package/dist/tools/state.js.map +1 -0
  371. package/dist/tools/suite.js +412 -0
  372. package/dist/tools/suite.js.map +1 -0
  373. package/dist/tools/testThis.js +774 -0
  374. package/dist/tools/testThis.js.map +1 -0
  375. package/dist/tools/wda.js +477 -0
  376. package/dist/tools/wda.js.map +1 -0
  377. package/dist/version.js +62 -0
  378. package/dist/version.js.map +1 -0
  379. package/dist/visual/ocr.js +72 -0
  380. package/dist/visual/ocr.js.map +1 -0
  381. package/dist/visual/provider.js +75 -0
  382. package/dist/visual/provider.js.map +1 -0
  383. package/docs/README.md +19 -0
  384. package/docs/assets/swipium-lockup-ink-on-light.png +0 -0
  385. package/docs/mcp-server.md +135 -0
  386. package/docs/tools.md +130 -0
  387. package/package.json +70 -0
@@ -0,0 +1,98 @@
1
+ // Release-gate policy (NEXT-PLAN: Reporting V3 / P1 release gate). A project can declare
2
+ // .swipium/policy.json to decide what blocks a release, what only warns, and which known issues
3
+ // to suppress. `swipium test` consults it to compute the final pass/fail.
4
+ //
5
+ // {
6
+ // "blockOn": ["native_crash", "app_error_boundary", "failed_required_flow"],
7
+ // "warnOn": ["visual_diff", "missing_test_data"],
8
+ // "ignoreKnown": ["REVENUECAT_BILLING_UNAVAILABLE_ON_EMULATOR"]
9
+ // }
10
+ //
11
+ // Tokens are matched case-insensitively against failure codes (e.g. NATIVE_CRASH ↔ "native_crash")
12
+ // and a few synonyms; `failed_required_flow` matches any failed flow regardless of code.
13
+ import { existsSync, readFileSync } from 'node:fs';
14
+ import { join } from 'node:path';
15
+ export function loadPolicy(root) {
16
+ const p = join(root, '.swipium', 'policy.json');
17
+ if (!existsSync(p))
18
+ return null;
19
+ try {
20
+ const j = JSON.parse(readFileSync(p, 'utf8'));
21
+ return { blockOn: j.blockOn ?? [], warnOn: j.warnOn ?? [], ignoreKnown: j.ignoreKnown ?? [], ciAllowMutations: j.ciAllowMutations ?? [] };
22
+ }
23
+ catch {
24
+ return null;
25
+ }
26
+ }
27
+ const norm = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, '');
28
+ // Map policy synonyms → the normalized failure-code form.
29
+ const SYNONYMS = {
30
+ appbug: 'assertionfailed',
31
+ visualdiff: 'assertionfailed',
32
+ crash: 'nativecrash',
33
+ errorboundary: 'errorboundary',
34
+ };
35
+ /** Decide pass/fail for a set of flow verdicts under a policy. With no policy, ANY failure blocks. */
36
+ export function applyPolicy(verdicts, policy) {
37
+ const blocked = [];
38
+ const warned = [];
39
+ const suppressed = [];
40
+ const inList = (list, code) => {
41
+ const c = norm(code);
42
+ return list.some((tok) => {
43
+ const t = norm(tok);
44
+ return t === c || SYNONYMS[t] === c || (t === 'failedrequiredflow');
45
+ });
46
+ };
47
+ for (const v of verdicts) {
48
+ if (v.passed)
49
+ continue;
50
+ const code = v.failureCode ?? 'UNKNOWN';
51
+ if (!policy) {
52
+ blocked.push(`${v.flow}: ${code}`);
53
+ continue;
54
+ }
55
+ if (policy.ignoreKnown.some((k) => norm(k) === norm(code))) {
56
+ suppressed.push(`${v.flow}: ${code}`);
57
+ continue;
58
+ }
59
+ // failed_required_flow blocks any failure; otherwise match the specific code.
60
+ if (policy.blockOn.length === 0 || inList(policy.blockOn, code))
61
+ blocked.push(`${v.flow}: ${code}`);
62
+ else if (inList(policy.warnOn, code))
63
+ warned.push(`${v.flow}: ${code}`);
64
+ else
65
+ blocked.push(`${v.flow}: ${code}`); // default: an unclassified failure blocks
66
+ }
67
+ const block = blocked.length > 0;
68
+ const reason = block
69
+ ? `release blocked: ${blocked.join(', ')}`
70
+ : warned.length
71
+ ? `passed with warnings: ${warned.join(', ')}`
72
+ : suppressed.length
73
+ ? `passed (suppressed known issues: ${suppressed.join(', ')})`
74
+ : 'all required flows passed';
75
+ return { block, blocked, warned, suppressed, reason };
76
+ }
77
+ export function ciMutationAllowed(policy, stepKind) {
78
+ if (!policy)
79
+ return false;
80
+ const allowed = policy.ciAllowMutations.map(norm);
81
+ const requested = norm(stepKind);
82
+ const aliases = {
83
+ networkoffline: ['network', 'networktoggle', 'connectivity'],
84
+ networkonline: ['network', 'networktoggle', 'connectivity'],
85
+ seed: ['seeds', 'fixtures', 'fixtureseed'],
86
+ restartapp: ['restart', 'lifecycle', 'appcontrol'],
87
+ cleardata: ['clearappdata', 'freshstart', 'appcontrol', 'destructiveappstate'],
88
+ freshstart: ['cleardata', 'clearappdata', 'appcontrol', 'destructiveappstate'],
89
+ permissiongrant: ['permissions', 'permissionchanges', 'permission'],
90
+ permissionrevoke: ['permissions', 'permissionchanges', 'permission'],
91
+ geolocation: ['location', 'gps', 'mocklocation'],
92
+ iosprivacyreset: ['privacyreset', 'permissions', 'permissionchanges', 'privacy'],
93
+ ioserase: ['simulatorerase', 'erase', 'destructiveappstate'],
94
+ };
95
+ const accepted = new Set([requested, ...(aliases[requested] ?? [])]);
96
+ return allowed.includes('all') || allowed.includes('*') || allowed.includes('mutatingsteps') || [...accepted].some((token) => allowed.includes(token));
97
+ }
98
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/report/policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ // QA level (Developer-3 plan Deliverable 6 / roadmap §3.11) — the single, deterministic, product-facing
2
+ // QA verdict label every Swipium run earns. This is DISTINCT from the automation `ReadinessLabel`
3
+ // (which scores the *generated suite*): the QA level answers "how far did QA actually get on this app?"
4
+ // — the rung a developer, QA engineer, reviewer, and CI all read straight off the report.
5
+ //
6
+ // Pure + deterministic so it is unit-testable and stable across runs. It NEVER claims a level whose
7
+ // evidence was not observed (Hard Product Rule: "always report what was attempted; never over-claim").
8
+ // Public v1 levels:
9
+ // observed -> smoke_tested -> automation_candidate -> automation_runnable -> ci_ready
10
+ export const QA_LEVELS = [
11
+ 'observed',
12
+ 'smoke_tested',
13
+ 'automation_candidate',
14
+ 'automation_runnable',
15
+ 'ci_ready',
16
+ ];
17
+ export const QA_LEVEL_MEANING = {
18
+ observed: 'Swipium launched the app and captured evidence.',
19
+ smoke_tested: 'Launch + health guardrails passed (no native crash or fatal app-error surface).',
20
+ automation_candidate: 'A POM automation suite was generated from recorded actions.',
21
+ automation_runnable: 'The generated suite compiled and dry-run validated.',
22
+ ci_ready: 'The suite replayed from a declared state profile — safe to gate CI on.',
23
+ };
24
+ // Prerequisites encode the honest public-v1 progression.
25
+ const PREREQ = {
26
+ observed: [],
27
+ smoke_tested: ['observed'],
28
+ automation_candidate: ['smoke_tested'],
29
+ automation_runnable: ['automation_candidate'],
30
+ ci_ready: ['automation_runnable'],
31
+ };
32
+ function signalFor(level, s) {
33
+ switch (level) {
34
+ case 'observed':
35
+ return s.observed;
36
+ case 'smoke_tested':
37
+ return s.smokePassed;
38
+ case 'automation_candidate':
39
+ return s.suiteGenerated;
40
+ case 'automation_runnable':
41
+ return s.suiteRunnable;
42
+ case 'ci_ready':
43
+ return s.ciReplayed;
44
+ }
45
+ }
46
+ export function qaLevelRequirement(level) {
47
+ switch (level) {
48
+ case 'observed':
49
+ return 'Launch the app and capture evidence.';
50
+ case 'smoke_tested':
51
+ return 'Pass launch + health guardrails (no crash, no fatal error surface, no high-severity finding).';
52
+ case 'automation_candidate':
53
+ return 'Record actions (qa_act / qa_smoke / qa_explore) so a POM suite can be generated.';
54
+ case 'automation_runnable':
55
+ return 'Compile and dry-run the generated suite (qa_suite_compile).';
56
+ case 'ci_ready':
57
+ return 'Replay the suite from a declared state profile.';
58
+ }
59
+ }
60
+ /**
61
+ * Derive the single QA level for a run from its observable signals. Deterministic and honest:
62
+ * a level is only `achieved` when its own evidence AND all its prerequisites are present.
63
+ */
64
+ export function deriveQaLevel(signals) {
65
+ const met = new Set();
66
+ for (const level of QA_LEVELS) {
67
+ if (PREREQ[level].every((p) => met.has(p)) && signalFor(level, signals))
68
+ met.add(level);
69
+ }
70
+ const achieved = QA_LEVELS.filter((l) => met.has(l));
71
+ // Honest floor: with zero evidence we report `not_observed`, never a fabricated `observed`.
72
+ const level = achieved.length ? achieved[achieved.length - 1] : 'not_observed';
73
+ const reportedIndex = achieved.length ? QA_LEVELS.indexOf(achieved[achieved.length - 1]) : -1;
74
+ // `next` is the next rung above the reported level, not an earlier gap.
75
+ const next = QA_LEVELS.find((l, i) => i > reportedIndex && !met.has(l)) ?? null;
76
+ const nextRequirement = next ? qaLevelRequirement(next) : null;
77
+ // Lower rungs that were skipped beneath the reported level (surfaced separately, never hidden).
78
+ const skipped = QA_LEVELS.filter((l, i) => i < reportedIndex && !met.has(l));
79
+ const notes = [];
80
+ if (!signals.observed)
81
+ notes.push('No evidence captured yet — the app may not have launched.');
82
+ if (signals.suiteGenerated && !signals.suiteRunnable) {
83
+ notes.push('A suite was generated but has not compiled/dry-run — it is a candidate, not runnable.');
84
+ }
85
+ if (signals.suiteRunnable && !signals.ciReplayed) {
86
+ notes.push('Suite is runnable but has not replayed from a declared state — not yet CI-ready.');
87
+ }
88
+ if (signals.observed && !signals.smokePassed) {
89
+ notes.push('Launch/health was not confirmed passing — smoke level not reached.');
90
+ }
91
+ const rationale = level === 'not_observed'
92
+ ? 'No QA level reached yet — no evidence was captured (the app may not have launched).'
93
+ : `Reached ${level}: ${QA_LEVEL_MEANING[level]}`;
94
+ return { level, achieved, next, nextRequirement, skipped, rationale, notes };
95
+ }
96
+ //# sourceMappingURL=qaLevel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qaLevel.js","sourceRoot":"","sources":["../../src/report/qaLevel.ts"],"names":[],"mappings":"AAAA,wGAAwG;AACxG,kGAAkG;AAClG,wGAAwG;AACxG,0FAA0F;AAC1F,EAAE;AACF,oGAAoG;AACpG,uGAAuG;AACvG,oBAAoB;AACpB,wFAAwF;AASxF,MAAM,CAAC,MAAM,SAAS,GAAuB;IAC3C,UAAU;IACV,cAAc;IACd,sBAAsB;IACtB,qBAAqB;IACrB,UAAU;CACX,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAA4B;IACvD,QAAQ,EAAE,iDAAiD;IAC3D,YAAY,EAAE,iFAAiF;IAC/F,oBAAoB,EAAE,6DAA6D;IACnF,mBAAmB,EAAE,qDAAqD;IAC1E,QAAQ,EAAE,wEAAwE;CACnF,CAAC;AAoCF,yDAAyD;AACzD,MAAM,MAAM,GAA+B;IACzC,QAAQ,EAAE,EAAE;IACZ,YAAY,EAAE,CAAC,UAAU,CAAC;IAC1B,oBAAoB,EAAE,CAAC,cAAc,CAAC;IACtC,mBAAmB,EAAE,CAAC,sBAAsB,CAAC;IAC7C,QAAQ,EAAE,CAAC,qBAAqB,CAAC;CAClC,CAAC;AAEF,SAAS,SAAS,CAAC,KAAc,EAAE,CAAiB;IAClD,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,UAAU;YACb,OAAO,CAAC,CAAC,QAAQ,CAAC;QACpB,KAAK,cAAc;YACjB,OAAO,CAAC,CAAC,WAAW,CAAC;QACvB,KAAK,sBAAsB;YACzB,OAAO,CAAC,CAAC,cAAc,CAAC;QAC1B,KAAK,qBAAqB;YACxB,OAAO,CAAC,CAAC,aAAa,CAAC;QACzB,KAAK,UAAU;YACb,OAAO,CAAC,CAAC,UAAU,CAAC;IACxB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,UAAU;YACb,OAAO,sCAAsC,CAAC;QAChD,KAAK,cAAc;YACjB,OAAO,+FAA+F,CAAC;QACzG,KAAK,sBAAsB;YACzB,OAAO,kFAAkF,CAAC;QAC5F,KAAK,qBAAqB;YACxB,OAAO,6DAA6D,CAAC;QACvE,KAAK,UAAU;YACb,OAAO,iDAAiD,CAAC;IAC7D,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAuB;IACnD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAW,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1F,CAAC;IACD,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,4FAA4F;IAC5F,MAAM,KAAK,GAA6B,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;IACzG,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9F,wEAAwE;IACxE,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,aAAa,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAChF,MAAM,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/D,gGAAgG;IAChG,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,aAAa,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;IAC/F,IAAI,OAAO,CAAC,cAAc,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QACrD,KAAK,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAC;IACtG,CAAC;IACD,IAAI,OAAO,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,kFAAkF,CAAC,CAAC;IACjG,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;IACnF,CAAC;IAED,MAAM,SAAS,GACb,KAAK,KAAK,cAAc;QACtB,CAAC,CAAC,qFAAqF;QACvF,CAAC,CAAC,WAAW,KAAK,KAAK,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;IACrD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AAC/E,CAAC"}
@@ -0,0 +1,213 @@
1
+ import { evidenceAssessmentForNote } from './evidence.js';
2
+ const READINESS_ORDER = ['observed', 'verified', 'generated', 'compiled', 'replayed', 'ci_ready'];
3
+ export function orderReadinessLabels(labels) {
4
+ const set = new Set(labels);
5
+ return READINESS_ORDER.filter((label) => set.has(label));
6
+ }
7
+ export function readinessForSession(session, opts = {}) {
8
+ const labels = [];
9
+ const artifacts = session.artifacts ?? [];
10
+ const notes = session.notes ?? [];
11
+ const findings = session.findings ?? [];
12
+ const recordedActions = session.recordedActions ?? [];
13
+ if (artifacts.length || session.exploration || notes.length || findings.length || recordedActions.length)
14
+ labels.push('observed');
15
+ if (notes.some((n) => n.outcome === 'pass') || findings.length || recordedActions.length)
16
+ labels.push('verified');
17
+ if (recordedActions.length)
18
+ labels.push('generated');
19
+ if (opts.suiteRunnable)
20
+ labels.push('compiled');
21
+ if (opts.suiteReplayed)
22
+ labels.push('replayed');
23
+ if (opts.ciReady)
24
+ labels.push('ci_ready');
25
+ return orderReadinessLabels(labels);
26
+ }
27
+ function pct(part, whole) {
28
+ return whole ? Math.round((part / whole) * 100) : 0;
29
+ }
30
+ function gradeFromScore(score) {
31
+ if (score >= 85)
32
+ return 'A';
33
+ if (score >= 70)
34
+ return 'B';
35
+ if (score >= 50)
36
+ return 'C';
37
+ return 'D';
38
+ }
39
+ function gradeFromOutcome(outcome, weakerEvidence, durablePct) {
40
+ if (outcome === 'fail')
41
+ return 'D';
42
+ if (outcome === 'blocked')
43
+ return 'C';
44
+ if (outcome === 'skipped' || outcome === 'not_applicable')
45
+ return 'C';
46
+ if (outcome === 'pass') {
47
+ if (durablePct >= 80 && !weakerEvidence)
48
+ return 'A';
49
+ if (durablePct >= 60 || weakerEvidence)
50
+ return 'B';
51
+ return 'C';
52
+ }
53
+ return durablePct >= 70 ? 'B' : durablePct >= 40 ? 'C' : 'D';
54
+ }
55
+ function locatable(actions) {
56
+ return actions.filter((a) => ['tap', 'type', 'clear', 'scroll', 'swipe', 'press', 'assert_visual'].includes(a.action));
57
+ }
58
+ function locatorCoverage(actions) {
59
+ const items = locatable(actions);
60
+ const byKind = {};
61
+ for (const a of items)
62
+ byKind[a.selectorKind ?? 'none'] = (byKind[a.selectorKind ?? 'none'] ?? 0) + 1;
63
+ const durableActions = items.filter((a) => a.selectorKind === 'accessibility_id' || a.selectorKind === 'resource_id').length;
64
+ const nativeFallbackActions = items.filter((a) => a.selectorKind === 'name' || a.selectorKind === 'predicate' || a.selectorKind === 'class_chain').length;
65
+ const textActions = items.filter((a) => a.selectorKind === 'text').length;
66
+ const coordinateActions = items.filter((a) => !a.selectorKind || a.selectorKind === 'coords').length;
67
+ return {
68
+ totalActions: items.length,
69
+ durableActions,
70
+ nativeFallbackActions,
71
+ textActions,
72
+ coordinateActions,
73
+ durablePct: pct(durableActions, items.length),
74
+ nativeOrDurablePct: pct(durableActions + nativeFallbackActions, items.length),
75
+ byKind,
76
+ };
77
+ }
78
+ function uniqueTop(items, limit = 10) {
79
+ const seen = new Set();
80
+ const out = [];
81
+ for (const item of items.map((x) => x.trim()).filter(Boolean)) {
82
+ if (seen.has(item))
83
+ continue;
84
+ seen.add(item);
85
+ out.push(item);
86
+ if (out.length >= limit)
87
+ break;
88
+ }
89
+ return out;
90
+ }
91
+ function noteFix(n) {
92
+ if (n.outcome === 'pass')
93
+ return undefined;
94
+ if (n.recommendedSetup)
95
+ return `${n.workflow}: ${n.recommendedSetup}`;
96
+ if (n.missingPrecondition)
97
+ return `${n.workflow}: add fixture/state profile for missing precondition "${n.missingPrecondition}"`;
98
+ if (n.reason)
99
+ return `${n.workflow}: resolve ${n.reason}`;
100
+ return `${n.workflow}: investigate ${n.outcome} outcome`;
101
+ }
102
+ function findingFix(f) {
103
+ return `${f.kind}: ${f.detail}`;
104
+ }
105
+ function actionFix(a) {
106
+ const where = a.screen ? ` on ${a.screen}` : '';
107
+ if (!a.selectorKind || a.selectorKind === 'coords')
108
+ return `Add a testID/accessibilityIdentifier for coordinate-only ${a.action}${where}.`;
109
+ if (a.selectorKind === 'text')
110
+ return `Promote text selector "${a.selector ?? 'unknown'}"${where} to a durable testID/accessibilityIdentifier.`;
111
+ if (a.selectorKind === 'name')
112
+ return `Promote iOS name selector "${a.selector ?? 'unknown'}"${where} to accessibilityIdentifier.`;
113
+ return undefined;
114
+ }
115
+ function screenGrades(actions) {
116
+ const groups = new Map();
117
+ for (const action of locatable(actions)) {
118
+ const screen = action.screen ?? 'unknown_screen';
119
+ groups.set(screen, [...(groups.get(screen) ?? []), action]);
120
+ }
121
+ return [...groups.entries()].map(([screen, group]) => {
122
+ const c = locatorCoverage(group);
123
+ const score = Math.round(c.durablePct * 0.8 + c.nativeOrDurablePct * 0.2);
124
+ return {
125
+ screen,
126
+ grade: gradeFromScore(score),
127
+ score,
128
+ actionCount: group.length,
129
+ durableLocatorPct: c.durablePct,
130
+ weakActions: c.textActions + c.coordinateActions,
131
+ fixes: uniqueTop(group.map(actionFix).filter((x) => !!x), 5),
132
+ };
133
+ }).sort((a, b) => a.grade.localeCompare(b.grade) || b.actionCount - a.actionCount);
134
+ }
135
+ function workflowGrades(notes, durablePct) {
136
+ if (!notes.length) {
137
+ return [{
138
+ workflow: 'recorded_session',
139
+ grade: gradeFromOutcome('unknown', false, durablePct),
140
+ outcome: 'unknown',
141
+ evidence: 'none',
142
+ fix: durablePct < 80 ? 'Record qa_note outcomes and promote weak locators before CI promotion.' : 'Record qa_note outcomes so product readiness is auditable.',
143
+ }];
144
+ }
145
+ return notes.map((n) => {
146
+ const evidence = evidenceAssessmentForNote(n);
147
+ return {
148
+ workflow: n.workflow,
149
+ grade: gradeFromOutcome(n.outcome, evidence.authority !== 'deterministic', durablePct),
150
+ outcome: n.outcome,
151
+ evidence: evidence.kind,
152
+ fix: noteFix(n),
153
+ };
154
+ });
155
+ }
156
+ function workflowEvidenceWeight(n) {
157
+ const evidence = evidenceAssessmentForNote(n);
158
+ if (evidence.authority === 'deterministic')
159
+ return 1;
160
+ if (evidence.authority === 'probabilistic')
161
+ return 0.65;
162
+ return 0.4;
163
+ }
164
+ function scoreBreakdown(session, labels, coverage) {
165
+ const weightedPassCount = session.notes.filter((n) => n.outcome === 'pass').reduce((sum, n) => sum + workflowEvidenceWeight(n), 0);
166
+ const failOrBlocked = session.notes.filter((n) => n.outcome === 'fail' || n.outcome === 'blocked').length;
167
+ const workflowEvidence = session.notes.length ? Math.max(0, Math.round((weightedPassCount / session.notes.length) * 15) - failOrBlocked * 2) : 0;
168
+ const stateProfiles = session.mutations.some((m) => m.action === 'state_profile_mutation' && m.status === 'executed') ? 10 : session.fixtures.length ? 5 : 0;
169
+ const idling = session.workarounds.some((w) => /idling: app-declared/i.test(w)) ? 10 : session.workarounds.some((w) => /idling:/i.test(w)) ? 5 : 0;
170
+ const riskyExecuted = session.mutations.filter((m) => m.risk === 'high' && m.status === 'executed').length;
171
+ const refusedOrBounded = session.mutations.some((m) => (m.status === 'refused' || m.status === 'blocked') && m.risk === 'high');
172
+ const safeDestructiveBoundaries = riskyExecuted ? 4 : refusedOrBounded ? 10 : 8;
173
+ const replayEvidence = labels.includes('ci_ready') ? 20 : labels.includes('replayed') ? 16 : labels.includes('compiled') ? 10 : labels.includes('generated') ? 5 : 0;
174
+ return {
175
+ durableLocators: coverage.totalActions ? Math.round(((coverage.durableActions + coverage.nativeFallbackActions * 0.6) / coverage.totalActions) * 35) : 0,
176
+ workflowEvidence,
177
+ stateProfiles,
178
+ idling,
179
+ safeDestructiveBoundaries,
180
+ replayEvidence,
181
+ };
182
+ }
183
+ export function automationReadinessForSession(session, opts = {}) {
184
+ const labels = readinessForSession(session, opts);
185
+ const coverage = locatorCoverage(session.recordedActions);
186
+ const breakdown = scoreBreakdown(session, labels, coverage);
187
+ const score = Math.max(0, Math.min(100, Object.values(breakdown).reduce((a, b) => a + b, 0)));
188
+ const fixes = uniqueTop([
189
+ ...session.notes.map(noteFix).filter((x) => !!x),
190
+ ...session.findings.map(findingFix),
191
+ ...session.recordedActions.map(actionFix).filter((x) => !!x),
192
+ coverage.totalActions && coverage.durablePct < 80 ? `Raise durable locator coverage from ${coverage.durablePct}% to at least 80% before release gating.` : '',
193
+ session.notes.length ? '' : 'Record workflow outcomes with qa_note so readiness can be reviewed by workflow.',
194
+ session.mutations.some((m) => m.action === 'state_profile_mutation' && m.status === 'executed') ? '' : 'Add a declared state profile for repeatable setup and teardown.',
195
+ session.workarounds.some((w) => /idling:/i.test(w)) ? '' : 'Add an app-declared idling hook for stable waits.',
196
+ ], 10);
197
+ return {
198
+ grade: gradeFromScore(score),
199
+ score,
200
+ labels,
201
+ scoreBreakdown: breakdown,
202
+ locatorCoverage: coverage,
203
+ locatorCoverageTrend: [{ label: 'current_session', durablePct: coverage.durablePct, totalActions: coverage.totalActions }],
204
+ workflowGrades: workflowGrades(session.notes, coverage.durablePct),
205
+ screenGrades: screenGrades(session.recordedActions),
206
+ topFixes: fixes,
207
+ prComments: fixes.slice(0, 5).map((fix, i) => ({
208
+ severity: i === 0 && score < 70 ? 'blocker' : score < 85 ? 'warning' : 'info',
209
+ body: `Swipium automation readiness: ${fix}`,
210
+ })),
211
+ };
212
+ }
213
+ //# sourceMappingURL=readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readiness.js","sourceRoot":"","sources":["../../src/report/readiness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ // Release assessment (PHASE3-PLAN §3.5 Report 2.0) — turn the accumulated health + outcomes
2
+ // into a single verdict a non-QA developer can act on: ship | caution | block, with reasons
3
+ // and the one most important next action. Pure + deterministic so it's unit-testable.
4
+ export function releaseAssessment(i) {
5
+ const reasons = [];
6
+ const blocking = i.nativeHealth === 'error' || i.appHealth === 'error' || i.highSeverityCount > 0 || i.failCount > 0;
7
+ if (i.nativeHealth === 'error')
8
+ reasons.push('native crash/ANR detected');
9
+ if (i.appHealth === 'error')
10
+ reasons.push('app-level error surface (ErrorBoundary/RedBox)');
11
+ if (i.highSeverityCount > 0)
12
+ reasons.push(`${i.highSeverityCount} high-severity finding(s)`);
13
+ if (i.failCount > 0)
14
+ reasons.push(`${i.failCount} workflow(s) failed`);
15
+ if (blocking) {
16
+ const next = i.topFail
17
+ ? `Fix "${i.topFail.workflow}"${i.topFail.reason ? ` — ${i.topFail.reason}` : ''} before shipping.`
18
+ : i.topHighFinding
19
+ ? `Investigate: ${i.topHighFinding}`
20
+ : 'Resolve the blocking health issue before shipping.';
21
+ return { risk: 'block', reasons, nextAction: next };
22
+ }
23
+ const cautions = [];
24
+ if (i.appHealth === 'degraded')
25
+ cautions.push('app health degraded (non-fatal warnings/LogBox)');
26
+ if (i.blockedCount > 0)
27
+ cautions.push(`${i.blockedCount} workflow(s) blocked by missing preconditions`);
28
+ if (i.overrideCount > 0)
29
+ cautions.push(`${i.overrideCount} guardrail override(s) used`);
30
+ if (cautions.length) {
31
+ const next = i.topBlocked
32
+ ? `Provide setup for "${i.topBlocked.workflow}"${i.topBlocked.recommendedSetup ? `: ${i.topBlocked.recommendedSetup}` : ''}, then re-run.`
33
+ : 'Review the cautions below before shipping.';
34
+ return { risk: 'caution', reasons: cautions, nextAction: next };
35
+ }
36
+ return {
37
+ risk: 'ship',
38
+ reasons: ['no blocking findings; native + app healthy'],
39
+ nextAction: 'No blocking issues found in simulator/emulator evidence.',
40
+ };
41
+ }
42
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/report/summary.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,4FAA4F;AAC5F,sFAAsF;AAsBtF,MAAM,UAAU,iBAAiB,CAAC,CAAY;IAC5C,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,MAAM,QAAQ,GACZ,CAAC,CAAC,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,SAAS,KAAK,OAAO,IAAI,CAAC,CAAC,iBAAiB,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;IACtG,IAAI,CAAC,CAAC,YAAY,KAAK,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAC1E,IAAI,CAAC,CAAC,SAAS,KAAK,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IAC5F,IAAI,CAAC,CAAC,iBAAiB,GAAG,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,2BAA2B,CAAC,CAAC;IAC7F,IAAI,CAAC,CAAC,SAAS,GAAG,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,qBAAqB,CAAC,CAAC;IAEvE,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO;YACpB,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,mBAAmB;YACnG,CAAC,CAAC,CAAC,CAAC,cAAc;gBAChB,CAAC,CAAC,gBAAgB,CAAC,CAAC,cAAc,EAAE;gBACpC,CAAC,CAAC,oDAAoD,CAAC;QAC3D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IACtD,CAAC;IAED,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,CAAC,CAAC,SAAS,KAAK,UAAU;QAAE,QAAQ,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;IACjG,IAAI,CAAC,CAAC,YAAY,GAAG,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,YAAY,+CAA+C,CAAC,CAAC;IACxG,IAAI,CAAC,CAAC,aAAa,GAAG,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,aAAa,6BAA6B,CAAC,CAAC;IACxF,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU;YACvB,CAAC,CAAC,sBAAsB,CAAC,CAAC,UAAU,CAAC,QAAQ,IAAI,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB;YAC1I,CAAC,CAAC,4CAA4C,CAAC;QACjD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAClE,CAAC;IAED,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,CAAC,4CAA4C,CAAC;QACvD,UAAU,EAAE,0DAA0D;KACvE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,93 @@
1
+ // Universal run test catalog (Developer-3 plan Deliverable 4 / review item #6). The POM test-case
2
+ // catalog only exists when a suite is generated; this builds a catalog for EVERY run — executed,
3
+ // skipped, blocked, and exploration-promoted workflows — straight from the session's observed state
4
+ // (smoke notes, findings, exploration summary, suite status). Pure + deterministic so blocked and
5
+ // no-suite runs are documented as thoroughly as a green suite run, and skipped/blocked entries are
6
+ // as visible as passing ones.
7
+ const KNOWN_STATUSES = ['pass', 'fail', 'blocked', 'skipped', 'not_applicable', 'observed'];
8
+ function asStatus(outcome) {
9
+ return KNOWN_STATUSES.includes(outcome) ? outcome : 'observed';
10
+ }
11
+ export function buildRunTestCatalog(input) {
12
+ const entries = [];
13
+ const automation = input.suiteGenerated ? 'partial' : 'manual';
14
+ const replayStatus = input.suiteReplayStatus ?? 'not_replayed';
15
+ const preconditions = ['app installed', ...(input.fixtures ?? [])];
16
+ // 1. One entry per recorded workflow outcome — pass/fail/blocked/skipped all equally visible.
17
+ input.notes.forEach((n, i) => {
18
+ const status = asStatus(n.outcome);
19
+ const blockers = [];
20
+ if (status === 'blocked' || status === 'fail') {
21
+ if (n.missingPrecondition)
22
+ blockers.push(`missing precondition: ${n.missingPrecondition}`);
23
+ if (n.reason)
24
+ blockers.push(n.reason);
25
+ if (n.recommendedSetup)
26
+ blockers.push(`recommended setup: ${n.recommendedSetup}`);
27
+ if (!blockers.length)
28
+ blockers.push(`${status} with no recorded reason`);
29
+ }
30
+ entries.push({
31
+ id: `RTC-${String(i + 1).padStart(3, '0')}`,
32
+ objective: `Verify the "${n.workflow}" workflow.`,
33
+ status,
34
+ preconditions,
35
+ steps: [`Exercise the ${n.workflow} workflow`],
36
+ expectedResult: 'Workflow completes without an error surface.',
37
+ actualResult: `${n.workflow}: ${n.outcome}${n.reason ? ` — ${n.reason}` : ''}${n.verifiedVisually || n.method === 'visual' ? ' (visual-only evidence — weaker than a structured assertion)' : ''}`,
38
+ evidence: n.artifactUris ?? [],
39
+ blockers,
40
+ cleanup: ['return to home/initial screen'],
41
+ automationReadiness: automation,
42
+ replayStatus,
43
+ source: 'note',
44
+ });
45
+ });
46
+ // 2. Guided exploration coverage as a first-class catalog entry (promoted/visited workflows).
47
+ if (input.exploration) {
48
+ const e = input.exploration;
49
+ entries.push({
50
+ id: `RTC-${String(entries.length + 1).padStart(3, '0')}`,
51
+ objective: 'Guided exploration coverage of reachable screens and workflows.',
52
+ status: e.appErrors > 0 ? 'fail' : e.screensVisited > 0 ? 'pass' : 'observed',
53
+ preconditions,
54
+ steps: [`Explore reachable screens safely (${e.screensVisited} visited, ${e.workflowsFound} transitions)`],
55
+ expectedResult: 'Reachable workflows explored without unsafe actions or error surfaces.',
56
+ actualResult: `${e.screensVisited} screens, ${e.workflowsFound} transitions, ${e.visualOnlyScreens} visual-only, ${e.unsafeActionsSkipped} unsafe skipped, ${e.appErrors} app errors`,
57
+ evidence: [],
58
+ blockers: e.blockers ?? [],
59
+ cleanup: [],
60
+ automationReadiness: input.suiteGenerated ? 'partial' : 'none',
61
+ replayStatus,
62
+ source: 'exploration',
63
+ });
64
+ }
65
+ // 3. Baseline launch entry when nothing else describes the run, so an "empty" run is still honest.
66
+ if (!entries.length) {
67
+ const findingBlockers = input.findings.filter((f) => f.severity === 'high').map((f) => `${f.kind}: ${f.detail}`);
68
+ entries.push({
69
+ id: 'RTC-001',
70
+ objective: 'Launch the app and capture baseline evidence.',
71
+ status: input.observed ? (findingBlockers.length ? 'fail' : 'observed') : 'not_applicable',
72
+ preconditions,
73
+ steps: ['Launch the app'],
74
+ expectedResult: 'App launches and is foregrounded without a crash or fatal error surface.',
75
+ actualResult: input.observed
76
+ ? findingBlockers.length
77
+ ? 'App launched but a high-severity issue was observed.'
78
+ : 'App launched and baseline evidence was captured (no discrete workflow recorded).'
79
+ : 'No launch evidence captured.',
80
+ evidence: [],
81
+ blockers: findingBlockers,
82
+ cleanup: [],
83
+ automationReadiness: 'none',
84
+ replayStatus: 'not_replayed',
85
+ source: 'baseline',
86
+ });
87
+ }
88
+ const counts = Object.fromEntries(KNOWN_STATUSES.map((s) => [s, 0]));
89
+ for (const entry of entries)
90
+ counts[entry.status]++;
91
+ return { entries, counts, total: entries.length };
92
+ }
93
+ //# sourceMappingURL=testCatalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testCatalog.js","sourceRoot":"","sources":["../../src/report/testCatalog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ export function phaseTimingsForSession(session, now = Date.now()) {
2
+ const start = session.milestones.session_start ?? session.createdAt;
3
+ const firstAction = session.milestones.first_action;
4
+ const sec = (ms) => Math.max(0, Math.round(ms / 1000));
5
+ const pair = (from, to) => {
6
+ const a = session.milestones[from];
7
+ const b = session.milestones[to];
8
+ return a != null && b != null ? sec(b - a) : null;
9
+ };
10
+ const aggregate = (key) => session.milestones[key] != null ? sec(session.milestones[key]) : null;
11
+ return {
12
+ totalSec: sec(now - start),
13
+ setupSec: sec((firstAction ?? now) - start),
14
+ activeSec: firstAction ? sec(now - firstAction) : 0,
15
+ timeToLoginSec: session.milestones.login_performed ? sec(session.milestones.login_performed - start) : null,
16
+ diagnostics: {
17
+ simulatorBootSec: pair('simulator_boot_start', 'simulator_boot_end'),
18
+ appInstallSec: pair('app_install_start', 'app_install_end'),
19
+ appLaunchSec: pair('app_launch_start', 'app_launch_end'),
20
+ wdaBuildSec: pair('wda_build_start', 'wda_build_end'),
21
+ wdaStartSec: pair('wda_start_start', 'wda_start_end'),
22
+ wdaReuseCheckSec: aggregate('wda_reuse_check_ms'),
23
+ wdaStartupWaitSec: aggregate('wda_startup_wait_ms'),
24
+ wdaSessionCreateSec: aggregate('wda_session_create_ms'),
25
+ wdaSourceSec: aggregate('wda_source_ms'),
26
+ wdaFindElementSec: aggregate('wda_find_element_ms'),
27
+ wdaTapSec: aggregate('wda_tap_ms'),
28
+ wdaTypeSec: aggregate('wda_type_ms'),
29
+ wdaClearSec: aggregate('wda_clear_ms'),
30
+ wdaScreenshotSec: aggregate('wda_screenshot_ms'),
31
+ flowRuntimeSec: aggregate('flow_runtime_ms'),
32
+ waitSec: aggregate('wait_ms'),
33
+ screenshotCount: session.counters?.screenshots ?? null,
34
+ },
35
+ };
36
+ }
37
+ //# sourceMappingURL=timing.js.map