@solidxai/core 0.1.15 → 0.1.16-beta.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 (171) hide show
  1. package/CHANGELOG.md +642 -0
  2. package/dist/commands/run-tests.command.d.ts +3 -1
  3. package/dist/commands/run-tests.command.d.ts.map +1 -1
  4. package/dist/commands/run-tests.command.js +6 -2
  5. package/dist/commands/run-tests.command.js.map +1 -1
  6. package/dist/controllers/test-run.controller.d.ts +12 -0
  7. package/dist/controllers/test-run.controller.d.ts.map +1 -0
  8. package/dist/controllers/test-run.controller.js +54 -0
  9. package/dist/controllers/test-run.controller.js.map +1 -0
  10. package/dist/dtos/test-run-request.dto.d.ts +35 -0
  11. package/dist/dtos/test-run-request.dto.d.ts.map +1 -0
  12. package/dist/dtos/test-run-request.dto.js +120 -0
  13. package/dist/dtos/test-run-request.dto.js.map +1 -0
  14. package/dist/guards/access-token.guard.d.ts +5 -1
  15. package/dist/guards/access-token.guard.d.ts.map +1 -1
  16. package/dist/guards/access-token.guard.js +20 -1
  17. package/dist/guards/access-token.guard.js.map +1 -1
  18. package/dist/index.d.ts +12 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +17 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/interfaces/active-user-data.interface.d.ts +1 -0
  23. package/dist/interfaces/active-user-data.interface.d.ts.map +1 -1
  24. package/dist/interfaces/active-user-data.interface.js.map +1 -1
  25. package/dist/jobs/database/test-run-queue-options-database.d.ts +8 -0
  26. package/dist/jobs/database/test-run-queue-options-database.d.ts.map +1 -0
  27. package/dist/jobs/database/test-run-queue-options-database.js +10 -0
  28. package/dist/jobs/database/test-run-queue-options-database.js.map +1 -0
  29. package/dist/jobs/database/test-run-queue-publisher-database.service.d.ts +12 -0
  30. package/dist/jobs/database/test-run-queue-publisher-database.service.d.ts.map +1 -0
  31. package/dist/jobs/database/test-run-queue-publisher-database.service.js +39 -0
  32. package/dist/jobs/database/test-run-queue-publisher-database.service.js.map +1 -0
  33. package/dist/jobs/database/test-run-queue-subscriber-database.service.d.ts +26 -0
  34. package/dist/jobs/database/test-run-queue-subscriber-database.service.d.ts.map +1 -0
  35. package/dist/jobs/database/test-run-queue-subscriber-database.service.js +120 -0
  36. package/dist/jobs/database/test-run-queue-subscriber-database.service.js.map +1 -0
  37. package/dist/seeders/seed-data/solid-core-metadata.json +3 -1
  38. package/dist/services/access-token-denylist.service.d.ts +16 -0
  39. package/dist/services/access-token-denylist.service.d.ts.map +1 -0
  40. package/dist/services/access-token-denylist.service.js +74 -0
  41. package/dist/services/access-token-denylist.service.js.map +1 -0
  42. package/dist/services/authentication.service.d.ts +9 -1
  43. package/dist/services/authentication.service.d.ts.map +1 -1
  44. package/dist/services/authentication.service.js +39 -4
  45. package/dist/services/authentication.service.js.map +1 -1
  46. package/dist/services/import-transaction.service.d.ts +1 -1
  47. package/dist/services/import-transaction.service.d.ts.map +1 -1
  48. package/dist/services/import-transaction.service.js +13 -23
  49. package/dist/services/import-transaction.service.js.map +1 -1
  50. package/dist/services/settings/default-settings-provider.service.d.ts +20 -0
  51. package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
  52. package/dist/services/settings/default-settings-provider.service.js +11 -0
  53. package/dist/services/settings/default-settings-provider.service.js.map +1 -1
  54. package/dist/services/workflow-secret.service.d.ts +3 -0
  55. package/dist/services/workflow-secret.service.d.ts.map +1 -1
  56. package/dist/services/workflow-secret.service.js +25 -0
  57. package/dist/services/workflow-secret.service.js.map +1 -1
  58. package/dist/solid-core.module.d.ts.map +1 -1
  59. package/dist/solid-core.module.js +9 -0
  60. package/dist/solid-core.module.js.map +1 -1
  61. package/dist/testing/adapters/ui/browser-provisioner.d.ts +5 -0
  62. package/dist/testing/adapters/ui/browser-provisioner.d.ts.map +1 -0
  63. package/dist/testing/adapters/ui/browser-provisioner.js +102 -0
  64. package/dist/testing/adapters/ui/browser-provisioner.js.map +1 -0
  65. package/dist/testing/adapters/ui/playwright-adapter.d.ts +40 -1
  66. package/dist/testing/adapters/ui/playwright-adapter.d.ts.map +1 -1
  67. package/dist/testing/adapters/ui/playwright-adapter.js +185 -3
  68. package/dist/testing/adapters/ui/playwright-adapter.js.map +1 -1
  69. package/dist/testing/adapters/ui/ui.types.d.ts +6 -0
  70. package/dist/testing/adapters/ui/ui.types.d.ts.map +1 -1
  71. package/dist/testing/adapters/ui/ui.types.js.map +1 -1
  72. package/dist/testing/contracts/runtime-context.types.d.ts +2 -0
  73. package/dist/testing/contracts/runtime-context.types.d.ts.map +1 -1
  74. package/dist/testing/contracts/runtime-context.types.js.map +1 -1
  75. package/dist/testing/core/interpolation.d.ts +1 -0
  76. package/dist/testing/core/interpolation.d.ts.map +1 -1
  77. package/dist/testing/core/interpolation.js +28 -68
  78. package/dist/testing/core/interpolation.js.map +1 -1
  79. package/dist/testing/core/path-resolution.spec.d.ts +2 -0
  80. package/dist/testing/core/path-resolution.spec.d.ts.map +1 -0
  81. package/dist/testing/core/path-resolution.spec.js +106 -0
  82. package/dist/testing/core/path-resolution.spec.js.map +1 -0
  83. package/dist/testing/core/path-segments.d.ts +2 -0
  84. package/dist/testing/core/path-segments.d.ts.map +1 -0
  85. package/dist/testing/core/path-segments.js +70 -0
  86. package/dist/testing/core/path-segments.js.map +1 -0
  87. package/dist/testing/core/resource-store.d.ts.map +1 -1
  88. package/dist/testing/core/resource-store.js +5 -2
  89. package/dist/testing/core/resource-store.js.map +1 -1
  90. package/dist/testing/core/testing-engine.d.ts.map +1 -1
  91. package/dist/testing/core/testing-engine.js +16 -0
  92. package/dist/testing/core/testing-engine.js.map +1 -1
  93. package/dist/testing/reporter/artifact-sink.d.ts +14 -0
  94. package/dist/testing/reporter/artifact-sink.d.ts.map +1 -0
  95. package/dist/testing/reporter/artifact-sink.js +3 -0
  96. package/dist/testing/reporter/artifact-sink.js.map +1 -0
  97. package/dist/testing/reporter/console-reporter.d.ts.map +1 -1
  98. package/dist/testing/reporter/console-reporter.js +7 -0
  99. package/dist/testing/reporter/console-reporter.js.map +1 -1
  100. package/dist/testing/reporter/file-service-artifact-sink.d.ts +22 -0
  101. package/dist/testing/reporter/file-service-artifact-sink.d.ts.map +1 -0
  102. package/dist/testing/reporter/file-service-artifact-sink.js +31 -0
  103. package/dist/testing/reporter/file-service-artifact-sink.js.map +1 -0
  104. package/dist/testing/reporter/lifecycle-events.types.d.ts +67 -0
  105. package/dist/testing/reporter/lifecycle-events.types.d.ts.map +1 -0
  106. package/dist/testing/reporter/lifecycle-events.types.js +3 -0
  107. package/dist/testing/reporter/lifecycle-events.types.js.map +1 -0
  108. package/dist/testing/reporter/lifecycle-webhook-reporter.d.ts +77 -0
  109. package/dist/testing/reporter/lifecycle-webhook-reporter.d.ts.map +1 -0
  110. package/dist/testing/reporter/lifecycle-webhook-reporter.js +275 -0
  111. package/dist/testing/reporter/lifecycle-webhook-reporter.js.map +1 -0
  112. package/dist/testing/reporter/progress-reporter.d.ts +3 -3
  113. package/dist/testing/reporter/progress-reporter.d.ts.map +1 -1
  114. package/dist/testing/reporter/progress-reporter.js.map +1 -1
  115. package/dist/testing/reporter/reporter.types.d.ts +13 -1
  116. package/dist/testing/reporter/reporter.types.d.ts.map +1 -1
  117. package/dist/testing/reporter/reporter.types.js.map +1 -1
  118. package/dist/testing/runner/read-scenarios-file.d.ts +9 -0
  119. package/dist/testing/runner/read-scenarios-file.d.ts.map +1 -0
  120. package/dist/testing/runner/read-scenarios-file.js +56 -0
  121. package/dist/testing/runner/read-scenarios-file.js.map +1 -0
  122. package/dist/testing/runner/run-from-metadata.d.ts +7 -2
  123. package/dist/testing/runner/run-from-metadata.d.ts.map +1 -1
  124. package/dist/testing/runner/run-from-metadata.js +57 -6
  125. package/dist/testing/runner/run-from-metadata.js.map +1 -1
  126. package/dist/testing/steps/ui/navigation.step.d.ts.map +1 -1
  127. package/dist/testing/steps/ui/navigation.step.js +12 -12
  128. package/dist/testing/steps/ui/navigation.step.js.map +1 -1
  129. package/package.json +1 -1
  130. package/postman/instant-logout.postman_collection.json +1493 -0
  131. package/src/commands/run-tests.command.ts +3 -0
  132. package/src/controllers/test-run.controller.ts +44 -0
  133. package/src/dtos/test-run-request.dto.ts +130 -0
  134. package/src/guards/access-token.guard.ts +48 -0
  135. package/src/index.ts +21 -1
  136. package/src/interfaces/active-user-data.interface.ts +8 -0
  137. package/src/jobs/database/test-run-queue-options-database.ts +9 -0
  138. package/src/jobs/database/test-run-queue-publisher-database.service.ts +24 -0
  139. package/src/jobs/database/test-run-queue-subscriber-database.service.ts +122 -0
  140. package/src/seeders/seed-data/solid-core-metadata.json +3 -1
  141. package/src/services/access-token-denylist.service.ts +145 -0
  142. package/src/services/authentication.service.ts +118 -2
  143. package/src/services/import-transaction.service.ts +19 -36
  144. package/src/services/settings/default-settings-provider.service.ts +12 -0
  145. package/src/services/workflow-secret.service.ts +61 -2
  146. package/src/solid-core.module.ts +11 -0
  147. package/src/testing/README.md +44 -1
  148. package/src/testing/adapters/ui/browser-provisioner.ts +115 -0
  149. package/src/testing/adapters/ui/playwright-adapter.ts +255 -5
  150. package/src/testing/adapters/ui/ui.types.ts +14 -0
  151. package/src/testing/contracts/runtime-context.types.ts +6 -0
  152. package/src/testing/core/interpolation.ts +39 -69
  153. package/src/testing/core/path-resolution.spec.ts +133 -0
  154. package/src/testing/core/path-segments.ts +81 -0
  155. package/src/testing/core/resource-store.ts +8 -2
  156. package/src/testing/core/testing-engine.ts +22 -0
  157. package/src/testing/reporter/artifact-sink.ts +16 -0
  158. package/src/testing/reporter/console-reporter.ts +9 -0
  159. package/src/testing/reporter/file-service-artifact-sink.ts +46 -0
  160. package/src/testing/reporter/lifecycle-events.types.ts +103 -0
  161. package/src/testing/reporter/lifecycle-webhook-reporter.ts +385 -0
  162. package/src/testing/reporter/progress-reporter.ts +3 -1
  163. package/src/testing/reporter/reporter.types.ts +10 -1
  164. package/src/testing/runner/read-scenarios-file.ts +44 -0
  165. package/src/testing/runner/run-from-metadata.ts +102 -9
  166. package/src/testing/steps/ui/navigation.step.ts +24 -20
  167. package/dist/services/access-token-storage.service.d.ts +0 -1
  168. package/dist/services/access-token-storage.service.d.ts.map +0 -1
  169. package/dist/services/access-token-storage.service.js +0 -1
  170. package/dist/services/access-token-storage.service.js.map +0 -1
  171. package/src/services/access-token-storage.service.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-webhook-reporter.js","sourceRoot":"","sources":["../../../src/testing/reporter/lifecycle-webhook-reporter.ts"],"names":[],"mappings":";;;AAAA,mCAAoC;AAEpC,yDAAqD;AAqCrD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,MAAM,eAAe,GAAG,SAAS,CAAC;AAElC,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,IAAI,GAAG,YAAY,KAAK;QAAE,OAAO,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC;IAC1D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,WAAW,GAAkB,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IAC3D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC3B,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE;QACxE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAC1B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,kBAAkB,CAAC;KAClE,CAAC,CAAC;IACH,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;AAC5C,CAAC,CAAC;AAGF,SAAS,kBAAkB,CAAC,IAAY,EAAE,WAAmB;IAC3D,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,WAAW,EAAE,CAAC,WAAW,EAAE,CAAC;IACpD,IAAI,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC/E,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,YAAY,CAAC;IACzF,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/C,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACvE,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,mBAAmB,CAAC,WAAmB;IAC9C,MAAM,EAAE,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,0BAA0B,CAAC;AACjG,CAAC;AASD,MAAa,wBAAyB,SAAQ,kCAAe;IAuB3D,YAAY,IAAqC;QAC/C,KAAK,EAAE,CAAC;QAdF,QAAG,GAAG,CAAC,CAAC;QACR,gBAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,UAAK,GAAG,CAAC,CAAC;QACV,kBAAa,GAAG,CAAC,CAAC;QAClB,WAAM,GAAG,CAAC,CAAC;QACX,WAAM,GAAG,CAAC,CAAC;QACX,iBAAY,GAAqB,EAAE,CAAC;QACpC,qBAAgB,GAAkB,EAAE,CAAC;QAErC,iBAAY,GAAkB,EAAE,CAAC;QAEjC,UAAK,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;QAI/C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACxC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAA,mBAAU,GAAE,CAAC;QACxC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACtC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC;IACvC,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,UAAU,CAAC,IAKV;QACC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAqB,EAAE,CAAC,CAAC;YAChG,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;IACL,CAAC;IAEQ,eAAe,CAAC,QAAsB;QAC7C,KAAK,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;YAC1B,UAAU,EAAE,QAAQ,CAAC,EAAE;YACvB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,KAAK;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;IACL,CAAC;IAEQ,SAAS,CAAC,IAOlB;QACC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;YACrB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;YACzB,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE;YACvB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;YACpB,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;SACxD,CAAC,CAAC;IACL,CAAC;IAEQ,MAAM,CAAC,IAKf;QACC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnB,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAMnF,IAAI,MAAM,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAc,CAAC;YAChC,MAAM,QAAQ,GAAgB;gBAC5B,IAAI;gBACJ,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,SAAS,EAAE,SAAS;gBACpB,SAAS,EAAE,GAAG,CAAC,UAAU;aAC1B,CAAC;YACF,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,KAAK,CAAC;YAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;YACnC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK;iBACpB,IAAI,CAAC,KAAK,IAAI,EAAE;gBACf,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAa,CAAC,GAAG,CAAC;oBACvC,KAAK;oBACL,UAAU;oBACV,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,IAAI,EAAE,GAAG;iBACV,CAAC,CAAC;gBACH,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;gBACrC,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;YACzB,CAAC,CAAC;iBACD,KAAK,CAAC,GAAG,EAAE;YAEZ,CAAC,CAAC,CAAC;YACL,OAAO;QACT,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YAIX,MAAM,KAAK,GAAG,IAAI,CAAC,IAAc,CAAC;YAClC,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACxC,MAAM,QAAQ,GAAgB;gBAC5B,IAAI;gBACJ,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,SAAS,EAAE,QAAQ;gBACnB,SAAS,EAAE,KAAK,CAAC,UAAU;aAC5B,CAAC;YACF,IAAI,MAAM,CAAC,MAAM,IAAI,eAAe,EAAE,CAAC;gBACrC,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC;YAC/B,CAAC;YACD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YACrC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC5B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAC5B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;YACzB,IAAI;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,SAAS,EAAE,QAAQ;YACnB,UAAU,EAAE,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI;YACjF,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;SACnC,CAAC,CAAC;IACL,CAAC;IAEQ,aAAa,CACpB,QAAsB,EACtB,MAA4D;QAE5D,KAAK,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACtC,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;QACnB,CAAC;QACD,MAAM,IAAI,GAAoB;YAC5B,UAAU,EAAE,QAAQ,CAAC,EAAE;YACvB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;YAC3D,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;YAC7B,SAAS,EAAE,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC;SACtC,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAOD,iBAAiB,CAAC,IAAkE;QAClF,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAEnF,IAAI,MAAM,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAc,CAAC;YAChC,MAAM,QAAQ,GAAgB;gBAC5B,IAAI;gBACJ,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,SAAS,EAAE,SAAS;gBACpB,SAAS,EAAE,GAAG,CAAC,UAAU;aAC1B,CAAC;YACF,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACjC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,KAAK,CAAC;YAC/C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK;iBACpB,IAAI,CAAC,KAAK,IAAI,EAAE;gBACf,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAa,CAAC,GAAG,CAAC;oBACvC,KAAK;oBACL,UAAU,EAAE,KAAK;oBACjB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,IAAI,EAAE,GAAG;iBACV,CAAC,CAAC;gBACH,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;gBACrC,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;YACzB,CAAC,CAAC;iBACD,KAAK,CAAC,GAAG,EAAE;YAEZ,CAAC,CAAC,CAAC;YACL,OAAO;QACT,CAAC;QAGD,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,KAAK,GAAG,IAAI,CAAC,IAAc,CAAC;YAClC,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACxC,MAAM,QAAQ,GAAgB;gBAC5B,IAAI;gBACJ,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,SAAS,EAAE,QAAQ;gBACnB,SAAS,EAAE,KAAK,CAAC,UAAU;aAC5B,CAAC;YACF,IAAI,MAAM,CAAC,MAAM,IAAI,eAAe;gBAAE,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC;YACnE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAC/F,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;YACrB,IAAI;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,SAAS,EAAE,QAAQ;YACnB,UAAU,EAAE,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI;YACjF,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;SACnC,CAAC,CAAC;IACL,CAAC;IAOD,KAAK,CAAC,YAAY,CAAC,QAAiB,EAAE,KAAc;QAClD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAGnB,EAAE,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,CAAC,CAAC;YACnE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM;YAC9C,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW;YACzC,QAAQ;YACR,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS;SACzE,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAEO,IAAI,CAAI,KAAyB,EAAE,IAAO;QAChD,MAAM,QAAQ,GAAyB;YACrC,KAAK;YACL,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;YACf,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,IAAI;SACL,CAAC;QACF,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC7E,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,QAA2B;QAC/C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE;gBACrD,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,kBAAkB;aAC9B,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,OAAO,CAAC,IAAI,CACV,8BAA8B,QAAQ,CAAC,KAAK,WAAW,GAAG,CAAC,MAAM,EAAE,CACpE,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CACV,gDAAgD,QAAQ,CAAC,KAAK,KAAK,GAAG,EAAE,CACzE,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AA9SD,4DA8SC","sourcesContent":["import { randomUUID } from \"crypto\";\n\nimport { ConsoleReporter } from \"./console-reporter\";\nimport type { IArtifactSink } from \"./artifact-sink\";\nimport type {\n ArtifactRef,\n LifecycleEnvelope,\n LifecycleEventType,\n ScenarioDescriptor,\n ScenarioEndData,\n StepResultData,\n} from \"./lifecycle-events.types\";\nimport type { OpStep, ScenarioSpec, ScenarioType } from \"../contracts/testing-metadata.types\";\nimport type { StepPhase } from \"../contracts/runtime-context.types\";\n\n/**\n * Pluggable POST function so the reporter stays DI-agnostic. The default uses the\n * global `fetch`; the Nest worker can inject an axios-backed implementation that\n * shares the existing HttpModule stack.\n */\nexport type WebhookPostFn = (\n url: string,\n body: unknown,\n opts: { headers?: Record<string, string>; timeoutMs?: number },\n) => Promise<{ ok: boolean; status: number }>;\n\nexport interface LifecycleWebhookReporterOptions {\n webhookUrl: string;\n runName: string;\n /** correlation id supplied by the caller (e.g. testingHub TestRun id). */\n externalRunId?: string;\n /** runner-generated uuid for this process run; auto-generated when omitted. */\n runId?: string;\n /** Phase 2: sink for binary artifacts (screenshots/video/HAR). */\n artifactSink?: IArtifactSink;\n headers?: Record<string, string>;\n post?: WebhookPostFn;\n}\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n/** Cap inline text artifacts so a webhook body never blows past receiver limits. */\nconst INLINE_TEXT_CAP = 1_000_000;\n\nfunction formatError(err: unknown): string {\n if (!err) return \"\";\n if (err instanceof Error) return err.stack || err.message;\n return String(err);\n}\n\nconst defaultPost: WebhookPostFn = async (url, body, opts) => {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...(opts.headers ?? {}) },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS),\n });\n return { ok: res.ok, status: res.status };\n};\n\n/** Map an `attach()` payload to an ArtifactRef. Covers API/console/network + video/screenshots. */\nfunction classifyAttachment(name: string, contentType: string): ArtifactRef[\"kind\"] {\n const hint = `${name} ${contentType}`.toLowerCase();\n if (contentType.startsWith(\"video/\") || hint.includes(\"video\")) return \"video\";\n if (hint.includes(\"screenshot\") || contentType.startsWith(\"image/\")) return \"screenshot\";\n if (hint.includes(\"console\")) return \"console\";\n if (hint.includes(\"network\") || hint.includes(\"har\")) return \"network\";\n if (hint.includes(\"api\")) return \"api-log\";\n return \"api-log\";\n}\n\nfunction isBinaryContentType(contentType: string): boolean {\n const ct = contentType.toLowerCase();\n return ct.startsWith(\"image/\") || ct.startsWith(\"video/\") || ct === \"application/octet-stream\";\n}\n\n/**\n * Emits incremental lifecycle webhooks (run.start → scenario.start → scenario.end →\n * run.end) to a single URL, while still printing to the console (extends\n * ConsoleReporter). Deliveries are serialized through an async chain so ordering is\n * preserved without blocking step execution, and a failed POST never throws into the\n * run. Distinct from the legacy {@link WebhookReporter}, which only fires once on flush.\n */\nexport class LifecycleWebhookReporter extends ConsoleReporter {\n private readonly webhookUrl: string;\n private readonly runName: string;\n private readonly externalRunId?: string;\n private readonly runId: string;\n private readonly headers?: Record<string, string>;\n private readonly post: WebhookPostFn;\n /** Phase 2: used to upload binary artifacts in onScenarioEnd. */\n protected readonly artifactSink?: IArtifactSink;\n\n private seq = 0;\n private startedAtMs = Date.now();\n private total = 0;\n private scenarioIndex = 0;\n private passed = 0;\n private failed = 0;\n private currentSteps: StepResultData[] = [];\n private currentArtifacts: ArtifactRef[] = [];\n /** Run-level artifacts (e.g. the whole-run video); emitted on run.end. */\n private runArtifacts: ArtifactRef[] = [];\n /** Serializes webhook deliveries to preserve order. */\n private chain: Promise<void> = Promise.resolve();\n\n constructor(opts: LifecycleWebhookReporterOptions) {\n super();\n this.webhookUrl = opts.webhookUrl;\n this.runName = opts.runName;\n this.externalRunId = opts.externalRunId;\n this.runId = opts.runId ?? randomUUID();\n this.artifactSink = opts.artifactSink;\n this.headers = opts.headers;\n this.post = opts.post ?? defaultPost;\n }\n\n getRunId(): string {\n return this.runId;\n }\n\n onRunStart(args: {\n total: number;\n startedAt: string;\n scenarioIds: string[];\n scenarios?: ScenarioDescriptor[];\n }): void {\n this.total = args.total;\n this.startedAtMs = Date.now();\n this.emit(\"run.start\", {\n total: args.total,\n scenarioIds: args.scenarioIds,\n scenarios: args.scenarios ?? args.scenarioIds.map((id) => ({ id, type: \"api\" as ScenarioType })),\n startedAt: args.startedAt,\n });\n }\n\n override onScenarioStart(scenario: ScenarioSpec): void {\n super.onScenarioStart(scenario);\n this.currentSteps = [];\n this.currentArtifacts = [];\n const index = this.scenarioIndex++;\n this.emit(\"scenario.start\", {\n scenarioId: scenario.id,\n name: scenario.name,\n type: scenario.type,\n index,\n total: this.total,\n });\n }\n\n override onStepEnd(args: {\n scenarioId: string;\n phase: StepPhase;\n step: OpStep;\n ok: boolean;\n error?: unknown;\n durationMs: number;\n }): void {\n super.onStepEnd(args);\n this.currentSteps.push({\n phase: String(args.phase),\n operation: args.step.op,\n name: args.step.name,\n ok: args.ok,\n durationMs: args.durationMs,\n error: args.error ? formatError(args.error) : undefined,\n });\n }\n\n override attach(args: {\n scenarioId: string;\n name: string;\n contentType: string;\n data: Buffer | string;\n }): void {\n super.attach(args);\n const kind = classifyAttachment(args.name, args.contentType);\n const binary = Buffer.isBuffer(args.data) && isBinaryContentType(args.contentType);\n\n // Binary artifacts (screenshots, video): when a storage sink is configured, upload the bytes\n // to shared storage and reference them by storageKey/url — never ship blobs inline (the\n // inline cap would silently drop anything large, e.g. a video). The ref is mutated in place\n // by an upload queued onto the delivery chain, so it resolves before scenario.end is posted.\n if (binary && this.artifactSink) {\n const buf = args.data as Buffer;\n const artifact: ArtifactRef = {\n kind,\n name: args.name,\n contentType: args.contentType,\n transport: \"storage\",\n sizeBytes: buf.byteLength,\n };\n this.currentArtifacts.push(artifact);\n const runId = this.externalRunId ?? this.runId;\n const scenarioId = args.scenarioId;\n this.chain = this.chain\n .then(async () => {\n const ref = await this.artifactSink!.put({\n runId,\n scenarioId,\n name: args.name,\n contentType: args.contentType,\n data: buf,\n });\n artifact.storageKey = ref.storageKey;\n artifact.url = ref.url;\n })\n .catch(() => {\n /* upload failed — leave the ref without a key; the ingest side skips empty refs */\n });\n return;\n }\n\n if (binary) {\n // Binary (e.g. a screenshot JPEG): base64-encode — a utf8 decode would corrupt the\n // bytes. Truncating base64 also corrupts it, so if it somehow exceeds the inline cap\n // we drop the payload rather than ship a broken image (viewport JPEGs stay well under).\n const bytes = args.data as Buffer;\n const base64 = bytes.toString(\"base64\");\n const artifact: ArtifactRef = {\n kind,\n name: args.name,\n contentType: args.contentType,\n transport: \"inline\",\n sizeBytes: bytes.byteLength,\n };\n if (base64.length <= INLINE_TEXT_CAP) {\n artifact.inlineData = base64;\n }\n this.currentArtifacts.push(artifact);\n return;\n }\n\n const text = Buffer.isBuffer(args.data)\n ? args.data.toString(\"utf8\")\n : String(args.data ?? \"\");\n this.currentArtifacts.push({\n kind,\n name: args.name,\n contentType: args.contentType,\n transport: \"inline\",\n inlineData: text.length > INLINE_TEXT_CAP ? text.slice(0, INLINE_TEXT_CAP) : text,\n sizeBytes: Buffer.byteLength(text),\n });\n }\n\n override onScenarioEnd(\n scenario: ScenarioSpec,\n result: { ok: boolean; error?: unknown; durationMs: number },\n ): void {\n super.onScenarioEnd(scenario, result);\n if (result.ok) {\n this.passed += 1;\n } else {\n this.failed += 1;\n }\n const data: ScenarioEndData = {\n scenarioId: scenario.id,\n name: scenario.name,\n ok: result.ok,\n durationMs: result.durationMs,\n error: result.error ? formatError(result.error) : undefined,\n steps: [...this.currentSteps],\n artifacts: [...this.currentArtifacts],\n };\n this.emit(\"scenario.end\", data);\n }\n\n /**\n * Attach a run-level binary artifact (e.g. the whole-run video). Uploaded to shared storage\n * via the sink (never inline for a video) and referenced by storageKey/url on run.end. Must\n * be called before {@link flushPending} so the upload is queued ahead of the run.end delivery.\n */\n attachRunArtifact(args: { name: string; contentType: string; data: Buffer | string }): void {\n const kind = classifyAttachment(args.name, args.contentType);\n const binary = Buffer.isBuffer(args.data) && isBinaryContentType(args.contentType);\n\n if (binary && this.artifactSink) {\n const buf = args.data as Buffer;\n const artifact: ArtifactRef = {\n kind,\n name: args.name,\n contentType: args.contentType,\n transport: \"storage\",\n sizeBytes: buf.byteLength,\n };\n this.runArtifacts.push(artifact);\n const runId = this.externalRunId ?? this.runId;\n this.chain = this.chain\n .then(async () => {\n const ref = await this.artifactSink!.put({\n runId,\n scenarioId: \"run\",\n name: args.name,\n contentType: args.contentType,\n data: buf,\n });\n artifact.storageKey = ref.storageKey;\n artifact.url = ref.url;\n })\n .catch(() => {\n /* upload failed — leave the ref without a key; ingest skips empty refs */\n });\n return;\n }\n\n // No sink: fall back to inline (a large video base64 that exceeds the cap is dropped).\n if (binary) {\n const bytes = args.data as Buffer;\n const base64 = bytes.toString(\"base64\");\n const artifact: ArtifactRef = {\n kind,\n name: args.name,\n contentType: args.contentType,\n transport: \"inline\",\n sizeBytes: bytes.byteLength,\n };\n if (base64.length <= INLINE_TEXT_CAP) artifact.inlineData = base64;\n this.runArtifacts.push(artifact);\n return;\n }\n\n const text = Buffer.isBuffer(args.data) ? args.data.toString(\"utf8\") : String(args.data ?? \"\");\n this.runArtifacts.push({\n kind,\n name: args.name,\n contentType: args.contentType,\n transport: \"inline\",\n inlineData: text.length > INLINE_TEXT_CAP ? text.slice(0, INLINE_TEXT_CAP) : text,\n sizeBytes: Buffer.byteLength(text),\n });\n }\n\n /**\n * Emit run.end and wait for all queued deliveries to complete. `error` names a\n * run-level failure reason (e.g. an unreadable scenario file) so a run that failed\n * before any scenario ran carries a clear message rather than a bare count.\n */\n async flushPending(exitCode?: number, error?: string): Promise<void> {\n this.emit(\"run.end\", {\n // A non-zero exitCode (e.g. the runner threw before any scenario ran) must\n // mark the run failed even when failed === 0.\n ok: this.failed === 0 && (exitCode === undefined || exitCode === 0),\n total: this.total || this.passed + this.failed,\n passed: this.passed,\n failed: this.failed,\n durationMs: Date.now() - this.startedAtMs,\n exitCode,\n error,\n artifacts: this.runArtifacts.length ? [...this.runArtifacts] : undefined,\n });\n await this.chain;\n }\n\n private emit<T>(event: LifecycleEventType, data: T): void {\n const envelope: LifecycleEnvelope<T> = {\n event,\n externalRunId: this.externalRunId,\n runId: this.runId,\n runName: this.runName,\n seq: this.seq++,\n emittedAt: new Date().toISOString(),\n data,\n };\n this.chain = this.chain.then(() => this.deliver(envelope)).catch(() => {});\n }\n\n private async deliver(envelope: LifecycleEnvelope): Promise<void> {\n try {\n const res = await this.post(this.webhookUrl, envelope, {\n headers: this.headers,\n timeoutMs: DEFAULT_TIMEOUT_MS,\n });\n if (!res.ok) {\n console.warn(\n `[LifecycleWebhookReporter] ${envelope.event} → HTTP ${res.status}`,\n );\n }\n } catch (err) {\n console.warn(\n `[LifecycleWebhookReporter] failed to deliver ${envelope.event}: ${err}`,\n );\n }\n }\n}\n"]}
@@ -2,6 +2,7 @@ import type { StepPhase } from "../contracts/runtime-context.types";
2
2
  import type { OpStep, ScenarioSpec } from "../contracts/testing-metadata.types";
3
3
  import type { SolidTestSpecResult } from "../contracts/test-spec.types";
4
4
  import type { Reporter } from "./reporter.types";
5
+ type RunStartArgs = Parameters<NonNullable<Reporter["onRunStart"]>>[0];
5
6
  export declare class ProgressReporter implements Reporter {
6
7
  private readonly delegate;
7
8
  private startedAt;
@@ -12,9 +13,7 @@ export declare class ProgressReporter implements Reporter {
12
13
  private timer?;
13
14
  private rendered;
14
15
  constructor(delegate: Reporter);
15
- onRunStart(args: {
16
- total: number;
17
- }): void;
16
+ onRunStart(args: RunStartArgs): void;
18
17
  onScenarioStart(scenario: ScenarioSpec): void;
19
18
  onScenarioEnd(scenario: ScenarioSpec, result: {
20
19
  ok: boolean;
@@ -61,4 +60,5 @@ export declare class ProgressReporter implements Reporter {
61
60
  private renderProgressBar;
62
61
  private isInteractive;
63
62
  }
63
+ export {};
64
64
  //# sourceMappingURL=progress-reporter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"progress-reporter.d.ts","sourceRoot":"","sources":["../../../src/testing/reporter/progress-reporter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAWjD,qBAAa,gBAAiB,YAAW,QAAQ;IASnC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IARrC,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,KAAK,CAAC,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAS;gBAEI,QAAQ,EAAE,QAAQ;IAE/C,UAAU,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAWzC,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAI7C,aAAa,CACX,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAC3D,IAAI;IAUP,WAAW,CAAC,IAAI,EAAE;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,SAAS,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,IAAI;IAIR,SAAS,CAAC,IAAI,EAAE;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,SAAS,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI;IAIR,YAAY,CAAC,IAAI,EAAE;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,mBAAmB,CAAC;KAC7B,GAAG,IAAI;IAIR,MAAM,CAAC,IAAI,EAAE;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,GAAG,IAAI;IAIR,QAAQ,CAAC,IAAI,EAAE;QACb,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI;IASR,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,aAAa;CAGtB"}
1
+ {"version":3,"file":"progress-reporter.d.ts","sourceRoot":"","sources":["../../../src/testing/reporter/progress-reporter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,KAAK,YAAY,GAAG,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAWvE,qBAAa,gBAAiB,YAAW,QAAQ;IASnC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IARrC,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,KAAK,CAAC,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAS;gBAEI,QAAQ,EAAE,QAAQ;IAE/C,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAWpC,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAI7C,aAAa,CACX,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAC3D,IAAI;IAUP,WAAW,CAAC,IAAI,EAAE;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,SAAS,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,IAAI;IAIR,SAAS,CAAC,IAAI,EAAE;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,SAAS,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI;IAIR,YAAY,CAAC,IAAI,EAAE;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,mBAAmB,CAAC;KAC7B,GAAG,IAAI;IAIR,MAAM,CAAC,IAAI,EAAE;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,GAAG,IAAI;IAIR,QAAQ,CAAC,IAAI,EAAE;QACb,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI;IASR,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,aAAa;CAGtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"progress-reporter.js","sourceRoot":"","sources":["../../../src/testing/reporter/progress-reporter.ts"],"names":[],"mappings":"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","sourcesContent":["import * as readline from \"readline\";\nimport type { StepPhase } from \"../contracts/runtime-context.types\";\nimport type { OpStep, ScenarioSpec } from \"../contracts/testing-metadata.types\";\nimport type { SolidTestSpecResult } from \"../contracts/test-spec.types\";\nimport type { Reporter } from \"./reporter.types\";\n\nconst ANSI_BOLD = \"\\u001b[1m\";\nconst ANSI_BOLD_OFF = \"\\u001b[22m\";\nconst ANSI_DIM = \"\\u001b[2m\";\nconst ANSI_GREEN = \"\\u001b[32m\";\nconst ANSI_COLOR_OFF = \"\\u001b[39m\";\nconst ANSI_RED = \"\\u001b[31m\";\nconst ANSI_INVERSE = \"\\u001b[7m\";\nconst ANSI_INVERSE_OFF = \"\\u001b[27m\";\n\nexport class ProgressReporter implements Reporter {\n private startedAt = Date.now();\n private total = 0;\n private completed = 0;\n private passed = 0;\n private failed = 0;\n private timer?: NodeJS.Timeout;\n private rendered = false;\n\n constructor(private readonly delegate: Reporter) {}\n\n onRunStart(args: { total: number }): void {\n this.total = args.total;\n this.startedAt = Date.now();\n this.completed = 0;\n this.passed = 0;\n this.failed = 0;\n this.delegate.onRunStart?.(args);\n this.startTimer();\n this.renderFooter();\n }\n\n onScenarioStart(scenario: ScenarioSpec): void {\n this.withFooterPaused(() => this.delegate.onScenarioStart(scenario));\n }\n\n onScenarioEnd(\n scenario: ScenarioSpec,\n result: { ok: boolean; error?: unknown; durationMs: number },\n ): void {\n this.completed += 1;\n if (result.ok) {\n this.passed += 1;\n } else {\n this.failed += 1;\n }\n this.withFooterPaused(() => this.delegate.onScenarioEnd(scenario, result));\n }\n\n onStepStart(args: {\n scenarioId: string;\n phase: StepPhase;\n step: OpStep;\n }): void {\n this.withFooterPaused(() => this.delegate.onStepStart(args));\n }\n\n onStepEnd(args: {\n scenarioId: string;\n phase: StepPhase;\n step: OpStep;\n ok: boolean;\n error?: unknown;\n durationMs: number;\n }): void {\n this.withFooterPaused(() => this.delegate.onStepEnd(args));\n }\n\n onSpecResult(args: {\n scenarioId: string;\n specId: string;\n stepName?: string;\n result: SolidTestSpecResult;\n }): void {\n this.withFooterPaused(() => this.delegate.onSpecResult?.(args));\n }\n\n attach(args: {\n scenarioId: string;\n name: string;\n contentType: string;\n data: Buffer | string;\n }): void {\n this.withFooterPaused(() => this.delegate.attach?.(args));\n }\n\n onRunEnd(args: {\n ok: boolean;\n total: number;\n passed: number;\n failed: number;\n durationMs: number;\n }): void {\n this.completed = args.passed + args.failed;\n this.passed = args.passed;\n this.failed = args.failed;\n this.total = args.total;\n this.stopTimer();\n this.withFooterPaused(() => this.delegate.onRunEnd?.(args), false);\n }\n\n private startTimer(): void {\n this.stopTimer();\n if (!this.isInteractive()) {\n return;\n }\n this.timer = setInterval(() => this.renderFooter(), 1_000);\n this.timer.unref?.();\n }\n\n private stopTimer(): void {\n if (!this.timer) {\n return;\n }\n clearInterval(this.timer);\n this.timer = undefined;\n }\n\n private withFooterPaused(callback: () => void, renderAfter = true): void {\n this.clearFooter();\n callback();\n if (renderAfter) {\n this.renderFooter();\n }\n }\n\n private renderFooter(): void {\n if (!this.isInteractive()) {\n return;\n }\n\n const terminalWidth = process.stdout.columns || 80;\n const elapsed = formatElapsed(Date.now() - this.startedAt);\n const progressText = `${this.completed}/${this.total}`;\n const resultText = `${ANSI_GREEN}${this.passed} passed${ANSI_COLOR_OFF}${ANSI_DIM} | ${ANSI_BOLD_OFF}${this.failed ? ANSI_RED : ANSI_DIM}${this.failed} failed${this.failed ? ANSI_COLOR_OFF : ANSI_BOLD_OFF}`;\n const footer = [\n `${ANSI_BOLD}Tests${ANSI_BOLD_OFF}: ${this.renderProgressBar(terminalWidth)} ${progressText}`,\n `${ANSI_BOLD}Elapsed${ANSI_BOLD_OFF}: ${elapsed}`,\n resultText,\n ].join(`${ANSI_DIM} | ${ANSI_BOLD_OFF}`);\n\n readline.clearLine(process.stdout, 0);\n readline.cursorTo(process.stdout, 0);\n process.stdout.write(truncateAnsiText(`${ANSI_INVERSE} ${footer} ${ANSI_INVERSE_OFF}`, terminalWidth));\n this.rendered = true;\n }\n\n private clearFooter(): void {\n if (!this.rendered || !this.isInteractive()) {\n return;\n }\n readline.clearLine(process.stdout, 0);\n readline.cursorTo(process.stdout, 0);\n this.rendered = false;\n }\n\n private renderProgressBar(terminalWidth: number): string {\n const width = terminalWidth >= 120 ? 30 : terminalWidth >= 90 ? 22 : 14;\n const ratio = this.total > 0 ? Math.min(1, this.completed / this.total) : 0;\n const filled = Math.round(width * ratio);\n const empty = Math.max(0, width - filled);\n return `[${ANSI_GREEN}${\"=\".repeat(filled)}${ANSI_COLOR_OFF}${\" \".repeat(empty)}]`;\n }\n\n private isInteractive(): boolean {\n return Boolean(process.stdout.isTTY || process.env.SOLIDCTL_TEST_PROGRESS === \"1\");\n }\n}\n\nfunction formatElapsed(durationMs: number): string {\n const totalSeconds = Math.max(0, Math.floor(durationMs / 1000));\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes < 60) {\n return `${minutes}:${seconds.toString().padStart(2, \"0\")}`;\n }\n const hours = Math.floor(minutes / 60);\n const remainingMinutes = minutes % 60;\n return `${hours}:${remainingMinutes.toString().padStart(2, \"0\")}:${seconds.toString().padStart(2, \"0\")}`;\n}\n\nfunction truncateAnsiText(text: string, maxWidth: number): string {\n if (maxWidth <= 0) {\n return \"\";\n }\n\n let visibleWidth = 0;\n let index = 0;\n let output = \"\";\n let hasEscape = false;\n\n while (index < text.length) {\n if (text[index] === \"\\u001b\") {\n const match = /\\u001b\\[[0-9;]*m/.exec(text.slice(index));\n if (!match) {\n break;\n }\n output += match[0];\n hasEscape = true;\n index += match[0].length;\n continue;\n }\n\n if (visibleWidth >= maxWidth) {\n break;\n }\n\n output += text[index];\n visibleWidth += 1;\n index += 1;\n }\n\n if (index < text.length && maxWidth >= 1) {\n output = trimAnsiText(output, maxWidth - 1) + \"…\";\n }\n\n if (hasEscape && !output.endsWith(ANSI_INVERSE_OFF)) {\n output += ANSI_INVERSE_OFF;\n }\n\n return output;\n}\n\nfunction trimAnsiText(text: string, maxWidth: number): string {\n let visibleWidth = 0;\n let index = 0;\n let output = \"\";\n\n while (index < text.length && visibleWidth < maxWidth) {\n if (text[index] === \"\\u001b\") {\n const match = /\\u001b\\[[0-9;]*m/.exec(text.slice(index));\n if (!match) {\n break;\n }\n output += match[0];\n index += match[0].length;\n continue;\n }\n\n output += text[index];\n visibleWidth += 1;\n index += 1;\n }\n\n return output;\n}\n"]}
1
+ {"version":3,"file":"progress-reporter.js","sourceRoot":"","sources":["../../../src/testing/reporter/progress-reporter.ts"],"names":[],"mappings":"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","sourcesContent":["import * as readline from \"readline\";\nimport type { StepPhase } from \"../contracts/runtime-context.types\";\nimport type { OpStep, ScenarioSpec } from \"../contracts/testing-metadata.types\";\nimport type { SolidTestSpecResult } from \"../contracts/test-spec.types\";\nimport type { Reporter } from \"./reporter.types\";\n\ntype RunStartArgs = Parameters<NonNullable<Reporter[\"onRunStart\"]>>[0];\n\nconst ANSI_BOLD = \"\\u001b[1m\";\nconst ANSI_BOLD_OFF = \"\\u001b[22m\";\nconst ANSI_DIM = \"\\u001b[2m\";\nconst ANSI_GREEN = \"\\u001b[32m\";\nconst ANSI_COLOR_OFF = \"\\u001b[39m\";\nconst ANSI_RED = \"\\u001b[31m\";\nconst ANSI_INVERSE = \"\\u001b[7m\";\nconst ANSI_INVERSE_OFF = \"\\u001b[27m\";\n\nexport class ProgressReporter implements Reporter {\n private startedAt = Date.now();\n private total = 0;\n private completed = 0;\n private passed = 0;\n private failed = 0;\n private timer?: NodeJS.Timeout;\n private rendered = false;\n\n constructor(private readonly delegate: Reporter) {}\n\n onRunStart(args: RunStartArgs): void {\n this.total = args.total;\n this.startedAt = Date.now();\n this.completed = 0;\n this.passed = 0;\n this.failed = 0;\n this.delegate.onRunStart?.(args);\n this.startTimer();\n this.renderFooter();\n }\n\n onScenarioStart(scenario: ScenarioSpec): void {\n this.withFooterPaused(() => this.delegate.onScenarioStart(scenario));\n }\n\n onScenarioEnd(\n scenario: ScenarioSpec,\n result: { ok: boolean; error?: unknown; durationMs: number },\n ): void {\n this.completed += 1;\n if (result.ok) {\n this.passed += 1;\n } else {\n this.failed += 1;\n }\n this.withFooterPaused(() => this.delegate.onScenarioEnd(scenario, result));\n }\n\n onStepStart(args: {\n scenarioId: string;\n phase: StepPhase;\n step: OpStep;\n }): void {\n this.withFooterPaused(() => this.delegate.onStepStart(args));\n }\n\n onStepEnd(args: {\n scenarioId: string;\n phase: StepPhase;\n step: OpStep;\n ok: boolean;\n error?: unknown;\n durationMs: number;\n }): void {\n this.withFooterPaused(() => this.delegate.onStepEnd(args));\n }\n\n onSpecResult(args: {\n scenarioId: string;\n specId: string;\n stepName?: string;\n result: SolidTestSpecResult;\n }): void {\n this.withFooterPaused(() => this.delegate.onSpecResult?.(args));\n }\n\n attach(args: {\n scenarioId: string;\n name: string;\n contentType: string;\n data: Buffer | string;\n }): void {\n this.withFooterPaused(() => this.delegate.attach?.(args));\n }\n\n onRunEnd(args: {\n ok: boolean;\n total: number;\n passed: number;\n failed: number;\n durationMs: number;\n }): void {\n this.completed = args.passed + args.failed;\n this.passed = args.passed;\n this.failed = args.failed;\n this.total = args.total;\n this.stopTimer();\n this.withFooterPaused(() => this.delegate.onRunEnd?.(args), false);\n }\n\n private startTimer(): void {\n this.stopTimer();\n if (!this.isInteractive()) {\n return;\n }\n this.timer = setInterval(() => this.renderFooter(), 1_000);\n this.timer.unref?.();\n }\n\n private stopTimer(): void {\n if (!this.timer) {\n return;\n }\n clearInterval(this.timer);\n this.timer = undefined;\n }\n\n private withFooterPaused(callback: () => void, renderAfter = true): void {\n this.clearFooter();\n callback();\n if (renderAfter) {\n this.renderFooter();\n }\n }\n\n private renderFooter(): void {\n if (!this.isInteractive()) {\n return;\n }\n\n const terminalWidth = process.stdout.columns || 80;\n const elapsed = formatElapsed(Date.now() - this.startedAt);\n const progressText = `${this.completed}/${this.total}`;\n const resultText = `${ANSI_GREEN}${this.passed} passed${ANSI_COLOR_OFF}${ANSI_DIM} | ${ANSI_BOLD_OFF}${this.failed ? ANSI_RED : ANSI_DIM}${this.failed} failed${this.failed ? ANSI_COLOR_OFF : ANSI_BOLD_OFF}`;\n const footer = [\n `${ANSI_BOLD}Tests${ANSI_BOLD_OFF}: ${this.renderProgressBar(terminalWidth)} ${progressText}`,\n `${ANSI_BOLD}Elapsed${ANSI_BOLD_OFF}: ${elapsed}`,\n resultText,\n ].join(`${ANSI_DIM} | ${ANSI_BOLD_OFF}`);\n\n readline.clearLine(process.stdout, 0);\n readline.cursorTo(process.stdout, 0);\n process.stdout.write(truncateAnsiText(`${ANSI_INVERSE} ${footer} ${ANSI_INVERSE_OFF}`, terminalWidth));\n this.rendered = true;\n }\n\n private clearFooter(): void {\n if (!this.rendered || !this.isInteractive()) {\n return;\n }\n readline.clearLine(process.stdout, 0);\n readline.cursorTo(process.stdout, 0);\n this.rendered = false;\n }\n\n private renderProgressBar(terminalWidth: number): string {\n const width = terminalWidth >= 120 ? 30 : terminalWidth >= 90 ? 22 : 14;\n const ratio = this.total > 0 ? Math.min(1, this.completed / this.total) : 0;\n const filled = Math.round(width * ratio);\n const empty = Math.max(0, width - filled);\n return `[${ANSI_GREEN}${\"=\".repeat(filled)}${ANSI_COLOR_OFF}${\" \".repeat(empty)}]`;\n }\n\n private isInteractive(): boolean {\n return Boolean(process.stdout.isTTY || process.env.SOLIDCTL_TEST_PROGRESS === \"1\");\n }\n}\n\nfunction formatElapsed(durationMs: number): string {\n const totalSeconds = Math.max(0, Math.floor(durationMs / 1000));\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes < 60) {\n return `${minutes}:${seconds.toString().padStart(2, \"0\")}`;\n }\n const hours = Math.floor(minutes / 60);\n const remainingMinutes = minutes % 60;\n return `${hours}:${remainingMinutes.toString().padStart(2, \"0\")}:${seconds.toString().padStart(2, \"0\")}`;\n}\n\nfunction truncateAnsiText(text: string, maxWidth: number): string {\n if (maxWidth <= 0) {\n return \"\";\n }\n\n let visibleWidth = 0;\n let index = 0;\n let output = \"\";\n let hasEscape = false;\n\n while (index < text.length) {\n if (text[index] === \"\\u001b\") {\n const match = /\\u001b\\[[0-9;]*m/.exec(text.slice(index));\n if (!match) {\n break;\n }\n output += match[0];\n hasEscape = true;\n index += match[0].length;\n continue;\n }\n\n if (visibleWidth >= maxWidth) {\n break;\n }\n\n output += text[index];\n visibleWidth += 1;\n index += 1;\n }\n\n if (index < text.length && maxWidth >= 1) {\n output = trimAnsiText(output, maxWidth - 1) + \"…\";\n }\n\n if (hasEscape && !output.endsWith(ANSI_INVERSE_OFF)) {\n output += ANSI_INVERSE_OFF;\n }\n\n return output;\n}\n\nfunction trimAnsiText(text: string, maxWidth: number): string {\n let visibleWidth = 0;\n let index = 0;\n let output = \"\";\n\n while (index < text.length && visibleWidth < maxWidth) {\n if (text[index] === \"\\u001b\") {\n const match = /\\u001b\\[[0-9;]*m/.exec(text.slice(index));\n if (!match) {\n break;\n }\n output += match[0];\n index += match[0].length;\n continue;\n }\n\n output += text[index];\n visibleWidth += 1;\n index += 1;\n }\n\n return output;\n}\n"]}
@@ -1,9 +1,16 @@
1
1
  import type { StepPhase } from "../contracts/runtime-context.types";
2
- import type { OpStep, ScenarioSpec } from "../contracts/testing-metadata.types";
2
+ import type { OpStep, ScenarioSpec, ScenarioType } from "../contracts/testing-metadata.types";
3
3
  import type { SolidTestSpecResult } from "../contracts/test-spec.types";
4
4
  export interface Reporter {
5
5
  onRunStart?(args: {
6
6
  total: number;
7
+ startedAt: string;
8
+ scenarioIds: string[];
9
+ scenarios?: Array<{
10
+ id: string;
11
+ name?: string;
12
+ type: ScenarioType;
13
+ }>;
7
14
  }): void;
8
15
  onScenarioStart(scenario: ScenarioSpec): void;
9
16
  onScenarioEnd(scenario: ScenarioSpec, result: {
@@ -36,6 +43,11 @@ export interface Reporter {
36
43
  contentType: string;
37
44
  data: Buffer | string;
38
45
  }): void;
46
+ attachRunArtifact?(args: {
47
+ name: string;
48
+ contentType: string;
49
+ data: Buffer | string;
50
+ }): void;
39
51
  onRunEnd?(args: {
40
52
  ok: boolean;
41
53
  total: number;
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.types.d.ts","sourceRoot":"","sources":["../../../src/testing/reporter/reporter.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,MAAM,WAAW,QAAQ;IACvB,UAAU,CAAC,CAAC,IAAI,EAAE;QAChB,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,IAAI,CAAC;IACT,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9C,aAAa,CACX,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAC3D,IAAI,CAAC;IACR,WAAW,CAAC,IAAI,EAAE;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,SAAS,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,IAAI,CAAC;IACT,SAAS,CAAC,IAAI,EAAE;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,SAAS,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;IACT,YAAY,CAAC,CAAC,IAAI,EAAE;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,mBAAmB,CAAC;KAC7B,GAAG,IAAI,CAAC;IACT,MAAM,CAAC,CAAC,IAAI,EAAE;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,GAAG,IAAI,CAAC;IACT,QAAQ,CAAC,CAAC,IAAI,EAAE;QACd,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;CACV"}
1
+ {"version":3,"file":"reporter.types.d.ts","sourceRoot":"","sources":["../../../src/testing/reporter/reporter.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAC9F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,MAAM,WAAW,QAAQ;IACvB,UAAU,CAAC,CAAC,IAAI,EAAE;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,SAAS,CAAC,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,YAAY,CAAA;SAAE,CAAC,CAAC;KACtE,GAAG,IAAI,CAAC;IACT,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9C,aAAa,CACX,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAC3D,IAAI,CAAC;IACR,WAAW,CAAC,IAAI,EAAE;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,SAAS,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,IAAI,CAAC;IACT,SAAS,CAAC,IAAI,EAAE;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,SAAS,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;IACT,YAAY,CAAC,CAAC,IAAI,EAAE;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,mBAAmB,CAAC;KAC7B,GAAG,IAAI,CAAC;IACT,MAAM,CAAC,CAAC,IAAI,EAAE;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,GAAG,IAAI,CAAC;IAET,iBAAiB,CAAC,CAAC,IAAI,EAAE;QACvB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,GAAG,IAAI,CAAC;IACT,QAAQ,CAAC,CAAC,IAAI,EAAE;QACd,EAAE,EAAE,OAAO,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;CACV"}
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.types.js","sourceRoot":"","sources":["../../../src/testing/reporter/reporter.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { StepPhase } from \"../contracts/runtime-context.types\";\nimport type { OpStep, ScenarioSpec } from \"../contracts/testing-metadata.types\";\nimport type { SolidTestSpecResult } from \"../contracts/test-spec.types\";\n\nexport interface Reporter {\n onRunStart?(args: {\n total: number;\n }): void;\n onScenarioStart(scenario: ScenarioSpec): void;\n onScenarioEnd(\n scenario: ScenarioSpec,\n result: { ok: boolean; error?: unknown; durationMs: number },\n ): void;\n onStepStart(args: {\n scenarioId: string;\n phase: StepPhase;\n step: OpStep;\n }): void;\n onStepEnd(args: {\n scenarioId: string;\n phase: StepPhase;\n step: OpStep;\n ok: boolean;\n error?: unknown;\n durationMs: number;\n }): void;\n onSpecResult?(args: {\n scenarioId: string;\n specId: string;\n stepName?: string;\n result: SolidTestSpecResult;\n }): void;\n attach?(args: {\n scenarioId: string;\n name: string;\n contentType: string;\n data: Buffer | string;\n }): void;\n onRunEnd?(args: {\n ok: boolean;\n total: number;\n passed: number;\n failed: number;\n durationMs: number;\n }): void;\n}\n"]}
1
+ {"version":3,"file":"reporter.types.js","sourceRoot":"","sources":["../../../src/testing/reporter/reporter.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { StepPhase } from \"../contracts/runtime-context.types\";\nimport type { OpStep, ScenarioSpec, ScenarioType } from \"../contracts/testing-metadata.types\";\nimport type { SolidTestSpecResult } from \"../contracts/test-spec.types\";\n\nexport interface Reporter {\n onRunStart?(args: {\n total: number;\n startedAt: string;\n scenarioIds: string[];\n scenarios?: Array<{ id: string; name?: string; type: ScenarioType }>;\n }): void;\n onScenarioStart(scenario: ScenarioSpec): void;\n onScenarioEnd(\n scenario: ScenarioSpec,\n result: { ok: boolean; error?: unknown; durationMs: number },\n ): void;\n onStepStart(args: {\n scenarioId: string;\n phase: StepPhase;\n step: OpStep;\n }): void;\n onStepEnd(args: {\n scenarioId: string;\n phase: StepPhase;\n step: OpStep;\n ok: boolean;\n error?: unknown;\n durationMs: number;\n }): void;\n onSpecResult?(args: {\n scenarioId: string;\n specId: string;\n stepName?: string;\n result: SolidTestSpecResult;\n }): void;\n attach?(args: {\n scenarioId: string;\n name: string;\n contentType: string;\n data: Buffer | string;\n }): void;\n /** Attach a run-level artifact (e.g. the whole-run video), emitted on run.end. */\n attachRunArtifact?(args: {\n name: string;\n contentType: string;\n data: Buffer | string;\n }): void;\n onRunEnd?(args: {\n ok: boolean;\n total: number;\n passed: number;\n failed: number;\n durationMs: number;\n }): void;\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import type { ScenarioSpec, TestingDataRecord } from "../contracts/testing-metadata.types";
2
+ export interface ReadScenariosResult {
3
+ scenarios: ScenarioSpec[];
4
+ data?: TestingDataRecord[];
5
+ ok: boolean;
6
+ error?: string;
7
+ }
8
+ export declare function readScenariosFile(absPath: string): ReadScenariosResult;
9
+ //# sourceMappingURL=read-scenarios-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-scenarios-file.d.ts","sourceRoot":"","sources":["../../../src/testing/runner/read-scenarios-file.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAM3F,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAaD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAiBtE"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.readScenariosFile = readScenariosFile;
37
+ const fs = __importStar(require("fs"));
38
+ function readScenariosFile(absPath) {
39
+ if (!absPath || !fs.existsSync(absPath)) {
40
+ return { scenarios: [], ok: false, error: "file_not_found" };
41
+ }
42
+ try {
43
+ const parsed = JSON.parse(fs.readFileSync(absPath, "utf-8"));
44
+ const rawScenarios = parsed?.testing?.scenarios ??
45
+ parsed?.scenarios ??
46
+ (Array.isArray(parsed) ? parsed : []);
47
+ const scenarios = Array.isArray(rawScenarios) ? rawScenarios : [];
48
+ const rawData = parsed?.testing?.data ?? parsed?.data;
49
+ const data = Array.isArray(rawData) ? rawData : undefined;
50
+ return { scenarios, data, ok: true };
51
+ }
52
+ catch (err) {
53
+ return { scenarios: [], ok: false, error: err?.message || "read_error" };
54
+ }
55
+ }
56
+ //# sourceMappingURL=read-scenarios-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-scenarios-file.js","sourceRoot":"","sources":["../../../src/testing/runner/read-scenarios-file.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,8CAiBC;AA3CD,uCAAyB;AA0BzB,SAAgB,iBAAiB,CAAC,OAAe;IAC/C,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC/D,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7D,MAAM,YAAY,GAChB,MAAM,EAAE,OAAO,EAAE,SAAS;YAC1B,MAAM,EAAE,SAAS;YACjB,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,SAAS,GAAmB,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QAClF,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,MAAM,EAAE,IAAI,CAAC;QACtD,MAAM,IAAI,GAAoC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3F,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAG,GAAa,EAAE,OAAO,IAAI,YAAY,EAAE,CAAC;IACtF,CAAC;AACH,CAAC","sourcesContent":["import * as fs from \"fs\";\n\nimport type { ScenarioSpec, TestingDataRecord } from \"../contracts/testing-metadata.types\";\n\n/**\n * Result of reading a scenario JSON file. `ok:false` means the file was missing,\n * unreadable, or contained invalid JSON — never a thrown error.\n */\nexport interface ReadScenariosResult {\n scenarios: ScenarioSpec[];\n data?: TestingDataRecord[];\n ok: boolean;\n error?: string;\n}\n\n/**\n * Read + parse an application's scenario file `{ testing: { scenarios, data } }` from an\n * absolute path, on the WORKER tier (which shares the filesystem with the caller in the\n * default single-process deployment). Tolerant by design — mirrors\n * ScenarioFileService.resolvePayload in testingHub — so a concurrent editor half-writing\n * the file, a deleted file (TOCTOU between existsSync and readFileSync), or invalid JSON\n * returns `{ ok:false }` instead of throwing. The worker fails the run loudly on `ok:false`.\n *\n * Lives in core (not testingHub) because the worker is a core component and must not import\n * testingHub code.\n */\nexport function readScenariosFile(absPath: string): ReadScenariosResult {\n if (!absPath || !fs.existsSync(absPath)) {\n return { scenarios: [], ok: false, error: \"file_not_found\" };\n }\n try {\n const parsed = JSON.parse(fs.readFileSync(absPath, \"utf-8\"));\n const rawScenarios =\n parsed?.testing?.scenarios ??\n parsed?.scenarios ??\n (Array.isArray(parsed) ? parsed : []);\n const scenarios: ScenarioSpec[] = Array.isArray(rawScenarios) ? rawScenarios : [];\n const rawData = parsed?.testing?.data ?? parsed?.data;\n const data: TestingDataRecord[] | undefined = Array.isArray(rawData) ? rawData : undefined;\n return { scenarios, data, ok: true };\n } catch (err) {\n return { scenarios: [], ok: false, error: (err as Error)?.message || \"read_error\" };\n }\n}\n"]}
@@ -1,10 +1,14 @@
1
1
  import type { Reporter } from "../reporter/reporter.types";
2
- import type { TestingMetadata } from "../contracts/testing-metadata.types";
2
+ import type { TestingMetadata, TestingDataRecord, ScenarioSpec } from "../contracts/testing-metadata.types";
3
3
  import type { ApiAdapterOptions } from "../adapters/api/api.types";
4
4
  import type { PlaywrightAdapterOptions } from "../adapters/ui/ui.types";
5
5
  import { SpecRegistry } from "../core/spec-registry";
6
6
  export type RunnerOptions = {
7
- metadata: TestingMetadata;
7
+ metadata?: TestingMetadata;
8
+ scenarios?: ScenarioSpec[];
9
+ data?: TestingDataRecord[];
10
+ externalRunId?: string;
11
+ env?: Record<string, string>;
8
12
  scenarioIds?: string[];
9
13
  includeTags?: string[];
10
14
  skipScenarioIds?: string[];
@@ -19,6 +23,7 @@ export type RunnerOptions = {
19
23
  printApiLogs?: boolean;
20
24
  };
21
25
  specs?: (registry: SpecRegistry) => void;
26
+ resolveSecrets?: (keys: string[]) => Promise<Record<string, any>>;
22
27
  };
23
28
  export declare function runFromMetadata(opts: RunnerOptions): Promise<void>;
24
29
  //# sourceMappingURL=run-from-metadata.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-from-metadata.d.ts","sourceRoot":"","sources":["../../../src/testing/runner/run-from-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,qCAAqC,CAAC;AAC9F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AASxE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAoBrD,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,GAAG,CAAC,EAAE,iBAAiB,CAAC;IACxB,EAAE,CAAC,EAAE,wBAAwB,CAAC;IAC9B,QAAQ,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACrC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;CAC1C,CAAC;AAEF,wBAAsB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA4DxE"}
1
+ {"version":3,"file":"run-from-metadata.d.ts","sourceRoot":"","sources":["../../../src/testing/runner/run-from-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAC5G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AASxE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAsBrD,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,GAAG,CAAC,EAAE,iBAAiB,CAAC;IACxB,EAAE,CAAC,EAAE,wBAAwB,CAAC;IAC9B,QAAQ,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACrC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IAMzC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;CACnE,CAAC;AA+CF,wBAAsB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgGxE"}
@@ -45,7 +45,9 @@ const step_registry_1 = require("../core/step-registry");
45
45
  const spec_registry_1 = require("../core/spec-registry");
46
46
  const testing_engine_1 = require("../core/testing-engine");
47
47
  const scenario_filter_1 = require("./scenario-filter");
48
+ const interpolation_1 = require("../core/interpolation");
48
49
  const lifecycle_1 = require("./lifecycle");
50
+ const browser_provisioner_1 = require("../adapters/ui/browser-provisioner");
49
51
  const console_reporter_1 = require("../reporter/console-reporter");
50
52
  function buildTestDataIndex(data) {
51
53
  const index = {};
@@ -61,6 +63,31 @@ function buildTestDataIndex(data) {
61
63
  }
62
64
  return index;
63
65
  }
66
+ async function resolveSecretsByScenario(scenarios, resolveSecrets) {
67
+ const keysByScenario = new Map();
68
+ const allKeys = new Set();
69
+ for (const scenario of scenarios) {
70
+ const keys = (0, interpolation_1.collectSecretKeys)(scenario);
71
+ if (keys.length === 0)
72
+ continue;
73
+ keysByScenario.set(scenario.id, keys);
74
+ keys.forEach((key) => allKeys.add(key));
75
+ }
76
+ if (allKeys.size === 0)
77
+ return new Map();
78
+ if (!resolveSecrets) {
79
+ throw new Error(`Scenarios reference secrets (${[...allKeys].join(", ")}) but no secret resolver was provided to the runner.`);
80
+ }
81
+ const resolved = await resolveSecrets([...allKeys]);
82
+ const byScenario = new Map();
83
+ for (const [scenarioId, keys] of keysByScenario) {
84
+ byScenario.set(scenarioId, keys.reduce((acc, key) => {
85
+ acc[key] = resolved[key];
86
+ return acc;
87
+ }, {}));
88
+ }
89
+ return byScenario;
90
+ }
64
91
  async function runFromMetadata(opts) {
65
92
  const startedAt = Date.now();
66
93
  const registry = new step_registry_1.StepRegistry();
@@ -70,34 +97,47 @@ async function runFromMetadata(opts) {
70
97
  (0, util_1.registerUtilSteps)(registry);
71
98
  (0, test_1.registerTestSteps)(registry);
72
99
  const engine = new testing_engine_1.TestingEngine(registry, opts.defaults);
73
- const scenarios = (0, scenario_filter_1.filterScenarios)(opts.metadata.testing.scenarios, {
100
+ const allScenarios = opts.scenarios ?? opts.metadata?.testing?.scenarios ?? [];
101
+ const scenarios = (0, scenario_filter_1.filterScenarios)(allScenarios, {
74
102
  scenarioIds: opts.scenarioIds,
75
103
  includeTags: opts.includeTags,
76
104
  skipScenarioIds: opts.skipScenarioIds,
77
105
  });
78
106
  const specRegistry = new spec_registry_1.SpecRegistry();
79
- const testData = buildTestDataIndex(opts.metadata.testing?.data);
107
+ const testData = buildTestDataIndex(opts.data ?? opts.metadata?.testing?.data);
80
108
  if (opts.specs) {
81
109
  opts.specs(specRegistry);
82
110
  }
111
+ if (scenarios.some(lifecycle_1.scenarioNeedsUi)) {
112
+ await (0, browser_provisioner_1.ensureChromiumInstalled)();
113
+ }
83
114
  const resources = new resource_store_1.SimpleResourceStore();
84
115
  const reporter = opts.reporter ?? new console_reporter_1.ConsoleReporter();
85
- reporter.onRunStart?.({ total: scenarios.length });
86
116
  const api = new api_adapter_1.ApiAdapter(opts.api);
87
117
  const { PlaywrightAdapter } = await Promise.resolve().then(() => __importStar(require("../adapters/ui/playwright-adapter")));
88
118
  const ui = new PlaywrightAdapter(opts.ui);
89
- const ctxBase = { resources, reporter, api, ui, specRegistry, testData, options: opts.options };
119
+ const ctxBase = { resources, reporter, api, ui, specRegistry, testData, env: opts.env, options: opts.options };
90
120
  const uiStarted = { value: false };
91
121
  let passed = 0;
92
122
  let failed = 0;
93
123
  let runError;
124
+ reporter.onRunStart?.({
125
+ total: scenarios.length,
126
+ startedAt: new Date(startedAt).toISOString(),
127
+ scenarioIds: scenarios.map((s) => s.id),
128
+ scenarios: scenarios.map((s) => ({ id: s.id, name: s.name, type: s.type })),
129
+ });
94
130
  try {
131
+ const secretsByScenario = await resolveSecretsByScenario(scenarios, opts.resolveSecrets);
95
132
  for (const scenario of scenarios) {
96
133
  if ((0, lifecycle_1.scenarioNeedsUi)(scenario)) {
97
134
  await (0, lifecycle_1.ensureUiStarted)(ctxBase, uiStarted);
98
135
  }
99
136
  try {
100
- await engine.runScenario(scenario, ctxBase);
137
+ await engine.runScenario(scenario, {
138
+ ...ctxBase,
139
+ secrets: secretsByScenario.get(scenario.id),
140
+ });
101
141
  passed += 1;
102
142
  }
103
143
  catch (error) {
@@ -107,6 +147,10 @@ async function runFromMetadata(opts) {
107
147
  }
108
148
  }
109
149
  }
150
+ catch (error) {
151
+ runError = error;
152
+ throw error;
153
+ }
110
154
  finally {
111
155
  reporter.onRunEnd?.({
112
156
  ok: !runError,
@@ -116,7 +160,14 @@ async function runFromMetadata(opts) {
116
160
  durationMs: Date.now() - startedAt,
117
161
  });
118
162
  if (uiStarted.value) {
119
- await ui.stop();
163
+ const keepVideo = !!runError;
164
+ await ui.stop({ keepVideo });
165
+ if (keepVideo) {
166
+ const video = ui.getRunVideo?.();
167
+ if (video && reporter.attachRunArtifact) {
168
+ reporter.attachRunArtifact({ name: video.name, contentType: video.contentType, data: video.data });
169
+ }
170
+ }
120
171
  }
121
172
  }
122
173
  }
@@ -1 +1 @@
1
- {"version":3,"file":"run-from-metadata.js","sourceRoot":"","sources":["../../../src/testing/runner/run-from-metadata.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,0CA4DC;AArGD,6DAAyD;AACzD,sCAAgD;AAChD,oCAA8C;AAC9C,4CAAsD;AACtD,wCAAkD;AAClD,wCAAkD;AAClD,2DAA6D;AAC7D,yDAAqD;AACrD,yDAAqD;AACrD,2DAAuD;AACvD,uDAAoD;AACpD,2CAA+D;AAC/D,mEAA+D;AAG/D,SAAS,kBAAkB,CAAC,IAA0B;IACpD,MAAM,KAAK,GAAwC,EAAE,CAAC;IACtD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,EAAE,YAAY,IAAI,CAAC,MAAM,EAAE,eAAe;YAAE,SAAS;QAChE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;YAChC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;QAClC,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;IACzE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAeM,KAAK,UAAU,eAAe,CAAC,IAAmB;IACvD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,IAAI,4BAAY,EAAE,CAAC;IACpC,IAAA,sBAAgB,EAAC,QAAQ,CAAC,CAAC;IAC3B,IAAA,oBAAe,EAAC,QAAQ,CAAC,CAAC;IAC1B,IAAA,4BAAmB,EAAC,QAAQ,CAAC,CAAC;IAC9B,IAAA,wBAAiB,EAAC,QAAQ,CAAC,CAAC;IAC5B,IAAA,wBAAiB,EAAC,QAAQ,CAAC,CAAC;IAE5B,MAAM,MAAM,GAAG,IAAI,8BAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,IAAA,iCAAe,EAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE;QACjE,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,eAAe,EAAE,IAAI,CAAC,eAAe;KACtC,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,IAAI,4BAAY,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACjE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,oCAAmB,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,kCAAe,EAAE,CAAC;IACxD,QAAQ,CAAC,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,IAAI,wBAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,EAAE,iBAAiB,EAAE,GAAG,wDAAa,mCAAmC,GAAC,CAAC;IAChF,MAAM,EAAE,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IAChG,MAAM,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACnC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,QAAiB,CAAC;IAEtB,IAAI,CAAC;QACH,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,IAAA,2BAAe,EAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAA,2BAAe,EAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAC5C,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAC5C,MAAM,IAAI,CAAC,CAAC;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,CAAC,CAAC;gBACZ,QAAQ,GAAG,KAAK,CAAC;gBACjB,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,QAAQ,CAAC,QAAQ,EAAE,CAAC;YAClB,EAAE,EAAE,CAAC,QAAQ;YACb,KAAK,EAAE,SAAS,CAAC,MAAM;YACvB,MAAM;YACN,MAAM;YACN,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SACnC,CAAC,CAAC;QACH,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import type { Reporter } from \"../reporter/reporter.types\";\nimport type { TestingMetadata, TestingDataRecord } from \"../contracts/testing-metadata.types\";\nimport type { ApiAdapterOptions } from \"../adapters/api/api.types\";\nimport type { PlaywrightAdapterOptions } from \"../adapters/ui/ui.types\";\nimport { ApiAdapter } from \"../adapters/api/api-adapter\";\nimport { registerApiSteps } from \"../steps/api\";\nimport { registerUiSteps } from \"../steps/ui\";\nimport { registerAssertSteps } from \"../steps/assert\";\nimport { registerUtilSteps } from \"../steps/util\";\nimport { registerTestSteps } from \"../steps/test\";\nimport { SimpleResourceStore } from \"../core/resource-store\";\nimport { StepRegistry } from \"../core/step-registry\";\nimport { SpecRegistry } from \"../core/spec-registry\";\nimport { TestingEngine } from \"../core/testing-engine\";\nimport { filterScenarios } from \"./scenario-filter\";\nimport { ensureUiStarted, scenarioNeedsUi } from \"./lifecycle\";\nimport { ConsoleReporter } from \"../reporter/console-reporter\";\n\n\nfunction buildTestDataIndex(data?: TestingDataRecord[]): Record<string, Record<string, any>> {\n const index: Record<string, Record<string, any>> = {};\n if (!Array.isArray(data)) return index;\n for (const record of data) {\n if (!record?.modelUserKey || !record?.recUserKeyValue) continue;\n if (!index[record.modelUserKey]) {\n index[record.modelUserKey] = {};\n }\n index[record.modelUserKey][record.recUserKeyValue] = record.data ?? {};\n }\n return index;\n}\n\nexport type RunnerOptions = {\n metadata: TestingMetadata;\n scenarioIds?: string[];\n includeTags?: string[];\n skipScenarioIds?: string[];\n reporter?: Reporter;\n api?: ApiAdapterOptions;\n ui?: PlaywrightAdapterOptions;\n defaults?: { timeoutMs?: number; retries?: number };\n options?: { printApiLogs?: boolean };\n specs?: (registry: SpecRegistry) => void;\n};\n\nexport async function runFromMetadata(opts: RunnerOptions): Promise<void> {\n const startedAt = Date.now();\n const registry = new StepRegistry();\n registerApiSteps(registry);\n registerUiSteps(registry);\n registerAssertSteps(registry);\n registerUtilSteps(registry);\n registerTestSteps(registry);\n\n const engine = new TestingEngine(registry, opts.defaults);\n const scenarios = filterScenarios(opts.metadata.testing.scenarios, {\n scenarioIds: opts.scenarioIds,\n includeTags: opts.includeTags,\n skipScenarioIds: opts.skipScenarioIds,\n });\n\n const specRegistry = new SpecRegistry();\n const testData = buildTestDataIndex(opts.metadata.testing?.data);\n if (opts.specs) {\n opts.specs(specRegistry);\n }\n\n const resources = new SimpleResourceStore();\n const reporter = opts.reporter ?? new ConsoleReporter();\n reporter.onRunStart?.({ total: scenarios.length });\n const api = new ApiAdapter(opts.api);\n const { PlaywrightAdapter } = await import(\"../adapters/ui/playwright-adapter\");\n const ui = new PlaywrightAdapter(opts.ui);\n const ctxBase = { resources, reporter, api, ui, specRegistry, testData, options: opts.options };\n const uiStarted = { value: false };\n let passed = 0;\n let failed = 0;\n let runError: unknown;\n\n try {\n for (const scenario of scenarios) {\n if (scenarioNeedsUi(scenario)) {\n await ensureUiStarted(ctxBase, uiStarted);\n }\n try {\n await engine.runScenario(scenario, ctxBase);\n passed += 1;\n } catch (error) {\n failed += 1;\n runError = error;\n throw error;\n }\n }\n } finally {\n reporter.onRunEnd?.({\n ok: !runError,\n total: scenarios.length,\n passed,\n failed,\n durationMs: Date.now() - startedAt,\n });\n if (uiStarted.value) {\n await ui.stop();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"run-from-metadata.js","sourceRoot":"","sources":["../../../src/testing/runner/run-from-metadata.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Reporter } from \"../reporter/reporter.types\";\nimport type { TestingMetadata, TestingDataRecord, ScenarioSpec } from \"../contracts/testing-metadata.types\";\nimport type { ApiAdapterOptions } from \"../adapters/api/api.types\";\nimport type { PlaywrightAdapterOptions } from \"../adapters/ui/ui.types\";\nimport { ApiAdapter } from \"../adapters/api/api-adapter\";\nimport { registerApiSteps } from \"../steps/api\";\nimport { registerUiSteps } from \"../steps/ui\";\nimport { registerAssertSteps } from \"../steps/assert\";\nimport { registerUtilSteps } from \"../steps/util\";\nimport { registerTestSteps } from \"../steps/test\";\nimport { SimpleResourceStore } from \"../core/resource-store\";\nimport { StepRegistry } from \"../core/step-registry\";\nimport { SpecRegistry } from \"../core/spec-registry\";\nimport { TestingEngine } from \"../core/testing-engine\";\nimport { filterScenarios } from \"./scenario-filter\";\nimport { collectSecretKeys } from \"../core/interpolation\";\nimport { ensureUiStarted, scenarioNeedsUi } from \"./lifecycle\";\nimport { ensureChromiumInstalled } from \"../adapters/ui/browser-provisioner\";\nimport { ConsoleReporter } from \"../reporter/console-reporter\";\n\n\nfunction buildTestDataIndex(data?: TestingDataRecord[]): Record<string, Record<string, any>> {\n const index: Record<string, Record<string, any>> = {};\n if (!Array.isArray(data)) return index;\n for (const record of data) {\n if (!record?.modelUserKey || !record?.recUserKeyValue) continue;\n if (!index[record.modelUserKey]) {\n index[record.modelUserKey] = {};\n }\n index[record.modelUserKey][record.recUserKeyValue] = record.data ?? {};\n }\n return index;\n}\n\nexport type RunnerOptions = {\n metadata?: TestingMetadata;\n scenarios?: ScenarioSpec[];\n data?: TestingDataRecord[];\n externalRunId?: string;\n env?: Record<string, string>;\n scenarioIds?: string[];\n includeTags?: string[];\n skipScenarioIds?: string[];\n reporter?: Reporter;\n api?: ApiAdapterOptions;\n ui?: PlaywrightAdapterOptions;\n defaults?: { timeoutMs?: number; retries?: number };\n options?: { printApiLogs?: boolean };\n specs?: (registry: SpecRegistry) => void;\n /**\n * Resolves `${secret:...}` references against the secret store. Injected by the\n * caller so this runner stays free of database and DI coupling. Required only if a\n * scenario actually references a secret.\n */\n resolveSecrets?: (keys: string[]) => Promise<Record<string, any>>;\n};\n\n/**\n * Resolves every secret referenced by the scenarios about to run, in one call, and\n * returns a per-scenario view of the result.\n *\n * Partitioned deliberately: ctxBase is shared across scenarios, so handing every\n * scenario the whole map would let each read secrets belonging to the others.\n */\nasync function resolveSecretsByScenario(\n scenarios: ScenarioSpec[],\n resolveSecrets?: RunnerOptions[\"resolveSecrets\"],\n): Promise<Map<string, Record<string, any>>> {\n const keysByScenario = new Map<string, string[]>();\n const allKeys = new Set<string>();\n\n for (const scenario of scenarios) {\n const keys = collectSecretKeys(scenario);\n if (keys.length === 0) continue;\n keysByScenario.set(scenario.id, keys);\n keys.forEach((key) => allKeys.add(key));\n }\n\n if (allKeys.size === 0) return new Map();\n\n if (!resolveSecrets) {\n throw new Error(\n `Scenarios reference secrets (${[...allKeys].join(\", \")}) but no secret resolver was provided to the runner.`,\n );\n }\n\n // Resolved up front so a missing secret fails the run before any scenario executes.\n const resolved = await resolveSecrets([...allKeys]);\n\n const byScenario = new Map<string, Record<string, any>>();\n for (const [scenarioId, keys] of keysByScenario) {\n byScenario.set(\n scenarioId,\n keys.reduce((acc, key) => {\n acc[key] = resolved[key];\n return acc;\n }, {} as Record<string, any>),\n );\n }\n return byScenario;\n}\n\nexport async function runFromMetadata(opts: RunnerOptions): Promise<void> {\n const startedAt = Date.now();\n const registry = new StepRegistry();\n registerApiSteps(registry);\n registerUiSteps(registry);\n registerAssertSteps(registry);\n registerUtilSteps(registry);\n registerTestSteps(registry);\n\n const engine = new TestingEngine(registry, opts.defaults);\n const allScenarios = opts.scenarios ?? opts.metadata?.testing?.scenarios ?? [];\n const scenarios = filterScenarios(allScenarios, {\n scenarioIds: opts.scenarioIds,\n includeTags: opts.includeTags,\n skipScenarioIds: opts.skipScenarioIds,\n });\n\n const specRegistry = new SpecRegistry();\n const testData = buildTestDataIndex(opts.data ?? opts.metadata?.testing?.data);\n if (opts.specs) {\n opts.specs(specRegistry);\n }\n\n // Fetch the browser before the reporter starts drawing its footer, so the download\n // gets a clean terminal and a missing browser fails before any scenario runs.\n if (scenarios.some(scenarioNeedsUi)) {\n await ensureChromiumInstalled();\n }\n\n const resources = new SimpleResourceStore();\n const reporter: Reporter = opts.reporter ?? new ConsoleReporter();\n const api = new ApiAdapter(opts.api);\n const { PlaywrightAdapter } = await import(\"../adapters/ui/playwright-adapter\");\n const ui = new PlaywrightAdapter(opts.ui);\n const ctxBase = { resources, reporter, api, ui, specRegistry, testData, env: opts.env, options: opts.options };\n const uiStarted = { value: false };\n let passed = 0;\n let failed = 0;\n let runError: unknown;\n\n reporter.onRunStart?.({\n total: scenarios.length,\n startedAt: new Date(startedAt).toISOString(),\n scenarioIds: scenarios.map((s) => s.id),\n scenarios: scenarios.map((s) => ({ id: s.id, name: s.name, type: s.type })),\n });\n\n try {\n // One query for the whole run, after onRunStart so a failure here still reports\n // run.end. Keys that do not resolve are not fatal — they surface at the step that\n // references them, where the reporter can name the token and locate the failure.\n const secretsByScenario = await resolveSecretsByScenario(scenarios, opts.resolveSecrets);\n\n for (const scenario of scenarios) {\n if (scenarioNeedsUi(scenario)) {\n await ensureUiStarted(ctxBase, uiStarted);\n }\n try {\n await engine.runScenario(scenario, {\n ...ctxBase,\n secrets: secretsByScenario.get(scenario.id),\n });\n passed += 1;\n } catch (error) {\n failed += 1;\n runError = error;\n throw error;\n }\n }\n } catch (error) {\n // Also catches a setup failure before the loop (unreachable database, absent\n // encryption key), which would otherwise leave runError unset and report ok: true.\n runError = error;\n throw error;\n } finally {\n reporter.onRunEnd?.({\n ok: !runError,\n total: scenarios.length,\n passed,\n failed,\n durationMs: Date.now() - startedAt,\n });\n if (uiStarted.value) {\n // Only KEEP the whole-run video when the run FAILED — passing runs discard it unread.\n const keepVideo = !!runError;\n await ui.stop({ keepVideo });\n // Video bytes are only finalized after ui.stop(); attach it as a run-level artifact so\n // the reporter uploads it and references it on run.end (queued before flushPending runs).\n if (keepVideo) {\n const video = ui.getRunVideo?.();\n if (video && reporter.attachRunArtifact) {\n reporter.attachRunArtifact({ name: video.name, contentType: video.contentType, data: video.data });\n }\n }\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.step.d.ts","sourceRoot":"","sources":["../../../../src/testing/steps/ui/navigation.step.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAYxD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAwCpE"}
1
+ {"version":3,"file":"navigation.step.d.ts","sourceRoot":"","sources":["../../../../src/testing/steps/ui/navigation.step.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAYxD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CA4CpE"}
@@ -22,20 +22,20 @@ function registerNavigationSteps(registry) {
22
22
  registry.register("ui.expectUrl", async (ctx, step) => {
23
23
  const page = requirePage(ctx, "ui.expectUrl");
24
24
  const input = (step.with ?? {});
25
- const current = page.url();
26
- if (input.equals !== undefined) {
27
- if (current !== input.equals) {
28
- throw new Error(`Expected URL to equal "${input.equals}" but got "${current}"`);
29
- }
30
- return;
25
+ if (input.equals === undefined && input.contains === undefined) {
26
+ throw new Error('Missing "equals" or "contains" in step.with for op "ui.expectUrl"');
31
27
  }
32
- if (input.contains !== undefined) {
33
- if (!current.includes(input.contains)) {
34
- throw new Error(`Expected URL to contain "${input.contains}" but got "${current}"`);
35
- }
36
- return;
28
+ const expectation = input.equals !== undefined
29
+ ? `equal "${input.equals}"`
30
+ : `contain "${input.contains}"`;
31
+ try {
32
+ await page.waitForURL((url) => input.equals !== undefined
33
+ ? url.toString() === input.equals
34
+ : url.toString().includes(String(input.contains)), { timeout: ctx.ui?.resolveNavigationTimeout(input.timeoutMs) });
35
+ }
36
+ catch {
37
+ throw new Error(`Expected URL to ${expectation} but got "${page.url()}"`);
37
38
  }
38
- throw new Error('Missing "equals" or "contains" in step.with for op "ui.expectUrl"');
39
39
  });
40
40
  }
41
41
  //# sourceMappingURL=navigation.step.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.step.js","sourceRoot":"","sources":["../../../../src/testing/steps/ui/navigation.step.ts"],"names":[],"mappings":";;AAcA,0DAwCC;AA/CD,SAAS,WAAW,CAAC,GAAgB,EAAE,EAAU;IAC/C,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,sCAAsC,EAAE,GAAG,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,SAAgB,uBAAuB,CAAC,QAAsB;IAC5D,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,GAAgB,EAAE,IAAY,EAAE,EAAE;QACpE,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAc,CAAC;QAC7C,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;QACD,MAAM,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC;QACvD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YACnB,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,wBAAwB,CAAC,KAAK,CAAC,SAAS,CAAC;SAC3D,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,EAAE,GAAgB,EAAE,IAAY,EAAE,EAAE;QACzE,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAmB,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE3B,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,OAAO,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CACb,0BAA0B,KAAK,CAAC,MAAM,cAAc,OAAO,GAAG,CAC/D,CAAC;YACJ,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACtC,MAAM,IAAI,KAAK,CACb,4BAA4B,KAAK,CAAC,QAAQ,cAAc,OAAO,GAAG,CACnE,CAAC;YACJ,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { TestContext } from \"../../contracts/runtime-context.types\";\nimport type { OpStep } from \"../../contracts/testing-metadata.types\";\nimport { StepRegistry } from \"../../core/step-registry\";\n\ntype GotoInput = { url: string; timeoutMs?: number };\ntype ExpectUrlInput = { equals?: string; contains?: string };\n\nfunction requirePage(ctx: TestContext, op: string) {\n if (!ctx.ui || !ctx.ui.page) {\n throw new Error(`Missing UI page on context for op \"${op}\"`);\n }\n return ctx.ui.page;\n}\n\nexport function registerNavigationSteps(registry: StepRegistry): void {\n registry.register(\"ui.goto\", async (ctx: TestContext, step: OpStep) => {\n const page = requirePage(ctx, \"ui.goto\");\n const input = (step.with ?? {}) as GotoInput;\n if (!input.url) {\n throw new Error('Missing \"url\" in step.with for op \"ui.goto\"');\n }\n const url = ctx.ui?.resolveUrl(input.url) ?? input.url;\n await page.goto(url, {\n timeout: ctx.ui?.resolveNavigationTimeout(input.timeoutMs),\n });\n });\n\n registry.register(\"ui.expectUrl\", async (ctx: TestContext, step: OpStep) => {\n const page = requirePage(ctx, \"ui.expectUrl\");\n const input = (step.with ?? {}) as ExpectUrlInput;\n const current = page.url();\n\n if (input.equals !== undefined) {\n if (current !== input.equals) {\n throw new Error(\n `Expected URL to equal \"${input.equals}\" but got \"${current}\"`,\n );\n }\n return;\n }\n\n if (input.contains !== undefined) {\n if (!current.includes(input.contains)) {\n throw new Error(\n `Expected URL to contain \"${input.contains}\" but got \"${current}\"`,\n );\n }\n return;\n }\n\n throw new Error(\n 'Missing \"equals\" or \"contains\" in step.with for op \"ui.expectUrl\"',\n );\n });\n}\n"]}
1
+ {"version":3,"file":"navigation.step.js","sourceRoot":"","sources":["../../../../src/testing/steps/ui/navigation.step.ts"],"names":[],"mappings":";;AAcA,0DA4CC;AAnDD,SAAS,WAAW,CAAC,GAAgB,EAAE,EAAU;IAC/C,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,sCAAsC,EAAE,GAAG,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,SAAgB,uBAAuB,CAAC,QAAsB;IAC5D,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,GAAgB,EAAE,IAAY,EAAE,EAAE;QACpE,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAc,CAAC;QAC7C,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;QACD,MAAM,GAAG,GAAG,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC;QACvD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YACnB,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,wBAAwB,CAAC,KAAK,CAAC,SAAS,CAAC;SAC3D,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,EAAE,GAAgB,EAAE,IAAY,EAAE,EAAE;QACzE,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAmB,CAAC;QAElD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC/D,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GACf,KAAK,CAAC,MAAM,KAAK,SAAS;YACxB,CAAC,CAAC,UAAU,KAAK,CAAC,MAAM,GAAG;YAC3B,CAAC,CAAC,YAAY,KAAK,CAAC,QAAQ,GAAG,CAAC;QAIpC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,UAAU,CACnB,CAAC,GAAG,EAAE,EAAE,CACN,KAAK,CAAC,MAAM,KAAK,SAAS;gBACxB,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,KAAK,CAAC,MAAM;gBACjC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EACrD,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,wBAAwB,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAC/D,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,mBAAmB,WAAW,aAAa,IAAI,CAAC,GAAG,EAAE,GAAG,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { TestContext } from \"../../contracts/runtime-context.types\";\nimport type { OpStep } from \"../../contracts/testing-metadata.types\";\nimport { StepRegistry } from \"../../core/step-registry\";\n\ntype GotoInput = { url: string; timeoutMs?: number };\ntype ExpectUrlInput = { equals?: string; contains?: string; timeoutMs?: number };\n\nfunction requirePage(ctx: TestContext, op: string) {\n if (!ctx.ui || !ctx.ui.page) {\n throw new Error(`Missing UI page on context for op \"${op}\"`);\n }\n return ctx.ui.page;\n}\n\nexport function registerNavigationSteps(registry: StepRegistry): void {\n registry.register(\"ui.goto\", async (ctx: TestContext, step: OpStep) => {\n const page = requirePage(ctx, \"ui.goto\");\n const input = (step.with ?? {}) as GotoInput;\n if (!input.url) {\n throw new Error('Missing \"url\" in step.with for op \"ui.goto\"');\n }\n const url = ctx.ui?.resolveUrl(input.url) ?? input.url;\n await page.goto(url, {\n timeout: ctx.ui?.resolveNavigationTimeout(input.timeoutMs),\n });\n });\n\n registry.register(\"ui.expectUrl\", async (ctx: TestContext, step: OpStep) => {\n const page = requirePage(ctx, \"ui.expectUrl\");\n const input = (step.with ?? {}) as ExpectUrlInput;\n\n if (input.equals === undefined && input.contains === undefined) {\n throw new Error(\n 'Missing \"equals\" or \"contains\" in step.with for op \"ui.expectUrl\"',\n );\n }\n\n const expectation =\n input.equals !== undefined\n ? `equal \"${input.equals}\"`\n : `contain \"${input.contains}\"`;\n\n // Waits for the URL rather than sampling it, so an assertion placed straight\n // after a click does not race the navigation.\n try {\n await page.waitForURL(\n (url) =>\n input.equals !== undefined\n ? url.toString() === input.equals\n : url.toString().includes(String(input.contains)),\n { timeout: ctx.ui?.resolveNavigationTimeout(input.timeoutMs) },\n );\n } catch {\n throw new Error(\n `Expected URL to ${expectation} but got \"${page.url()}\"`,\n );\n }\n });\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidxai/core",
3
- "version": "0.1.15",
3
+ "version": "0.1.16-beta.0",
4
4
  "description": "This module is a NestJS module containing all the required core providers required by a Solid application",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",