create-appraise 0.1.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 (330) hide show
  1. package/README.md +52 -0
  2. package/package.json +63 -0
  3. package/templates/default/.env.example +2 -0
  4. package/templates/default/README.md +51 -0
  5. package/templates/default/appraise.config.json +4 -0
  6. package/templates/default/components.json +24 -0
  7. package/templates/default/eslint.config.mjs +15 -0
  8. package/templates/default/next-env.d.ts +6 -0
  9. package/templates/default/next.config.ts +7 -0
  10. package/templates/default/package-lock.json +14321 -0
  11. package/templates/default/package.json +124 -0
  12. package/templates/default/postcss.config.mjs +8 -0
  13. package/templates/default/prisma/migrations/20251026202316_migrate_back_to_sqlite/migration.sql +257 -0
  14. package/templates/default/prisma/migrations/20251104113456_add_type_for_template_step_groups/migration.sql +16 -0
  15. package/templates/default/prisma/migrations/20251104170946_add_tags_to_test_suite_and_test_case/migration.sql +27 -0
  16. package/templates/default/prisma/migrations/20251112190024_add_cascade_delete_to_test_run_test_case/migration.sql +17 -0
  17. package/templates/default/prisma/migrations/20251113181100_add_test_run_log/migration.sql +12 -0
  18. package/templates/default/prisma/migrations/20251119191838_add_tag_type/migration.sql +28 -0
  19. package/templates/default/prisma/migrations/20251121164059_add_conflict_resolution/migration.sql +12 -0
  20. package/templates/default/prisma/migrations/20251130190737_add_trace_path_to_test_run_test_case/migration.sql +2 -0
  21. package/templates/default/prisma/migrations/20251213074835_add_log_path_to_test_run/migration.sql +2 -0
  22. package/templates/default/prisma/migrations/20251213183952_add_name_property_for_the_test_run_entities/migration.sql +30 -0
  23. package/templates/default/prisma/migrations/20251223183400_add_report_model_to_db_schema/migration.sql +10 -0
  24. package/templates/default/prisma/migrations/20251223183637_add_report_test_case_entity_for_storing_test_results_for_individual_test_cases/migration.sql +10 -0
  25. package/templates/default/prisma/migrations/20251224083549_add_comprehensive_report_storage/migration.sql +108 -0
  26. package/templates/default/prisma/migrations/20251229194422_migrate_duration_to_string/migration.sql +55 -0
  27. package/templates/default/prisma/migrations/20251230124637_add_unique_constraint_to_test_run_name/migration.sql +27 -0
  28. package/templates/default/prisma/migrations/20260115094436_add_dashboard_metrics/migration.sql +59 -0
  29. package/templates/default/prisma/migrations/20260127172022_add_cascade_delete_to_step_parameters/migration.sql +34 -0
  30. package/templates/default/prisma/migrations/migration_lock.toml +3 -0
  31. package/templates/default/prisma/schema.prisma +554 -0
  32. package/templates/default/public/favicon.ico +0 -0
  33. package/templates/default/public/file.svg +1 -0
  34. package/templates/default/public/globe.svg +1 -0
  35. package/templates/default/public/next.svg +1 -0
  36. package/templates/default/public/vercel.svg +1 -0
  37. package/templates/default/public/window.svg +1 -0
  38. package/templates/default/scripts/regenerate-features.ts +94 -0
  39. package/templates/default/scripts/setup-env.ts +19 -0
  40. package/templates/default/scripts/sync-all.ts +341 -0
  41. package/templates/default/scripts/sync-environments.ts +323 -0
  42. package/templates/default/scripts/sync-locator-groups.ts +413 -0
  43. package/templates/default/scripts/sync-locators.ts +402 -0
  44. package/templates/default/scripts/sync-modules.ts +349 -0
  45. package/templates/default/scripts/sync-tags.ts +292 -0
  46. package/templates/default/scripts/sync-template-step-groups.ts +399 -0
  47. package/templates/default/scripts/sync-template-steps.ts +806 -0
  48. package/templates/default/scripts/sync-test-cases.ts +905 -0
  49. package/templates/default/scripts/sync-test-suites.ts +411 -0
  50. package/templates/default/src/actions/conflict/conflict.action.ts +33 -0
  51. package/templates/default/src/actions/dashboard/dashboard-actions.ts +241 -0
  52. package/templates/default/src/actions/environments/environment-actions.ts +205 -0
  53. package/templates/default/src/actions/locator/locator-actions.ts +547 -0
  54. package/templates/default/src/actions/locator-groups/locator-group-actions.ts +344 -0
  55. package/templates/default/src/actions/modules/module-actions.ts +133 -0
  56. package/templates/default/src/actions/reports/report-actions.ts +614 -0
  57. package/templates/default/src/actions/review/review-actions.ts +147 -0
  58. package/templates/default/src/actions/tags/tag-actions.ts +104 -0
  59. package/templates/default/src/actions/template-step/template-step-actions.ts +332 -0
  60. package/templates/default/src/actions/template-step-group/template-step-group-actions.ts +278 -0
  61. package/templates/default/src/actions/template-test-case/template-test-case-actions.ts +238 -0
  62. package/templates/default/src/actions/test-case/test-case-actions.ts +419 -0
  63. package/templates/default/src/actions/test-run/test-run-actions.ts +1185 -0
  64. package/templates/default/src/actions/test-suite/test-suite-actions.ts +253 -0
  65. package/templates/default/src/actions/user/user-actions.ts +13 -0
  66. package/templates/default/src/app/(base)/environments/create/page.tsx +28 -0
  67. package/templates/default/src/app/(base)/environments/environment-form.tsx +219 -0
  68. package/templates/default/src/app/(base)/environments/environment-table-columns.tsx +96 -0
  69. package/templates/default/src/app/(base)/environments/environment-table.tsx +24 -0
  70. package/templates/default/src/app/(base)/environments/modify/[id]/page.tsx +46 -0
  71. package/templates/default/src/app/(base)/environments/page.tsx +59 -0
  72. package/templates/default/src/app/(base)/layout.tsx +10 -0
  73. package/templates/default/src/app/(base)/locator-groups/create/page.tsx +44 -0
  74. package/templates/default/src/app/(base)/locator-groups/locator-group-form.tsx +215 -0
  75. package/templates/default/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -0
  76. package/templates/default/src/app/(base)/locator-groups/locator-group-table.tsx +28 -0
  77. package/templates/default/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -0
  78. package/templates/default/src/app/(base)/locator-groups/page.tsx +61 -0
  79. package/templates/default/src/app/(base)/locators/create/page.tsx +38 -0
  80. package/templates/default/src/app/(base)/locators/locator-form.tsx +163 -0
  81. package/templates/default/src/app/(base)/locators/locator-table-columns.tsx +90 -0
  82. package/templates/default/src/app/(base)/locators/locator-table.tsx +28 -0
  83. package/templates/default/src/app/(base)/locators/modify/[id]/page.tsx +45 -0
  84. package/templates/default/src/app/(base)/locators/page.tsx +65 -0
  85. package/templates/default/src/app/(base)/locators/sync-locators-button.tsx +66 -0
  86. package/templates/default/src/app/(base)/modules/create/page.tsx +34 -0
  87. package/templates/default/src/app/(base)/modules/modify/[id]/page.tsx +46 -0
  88. package/templates/default/src/app/(base)/modules/module-form.tsx +126 -0
  89. package/templates/default/src/app/(base)/modules/module-table-columns.tsx +85 -0
  90. package/templates/default/src/app/(base)/modules/module-table.tsx +24 -0
  91. package/templates/default/src/app/(base)/modules/page.tsx +59 -0
  92. package/templates/default/src/app/(base)/reports/[id]/page.tsx +517 -0
  93. package/templates/default/src/app/(base)/reports/duration-chart.tsx +33 -0
  94. package/templates/default/src/app/(base)/reports/feature-chart.tsx +78 -0
  95. package/templates/default/src/app/(base)/reports/overview-chart.tsx +46 -0
  96. package/templates/default/src/app/(base)/reports/page.tsx +98 -0
  97. package/templates/default/src/app/(base)/reports/report-metric-card.tsx +16 -0
  98. package/templates/default/src/app/(base)/reports/report-table-columns.tsx +189 -0
  99. package/templates/default/src/app/(base)/reports/report-table.tsx +72 -0
  100. package/templates/default/src/app/(base)/reports/report-view-table-columns.tsx +131 -0
  101. package/templates/default/src/app/(base)/reports/report-view-table.tsx +82 -0
  102. package/templates/default/src/app/(base)/reports/test-cases/page.tsx +42 -0
  103. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +115 -0
  104. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -0
  105. package/templates/default/src/app/(base)/reports/test-suites/page.tsx +42 -0
  106. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +79 -0
  107. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +27 -0
  108. package/templates/default/src/app/(base)/reports/view-logs-button.tsx +60 -0
  109. package/templates/default/src/app/(base)/reviews/create/page.tsx +26 -0
  110. package/templates/default/src/app/(base)/reviews/created-reviews-table.tsx +15 -0
  111. package/templates/default/src/app/(base)/reviews/modify/[id]/page.tsx +26 -0
  112. package/templates/default/src/app/(base)/reviews/page.tsx +26 -0
  113. package/templates/default/src/app/(base)/reviews/review/[id]/page.tsx +26 -0
  114. package/templates/default/src/app/(base)/reviews/review-form.tsx +11 -0
  115. package/templates/default/src/app/(base)/reviews/review-table-by-creator-columns.tsx +9 -0
  116. package/templates/default/src/app/(base)/reviews/review-table-by-reviewer-columns.tsx +9 -0
  117. package/templates/default/src/app/(base)/reviews/reviewer-reviews-table.tsx +15 -0
  118. package/templates/default/src/app/(base)/tags/create/page.tsx +39 -0
  119. package/templates/default/src/app/(base)/tags/modify/[id]/page.tsx +50 -0
  120. package/templates/default/src/app/(base)/tags/page.tsx +58 -0
  121. package/templates/default/src/app/(base)/tags/tag-form.tsx +147 -0
  122. package/templates/default/src/app/(base)/tags/tag-table-columns.tsx +63 -0
  123. package/templates/default/src/app/(base)/tags/tag-table.tsx +29 -0
  124. package/templates/default/src/app/(base)/template-step-groups/create/page.tsx +28 -0
  125. package/templates/default/src/app/(base)/template-step-groups/modify/[id]/page.tsx +45 -0
  126. package/templates/default/src/app/(base)/template-step-groups/page.tsx +60 -0
  127. package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.tsx +167 -0
  128. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table-columns.tsx +89 -0
  129. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table.tsx +32 -0
  130. package/templates/default/src/app/(base)/template-steps/create/page.tsx +37 -0
  131. package/templates/default/src/app/(base)/template-steps/modify/[id]/page.tsx +49 -0
  132. package/templates/default/src/app/(base)/template-steps/page.tsx +59 -0
  133. package/templates/default/src/app/(base)/template-steps/paramChip.tsx +213 -0
  134. package/templates/default/src/app/(base)/template-steps/template-step-form.tsx +384 -0
  135. package/templates/default/src/app/(base)/template-steps/template-step-table-columns.tsx +158 -0
  136. package/templates/default/src/app/(base)/template-steps/template-step-table.tsx +24 -0
  137. package/templates/default/src/app/(base)/template-test-cases/create/page.tsx +56 -0
  138. package/templates/default/src/app/(base)/template-test-cases/modify/[id]/page.tsx +89 -0
  139. package/templates/default/src/app/(base)/template-test-cases/page.tsx +58 -0
  140. package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.tsx +84 -0
  141. package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.tsx +262 -0
  142. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -0
  143. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -0
  144. package/templates/default/src/app/(base)/test-cases/create/page.tsx +76 -0
  145. package/templates/default/src/app/(base)/test-cases/create-from-template/generate/[id]/page.tsx +96 -0
  146. package/templates/default/src/app/(base)/test-cases/create-from-template/page.tsx +38 -0
  147. package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.tsx +73 -0
  148. package/templates/default/src/app/(base)/test-cases/modify/[id]/page.tsx +106 -0
  149. package/templates/default/src/app/(base)/test-cases/page.tsx +60 -0
  150. package/templates/default/src/app/(base)/test-cases/test-case-flow.tsx +82 -0
  151. package/templates/default/src/app/(base)/test-cases/test-case-form.tsx +395 -0
  152. package/templates/default/src/app/(base)/test-cases/test-case-table-columns.tsx +90 -0
  153. package/templates/default/src/app/(base)/test-cases/test-case-table.tsx +35 -0
  154. package/templates/default/src/app/(base)/test-runs/[id]/page.tsx +56 -0
  155. package/templates/default/src/app/(base)/test-runs/create/page.tsx +47 -0
  156. package/templates/default/src/app/(base)/test-runs/page.tsx +60 -0
  157. package/templates/default/src/app/(base)/test-runs/test-run-form.tsx +512 -0
  158. package/templates/default/src/app/(base)/test-runs/test-run-table-columns.tsx +229 -0
  159. package/templates/default/src/app/(base)/test-runs/test-run-table.tsx +127 -0
  160. package/templates/default/src/app/(base)/test-suites/create/page.tsx +45 -0
  161. package/templates/default/src/app/(base)/test-suites/modify/[id]/page.tsx +55 -0
  162. package/templates/default/src/app/(base)/test-suites/page.tsx +82 -0
  163. package/templates/default/src/app/(base)/test-suites/test-suite-form.tsx +269 -0
  164. package/templates/default/src/app/(base)/test-suites/test-suite-table-columns.tsx +97 -0
  165. package/templates/default/src/app/(base)/test-suites/test-suite-table.tsx +29 -0
  166. package/templates/default/src/app/(dashboard-components)/app-drawer.tsx +187 -0
  167. package/templates/default/src/app/(dashboard-components)/data-card-grid.tsx +13 -0
  168. package/templates/default/src/app/(dashboard-components)/data-card.tsx +27 -0
  169. package/templates/default/src/app/(dashboard-components)/execution-health-panel.tsx +57 -0
  170. package/templates/default/src/app/(dashboard-components)/ongoing-test-runs-card.tsx +87 -0
  171. package/templates/default/src/app/(dashboard-components)/quick-actions-drawer.tsx +45 -0
  172. package/templates/default/src/app/api/test-runs/[runId]/download/route.ts +133 -0
  173. package/templates/default/src/app/api/test-runs/[runId]/logs/route.ts +420 -0
  174. package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.ts +146 -0
  175. package/templates/default/src/app/favicon.ico +0 -0
  176. package/templates/default/src/app/globals.css +147 -0
  177. package/templates/default/src/app/layout.tsx +171 -0
  178. package/templates/default/src/app/page.tsx +64 -0
  179. package/templates/default/src/assets/icons/empty-tube.tsx +23 -0
  180. package/templates/default/src/assets/icons/tube-plus.tsx +29 -0
  181. package/templates/default/src/components/base-node.tsx +21 -0
  182. package/templates/default/src/components/chart/pie-chart.tsx +73 -0
  183. package/templates/default/src/components/data-extraction/locator-inspector.tsx +460 -0
  184. package/templates/default/src/components/data-state/empty-state.tsx +40 -0
  185. package/templates/default/src/components/data-visualization/info-card.tsx +70 -0
  186. package/templates/default/src/components/data-visualization/info-grid.tsx +22 -0
  187. package/templates/default/src/components/devtools/providers.tsx +13 -0
  188. package/templates/default/src/components/diagram/button-edge.tsx +54 -0
  189. package/templates/default/src/components/diagram/dynamic-parameters.tsx +438 -0
  190. package/templates/default/src/components/diagram/edit-header-option.tsx +36 -0
  191. package/templates/default/src/components/diagram/flow-diagram.tsx +470 -0
  192. package/templates/default/src/components/diagram/node-form.tsx +262 -0
  193. package/templates/default/src/components/diagram/options-header-node.tsx +57 -0
  194. package/templates/default/src/components/diagram/template-step-combobox.tsx +155 -0
  195. package/templates/default/src/components/form/error-message.tsx +7 -0
  196. package/templates/default/src/components/kokonutui/smooth-tab.tsx +453 -0
  197. package/templates/default/src/components/loading-skeleton/data-table/data-table-skeleton.tsx +30 -0
  198. package/templates/default/src/components/loading-skeleton/form/button-skeleton.tsx +8 -0
  199. package/templates/default/src/components/loading-skeleton/form/icon-button-skeleton.tsx +8 -0
  200. package/templates/default/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -0
  201. package/templates/default/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -0
  202. package/templates/default/src/components/logo.tsx +15 -0
  203. package/templates/default/src/components/navigation/command-badge.tsx +34 -0
  204. package/templates/default/src/components/navigation/command-chain-input.tsx +51 -0
  205. package/templates/default/src/components/navigation/entity-search-command.tsx +116 -0
  206. package/templates/default/src/components/navigation/nav-card.tsx +31 -0
  207. package/templates/default/src/components/navigation/nav-command.tsx +508 -0
  208. package/templates/default/src/components/navigation/nav-link.tsx +60 -0
  209. package/templates/default/src/components/navigation/nav-menu-card-deck.tsx +112 -0
  210. package/templates/default/src/components/node-header.tsx +159 -0
  211. package/templates/default/src/components/reports/test-case-logs-modal.tsx +253 -0
  212. package/templates/default/src/components/table/table-actions.tsx +172 -0
  213. package/templates/default/src/components/test-run/download-logs-button.tsx +99 -0
  214. package/templates/default/src/components/test-run/log-viewer.tsx +445 -0
  215. package/templates/default/src/components/test-run/test-run-details.tsx +611 -0
  216. package/templates/default/src/components/test-run/test-run-header.tsx +149 -0
  217. package/templates/default/src/components/test-run/view-report-button.tsx +102 -0
  218. package/templates/default/src/components/theme/mode-toggle.tsx +54 -0
  219. package/templates/default/src/components/theme/theme-provider.tsx +8 -0
  220. package/templates/default/src/components/typography/page-header-subtitle.tsx +7 -0
  221. package/templates/default/src/components/typography/page-header.tsx +7 -0
  222. package/templates/default/src/components/ui/alert-dialog.tsx +106 -0
  223. package/templates/default/src/components/ui/alert.tsx +43 -0
  224. package/templates/default/src/components/ui/avatar.tsx +40 -0
  225. package/templates/default/src/components/ui/badge.tsx +29 -0
  226. package/templates/default/src/components/ui/button.tsx +47 -0
  227. package/templates/default/src/components/ui/calendar.tsx +158 -0
  228. package/templates/default/src/components/ui/card.tsx +43 -0
  229. package/templates/default/src/components/ui/chart.tsx +369 -0
  230. package/templates/default/src/components/ui/checkbox.tsx +28 -0
  231. package/templates/default/src/components/ui/command.tsx +135 -0
  232. package/templates/default/src/components/ui/data-table-column-header.tsx +61 -0
  233. package/templates/default/src/components/ui/data-table-pagination.tsx +87 -0
  234. package/templates/default/src/components/ui/data-table-view-options.tsx +50 -0
  235. package/templates/default/src/components/ui/data-table.tsx +267 -0
  236. package/templates/default/src/components/ui/dialog.tsx +97 -0
  237. package/templates/default/src/components/ui/dropdown-menu.tsx +182 -0
  238. package/templates/default/src/components/ui/empty.tsx +104 -0
  239. package/templates/default/src/components/ui/input.tsx +22 -0
  240. package/templates/default/src/components/ui/kbd.tsx +28 -0
  241. package/templates/default/src/components/ui/label.tsx +19 -0
  242. package/templates/default/src/components/ui/loading.tsx +12 -0
  243. package/templates/default/src/components/ui/multi-select-with-preview.tsx +116 -0
  244. package/templates/default/src/components/ui/multi-select.tsx +142 -0
  245. package/templates/default/src/components/ui/navigation-menu.tsx +120 -0
  246. package/templates/default/src/components/ui/popover.tsx +33 -0
  247. package/templates/default/src/components/ui/progress.tsx +25 -0
  248. package/templates/default/src/components/ui/radio-group.tsx +44 -0
  249. package/templates/default/src/components/ui/scroll-area.tsx +40 -0
  250. package/templates/default/src/components/ui/select.tsx +144 -0
  251. package/templates/default/src/components/ui/separator.tsx +22 -0
  252. package/templates/default/src/components/ui/skeleton.tsx +7 -0
  253. package/templates/default/src/components/ui/table.tsx +76 -0
  254. package/templates/default/src/components/ui/tabs.tsx +55 -0
  255. package/templates/default/src/components/ui/textarea.tsx +21 -0
  256. package/templates/default/src/components/ui/toast.tsx +113 -0
  257. package/templates/default/src/components/ui/toaster.tsx +26 -0
  258. package/templates/default/src/components/ui/tooltip.tsx +32 -0
  259. package/templates/default/src/components/user-prompt/delete-prompt.tsx +87 -0
  260. package/templates/default/src/config/db-config.ts +10 -0
  261. package/templates/default/src/constants/form-opts/diagram/node-form.ts +30 -0
  262. package/templates/default/src/constants/form-opts/environment-form-opts.ts +24 -0
  263. package/templates/default/src/constants/form-opts/locator-form-opts.ts +20 -0
  264. package/templates/default/src/constants/form-opts/locator-group-form-opts.ts +28 -0
  265. package/templates/default/src/constants/form-opts/module-form-opts.ts +21 -0
  266. package/templates/default/src/constants/form-opts/review-form-opts.ts +23 -0
  267. package/templates/default/src/constants/form-opts/tag-form-opts.ts +42 -0
  268. package/templates/default/src/constants/form-opts/template-selection-form-opts.ts +16 -0
  269. package/templates/default/src/constants/form-opts/template-step-group-form-opts.ts +24 -0
  270. package/templates/default/src/constants/form-opts/template-test-case-form-opts.ts +39 -0
  271. package/templates/default/src/constants/form-opts/template-test-step-form-opts.ts +36 -0
  272. package/templates/default/src/constants/form-opts/test-case-form-opts.ts +43 -0
  273. package/templates/default/src/constants/form-opts/test-run-form-opts.ts +31 -0
  274. package/templates/default/src/constants/form-opts/test-suite-form-opts.ts +24 -0
  275. package/templates/default/src/hooks/use-toast.ts +187 -0
  276. package/templates/default/src/lib/bidirectional-sync.ts +432 -0
  277. package/templates/default/src/lib/database-sync.ts +531 -0
  278. package/templates/default/src/lib/environment-file-utils.ts +221 -0
  279. package/templates/default/src/lib/feature-file-generator.ts +411 -0
  280. package/templates/default/src/lib/gherkin-parser.ts +259 -0
  281. package/templates/default/src/lib/locator-group-file-utils.ts +370 -0
  282. package/templates/default/src/lib/metrics/metric-calculator.ts +613 -0
  283. package/templates/default/src/lib/module-hierarchy-builder.ts +205 -0
  284. package/templates/default/src/lib/path-helpers/module-path.ts +71 -0
  285. package/templates/default/src/lib/test-case-utils.ts +6 -0
  286. package/templates/default/src/lib/test-run/log-formatter.ts +83 -0
  287. package/templates/default/src/lib/test-run/process-manager.ts +191 -0
  288. package/templates/default/src/lib/test-run/report-parser.ts +316 -0
  289. package/templates/default/src/lib/test-run/test-run-executor.ts +144 -0
  290. package/templates/default/src/lib/test-run/winston-logger.ts +95 -0
  291. package/templates/default/src/lib/transformers/gherkin-converter.ts +42 -0
  292. package/templates/default/src/lib/transformers/key-to-icon-transformer.tsx +95 -0
  293. package/templates/default/src/lib/transformers/template-test-case-converter.ts +160 -0
  294. package/templates/default/src/lib/utils/node-param-validation.ts +81 -0
  295. package/templates/default/src/lib/utils/template-step-file-generator.ts +167 -0
  296. package/templates/default/src/lib/utils/template-step-file-manager-intelligent.ts +723 -0
  297. package/templates/default/src/lib/utils/template-step-file-manager.ts +166 -0
  298. package/templates/default/src/lib/utils.ts +31 -0
  299. package/templates/default/src/tests/config/environments/environments.json +14 -0
  300. package/templates/default/src/tests/config/executor/world.ts +41 -0
  301. package/templates/default/src/tests/executor.ts +80 -0
  302. package/templates/default/src/tests/hooks/hooks.ts +99 -0
  303. package/templates/default/src/tests/mapping/locator-map.json +1 -0
  304. package/templates/default/src/tests/steps/actions/click.step.ts +62 -0
  305. package/templates/default/src/tests/steps/actions/hover.step.ts +31 -0
  306. package/templates/default/src/tests/steps/actions/input.step.ts +149 -0
  307. package/templates/default/src/tests/steps/actions/navigation.step.ts +72 -0
  308. package/templates/default/src/tests/steps/actions/random_data.step.ts +146 -0
  309. package/templates/default/src/tests/steps/actions/store.step.ts +90 -0
  310. package/templates/default/src/tests/steps/actions/wait.step.ts +107 -0
  311. package/templates/default/src/tests/steps/validations/active_state_assertion.step.ts +34 -0
  312. package/templates/default/src/tests/steps/validations/navigation_assertion.step.ts +23 -0
  313. package/templates/default/src/tests/steps/validations/text_assertion.step.ts +111 -0
  314. package/templates/default/src/tests/steps/validations/visibility_assertion.step.ts +30 -0
  315. package/templates/default/src/tests/support/parameter-types.ts +12 -0
  316. package/templates/default/src/tests/utils/cache.util.ts +260 -0
  317. package/templates/default/src/tests/utils/cli.util.ts +177 -0
  318. package/templates/default/src/tests/utils/environment.util.ts +65 -0
  319. package/templates/default/src/tests/utils/locator.util.ts +248 -0
  320. package/templates/default/src/tests/utils/random-data.util.ts +45 -0
  321. package/templates/default/src/tests/utils/spawner.util.ts +617 -0
  322. package/templates/default/src/types/diagram/diagram.ts +34 -0
  323. package/templates/default/src/types/diagram/template-step.ts +11 -0
  324. package/templates/default/src/types/executor/browser.type.ts +1 -0
  325. package/templates/default/src/types/form/actionHandler.ts +6 -0
  326. package/templates/default/src/types/locator/locator.type.ts +11 -0
  327. package/templates/default/src/types/step/step.type.ts +1 -0
  328. package/templates/default/src/types/table/data-table.ts +6 -0
  329. package/templates/default/tailwind.config.ts +62 -0
  330. package/templates/default/tsconfig.json +28 -0
@@ -0,0 +1,617 @@
1
+ import { execa, type Options as ExecaOptions } from 'execa'
2
+ import type { ChildProcess } from 'child_process'
3
+ import { EventEmitter } from 'events'
4
+
5
+ /**
6
+ * Configuration options for spawning child processes
7
+ * @extends ExecaOptions - Extends execa Options for additional functionality
8
+ */
9
+ export interface SpawnerOptions extends ExecaOptions {
10
+ /** Whether to stream logs to console (default: true) */
11
+ streamLogs?: boolean
12
+ /** Whether to prefix logs with process name (default: true) */
13
+ prefixLogs?: boolean
14
+ /** Custom prefix for logs (default: process name) */
15
+ logPrefix?: string
16
+ /** Whether to capture output for later retrieval (default: false) */
17
+ captureOutput?: boolean
18
+ }
19
+
20
+ /**
21
+ * Represents a spawned child process with metadata and output tracking
22
+ */
23
+ export interface SpawnedProcess {
24
+ /** The underlying Node.js ChildProcess instance (returned by execa) */
25
+ process: ChildProcess
26
+ /** Process ID (PID) of the spawned process */
27
+ pid: number | undefined
28
+ /** Unique name identifier for the process */
29
+ name: string
30
+ /** Captured output from the process */
31
+ output: {
32
+ /** Standard output lines */
33
+ stdout: string[]
34
+ /** Standard error lines */
35
+ stderr: string[]
36
+ }
37
+ /** Whether the process is currently running */
38
+ isRunning: boolean
39
+ /** Exit code of the process (null if still running) */
40
+ exitCode: number | null
41
+ /** Timestamp when the process was started */
42
+ startTime: Date
43
+ /** Timestamp when the process ended (null if still running) */
44
+ endTime: Date | null
45
+ }
46
+
47
+ /**
48
+ * A comprehensive task spawner that manages child processes with logging, output capture,
49
+ * and process lifecycle management. Extends EventEmitter to provide process events.
50
+ *
51
+ * Features:
52
+ * - Concurrent process spawning and management
53
+ * - Real-time log streaming with customizable prefixes
54
+ * - Output capture and buffering
55
+ * - Process lifecycle tracking (start/end times, exit codes)
56
+ * - Event-driven architecture for process monitoring
57
+ * - Graceful process termination
58
+ */
59
+ export class TaskSpawner extends EventEmitter {
60
+ /** Map of process names to SpawnedProcess instances */
61
+ private processes: Map<string, SpawnedProcess> = new Map()
62
+ /** Counter for generating unique process names */
63
+ private processCounter = 0
64
+ /** Internal buffers for processing output streams line by line */
65
+ private outputBuffers: Map<string, { stdout: string; stderr: string }> = new Map()
66
+
67
+ /**
68
+ * Spawns a child process with comprehensive logging and output management
69
+ *
70
+ * @param command - The command to execute
71
+ * @param args - Array of command line arguments (default: [])
72
+ * @param options - Configuration options for spawning and logging
73
+ * @returns Promise that resolves to a SpawnedProcess instance
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * const process = await spawner.spawn('npm', ['test'], {
78
+ * streamLogs: true,
79
+ * captureOutput: true,
80
+ * logPrefix: 'test-runner'
81
+ * });
82
+ * ```
83
+ */
84
+ async spawn(command: string, args: string[] = [], options: SpawnerOptions = {}): Promise<SpawnedProcess> {
85
+ const { streamLogs = true, prefixLogs = true, logPrefix, captureOutput = false, ...spawnOptions } = options
86
+
87
+ const processName = logPrefix || `${command}_${++this.processCounter}`
88
+
89
+ // Create the spawned process object
90
+ const spawnedProcess: SpawnedProcess = {
91
+ process: null as unknown as ChildProcess, // Will be set below
92
+ pid: undefined, // Will be set below
93
+ name: processName,
94
+ output: {
95
+ stdout: [],
96
+ stderr: [],
97
+ },
98
+ isRunning: false,
99
+ exitCode: null,
100
+ startTime: new Date(),
101
+ endTime: null,
102
+ }
103
+
104
+ // Spawn the child process using execa
105
+ // Always use 'pipe' when captureOutput is true to enable output capture
106
+ // streamLogs just controls whether we also log to console, not whether we can capture
107
+ const stdioConfig = captureOutput ? 'pipe' : streamLogs ? 'inherit' : 'pipe'
108
+ const childProcess = execa(command, args, {
109
+ stdio: stdioConfig,
110
+ ...spawnOptions,
111
+ })
112
+
113
+ spawnedProcess.process = childProcess
114
+ spawnedProcess.pid = childProcess.pid
115
+ spawnedProcess.isRunning = true
116
+
117
+ // Store the process
118
+ this.processes.set(processName, spawnedProcess)
119
+
120
+ // Initialize output buffers for this process
121
+ this.outputBuffers.set(processName, { stdout: '', stderr: '' })
122
+
123
+ // Set up event listeners
124
+ this.setupProcessListeners(spawnedProcess, {
125
+ streamLogs,
126
+ prefixLogs,
127
+ captureOutput,
128
+ stdioConfig,
129
+ })
130
+
131
+ // Emit spawn event
132
+ this.emit('spawn', spawnedProcess)
133
+
134
+ return spawnedProcess
135
+ }
136
+
137
+ /**
138
+ * Spawns multiple processes concurrently and returns a map of process names to instances
139
+ *
140
+ * @param tasks - Array of task configurations to spawn
141
+ * @returns Promise that resolves to a Map of process names to SpawnedProcess instances
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * const processes = await spawner.spawnMultiple([
146
+ * { name: 'server', command: 'npm', args: ['start'] },
147
+ * { name: 'tests', command: 'npm', args: ['test'] }
148
+ * ]);
149
+ * ```
150
+ */
151
+ async spawnMultiple(
152
+ tasks: Array<{
153
+ name: string
154
+ command: string
155
+ args?: string[]
156
+ options?: SpawnerOptions
157
+ }>,
158
+ ): Promise<Map<string, SpawnedProcess>> {
159
+ const promises = tasks.map(async task => {
160
+ const process = await this.spawn(task.command, task.args || [], {
161
+ logPrefix: task.name,
162
+ ...task.options,
163
+ })
164
+ return { name: task.name, process }
165
+ })
166
+
167
+ const results = await Promise.all(promises)
168
+ const processMap = new Map<string, SpawnedProcess>()
169
+
170
+ results.forEach(({ name, process }) => {
171
+ processMap.set(name, process)
172
+ })
173
+
174
+ return processMap
175
+ }
176
+
177
+ /**
178
+ * Terminates a specific process by name
179
+ *
180
+ * @param processName - The name of the process to kill
181
+ * @param signal - The signal to send to the process (default: 'SIGTERM')
182
+ * @returns True if the process was found and killed, false otherwise
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * const killed = spawner.killProcess('my-process', 'SIGKILL');
187
+ * ```
188
+ */
189
+ killProcess(processName: string, signal: NodeJS.Signals = 'SIGTERM'): boolean {
190
+ const spawnedProcess = this.processes.get(processName)
191
+ if (!spawnedProcess || !spawnedProcess.isRunning) {
192
+ return false
193
+ }
194
+ console.log(`[TaskSpawner] Killing process: ${processName}, PID: ${spawnedProcess.pid}, signal: ${signal}`)
195
+ spawnedProcess.process.kill(signal)
196
+ return true
197
+ }
198
+
199
+ /**
200
+ * Terminates all currently running processes managed by this spawner
201
+ *
202
+ * @param signal - The signal to send to all processes (default: 'SIGTERM')
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * spawner.killAll('SIGKILL'); // Force kill all processes
207
+ * ```
208
+ */
209
+ killAll(signal: NodeJS.Signals = 'SIGTERM'): void {
210
+ this.processes.forEach(spawnedProcess => {
211
+ if (spawnedProcess.isRunning) {
212
+ spawnedProcess.process.kill(signal)
213
+ }
214
+ })
215
+ }
216
+
217
+ /**
218
+ * Waits for a specific process to complete and returns its exit code
219
+ *
220
+ * @param processName - The name of the process to wait for
221
+ * @returns Promise that resolves to the exit code (null if process not found)
222
+ * @throws Error if the process name is not found
223
+ *
224
+ * @example
225
+ * ```typescript
226
+ * const exitCode = await spawner.waitForProcess('my-process');
227
+ * console.log(`Process exited with code: ${exitCode}`);
228
+ * ```
229
+ */
230
+ async waitForProcess(processName: string): Promise<number | null> {
231
+ const spawnedProcess = this.processes.get(processName)
232
+ if (!spawnedProcess) {
233
+ throw new Error(`Process '${processName}' not found`)
234
+ }
235
+
236
+ return new Promise(resolve => {
237
+ if (!spawnedProcess.isRunning) {
238
+ resolve(spawnedProcess.exitCode)
239
+ return
240
+ }
241
+
242
+ spawnedProcess.process.on('exit', (code: number | null) => {
243
+ resolve(code)
244
+ })
245
+ })
246
+ }
247
+
248
+ /**
249
+ * Waits for all currently running processes to complete
250
+ *
251
+ * @returns Promise that resolves to a Map of process names to their exit codes
252
+ *
253
+ * @example
254
+ * ```typescript
255
+ * const results = await spawner.waitForAll();
256
+ * results.forEach((exitCode, processName) => {
257
+ * console.log(`${processName} exited with code: ${exitCode}`);
258
+ * });
259
+ * ```
260
+ */
261
+ async waitForAll(): Promise<Map<string, number | null>> {
262
+ const results = new Map<string, number | null>()
263
+ const promises: Array<Promise<[string, number | null]>> = []
264
+
265
+ this.processes.forEach((spawnedProcess, name) => {
266
+ if (spawnedProcess.isRunning) {
267
+ promises.push(this.waitForProcess(name).then(code => [name, code] as [string, number | null]))
268
+ } else {
269
+ results.set(name, spawnedProcess.exitCode)
270
+ }
271
+ })
272
+
273
+ const completed = await Promise.all(promises)
274
+ completed.forEach(([name, code]) => {
275
+ results.set(name, code)
276
+ })
277
+
278
+ return results
279
+ }
280
+
281
+ /**
282
+ * Retrieves a specific process by name
283
+ *
284
+ * @param processName - The name of the process to retrieve
285
+ * @returns The SpawnedProcess instance or undefined if not found
286
+ *
287
+ * @example
288
+ * ```typescript
289
+ * const process = spawner.getProcess('my-process');
290
+ * if (process) {
291
+ * console.log(`Process is running: ${process.isRunning}`);
292
+ * }
293
+ * ```
294
+ */
295
+ getProcess(processName: string): SpawnedProcess | undefined {
296
+ return this.processes.get(processName)
297
+ }
298
+
299
+ /**
300
+ * Retrieves all processes managed by this spawner (running and completed)
301
+ *
302
+ * @returns A Map of process names to SpawnedProcess instances
303
+ *
304
+ * @example
305
+ * ```typescript
306
+ * const allProcesses = spawner.getAllProcesses();
307
+ * console.log(`Total processes: ${allProcesses.size}`);
308
+ * ```
309
+ */
310
+ getAllProcesses(): Map<string, SpawnedProcess> {
311
+ return new Map(this.processes)
312
+ }
313
+
314
+ /**
315
+ * Retrieves only the currently running processes
316
+ *
317
+ * @returns A Map of running process names to SpawnedProcess instances
318
+ *
319
+ * @example
320
+ * ```typescript
321
+ * const running = spawner.getRunningProcesses();
322
+ * console.log(`Running processes: ${running.size}`);
323
+ * ```
324
+ */
325
+ getRunningProcesses(): Map<string, SpawnedProcess> {
326
+ const running = new Map<string, SpawnedProcess>()
327
+ this.processes.forEach((process, name) => {
328
+ if (process.isRunning) {
329
+ running.set(name, process)
330
+ }
331
+ })
332
+ return running
333
+ }
334
+
335
+ /**
336
+ * Retrieves the captured output from a specific process
337
+ *
338
+ * @param processName - The name of the process to get output for
339
+ * @returns Object containing stdout and stderr arrays, or null if process not found
340
+ *
341
+ * @example
342
+ * ```typescript
343
+ * const output = spawner.getProcessOutput('my-process');
344
+ * if (output) {
345
+ * console.log('STDOUT:', output.stdout.join('\n'));
346
+ * console.log('STDERR:', output.stderr.join('\n'));
347
+ * }
348
+ * ```
349
+ */
350
+ getProcessOutput(processName: string): { stdout: string[]; stderr: string[] } | null {
351
+ const spawnedProcess = this.processes.get(processName)
352
+ return spawnedProcess?.output || null
353
+ }
354
+
355
+ /**
356
+ * Clears all process history and resets the spawner to initial state
357
+ *
358
+ * @example
359
+ * ```typescript
360
+ * spawner.clearHistory(); // Removes all tracked processes
361
+ * ```
362
+ */
363
+ clearHistory(): void {
364
+ this.processes.clear()
365
+ this.outputBuffers.clear()
366
+ this.processCounter = 0
367
+ }
368
+
369
+ /**
370
+ * Processes buffered output and emits complete lines
371
+ *
372
+ * @private
373
+ * @param processName - The name of the process
374
+ * @param stream - The stream type ('stdout' or 'stderr')
375
+ * @param streamLogs - Whether to stream logs to console
376
+ * @param prefixLogs - Whether to prefix logs with process name
377
+ * @param captureOutput - Whether to capture output for later retrieval
378
+ * @param spawnedProcess - The spawned process instance
379
+ */
380
+ private processBufferedOutput(
381
+ processName: string,
382
+ stream: 'stdout' | 'stderr',
383
+ streamLogs: boolean,
384
+ prefixLogs: boolean,
385
+ captureOutput: boolean,
386
+ spawnedProcess: SpawnedProcess,
387
+ ): void {
388
+ const buffer = this.outputBuffers.get(processName)
389
+ if (!buffer) return
390
+
391
+ const currentBuffer = buffer[stream]
392
+ const lines = currentBuffer.split('\n')
393
+
394
+ // Keep the last line in buffer (might be incomplete)
395
+ buffer[stream] = lines.pop() || ''
396
+
397
+ // Process complete lines
398
+ for (const line of lines) {
399
+ if (captureOutput) {
400
+ spawnedProcess.output[stream].push(line + '\n')
401
+ }
402
+
403
+ if (streamLogs) {
404
+ const prefix = prefixLogs ? `[${processName}] ` : ''
405
+ if (stream === 'stdout') {
406
+ console.log(`${prefix}${line}`)
407
+ } else {
408
+ console.error(`${prefix}${line}`)
409
+ }
410
+ }
411
+
412
+ this.emit(stream, { processName, data: line + '\n' })
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Sets up event listeners for a spawned process
418
+ *
419
+ * @private
420
+ * @param spawnedProcess - The spawned process instance
421
+ * @param options - Configuration options for the listeners
422
+ */
423
+ private setupProcessListeners(
424
+ spawnedProcess: SpawnedProcess,
425
+ options: {
426
+ streamLogs: boolean
427
+ prefixLogs: boolean
428
+ captureOutput: boolean
429
+ stdioConfig: string | string[]
430
+ },
431
+ ): void {
432
+ const { streamLogs, prefixLogs, captureOutput, stdioConfig } = options
433
+ const { process: childProcess, name } = spawnedProcess
434
+
435
+ // Only set up data listeners when stdio is 'pipe'
436
+ if (stdioConfig === 'pipe') {
437
+ // Handle stdout
438
+ childProcess.stdout?.on('data', (data: Buffer) => {
439
+ const output = data.toString()
440
+ const buffer = this.outputBuffers.get(name)
441
+
442
+ if (buffer) {
443
+ buffer.stdout += output
444
+ this.processBufferedOutput(name, 'stdout', streamLogs, prefixLogs, captureOutput, spawnedProcess)
445
+ } else {
446
+ console.warn(`[TaskSpawner] No output buffer found for process: ${name}`)
447
+ }
448
+ })
449
+
450
+ // Handle stderr
451
+ childProcess.stderr?.on('data', (data: Buffer) => {
452
+ const output = data.toString()
453
+ const buffer = this.outputBuffers.get(name)
454
+
455
+ if (buffer) {
456
+ buffer.stderr += output
457
+ this.processBufferedOutput(name, 'stderr', streamLogs, prefixLogs, captureOutput, spawnedProcess)
458
+ } else {
459
+ console.warn(`[TaskSpawner] No output buffer found for process: ${name}`)
460
+ }
461
+ })
462
+ }
463
+
464
+ // Handle process exit
465
+ childProcess.on('exit', (code: number | null) => {
466
+ // Only flush buffered output when stdio is 'pipe'
467
+ if (stdioConfig === 'pipe') {
468
+ const buffer = this.outputBuffers.get(name)
469
+ if (buffer) {
470
+ // Process remaining stdout
471
+ if (buffer.stdout) {
472
+ if (captureOutput) {
473
+ spawnedProcess.output.stdout.push(buffer.stdout)
474
+ }
475
+ if (streamLogs) {
476
+ const prefix = prefixLogs ? `[${name}] ` : ''
477
+ console.log(`${prefix}${buffer.stdout}`)
478
+ }
479
+ console.log(
480
+ `[TaskSpawner] Emitting final stdout event for process: ${name}, data length: ${buffer.stdout.length} chars`,
481
+ )
482
+ this.emit('stdout', {
483
+ processName: name,
484
+ data: buffer.stdout,
485
+ })
486
+ }
487
+
488
+ // Process remaining stderr
489
+ if (buffer.stderr) {
490
+ if (captureOutput) {
491
+ spawnedProcess.output.stderr.push(buffer.stderr)
492
+ }
493
+ if (streamLogs) {
494
+ const prefix = prefixLogs ? `[${name}] ` : ''
495
+ console.error(`${prefix}${buffer.stderr}`)
496
+ }
497
+ console.log(
498
+ `[TaskSpawner] Emitting final stderr event for process: ${name}, data length: ${buffer.stderr.length} chars`,
499
+ )
500
+ this.emit('stderr', {
501
+ processName: name,
502
+ data: buffer.stderr,
503
+ })
504
+ }
505
+
506
+ // Clear the buffer
507
+ this.outputBuffers.delete(name)
508
+ }
509
+ }
510
+
511
+ spawnedProcess.isRunning = false
512
+ spawnedProcess.exitCode = code
513
+ spawnedProcess.endTime = new Date()
514
+
515
+ console.log(`[TaskSpawner] Process exited: ${name}, code: ${code}, emitting exit event`)
516
+ this.emit('exit', { processName: name, code })
517
+ })
518
+
519
+ // Handle process error
520
+ childProcess.on('error', (error: Error) => {
521
+ spawnedProcess.isRunning = false
522
+ spawnedProcess.endTime = new Date()
523
+
524
+ if (streamLogs) {
525
+ const prefix = prefixLogs ? `[${name}] ` : ''
526
+ console.error(`${prefix}ERROR: ${error.message}`)
527
+ }
528
+
529
+ this.emit('error', { processName: name, error })
530
+ })
531
+
532
+ // Handle uncaught exceptions to prevent crashes
533
+ childProcess.on('uncaughtException', (error: Error) => {
534
+ spawnedProcess.isRunning = false
535
+ spawnedProcess.endTime = new Date()
536
+
537
+ if (streamLogs) {
538
+ const prefix = prefixLogs ? `[${name}] ` : ''
539
+ console.error(`${prefix}UNCAUGHT EXCEPTION: ${error.message}`)
540
+ }
541
+
542
+ this.emit('error', { processName: name, error })
543
+ })
544
+ }
545
+ }
546
+
547
+ /**
548
+ * Default TaskSpawner instance for convenience
549
+ * Use this when you don't need multiple spawner instances
550
+ * Uses global variable pattern (like Prisma) to persist across Next.js runtime contexts
551
+ */
552
+ const globalForTaskSpawner = global as unknown as {
553
+ taskSpawner: TaskSpawner | undefined
554
+ }
555
+
556
+ export const taskSpawner = globalForTaskSpawner.taskSpawner ?? new TaskSpawner()
557
+
558
+ if (!globalForTaskSpawner.taskSpawner) {
559
+ globalForTaskSpawner.taskSpawner = taskSpawner
560
+ }
561
+
562
+ /**
563
+ * Convenience function to spawn a single task using the default spawner
564
+ *
565
+ * @param command - The command to execute
566
+ * @param args - Array of command line arguments
567
+ * @param options - Configuration options for spawning
568
+ * @returns Promise that resolves to a SpawnedProcess instance
569
+ */
570
+ export const spawnTask = (command: string, args: string[] = [], options: SpawnerOptions = {}) =>
571
+ taskSpawner.spawn(command, args, options)
572
+
573
+ /**
574
+ * Convenience function to spawn multiple tasks using the default spawner
575
+ *
576
+ * @param tasks - Array of task configurations to spawn
577
+ * @returns Promise that resolves to a Map of process names to SpawnedProcess instances
578
+ */
579
+ export const spawnMultipleTasks = (
580
+ tasks: Array<{
581
+ name: string
582
+ command: string
583
+ args?: string[]
584
+ options?: SpawnerOptions
585
+ }>,
586
+ ) => taskSpawner.spawnMultiple(tasks)
587
+
588
+ /**
589
+ * Convenience function to kill a task using the default spawner
590
+ *
591
+ * @param processName - The name of the process to kill
592
+ * @param signal - The signal to send to the process
593
+ * @returns True if the process was found and killed, false otherwise
594
+ */
595
+ export const killTask = (processName: string, signal?: NodeJS.Signals) => taskSpawner.killProcess(processName, signal)
596
+
597
+ /**
598
+ * Convenience function to kill all tasks using the default spawner
599
+ *
600
+ * @param signal - The signal to send to all processes
601
+ */
602
+ export const killAllTasks = (signal?: NodeJS.Signals) => taskSpawner.killAll(signal)
603
+
604
+ /**
605
+ * Convenience function to wait for a task using the default spawner
606
+ *
607
+ * @param processName - The name of the process to wait for
608
+ * @returns Promise that resolves to the exit code
609
+ */
610
+ export const waitForTask = (processName: string) => taskSpawner.waitForProcess(processName)
611
+
612
+ /**
613
+ * Convenience function to wait for all tasks using the default spawner
614
+ *
615
+ * @returns Promise that resolves to a Map of process names to exit codes
616
+ */
617
+ export const waitForAllTasks = () => taskSpawner.waitForAll()
@@ -0,0 +1,34 @@
1
+ import { StepParameterType } from '@prisma/client'
2
+
3
+ export type NodeData = {
4
+ order: number
5
+ label: string
6
+ gherkinStep?: string
7
+ isFirstNode?: boolean
8
+ icon?: string
9
+ parameters: {
10
+ name: string
11
+ value: string
12
+ type: StepParameterType
13
+ order: number
14
+ }[]
15
+ templateStepId: string
16
+ }
17
+
18
+ export type NodeOrderMap = Record<string, NodeData>
19
+
20
+ export type TemplateTestCaseNodeData = {
21
+ order: number
22
+ label: string
23
+ gherkinStep?: string
24
+ icon?: string
25
+ parameters: {
26
+ name: string
27
+ defaultValue: string
28
+ type: StepParameterType
29
+ order: number
30
+ }[]
31
+ templateStepId: string
32
+ }
33
+
34
+ export type TemplateTestCaseNodeOrderMap = Record<string, TemplateTestCaseNodeData>
@@ -0,0 +1,11 @@
1
+ import { TemplateStep, TemplateStepGroup } from '@prisma/client'
2
+
3
+ /** Template step with optional group relation (e.g. from getAllTemplateStepsAction). */
4
+ export type TemplateStepWithGroup = TemplateStep & {
5
+ templateStepGroup?: TemplateStepGroup
6
+ }
7
+
8
+ /** Returns the group name in title case for display (e.g. "navigation" -> "Navigation"). */
9
+ export function capitalizeGroupName(name: string): string {
10
+ return name.replace(/\b\w/g, c => c.toUpperCase())
11
+ }
@@ -0,0 +1 @@
1
+ export type BrowserName = 'chromium' | 'firefox' | 'webkit'
@@ -0,0 +1,6 @@
1
+ export type ActionResponse = {
2
+ status: number
3
+ data?: Record<string, unknown> | Record<string, unknown>[] | unknown[] | unknown
4
+ message?: string
5
+ error?: string
6
+ }
@@ -0,0 +1,11 @@
1
+ export type CSSSelector = string
2
+ export type XPathSelector = `/${string}` | `//${string}`
3
+ export type SelectorName = string
4
+ export type Selector = CSSSelector | XPathSelector
5
+ export type Locator = Record<string, Selector>
6
+ export type LocatorMap = {
7
+ name: string
8
+ path: string
9
+ }
10
+
11
+ export type LocatorCollection = Record<string, Locator>
@@ -0,0 +1 @@
1
+ export type Locator = string
@@ -0,0 +1,6 @@
1
+ import { ColumnDef } from '@tanstack/react-table'
2
+
3
+ export interface DataTableProps<TData, TValue> {
4
+ columns: ColumnDef<TData, TValue>[]
5
+ data: TData[]
6
+ }