create-appraisejs 0.1.7 → 0.1.8-alpha

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 (316) hide show
  1. package/README.md +45 -45
  2. package/dist/cli.js +2 -2
  3. package/dist/cli.js.map +1 -1
  4. package/dist/copy-template.d.ts.map +1 -1
  5. package/dist/copy-template.js.map +1 -1
  6. package/package.json +69 -67
  7. package/templates/default/.vscode/settings.json +5 -0
  8. package/templates/default/appraisejs.config.json +1 -1
  9. package/templates/default/components.json +24 -24
  10. package/templates/default/cucumber.mjs +16 -0
  11. package/templates/default/eslint.config.mjs +15 -15
  12. package/templates/default/next.config.ts +13 -7
  13. package/templates/default/package-lock.json +13732 -14321
  14. package/templates/default/package.json +11 -9
  15. package/templates/default/postcss.config.mjs +8 -8
  16. package/templates/default/prisma/migrations/20251104113456_add_type_for_template_step_groups/migration.sql +16 -16
  17. package/templates/default/prisma/migrations/20251104170946_add_tags_to_test_suite_and_test_case/migration.sql +27 -27
  18. package/templates/default/prisma/migrations/20251112190024_add_cascade_delete_to_test_run_test_case/migration.sql +17 -17
  19. package/templates/default/prisma/migrations/20251113181100_add_test_run_log/migration.sql +12 -12
  20. package/templates/default/prisma/migrations/20251119191838_add_tag_type/migration.sql +28 -28
  21. package/templates/default/prisma/migrations/20251121164059_add_conflict_resolution/migration.sql +12 -12
  22. package/templates/default/prisma/migrations/20251223183400_add_report_model_to_db_schema/migration.sql +10 -10
  23. package/templates/default/prisma/migrations/20251223183637_add_report_test_case_entity_for_storing_test_results_for_individual_test_cases/migration.sql +10 -10
  24. package/templates/default/prisma/migrations/20251224083549_add_comprehensive_report_storage/migration.sql +108 -108
  25. package/templates/default/prisma/migrations/20251229194422_migrate_duration_to_string/migration.sql +55 -55
  26. package/templates/default/prisma/migrations/20251230124637_add_unique_constraint_to_test_run_name/migration.sql +27 -27
  27. package/templates/default/prisma/migrations/20260115094436_add_dashboard_metrics/migration.sql +59 -59
  28. package/templates/default/prisma/migrations/20260127172022_add_cascade_delete_to_step_parameters/migration.sql +34 -34
  29. package/templates/default/prisma/schema.prisma +554 -554
  30. package/templates/default/scripts/regenerate-features.ts +94 -94
  31. package/templates/default/scripts/setup-env.ts +19 -19
  32. package/templates/default/scripts/sync-all.ts +341 -341
  33. package/templates/default/scripts/sync-appraise-base-template.ts +52 -2
  34. package/templates/default/scripts/sync-environments.ts +323 -323
  35. package/templates/default/scripts/sync-locator-groups.ts +413 -413
  36. package/templates/default/scripts/sync-locators.ts +402 -402
  37. package/templates/default/scripts/sync-modules.ts +349 -349
  38. package/templates/default/scripts/sync-tags.ts +292 -292
  39. package/templates/default/scripts/sync-template-step-groups.ts +399 -399
  40. package/templates/default/scripts/sync-template-steps.ts +806 -806
  41. package/templates/default/scripts/sync-test-cases.ts +905 -905
  42. package/templates/default/scripts/sync-test-suites.ts +411 -411
  43. package/templates/default/src/actions/conflict/conflict.action.ts +33 -33
  44. package/templates/default/src/actions/dashboard/dashboard-actions.ts +240 -240
  45. package/templates/default/src/actions/environments/environment-actions.ts +205 -205
  46. package/templates/default/src/actions/locator/locator-actions.ts +547 -547
  47. package/templates/default/src/actions/locator-groups/locator-group-actions.ts +344 -344
  48. package/templates/default/src/actions/modules/module-actions.ts +133 -133
  49. package/templates/default/src/actions/reports/report-actions.ts +613 -613
  50. package/templates/default/src/actions/review/review-actions.ts +147 -147
  51. package/templates/default/src/actions/tags/tag-actions.ts +104 -104
  52. package/templates/default/src/actions/template-step/template-step-actions.ts +332 -332
  53. package/templates/default/src/actions/template-step-group/template-step-group-actions.ts +278 -278
  54. package/templates/default/src/actions/template-test-case/template-test-case-actions.ts +238 -238
  55. package/templates/default/src/actions/test-case/test-case-actions.ts +419 -419
  56. package/templates/default/src/actions/test-run/test-run-actions.ts +1185 -1185
  57. package/templates/default/src/actions/test-suite/test-suite-actions.ts +253 -253
  58. package/templates/default/src/actions/user/user-actions.ts +13 -13
  59. package/templates/default/src/app/(base)/environments/create/page.tsx +28 -28
  60. package/templates/default/src/app/(base)/environments/environment-form.tsx +219 -219
  61. package/templates/default/src/app/(base)/environments/environment-table-columns.tsx +96 -96
  62. package/templates/default/src/app/(base)/environments/environment-table.tsx +24 -24
  63. package/templates/default/src/app/(base)/environments/modify/[id]/page.tsx +46 -46
  64. package/templates/default/src/app/(base)/environments/page.tsx +59 -59
  65. package/templates/default/src/app/(base)/layout.tsx +10 -10
  66. package/templates/default/src/app/(base)/locator-groups/create/page.tsx +44 -44
  67. package/templates/default/src/app/(base)/locator-groups/locator-group-form.tsx +215 -215
  68. package/templates/default/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
  69. package/templates/default/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
  70. package/templates/default/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
  71. package/templates/default/src/app/(base)/locator-groups/page.tsx +61 -61
  72. package/templates/default/src/app/(base)/locators/create/page.tsx +38 -38
  73. package/templates/default/src/app/(base)/locators/locator-form.tsx +163 -163
  74. package/templates/default/src/app/(base)/locators/locator-table-columns.tsx +73 -90
  75. package/templates/default/src/app/(base)/locators/locator-table.tsx +28 -28
  76. package/templates/default/src/app/(base)/locators/modify/[id]/page.tsx +45 -45
  77. package/templates/default/src/app/(base)/locators/page.tsx +65 -65
  78. package/templates/default/src/app/(base)/locators/sync-locators-button.tsx +66 -66
  79. package/templates/default/src/app/(base)/modules/create/page.tsx +34 -34
  80. package/templates/default/src/app/(base)/modules/modify/[id]/page.tsx +46 -46
  81. package/templates/default/src/app/(base)/modules/module-form.tsx +126 -126
  82. package/templates/default/src/app/(base)/modules/module-table-columns.tsx +85 -85
  83. package/templates/default/src/app/(base)/modules/module-table.tsx +24 -24
  84. package/templates/default/src/app/(base)/modules/page.tsx +59 -59
  85. package/templates/default/src/app/(base)/reports/[id]/page.tsx +517 -517
  86. package/templates/default/src/app/(base)/reports/duration-chart.tsx +33 -33
  87. package/templates/default/src/app/(base)/reports/feature-chart.tsx +78 -78
  88. package/templates/default/src/app/(base)/reports/overview-chart.tsx +46 -46
  89. package/templates/default/src/app/(base)/reports/page.tsx +98 -98
  90. package/templates/default/src/app/(base)/reports/report-metric-card.tsx +16 -16
  91. package/templates/default/src/app/(base)/reports/report-table-columns.tsx +189 -189
  92. package/templates/default/src/app/(base)/reports/report-table.tsx +72 -72
  93. package/templates/default/src/app/(base)/reports/report-view-table-columns.tsx +131 -131
  94. package/templates/default/src/app/(base)/reports/report-view-table.tsx +82 -82
  95. package/templates/default/src/app/(base)/reports/test-cases/page.tsx +42 -42
  96. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +115 -115
  97. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
  98. package/templates/default/src/app/(base)/reports/test-suites/page.tsx +42 -42
  99. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +79 -79
  100. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +27 -27
  101. package/templates/default/src/app/(base)/reports/view-logs-button.tsx +60 -60
  102. package/templates/default/src/app/(base)/reviews/create/page.tsx +26 -26
  103. package/templates/default/src/app/(base)/reviews/created-reviews-table.tsx +15 -15
  104. package/templates/default/src/app/(base)/reviews/modify/[id]/page.tsx +26 -26
  105. package/templates/default/src/app/(base)/reviews/page.tsx +26 -26
  106. package/templates/default/src/app/(base)/reviews/review/[id]/page.tsx +26 -26
  107. package/templates/default/src/app/(base)/reviews/review-form.tsx +11 -11
  108. package/templates/default/src/app/(base)/reviews/review-table-by-creator-columns.tsx +9 -9
  109. package/templates/default/src/app/(base)/reviews/review-table-by-reviewer-columns.tsx +9 -9
  110. package/templates/default/src/app/(base)/reviews/reviewer-reviews-table.tsx +15 -15
  111. package/templates/default/src/app/(base)/tags/create/page.tsx +39 -39
  112. package/templates/default/src/app/(base)/tags/modify/[id]/page.tsx +50 -50
  113. package/templates/default/src/app/(base)/tags/page.tsx +58 -58
  114. package/templates/default/src/app/(base)/tags/tag-form.tsx +147 -147
  115. package/templates/default/src/app/(base)/tags/tag-table-columns.tsx +63 -63
  116. package/templates/default/src/app/(base)/tags/tag-table.tsx +29 -29
  117. package/templates/default/src/app/(base)/template-step-groups/create/page.tsx +28 -28
  118. package/templates/default/src/app/(base)/template-step-groups/modify/[id]/page.tsx +45 -45
  119. package/templates/default/src/app/(base)/template-step-groups/page.tsx +60 -60
  120. package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.tsx +167 -167
  121. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table-columns.tsx +89 -89
  122. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table.tsx +32 -32
  123. package/templates/default/src/app/(base)/template-steps/create/page.tsx +37 -37
  124. package/templates/default/src/app/(base)/template-steps/modify/[id]/page.tsx +49 -49
  125. package/templates/default/src/app/(base)/template-steps/page.tsx +59 -59
  126. package/templates/default/src/app/(base)/template-steps/paramChip.tsx +213 -213
  127. package/templates/default/src/app/(base)/template-steps/template-step-form.tsx +384 -384
  128. package/templates/default/src/app/(base)/template-steps/template-step-table-columns.tsx +158 -158
  129. package/templates/default/src/app/(base)/template-steps/template-step-table.tsx +24 -24
  130. package/templates/default/src/app/(base)/template-test-cases/create/page.tsx +56 -56
  131. package/templates/default/src/app/(base)/template-test-cases/modify/[id]/page.tsx +89 -89
  132. package/templates/default/src/app/(base)/template-test-cases/page.tsx +58 -58
  133. package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.tsx +84 -84
  134. package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.tsx +262 -262
  135. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
  136. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
  137. package/templates/default/src/app/(base)/test-cases/create/page.tsx +76 -76
  138. package/templates/default/src/app/(base)/test-cases/create-from-template/generate/[id]/page.tsx +96 -96
  139. package/templates/default/src/app/(base)/test-cases/create-from-template/page.tsx +38 -38
  140. package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.tsx +73 -73
  141. package/templates/default/src/app/(base)/test-cases/modify/[id]/page.tsx +106 -106
  142. package/templates/default/src/app/(base)/test-cases/page.tsx +60 -60
  143. package/templates/default/src/app/(base)/test-cases/test-case-flow.tsx +82 -82
  144. package/templates/default/src/app/(base)/test-cases/test-case-form.tsx +395 -395
  145. package/templates/default/src/app/(base)/test-cases/test-case-table-columns.tsx +90 -90
  146. package/templates/default/src/app/(base)/test-cases/test-case-table.tsx +35 -35
  147. package/templates/default/src/app/(base)/test-runs/[id]/page.tsx +56 -56
  148. package/templates/default/src/app/(base)/test-runs/create/page.tsx +47 -47
  149. package/templates/default/src/app/(base)/test-runs/page.tsx +60 -60
  150. package/templates/default/src/app/(base)/test-runs/test-run-form.tsx +508 -512
  151. package/templates/default/src/app/(base)/test-runs/test-run-table-columns.tsx +229 -229
  152. package/templates/default/src/app/(base)/test-runs/test-run-table.tsx +127 -127
  153. package/templates/default/src/app/(base)/test-suites/create/page.tsx +45 -45
  154. package/templates/default/src/app/(base)/test-suites/modify/[id]/page.tsx +55 -55
  155. package/templates/default/src/app/(base)/test-suites/page.tsx +82 -82
  156. package/templates/default/src/app/(base)/test-suites/test-suite-form.tsx +269 -269
  157. package/templates/default/src/app/(base)/test-suites/test-suite-table-columns.tsx +97 -97
  158. package/templates/default/src/app/(base)/test-suites/test-suite-table.tsx +29 -29
  159. package/templates/default/src/app/(dashboard-components)/app-drawer.tsx +187 -187
  160. package/templates/default/src/app/(dashboard-components)/data-card-grid.tsx +12 -12
  161. package/templates/default/src/app/(dashboard-components)/data-card.tsx +26 -26
  162. package/templates/default/src/app/(dashboard-components)/execution-health-panel.tsx +56 -56
  163. package/templates/default/src/app/(dashboard-components)/ongoing-test-runs-card.tsx +87 -87
  164. package/templates/default/src/app/(dashboard-components)/quick-actions-drawer.tsx +44 -44
  165. package/templates/default/src/app/api/test-runs/[runId]/download/route.ts +133 -133
  166. package/templates/default/src/app/api/test-runs/[runId]/logs/route.ts +420 -420
  167. package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.ts +146 -146
  168. package/templates/default/src/app/globals.css +147 -147
  169. package/templates/default/src/app/layout.tsx +171 -171
  170. package/templates/default/src/app/page.tsx +64 -64
  171. package/templates/default/src/assets/icons/empty-tube.tsx +23 -23
  172. package/templates/default/src/assets/icons/tube-plus.tsx +29 -29
  173. package/templates/default/src/components/base-node.tsx +21 -21
  174. package/templates/default/src/components/chart/pie-chart.tsx +73 -73
  175. package/templates/default/src/components/data-extraction/locator-inspector.tsx +460 -460
  176. package/templates/default/src/components/data-state/empty-state.tsx +40 -40
  177. package/templates/default/src/components/data-visualization/info-card.tsx +70 -70
  178. package/templates/default/src/components/data-visualization/info-grid.tsx +22 -22
  179. package/templates/default/src/components/devtools/providers.tsx +19 -13
  180. package/templates/default/src/components/diagram/button-edge.tsx +54 -54
  181. package/templates/default/src/components/diagram/dynamic-parameters.tsx +438 -438
  182. package/templates/default/src/components/diagram/edit-header-option.tsx +36 -36
  183. package/templates/default/src/components/diagram/flow-diagram.tsx +470 -470
  184. package/templates/default/src/components/diagram/node-form.tsx +262 -262
  185. package/templates/default/src/components/diagram/options-header-node.tsx +57 -57
  186. package/templates/default/src/components/diagram/template-step-combobox.tsx +155 -155
  187. package/templates/default/src/components/form/error-message.tsx +7 -7
  188. package/templates/default/src/components/kokonutui/smooth-tab.tsx +453 -453
  189. package/templates/default/src/components/loading-skeleton/data-table/data-table-skeleton.tsx +30 -30
  190. package/templates/default/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
  191. package/templates/default/src/components/loading-skeleton/form/icon-button-skeleton.tsx +8 -8
  192. package/templates/default/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
  193. package/templates/default/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
  194. package/templates/default/src/components/logo.tsx +15 -15
  195. package/templates/default/src/components/navigation/command-badge.tsx +34 -34
  196. package/templates/default/src/components/navigation/command-chain-input.tsx +51 -51
  197. package/templates/default/src/components/navigation/entity-search-command.tsx +116 -116
  198. package/templates/default/src/components/navigation/nav-card.tsx +31 -31
  199. package/templates/default/src/components/navigation/nav-command.tsx +508 -508
  200. package/templates/default/src/components/navigation/nav-link.tsx +60 -60
  201. package/templates/default/src/components/navigation/nav-menu-card-deck.tsx +112 -112
  202. package/templates/default/src/components/node-header.tsx +159 -159
  203. package/templates/default/src/components/reports/test-case-logs-modal.tsx +253 -253
  204. package/templates/default/src/components/table/table-actions.tsx +172 -172
  205. package/templates/default/src/components/test-run/download-logs-button.tsx +99 -99
  206. package/templates/default/src/components/test-run/log-viewer.tsx +445 -445
  207. package/templates/default/src/components/test-run/test-run-details.tsx +611 -611
  208. package/templates/default/src/components/test-run/test-run-header.tsx +149 -149
  209. package/templates/default/src/components/test-run/view-report-button.tsx +102 -102
  210. package/templates/default/src/components/theme/mode-toggle.tsx +54 -54
  211. package/templates/default/src/components/theme/theme-provider.tsx +8 -8
  212. package/templates/default/src/components/typography/page-header-subtitle.tsx +7 -7
  213. package/templates/default/src/components/typography/page-header.tsx +7 -7
  214. package/templates/default/src/components/ui/alert-dialog.tsx +106 -106
  215. package/templates/default/src/components/ui/alert.tsx +43 -43
  216. package/templates/default/src/components/ui/avatar.tsx +40 -40
  217. package/templates/default/src/components/ui/badge.tsx +29 -29
  218. package/templates/default/src/components/ui/button.tsx +47 -47
  219. package/templates/default/src/components/ui/calendar.tsx +158 -158
  220. package/templates/default/src/components/ui/card.tsx +43 -43
  221. package/templates/default/src/components/ui/checkbox.tsx +28 -28
  222. package/templates/default/src/components/ui/command.tsx +135 -135
  223. package/templates/default/src/components/ui/data-table-column-header.tsx +61 -61
  224. package/templates/default/src/components/ui/data-table-pagination.tsx +87 -87
  225. package/templates/default/src/components/ui/data-table-view-options.tsx +50 -50
  226. package/templates/default/src/components/ui/data-table.tsx +267 -267
  227. package/templates/default/src/components/ui/dialog.tsx +97 -97
  228. package/templates/default/src/components/ui/dropdown-menu.tsx +182 -182
  229. package/templates/default/src/components/ui/input.tsx +22 -22
  230. package/templates/default/src/components/ui/kbd.tsx +28 -28
  231. package/templates/default/src/components/ui/label.tsx +19 -19
  232. package/templates/default/src/components/ui/loading.tsx +12 -12
  233. package/templates/default/src/components/ui/multi-select-with-preview.tsx +116 -116
  234. package/templates/default/src/components/ui/multi-select.tsx +142 -142
  235. package/templates/default/src/components/ui/navigation-menu.tsx +120 -120
  236. package/templates/default/src/components/ui/popover.tsx +33 -33
  237. package/templates/default/src/components/ui/progress.tsx +25 -25
  238. package/templates/default/src/components/ui/radio-group.tsx +44 -44
  239. package/templates/default/src/components/ui/scroll-area.tsx +40 -40
  240. package/templates/default/src/components/ui/select.tsx +151 -144
  241. package/templates/default/src/components/ui/separator.tsx +22 -22
  242. package/templates/default/src/components/ui/skeleton.tsx +7 -7
  243. package/templates/default/src/components/ui/table.tsx +76 -76
  244. package/templates/default/src/components/ui/tabs.tsx +55 -55
  245. package/templates/default/src/components/ui/textarea.tsx +21 -21
  246. package/templates/default/src/components/ui/toast.tsx +113 -113
  247. package/templates/default/src/components/ui/toaster.tsx +26 -26
  248. package/templates/default/src/components/user-prompt/delete-prompt.tsx +87 -87
  249. package/templates/default/src/config/db-config.ts +10 -10
  250. package/templates/default/src/constants/form-opts/diagram/node-form.ts +30 -30
  251. package/templates/default/src/constants/form-opts/environment-form-opts.ts +24 -24
  252. package/templates/default/src/constants/form-opts/locator-form-opts.ts +20 -20
  253. package/templates/default/src/constants/form-opts/locator-group-form-opts.ts +28 -28
  254. package/templates/default/src/constants/form-opts/module-form-opts.ts +21 -21
  255. package/templates/default/src/constants/form-opts/review-form-opts.ts +23 -23
  256. package/templates/default/src/constants/form-opts/tag-form-opts.ts +42 -42
  257. package/templates/default/src/constants/form-opts/template-selection-form-opts.ts +16 -16
  258. package/templates/default/src/constants/form-opts/template-step-group-form-opts.ts +24 -24
  259. package/templates/default/src/constants/form-opts/template-test-case-form-opts.ts +39 -39
  260. package/templates/default/src/constants/form-opts/template-test-step-form-opts.ts +36 -36
  261. package/templates/default/src/constants/form-opts/test-case-form-opts.ts +43 -43
  262. package/templates/default/src/constants/form-opts/test-run-form-opts.ts +31 -31
  263. package/templates/default/src/constants/form-opts/test-suite-form-opts.ts +24 -24
  264. package/templates/default/src/hooks/use-toast.ts +187 -187
  265. package/templates/default/src/lib/bidirectional-sync.ts +432 -432
  266. package/templates/default/src/lib/database-sync.ts +531 -531
  267. package/templates/default/src/lib/environment-file-utils.ts +221 -221
  268. package/templates/default/src/lib/feature-file-generator.ts +411 -411
  269. package/templates/default/src/lib/gherkin-parser.ts +259 -259
  270. package/templates/default/src/lib/locator-group-file-utils.ts +370 -370
  271. package/templates/default/src/lib/metrics/metric-calculator.ts +613 -613
  272. package/templates/default/src/lib/module-hierarchy-builder.ts +205 -205
  273. package/templates/default/src/lib/path-helpers/module-path.ts +71 -71
  274. package/templates/default/src/lib/test-case-utils.ts +6 -6
  275. package/templates/default/src/lib/test-run/log-formatter.ts +83 -83
  276. package/templates/default/src/lib/test-run/process-manager.ts +191 -191
  277. package/templates/default/src/lib/test-run/report-parser.ts +316 -316
  278. package/templates/default/src/lib/test-run/test-run-executor.ts +144 -144
  279. package/templates/default/src/lib/test-run/winston-logger.ts +95 -95
  280. package/templates/default/src/lib/transformers/gherkin-converter.ts +42 -42
  281. package/templates/default/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
  282. package/templates/default/src/lib/transformers/template-test-case-converter.ts +160 -160
  283. package/templates/default/src/lib/utils/node-param-validation.ts +81 -81
  284. package/templates/default/src/lib/utils/template-step-file-generator.ts +167 -167
  285. package/templates/default/src/lib/utils/template-step-file-manager-intelligent.ts +723 -723
  286. package/templates/default/src/lib/utils/template-step-file-manager.ts +166 -166
  287. package/templates/default/src/lib/utils.ts +31 -31
  288. package/templates/default/src/tests/config/executor/world.ts +41 -41
  289. package/templates/default/src/tests/executor.ts +80 -80
  290. package/templates/default/src/tests/hooks/hooks.ts +99 -99
  291. package/templates/default/src/tests/mapping/locator-map.json +1 -1
  292. package/templates/default/src/tests/steps/actions/click.step.ts +62 -62
  293. package/templates/default/src/tests/steps/actions/navigation.step.ts +73 -72
  294. package/templates/default/src/tests/steps/validations/active_state_assertion.step.ts +34 -34
  295. package/templates/default/src/tests/steps/validations/navigation_assertion.step.ts +24 -23
  296. package/templates/default/src/tests/steps/validations/text_assertion.step.ts +111 -111
  297. package/templates/default/src/tests/steps/validations/visibility_assertion.step.ts +30 -30
  298. package/templates/default/src/tests/support/parameter-types.ts +12 -12
  299. package/templates/default/src/tests/utils/cache.util.ts +260 -260
  300. package/templates/default/src/tests/utils/cli.util.ts +177 -177
  301. package/templates/default/src/tests/utils/environment.util.ts +65 -65
  302. package/templates/default/src/tests/utils/locator.util.ts +248 -248
  303. package/templates/default/src/tests/utils/random-data.util.ts +44 -44
  304. package/templates/default/src/tests/utils/spawner.util.ts +617 -617
  305. package/templates/default/src/types/diagram/diagram.ts +34 -34
  306. package/templates/default/src/types/diagram/template-step.ts +11 -11
  307. package/templates/default/src/types/executor/browser.type.ts +1 -1
  308. package/templates/default/src/types/form/actionHandler.ts +6 -6
  309. package/templates/default/src/types/locator/locator.type.ts +11 -11
  310. package/templates/default/src/types/step/step.type.ts +1 -1
  311. package/templates/default/src/types/table/data-table.ts +6 -6
  312. package/templates/default/tailwind.config.ts +62 -62
  313. package/templates/default/.env +0 -2
  314. package/templates/default/next-env.d.ts +0 -6
  315. package/templates/default/prisma/prisma/dev.db +0 -0
  316. package/templates/default/src/tests/config/environments/environments.json +0 -14
@@ -1,83 +1,83 @@
1
- /**
2
- * Log formatting utilities for storing and retrieving test run logs
3
- */
4
-
5
- export interface LogEntry {
6
- type: 'stdout' | 'stderr' | 'status'
7
- message: string
8
- timestamp: Date
9
- }
10
-
11
- /**
12
- * Formats log entries into a single text string for storage in the database
13
- * Format: [timestamp] [TYPE] message
14
- *
15
- * @param logs - Array of log entries to format
16
- * @returns Formatted log string
17
- */
18
- export function formatLogsForStorage(logs: LogEntry[]): string {
19
- return logs
20
- .map(log => {
21
- const timestamp = log.timestamp.toISOString()
22
- const type = log.type.toUpperCase()
23
- // Escape newlines in message to preserve them in the formatted string
24
- const escapedMessage = log.message.replace(/\n/g, '\\n')
25
- return `[${timestamp}] [${type}] ${escapedMessage}`
26
- })
27
- .join('\n')
28
- }
29
-
30
- /**
31
- * Parses formatted log text back into an array of LogEntry objects
32
- *
33
- * @param formattedLogs - Formatted log string from database
34
- * @returns Array of log entries
35
- */
36
- export function parseLogsFromStorage(formattedLogs: string): LogEntry[] {
37
- if (!formattedLogs || formattedLogs.trim() === '') {
38
- return []
39
- }
40
-
41
- const lines = formattedLogs.split('\n')
42
- const parsedLogs: LogEntry[] = []
43
-
44
- for (const line of lines) {
45
- if (!line.trim()) continue
46
-
47
- try {
48
- // Match format: [timestamp] [TYPE] message
49
- const match = line.match(/^\[([^\]]+)\] \[([^\]]+)\] (.+)$/)
50
-
51
- if (match) {
52
- const [, timestampStr, typeStr, message] = match
53
- const timestamp = new Date(timestampStr)
54
- const type = typeStr.toLowerCase() as 'stdout' | 'stderr' | 'status'
55
-
56
- // Unescape newlines in message
57
- const unescapedMessage = message.replace(/\\n/g, '\n')
58
-
59
- // Validate type
60
- if (type === 'stdout' || type === 'stderr' || type === 'status') {
61
- parsedLogs.push({
62
- type,
63
- message: unescapedMessage,
64
- timestamp: isNaN(timestamp.getTime()) ? new Date() : timestamp,
65
- })
66
- }
67
- } else {
68
- // Fallback: treat as stdout if format doesn't match
69
- parsedLogs.push({
70
- type: 'stdout',
71
- message: line,
72
- timestamp: new Date(),
73
- })
74
- }
75
- } catch (error) {
76
- // Skip malformed lines
77
- console.error('[LogFormatter] Error parsing log line:', line, error)
78
- }
79
- }
80
-
81
- return parsedLogs
82
- }
83
-
1
+ /**
2
+ * Log formatting utilities for storing and retrieving test run logs
3
+ */
4
+
5
+ export interface LogEntry {
6
+ type: 'stdout' | 'stderr' | 'status'
7
+ message: string
8
+ timestamp: Date
9
+ }
10
+
11
+ /**
12
+ * Formats log entries into a single text string for storage in the database
13
+ * Format: [timestamp] [TYPE] message
14
+ *
15
+ * @param logs - Array of log entries to format
16
+ * @returns Formatted log string
17
+ */
18
+ export function formatLogsForStorage(logs: LogEntry[]): string {
19
+ return logs
20
+ .map(log => {
21
+ const timestamp = log.timestamp.toISOString()
22
+ const type = log.type.toUpperCase()
23
+ // Escape newlines in message to preserve them in the formatted string
24
+ const escapedMessage = log.message.replace(/\n/g, '\\n')
25
+ return `[${timestamp}] [${type}] ${escapedMessage}`
26
+ })
27
+ .join('\n')
28
+ }
29
+
30
+ /**
31
+ * Parses formatted log text back into an array of LogEntry objects
32
+ *
33
+ * @param formattedLogs - Formatted log string from database
34
+ * @returns Array of log entries
35
+ */
36
+ export function parseLogsFromStorage(formattedLogs: string): LogEntry[] {
37
+ if (!formattedLogs || formattedLogs.trim() === '') {
38
+ return []
39
+ }
40
+
41
+ const lines = formattedLogs.split('\n')
42
+ const parsedLogs: LogEntry[] = []
43
+
44
+ for (const line of lines) {
45
+ if (!line.trim()) continue
46
+
47
+ try {
48
+ // Match format: [timestamp] [TYPE] message
49
+ const match = line.match(/^\[([^\]]+)\] \[([^\]]+)\] (.+)$/)
50
+
51
+ if (match) {
52
+ const [, timestampStr, typeStr, message] = match
53
+ const timestamp = new Date(timestampStr)
54
+ const type = typeStr.toLowerCase() as 'stdout' | 'stderr' | 'status'
55
+
56
+ // Unescape newlines in message
57
+ const unescapedMessage = message.replace(/\\n/g, '\n')
58
+
59
+ // Validate type
60
+ if (type === 'stdout' || type === 'stderr' || type === 'status') {
61
+ parsedLogs.push({
62
+ type,
63
+ message: unescapedMessage,
64
+ timestamp: isNaN(timestamp.getTime()) ? new Date() : timestamp,
65
+ })
66
+ }
67
+ } else {
68
+ // Fallback: treat as stdout if format doesn't match
69
+ parsedLogs.push({
70
+ type: 'stdout',
71
+ message: line,
72
+ timestamp: new Date(),
73
+ })
74
+ }
75
+ } catch (error) {
76
+ // Skip malformed lines
77
+ console.error('[LogFormatter] Error parsing log line:', line, error)
78
+ }
79
+ }
80
+
81
+ return parsedLogs
82
+ }
83
+
@@ -1,191 +1,191 @@
1
- import type { SpawnedProcess } from '@/tests/utils/spawner.util'
2
- import { EventEmitter } from 'events'
3
- import { taskSpawner } from '@/tests/utils/spawner.util'
4
-
5
- /**
6
- * Process Manager - Singleton to track running test processes by test run ID
7
- *
8
- * This manager maintains a registry of active test processes, allowing
9
- * the SSE route handler to look up processes and stream their logs.
10
- *
11
- * Uses global variable pattern (like Prisma) to persist across Next.js runtime contexts
12
- *
13
- * Security: Currently stores processes by testRunId only.
14
- * TODO: When user authentication is implemented, consider adding user isolation:
15
- * - Option 1: Use composite keys like `${userId}:${testRunId}`
16
- * - Option 2: Store userId in process metadata and filter by userId in get() method
17
- * - Option 3: Create separate ProcessManager instances per user (more complex)
18
- */
19
- class ProcessManager extends EventEmitter {
20
- private processes: Map<string, SpawnedProcess> = new Map()
21
- // Track event listeners for cleanup
22
- private eventListeners: Map<string, Map<string, () => void>> = new Map()
23
-
24
- private constructor() {
25
- super()
26
- // Private constructor for singleton pattern
27
- }
28
-
29
- /**
30
- * Get the singleton instance of ProcessManager
31
- * Uses global variable to persist across Next.js runtime contexts
32
- */
33
- static getInstance(): ProcessManager {
34
- const globalForProcessManager = global as unknown as {
35
- processManager: ProcessManager | undefined
36
- }
37
-
38
- if (!globalForProcessManager.processManager) {
39
- globalForProcessManager.processManager = new ProcessManager()
40
- }
41
-
42
- return globalForProcessManager.processManager
43
- }
44
-
45
- /**
46
- * Register a process for a test run
47
- * Sets up event listeners to parse custom events from stdout/stderr
48
- * @param testRunId - The test run ID
49
- * @param process - The spawned process instance
50
- */
51
- register(testRunId: string, process: SpawnedProcess): void {
52
- this.processes.set(testRunId, process)
53
-
54
- // Set up listeners to parse custom events from stdout/stderr
55
- const listeners = new Map<string, () => void>()
56
-
57
- // Handler for stdout events - parse for custom events
58
- const onStdout = ({ processName, data }: { processName: string; data: string }) => {
59
- if (processName === process.name) {
60
- this.parseAndEmitCustomEvents(testRunId, data)
61
- }
62
- }
63
-
64
- // Handler for stderr events - parse for custom events
65
- const onStderr = ({ processName, data }: { processName: string; data: string }) => {
66
- if (processName === process.name) {
67
- this.parseAndEmitCustomEvents(testRunId, data)
68
- }
69
- }
70
-
71
- // Store cleanup functions
72
- listeners.set('stdout', () => taskSpawner.removeListener('stdout', onStdout))
73
- listeners.set('stderr', () => taskSpawner.removeListener('stderr', onStderr))
74
-
75
- // Register listeners
76
- taskSpawner.on('stdout', onStdout)
77
- taskSpawner.on('stderr', onStderr)
78
-
79
- this.eventListeners.set(testRunId, listeners)
80
- }
81
-
82
- /**
83
- * Parse stdout/stderr output for custom event markers and emit them
84
- * Expects events in JSON format: {"event":"scenario::end","data":{...}}
85
- */
86
- private parseAndEmitCustomEvents(testRunId: string, output: string): void {
87
- // Split by newlines to handle multi-line output
88
- const lines = output.split('\n')
89
-
90
- for (const line of lines) {
91
- if (!line.trim()) continue
92
-
93
- try {
94
- // Look for JSON objects in the line that contain an "event" field
95
- // Matches: {"event":"scenario::end","data":{...}}
96
- const jsonMatch = line.match(/\{[\s\S]*"event"[\s\S]*\}/)
97
- if (jsonMatch) {
98
- const eventData = JSON.parse(jsonMatch[0])
99
- if (eventData.event === 'scenario::end') {
100
- console.log(`[ProcessManager] Parsed scenario::end event for testRunId: ${testRunId}`, eventData)
101
- this.emit('scenario::end', {
102
- testRunId,
103
- scenarioName: eventData.data?.scenarioName,
104
- status: eventData.data?.status,
105
- tracePath: eventData.data?.tracePath,
106
- ...eventData.data,
107
- })
108
- console.log(`[ProcessManager] Emitted scenario::end event for testRunId: ${testRunId}`)
109
- }
110
- }
111
- } catch (error) {
112
- // Not a custom event, continue parsing other lines
113
- // This is expected for regular log output
114
- // Only log if it looks like it might be a JSON parse error
115
- if (line.trim().startsWith('{')) {
116
- console.warn(`[ProcessManager] Failed to parse potential event JSON: ${line.substring(0, 100)}`, error)
117
- }
118
- }
119
- }
120
- }
121
-
122
- /**
123
- * Get a process by test run ID
124
- * @param testRunId - The test run ID
125
- * @returns The spawned process or undefined if not found
126
- */
127
- get(testRunId: string): SpawnedProcess | undefined {
128
- return this.processes.get(testRunId)
129
- }
130
-
131
- /**
132
- * Unregister a process for a test run
133
- * Cleans up event listeners
134
- * @param testRunId - The test run ID
135
- * @returns True if the process was found and removed, false otherwise
136
- */
137
- unregister(testRunId: string): boolean {
138
- // Clean up event listeners
139
- const listeners = this.eventListeners.get(testRunId)
140
- if (listeners) {
141
- listeners.forEach(cleanup => cleanup())
142
- this.eventListeners.delete(testRunId)
143
- }
144
-
145
- const deleted = this.processes.delete(testRunId)
146
- console.log(
147
- `[ProcessManager] Unregistering process for testRunId: ${testRunId}, deleted: ${deleted}, remaining processes: ${this.processes.size}`,
148
- )
149
- return deleted
150
- }
151
-
152
- /**
153
- * Check if a process exists for a test run
154
- * @param testRunId - The test run ID
155
- * @returns True if a process exists, false otherwise
156
- */
157
- has(testRunId: string): boolean {
158
- return this.processes.has(testRunId)
159
- }
160
-
161
- /**
162
- * Get all registered test run IDs (for debugging)
163
- * @returns Array of test run IDs
164
- */
165
- getAllTestRunIds(): string[] {
166
- return Array.from(this.processes.keys())
167
- }
168
-
169
- /**
170
- * Clear all registered processes (useful for cleanup)
171
- */
172
- clear(): void {
173
- // Clean up all event listeners
174
- this.eventListeners.forEach(listeners => {
175
- listeners.forEach(cleanup => cleanup())
176
- })
177
- this.eventListeners.clear()
178
- this.processes.clear()
179
- }
180
-
181
- /**
182
- * Get the number of active processes
183
- * @returns The number of registered processes
184
- */
185
- size(): number {
186
- return this.processes.size
187
- }
188
- }
189
-
190
- // Export singleton instance
191
- export const processManager = ProcessManager.getInstance()
1
+ import type { SpawnedProcess } from '@/tests/utils/spawner.util'
2
+ import { EventEmitter } from 'events'
3
+ import { taskSpawner } from '@/tests/utils/spawner.util'
4
+
5
+ /**
6
+ * Process Manager - Singleton to track running test processes by test run ID
7
+ *
8
+ * This manager maintains a registry of active test processes, allowing
9
+ * the SSE route handler to look up processes and stream their logs.
10
+ *
11
+ * Uses global variable pattern (like Prisma) to persist across Next.js runtime contexts
12
+ *
13
+ * Security: Currently stores processes by testRunId only.
14
+ * TODO: When user authentication is implemented, consider adding user isolation:
15
+ * - Option 1: Use composite keys like `${userId}:${testRunId}`
16
+ * - Option 2: Store userId in process metadata and filter by userId in get() method
17
+ * - Option 3: Create separate ProcessManager instances per user (more complex)
18
+ */
19
+ class ProcessManager extends EventEmitter {
20
+ private processes: Map<string, SpawnedProcess> = new Map()
21
+ // Track event listeners for cleanup
22
+ private eventListeners: Map<string, Map<string, () => void>> = new Map()
23
+
24
+ private constructor() {
25
+ super()
26
+ // Private constructor for singleton pattern
27
+ }
28
+
29
+ /**
30
+ * Get the singleton instance of ProcessManager
31
+ * Uses global variable to persist across Next.js runtime contexts
32
+ */
33
+ static getInstance(): ProcessManager {
34
+ const globalForProcessManager = global as unknown as {
35
+ processManager: ProcessManager | undefined
36
+ }
37
+
38
+ if (!globalForProcessManager.processManager) {
39
+ globalForProcessManager.processManager = new ProcessManager()
40
+ }
41
+
42
+ return globalForProcessManager.processManager
43
+ }
44
+
45
+ /**
46
+ * Register a process for a test run
47
+ * Sets up event listeners to parse custom events from stdout/stderr
48
+ * @param testRunId - The test run ID
49
+ * @param process - The spawned process instance
50
+ */
51
+ register(testRunId: string, process: SpawnedProcess): void {
52
+ this.processes.set(testRunId, process)
53
+
54
+ // Set up listeners to parse custom events from stdout/stderr
55
+ const listeners = new Map<string, () => void>()
56
+
57
+ // Handler for stdout events - parse for custom events
58
+ const onStdout = ({ processName, data }: { processName: string; data: string }) => {
59
+ if (processName === process.name) {
60
+ this.parseAndEmitCustomEvents(testRunId, data)
61
+ }
62
+ }
63
+
64
+ // Handler for stderr events - parse for custom events
65
+ const onStderr = ({ processName, data }: { processName: string; data: string }) => {
66
+ if (processName === process.name) {
67
+ this.parseAndEmitCustomEvents(testRunId, data)
68
+ }
69
+ }
70
+
71
+ // Store cleanup functions
72
+ listeners.set('stdout', () => taskSpawner.removeListener('stdout', onStdout))
73
+ listeners.set('stderr', () => taskSpawner.removeListener('stderr', onStderr))
74
+
75
+ // Register listeners
76
+ taskSpawner.on('stdout', onStdout)
77
+ taskSpawner.on('stderr', onStderr)
78
+
79
+ this.eventListeners.set(testRunId, listeners)
80
+ }
81
+
82
+ /**
83
+ * Parse stdout/stderr output for custom event markers and emit them
84
+ * Expects events in JSON format: {"event":"scenario::end","data":{...}}
85
+ */
86
+ private parseAndEmitCustomEvents(testRunId: string, output: string): void {
87
+ // Split by newlines to handle multi-line output
88
+ const lines = output.split('\n')
89
+
90
+ for (const line of lines) {
91
+ if (!line.trim()) continue
92
+
93
+ try {
94
+ // Look for JSON objects in the line that contain an "event" field
95
+ // Matches: {"event":"scenario::end","data":{...}}
96
+ const jsonMatch = line.match(/\{[\s\S]*"event"[\s\S]*\}/)
97
+ if (jsonMatch) {
98
+ const eventData = JSON.parse(jsonMatch[0])
99
+ if (eventData.event === 'scenario::end') {
100
+ console.log(`[ProcessManager] Parsed scenario::end event for testRunId: ${testRunId}`, eventData)
101
+ this.emit('scenario::end', {
102
+ testRunId,
103
+ scenarioName: eventData.data?.scenarioName,
104
+ status: eventData.data?.status,
105
+ tracePath: eventData.data?.tracePath,
106
+ ...eventData.data,
107
+ })
108
+ console.log(`[ProcessManager] Emitted scenario::end event for testRunId: ${testRunId}`)
109
+ }
110
+ }
111
+ } catch (error) {
112
+ // Not a custom event, continue parsing other lines
113
+ // This is expected for regular log output
114
+ // Only log if it looks like it might be a JSON parse error
115
+ if (line.trim().startsWith('{')) {
116
+ console.warn(`[ProcessManager] Failed to parse potential event JSON: ${line.substring(0, 100)}`, error)
117
+ }
118
+ }
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Get a process by test run ID
124
+ * @param testRunId - The test run ID
125
+ * @returns The spawned process or undefined if not found
126
+ */
127
+ get(testRunId: string): SpawnedProcess | undefined {
128
+ return this.processes.get(testRunId)
129
+ }
130
+
131
+ /**
132
+ * Unregister a process for a test run
133
+ * Cleans up event listeners
134
+ * @param testRunId - The test run ID
135
+ * @returns True if the process was found and removed, false otherwise
136
+ */
137
+ unregister(testRunId: string): boolean {
138
+ // Clean up event listeners
139
+ const listeners = this.eventListeners.get(testRunId)
140
+ if (listeners) {
141
+ listeners.forEach(cleanup => cleanup())
142
+ this.eventListeners.delete(testRunId)
143
+ }
144
+
145
+ const deleted = this.processes.delete(testRunId)
146
+ console.log(
147
+ `[ProcessManager] Unregistering process for testRunId: ${testRunId}, deleted: ${deleted}, remaining processes: ${this.processes.size}`,
148
+ )
149
+ return deleted
150
+ }
151
+
152
+ /**
153
+ * Check if a process exists for a test run
154
+ * @param testRunId - The test run ID
155
+ * @returns True if a process exists, false otherwise
156
+ */
157
+ has(testRunId: string): boolean {
158
+ return this.processes.has(testRunId)
159
+ }
160
+
161
+ /**
162
+ * Get all registered test run IDs (for debugging)
163
+ * @returns Array of test run IDs
164
+ */
165
+ getAllTestRunIds(): string[] {
166
+ return Array.from(this.processes.keys())
167
+ }
168
+
169
+ /**
170
+ * Clear all registered processes (useful for cleanup)
171
+ */
172
+ clear(): void {
173
+ // Clean up all event listeners
174
+ this.eventListeners.forEach(listeners => {
175
+ listeners.forEach(cleanup => cleanup())
176
+ })
177
+ this.eventListeners.clear()
178
+ this.processes.clear()
179
+ }
180
+
181
+ /**
182
+ * Get the number of active processes
183
+ * @returns The number of registered processes
184
+ */
185
+ size(): number {
186
+ return this.processes.size
187
+ }
188
+ }
189
+
190
+ // Export singleton instance
191
+ export const processManager = ProcessManager.getInstance()