create-appraisejs 0.1.6 → 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 (320) hide show
  1. package/README.md +45 -45
  2. package/dist/cli.js +4 -4
  3. package/dist/cli.js.map +1 -1
  4. package/dist/copy-template.d.ts +2 -1
  5. package/dist/copy-template.d.ts.map +1 -1
  6. package/dist/copy-template.js +10 -7
  7. package/dist/copy-template.js.map +1 -1
  8. package/dist/copy-template.test.js +19 -0
  9. package/dist/copy-template.test.js.map +1 -1
  10. package/package.json +69 -67
  11. package/templates/default/.vscode/settings.json +5 -0
  12. package/templates/default/appraisejs.config.json +1 -1
  13. package/templates/default/components.json +24 -24
  14. package/templates/default/cucumber.mjs +16 -0
  15. package/templates/default/eslint.config.mjs +15 -15
  16. package/templates/default/next.config.ts +13 -7
  17. package/templates/default/package-lock.json +13732 -14321
  18. package/templates/default/package.json +11 -9
  19. package/templates/default/postcss.config.mjs +8 -8
  20. package/templates/default/prisma/migrations/20251104113456_add_type_for_template_step_groups/migration.sql +16 -16
  21. package/templates/default/prisma/migrations/20251104170946_add_tags_to_test_suite_and_test_case/migration.sql +27 -27
  22. package/templates/default/prisma/migrations/20251112190024_add_cascade_delete_to_test_run_test_case/migration.sql +17 -17
  23. package/templates/default/prisma/migrations/20251113181100_add_test_run_log/migration.sql +12 -12
  24. package/templates/default/prisma/migrations/20251119191838_add_tag_type/migration.sql +28 -28
  25. package/templates/default/prisma/migrations/20251121164059_add_conflict_resolution/migration.sql +12 -12
  26. package/templates/default/prisma/migrations/20251223183400_add_report_model_to_db_schema/migration.sql +10 -10
  27. package/templates/default/prisma/migrations/20251223183637_add_report_test_case_entity_for_storing_test_results_for_individual_test_cases/migration.sql +10 -10
  28. package/templates/default/prisma/migrations/20251224083549_add_comprehensive_report_storage/migration.sql +108 -108
  29. package/templates/default/prisma/migrations/20251229194422_migrate_duration_to_string/migration.sql +55 -55
  30. package/templates/default/prisma/migrations/20251230124637_add_unique_constraint_to_test_run_name/migration.sql +27 -27
  31. package/templates/default/prisma/migrations/20260115094436_add_dashboard_metrics/migration.sql +59 -59
  32. package/templates/default/prisma/migrations/20260127172022_add_cascade_delete_to_step_parameters/migration.sql +34 -34
  33. package/templates/default/prisma/schema.prisma +554 -554
  34. package/templates/default/scripts/regenerate-features.ts +94 -94
  35. package/templates/default/scripts/setup-env.ts +19 -19
  36. package/templates/default/scripts/sync-all.ts +341 -341
  37. package/templates/default/scripts/sync-appraise-base-template.ts +52 -2
  38. package/templates/default/scripts/sync-environments.ts +323 -323
  39. package/templates/default/scripts/sync-locator-groups.ts +413 -413
  40. package/templates/default/scripts/sync-locators.ts +402 -402
  41. package/templates/default/scripts/sync-modules.ts +349 -349
  42. package/templates/default/scripts/sync-tags.ts +292 -292
  43. package/templates/default/scripts/sync-template-step-groups.ts +399 -399
  44. package/templates/default/scripts/sync-template-steps.ts +806 -806
  45. package/templates/default/scripts/sync-test-cases.ts +905 -905
  46. package/templates/default/scripts/sync-test-suites.ts +411 -411
  47. package/templates/default/src/actions/conflict/conflict.action.ts +33 -33
  48. package/templates/default/src/actions/dashboard/dashboard-actions.ts +240 -240
  49. package/templates/default/src/actions/environments/environment-actions.ts +205 -205
  50. package/templates/default/src/actions/locator/locator-actions.ts +547 -547
  51. package/templates/default/src/actions/locator-groups/locator-group-actions.ts +344 -344
  52. package/templates/default/src/actions/modules/module-actions.ts +133 -133
  53. package/templates/default/src/actions/reports/report-actions.ts +613 -613
  54. package/templates/default/src/actions/review/review-actions.ts +147 -147
  55. package/templates/default/src/actions/tags/tag-actions.ts +104 -104
  56. package/templates/default/src/actions/template-step/template-step-actions.ts +332 -332
  57. package/templates/default/src/actions/template-step-group/template-step-group-actions.ts +278 -278
  58. package/templates/default/src/actions/template-test-case/template-test-case-actions.ts +238 -238
  59. package/templates/default/src/actions/test-case/test-case-actions.ts +419 -419
  60. package/templates/default/src/actions/test-run/test-run-actions.ts +1185 -1185
  61. package/templates/default/src/actions/test-suite/test-suite-actions.ts +253 -253
  62. package/templates/default/src/actions/user/user-actions.ts +13 -13
  63. package/templates/default/src/app/(base)/environments/create/page.tsx +28 -28
  64. package/templates/default/src/app/(base)/environments/environment-form.tsx +219 -219
  65. package/templates/default/src/app/(base)/environments/environment-table-columns.tsx +96 -96
  66. package/templates/default/src/app/(base)/environments/environment-table.tsx +24 -24
  67. package/templates/default/src/app/(base)/environments/modify/[id]/page.tsx +46 -46
  68. package/templates/default/src/app/(base)/environments/page.tsx +59 -59
  69. package/templates/default/src/app/(base)/layout.tsx +10 -10
  70. package/templates/default/src/app/(base)/locator-groups/create/page.tsx +44 -44
  71. package/templates/default/src/app/(base)/locator-groups/locator-group-form.tsx +215 -215
  72. package/templates/default/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
  73. package/templates/default/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
  74. package/templates/default/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
  75. package/templates/default/src/app/(base)/locator-groups/page.tsx +61 -61
  76. package/templates/default/src/app/(base)/locators/create/page.tsx +38 -38
  77. package/templates/default/src/app/(base)/locators/locator-form.tsx +163 -163
  78. package/templates/default/src/app/(base)/locators/locator-table-columns.tsx +73 -90
  79. package/templates/default/src/app/(base)/locators/locator-table.tsx +28 -28
  80. package/templates/default/src/app/(base)/locators/modify/[id]/page.tsx +45 -45
  81. package/templates/default/src/app/(base)/locators/page.tsx +65 -65
  82. package/templates/default/src/app/(base)/locators/sync-locators-button.tsx +66 -66
  83. package/templates/default/src/app/(base)/modules/create/page.tsx +34 -34
  84. package/templates/default/src/app/(base)/modules/modify/[id]/page.tsx +46 -46
  85. package/templates/default/src/app/(base)/modules/module-form.tsx +126 -126
  86. package/templates/default/src/app/(base)/modules/module-table-columns.tsx +85 -85
  87. package/templates/default/src/app/(base)/modules/module-table.tsx +24 -24
  88. package/templates/default/src/app/(base)/modules/page.tsx +59 -59
  89. package/templates/default/src/app/(base)/reports/[id]/page.tsx +517 -517
  90. package/templates/default/src/app/(base)/reports/duration-chart.tsx +33 -33
  91. package/templates/default/src/app/(base)/reports/feature-chart.tsx +78 -78
  92. package/templates/default/src/app/(base)/reports/overview-chart.tsx +46 -46
  93. package/templates/default/src/app/(base)/reports/page.tsx +98 -98
  94. package/templates/default/src/app/(base)/reports/report-metric-card.tsx +16 -16
  95. package/templates/default/src/app/(base)/reports/report-table-columns.tsx +189 -189
  96. package/templates/default/src/app/(base)/reports/report-table.tsx +72 -72
  97. package/templates/default/src/app/(base)/reports/report-view-table-columns.tsx +131 -131
  98. package/templates/default/src/app/(base)/reports/report-view-table.tsx +82 -82
  99. package/templates/default/src/app/(base)/reports/test-cases/page.tsx +42 -42
  100. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +115 -115
  101. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
  102. package/templates/default/src/app/(base)/reports/test-suites/page.tsx +42 -42
  103. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +79 -79
  104. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +27 -27
  105. package/templates/default/src/app/(base)/reports/view-logs-button.tsx +60 -60
  106. package/templates/default/src/app/(base)/reviews/create/page.tsx +26 -26
  107. package/templates/default/src/app/(base)/reviews/created-reviews-table.tsx +15 -15
  108. package/templates/default/src/app/(base)/reviews/modify/[id]/page.tsx +26 -26
  109. package/templates/default/src/app/(base)/reviews/page.tsx +26 -26
  110. package/templates/default/src/app/(base)/reviews/review/[id]/page.tsx +26 -26
  111. package/templates/default/src/app/(base)/reviews/review-form.tsx +11 -11
  112. package/templates/default/src/app/(base)/reviews/review-table-by-creator-columns.tsx +9 -9
  113. package/templates/default/src/app/(base)/reviews/review-table-by-reviewer-columns.tsx +9 -9
  114. package/templates/default/src/app/(base)/reviews/reviewer-reviews-table.tsx +15 -15
  115. package/templates/default/src/app/(base)/tags/create/page.tsx +39 -39
  116. package/templates/default/src/app/(base)/tags/modify/[id]/page.tsx +50 -50
  117. package/templates/default/src/app/(base)/tags/page.tsx +58 -58
  118. package/templates/default/src/app/(base)/tags/tag-form.tsx +147 -147
  119. package/templates/default/src/app/(base)/tags/tag-table-columns.tsx +63 -63
  120. package/templates/default/src/app/(base)/tags/tag-table.tsx +29 -29
  121. package/templates/default/src/app/(base)/template-step-groups/create/page.tsx +28 -28
  122. package/templates/default/src/app/(base)/template-step-groups/modify/[id]/page.tsx +45 -45
  123. package/templates/default/src/app/(base)/template-step-groups/page.tsx +60 -60
  124. package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.tsx +167 -167
  125. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table-columns.tsx +89 -89
  126. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table.tsx +32 -32
  127. package/templates/default/src/app/(base)/template-steps/create/page.tsx +37 -37
  128. package/templates/default/src/app/(base)/template-steps/modify/[id]/page.tsx +49 -49
  129. package/templates/default/src/app/(base)/template-steps/page.tsx +59 -59
  130. package/templates/default/src/app/(base)/template-steps/paramChip.tsx +213 -213
  131. package/templates/default/src/app/(base)/template-steps/template-step-form.tsx +384 -384
  132. package/templates/default/src/app/(base)/template-steps/template-step-table-columns.tsx +158 -158
  133. package/templates/default/src/app/(base)/template-steps/template-step-table.tsx +24 -24
  134. package/templates/default/src/app/(base)/template-test-cases/create/page.tsx +56 -56
  135. package/templates/default/src/app/(base)/template-test-cases/modify/[id]/page.tsx +89 -89
  136. package/templates/default/src/app/(base)/template-test-cases/page.tsx +58 -58
  137. package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.tsx +84 -84
  138. package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.tsx +262 -262
  139. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
  140. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
  141. package/templates/default/src/app/(base)/test-cases/create/page.tsx +76 -76
  142. package/templates/default/src/app/(base)/test-cases/create-from-template/generate/[id]/page.tsx +96 -96
  143. package/templates/default/src/app/(base)/test-cases/create-from-template/page.tsx +38 -38
  144. package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.tsx +73 -73
  145. package/templates/default/src/app/(base)/test-cases/modify/[id]/page.tsx +106 -106
  146. package/templates/default/src/app/(base)/test-cases/page.tsx +60 -60
  147. package/templates/default/src/app/(base)/test-cases/test-case-flow.tsx +82 -82
  148. package/templates/default/src/app/(base)/test-cases/test-case-form.tsx +395 -395
  149. package/templates/default/src/app/(base)/test-cases/test-case-table-columns.tsx +90 -90
  150. package/templates/default/src/app/(base)/test-cases/test-case-table.tsx +35 -35
  151. package/templates/default/src/app/(base)/test-runs/[id]/page.tsx +56 -56
  152. package/templates/default/src/app/(base)/test-runs/create/page.tsx +47 -47
  153. package/templates/default/src/app/(base)/test-runs/page.tsx +60 -60
  154. package/templates/default/src/app/(base)/test-runs/test-run-form.tsx +508 -512
  155. package/templates/default/src/app/(base)/test-runs/test-run-table-columns.tsx +229 -229
  156. package/templates/default/src/app/(base)/test-runs/test-run-table.tsx +127 -127
  157. package/templates/default/src/app/(base)/test-suites/create/page.tsx +45 -45
  158. package/templates/default/src/app/(base)/test-suites/modify/[id]/page.tsx +55 -55
  159. package/templates/default/src/app/(base)/test-suites/page.tsx +82 -82
  160. package/templates/default/src/app/(base)/test-suites/test-suite-form.tsx +269 -269
  161. package/templates/default/src/app/(base)/test-suites/test-suite-table-columns.tsx +97 -97
  162. package/templates/default/src/app/(base)/test-suites/test-suite-table.tsx +29 -29
  163. package/templates/default/src/app/(dashboard-components)/app-drawer.tsx +187 -187
  164. package/templates/default/src/app/(dashboard-components)/data-card-grid.tsx +12 -12
  165. package/templates/default/src/app/(dashboard-components)/data-card.tsx +26 -26
  166. package/templates/default/src/app/(dashboard-components)/execution-health-panel.tsx +56 -56
  167. package/templates/default/src/app/(dashboard-components)/ongoing-test-runs-card.tsx +87 -87
  168. package/templates/default/src/app/(dashboard-components)/quick-actions-drawer.tsx +44 -44
  169. package/templates/default/src/app/api/test-runs/[runId]/download/route.ts +133 -133
  170. package/templates/default/src/app/api/test-runs/[runId]/logs/route.ts +420 -420
  171. package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.ts +146 -146
  172. package/templates/default/src/app/globals.css +147 -147
  173. package/templates/default/src/app/layout.tsx +171 -171
  174. package/templates/default/src/app/page.tsx +64 -64
  175. package/templates/default/src/assets/icons/empty-tube.tsx +23 -23
  176. package/templates/default/src/assets/icons/tube-plus.tsx +29 -29
  177. package/templates/default/src/components/base-node.tsx +21 -21
  178. package/templates/default/src/components/chart/pie-chart.tsx +73 -73
  179. package/templates/default/src/components/data-extraction/locator-inspector.tsx +460 -460
  180. package/templates/default/src/components/data-state/empty-state.tsx +40 -40
  181. package/templates/default/src/components/data-visualization/info-card.tsx +70 -70
  182. package/templates/default/src/components/data-visualization/info-grid.tsx +22 -22
  183. package/templates/default/src/components/devtools/providers.tsx +19 -13
  184. package/templates/default/src/components/diagram/button-edge.tsx +54 -54
  185. package/templates/default/src/components/diagram/dynamic-parameters.tsx +438 -438
  186. package/templates/default/src/components/diagram/edit-header-option.tsx +36 -36
  187. package/templates/default/src/components/diagram/flow-diagram.tsx +470 -470
  188. package/templates/default/src/components/diagram/node-form.tsx +262 -262
  189. package/templates/default/src/components/diagram/options-header-node.tsx +57 -57
  190. package/templates/default/src/components/diagram/template-step-combobox.tsx +155 -155
  191. package/templates/default/src/components/form/error-message.tsx +7 -7
  192. package/templates/default/src/components/kokonutui/smooth-tab.tsx +453 -453
  193. package/templates/default/src/components/loading-skeleton/data-table/data-table-skeleton.tsx +30 -30
  194. package/templates/default/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
  195. package/templates/default/src/components/loading-skeleton/form/icon-button-skeleton.tsx +8 -8
  196. package/templates/default/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
  197. package/templates/default/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
  198. package/templates/default/src/components/logo.tsx +15 -15
  199. package/templates/default/src/components/navigation/command-badge.tsx +34 -34
  200. package/templates/default/src/components/navigation/command-chain-input.tsx +51 -51
  201. package/templates/default/src/components/navigation/entity-search-command.tsx +116 -116
  202. package/templates/default/src/components/navigation/nav-card.tsx +31 -31
  203. package/templates/default/src/components/navigation/nav-command.tsx +508 -508
  204. package/templates/default/src/components/navigation/nav-link.tsx +60 -60
  205. package/templates/default/src/components/navigation/nav-menu-card-deck.tsx +112 -112
  206. package/templates/default/src/components/node-header.tsx +159 -159
  207. package/templates/default/src/components/reports/test-case-logs-modal.tsx +253 -253
  208. package/templates/default/src/components/table/table-actions.tsx +172 -172
  209. package/templates/default/src/components/test-run/download-logs-button.tsx +99 -99
  210. package/templates/default/src/components/test-run/log-viewer.tsx +445 -445
  211. package/templates/default/src/components/test-run/test-run-details.tsx +611 -611
  212. package/templates/default/src/components/test-run/test-run-header.tsx +149 -149
  213. package/templates/default/src/components/test-run/view-report-button.tsx +102 -102
  214. package/templates/default/src/components/theme/mode-toggle.tsx +54 -54
  215. package/templates/default/src/components/theme/theme-provider.tsx +8 -8
  216. package/templates/default/src/components/typography/page-header-subtitle.tsx +7 -7
  217. package/templates/default/src/components/typography/page-header.tsx +7 -7
  218. package/templates/default/src/components/ui/alert-dialog.tsx +106 -106
  219. package/templates/default/src/components/ui/alert.tsx +43 -43
  220. package/templates/default/src/components/ui/avatar.tsx +40 -40
  221. package/templates/default/src/components/ui/badge.tsx +29 -29
  222. package/templates/default/src/components/ui/button.tsx +47 -47
  223. package/templates/default/src/components/ui/calendar.tsx +158 -158
  224. package/templates/default/src/components/ui/card.tsx +43 -43
  225. package/templates/default/src/components/ui/checkbox.tsx +28 -28
  226. package/templates/default/src/components/ui/command.tsx +135 -135
  227. package/templates/default/src/components/ui/data-table-column-header.tsx +61 -61
  228. package/templates/default/src/components/ui/data-table-pagination.tsx +87 -87
  229. package/templates/default/src/components/ui/data-table-view-options.tsx +50 -50
  230. package/templates/default/src/components/ui/data-table.tsx +267 -267
  231. package/templates/default/src/components/ui/dialog.tsx +97 -97
  232. package/templates/default/src/components/ui/dropdown-menu.tsx +182 -182
  233. package/templates/default/src/components/ui/input.tsx +22 -22
  234. package/templates/default/src/components/ui/kbd.tsx +28 -28
  235. package/templates/default/src/components/ui/label.tsx +19 -19
  236. package/templates/default/src/components/ui/loading.tsx +12 -12
  237. package/templates/default/src/components/ui/multi-select-with-preview.tsx +116 -116
  238. package/templates/default/src/components/ui/multi-select.tsx +142 -142
  239. package/templates/default/src/components/ui/navigation-menu.tsx +120 -120
  240. package/templates/default/src/components/ui/popover.tsx +33 -33
  241. package/templates/default/src/components/ui/progress.tsx +25 -25
  242. package/templates/default/src/components/ui/radio-group.tsx +44 -44
  243. package/templates/default/src/components/ui/scroll-area.tsx +40 -40
  244. package/templates/default/src/components/ui/select.tsx +151 -144
  245. package/templates/default/src/components/ui/separator.tsx +22 -22
  246. package/templates/default/src/components/ui/skeleton.tsx +7 -7
  247. package/templates/default/src/components/ui/table.tsx +76 -76
  248. package/templates/default/src/components/ui/tabs.tsx +55 -55
  249. package/templates/default/src/components/ui/textarea.tsx +21 -21
  250. package/templates/default/src/components/ui/toast.tsx +113 -113
  251. package/templates/default/src/components/ui/toaster.tsx +26 -26
  252. package/templates/default/src/components/user-prompt/delete-prompt.tsx +87 -87
  253. package/templates/default/src/config/db-config.ts +10 -10
  254. package/templates/default/src/constants/form-opts/diagram/node-form.ts +30 -30
  255. package/templates/default/src/constants/form-opts/environment-form-opts.ts +24 -24
  256. package/templates/default/src/constants/form-opts/locator-form-opts.ts +20 -20
  257. package/templates/default/src/constants/form-opts/locator-group-form-opts.ts +28 -28
  258. package/templates/default/src/constants/form-opts/module-form-opts.ts +21 -21
  259. package/templates/default/src/constants/form-opts/review-form-opts.ts +23 -23
  260. package/templates/default/src/constants/form-opts/tag-form-opts.ts +42 -42
  261. package/templates/default/src/constants/form-opts/template-selection-form-opts.ts +16 -16
  262. package/templates/default/src/constants/form-opts/template-step-group-form-opts.ts +24 -24
  263. package/templates/default/src/constants/form-opts/template-test-case-form-opts.ts +39 -39
  264. package/templates/default/src/constants/form-opts/template-test-step-form-opts.ts +36 -36
  265. package/templates/default/src/constants/form-opts/test-case-form-opts.ts +43 -43
  266. package/templates/default/src/constants/form-opts/test-run-form-opts.ts +31 -31
  267. package/templates/default/src/constants/form-opts/test-suite-form-opts.ts +24 -24
  268. package/templates/default/src/hooks/use-toast.ts +187 -187
  269. package/templates/default/src/lib/bidirectional-sync.ts +432 -432
  270. package/templates/default/src/lib/database-sync.ts +531 -531
  271. package/templates/default/src/lib/environment-file-utils.ts +221 -221
  272. package/templates/default/src/lib/feature-file-generator.ts +411 -411
  273. package/templates/default/src/lib/gherkin-parser.ts +259 -259
  274. package/templates/default/src/lib/locator-group-file-utils.ts +370 -370
  275. package/templates/default/src/lib/metrics/metric-calculator.ts +613 -613
  276. package/templates/default/src/lib/module-hierarchy-builder.ts +205 -205
  277. package/templates/default/src/lib/path-helpers/module-path.ts +71 -71
  278. package/templates/default/src/lib/test-case-utils.ts +6 -6
  279. package/templates/default/src/lib/test-run/log-formatter.ts +83 -83
  280. package/templates/default/src/lib/test-run/process-manager.ts +191 -191
  281. package/templates/default/src/lib/test-run/report-parser.ts +316 -316
  282. package/templates/default/src/lib/test-run/test-run-executor.ts +144 -144
  283. package/templates/default/src/lib/test-run/winston-logger.ts +95 -95
  284. package/templates/default/src/lib/transformers/gherkin-converter.ts +42 -42
  285. package/templates/default/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
  286. package/templates/default/src/lib/transformers/template-test-case-converter.ts +160 -160
  287. package/templates/default/src/lib/utils/node-param-validation.ts +81 -81
  288. package/templates/default/src/lib/utils/template-step-file-generator.ts +167 -167
  289. package/templates/default/src/lib/utils/template-step-file-manager-intelligent.ts +723 -723
  290. package/templates/default/src/lib/utils/template-step-file-manager.ts +166 -166
  291. package/templates/default/src/lib/utils.ts +31 -31
  292. package/templates/default/src/tests/config/executor/world.ts +41 -41
  293. package/templates/default/src/tests/executor.ts +80 -80
  294. package/templates/default/src/tests/hooks/hooks.ts +99 -99
  295. package/templates/default/src/tests/mapping/locator-map.json +1 -1
  296. package/templates/default/src/tests/steps/actions/click.step.ts +62 -62
  297. package/templates/default/src/tests/steps/actions/navigation.step.ts +73 -72
  298. package/templates/default/src/tests/steps/validations/active_state_assertion.step.ts +34 -34
  299. package/templates/default/src/tests/steps/validations/navigation_assertion.step.ts +24 -23
  300. package/templates/default/src/tests/steps/validations/text_assertion.step.ts +111 -111
  301. package/templates/default/src/tests/steps/validations/visibility_assertion.step.ts +30 -30
  302. package/templates/default/src/tests/support/parameter-types.ts +12 -12
  303. package/templates/default/src/tests/utils/cache.util.ts +260 -260
  304. package/templates/default/src/tests/utils/cli.util.ts +177 -177
  305. package/templates/default/src/tests/utils/environment.util.ts +65 -65
  306. package/templates/default/src/tests/utils/locator.util.ts +248 -248
  307. package/templates/default/src/tests/utils/random-data.util.ts +44 -44
  308. package/templates/default/src/tests/utils/spawner.util.ts +617 -617
  309. package/templates/default/src/types/diagram/diagram.ts +34 -34
  310. package/templates/default/src/types/diagram/template-step.ts +11 -11
  311. package/templates/default/src/types/executor/browser.type.ts +1 -1
  312. package/templates/default/src/types/form/actionHandler.ts +6 -6
  313. package/templates/default/src/types/locator/locator.type.ts +11 -11
  314. package/templates/default/src/types/step/step.type.ts +1 -1
  315. package/templates/default/src/types/table/data-table.ts +6 -6
  316. package/templates/default/tailwind.config.ts +62 -62
  317. package/templates/default/.env +0 -2
  318. package/templates/default/next-env.d.ts +0 -6
  319. package/templates/default/prisma/prisma/dev.db +0 -0
  320. package/templates/default/src/tests/config/environments/environments.json +0 -14
@@ -1,166 +1,166 @@
1
- import prisma from '@/config/db-config'
2
- import { writeTemplateStepFile, deleteTemplateStepFile, generateFileContent } from './template-step-file-generator'
3
- import { TemplateStepGroupType } from '@prisma/client'
4
-
5
- // TemplateStepGroupType helper - will be available from @prisma/client after migration
6
- type TemplateStepGroupTypeLocal = 'ACTION' | 'VALIDATION'
7
-
8
- // Type helper to safely extract type from Prisma templateStepGroup records
9
- type TemplateStepGroupWithType = {
10
- id: string
11
- name: string
12
- description: string | null
13
- type?: TemplateStepGroupTypeLocal
14
- createdAt: Date
15
- updatedAt: Date
16
- }
17
-
18
- function getGroupType(group: unknown): TemplateStepGroupTypeLocal {
19
- const groupWithType = group as TemplateStepGroupWithType
20
- const type = groupWithType.type
21
- if (type === 'VALIDATION' || type === 'ACTION') {
22
- return type
23
- }
24
- return 'ACTION' // default
25
- }
26
-
27
- /**
28
- * Regenerates the file for a specific template step group
29
- * This function is called whenever template steps in a group change
30
- */
31
- export async function regenerateTemplateStepGroupFile(groupId: string): Promise<void> {
32
- try {
33
- // Get the template step group with all its template steps
34
- const group = await prisma.templateStepGroup.findUnique({
35
- where: { id: groupId },
36
- include: {
37
- templateSteps: {
38
- orderBy: {
39
- // Order by creation time or any other field you prefer
40
- createdAt: 'asc',
41
- },
42
- },
43
- },
44
- })
45
-
46
- if (!group) {
47
- throw new Error(`Template step group with ID ${groupId} not found`)
48
- }
49
-
50
- // Generate file content from template steps
51
- const content = generateFileContent(group.templateSteps)
52
-
53
- // Write the file
54
- const type = getGroupType(group)
55
- await writeTemplateStepFile(group.name, content, type)
56
-
57
- console.log(`File regenerated for template step group: ${group.name}`)
58
- } catch (error) {
59
- console.error(`Failed to regenerate file for template step group ${groupId}:`, error)
60
- throw new Error(`File regeneration failed: ${error}`)
61
- }
62
- }
63
-
64
- /**
65
- * Creates a placeholder file for a new template step group
66
- * Called when a new group is created
67
- * @deprecated Use createTemplateStepGroupFile from template-step-file-manager-intelligent.ts instead
68
- */
69
- export async function createTemplateStepGroupFile(
70
- groupName: string,
71
- type: TemplateStepGroupType | string = 'ACTION',
72
- ): Promise<void> {
73
- try {
74
- // Create empty placeholder content with required imports
75
- const placeholderContent =
76
- '// This file is generated automatically. Add template steps to this group to generate content.'
77
-
78
- // Write the placeholder file
79
- await writeTemplateStepFile(groupName, placeholderContent, type)
80
-
81
- console.log(`Placeholder file created for template step group: ${groupName}`)
82
- } catch (error) {
83
- console.error(`Failed to create placeholder file for group "${groupName}":`, error)
84
- throw new Error(`File creation failed: ${error}`)
85
- }
86
- }
87
-
88
- /**
89
- * Deletes the file for a template step group
90
- * Called when a group is deleted
91
- * @deprecated Use removeTemplateStepGroupFile from template-step-file-manager-intelligent.ts instead
92
- */
93
- export async function removeTemplateStepGroupFile(
94
- groupName: string,
95
- type: TemplateStepGroupType | string = 'ACTION',
96
- ): Promise<void> {
97
- try {
98
- await deleteTemplateStepFile(groupName, type)
99
-
100
- console.log(`File deleted for template step group: ${groupName}`)
101
- } catch (error) {
102
- console.error(`Failed to delete file for group "${groupName}":`, error)
103
- throw new Error(`File deletion failed: ${error}`)
104
- }
105
- }
106
-
107
- /**
108
- * Handles file regeneration when a template step is created, updated, or deleted
109
- * This function determines which groups need file regeneration
110
- */
111
- export async function handleTemplateStepChange(
112
- templateStepId: string,
113
- operation: 'create' | 'update' | 'delete',
114
- ): Promise<void> {
115
- try {
116
- let groupId: string | null = null
117
-
118
- if (operation === 'delete') {
119
- // For delete operations, we need to get the group ID before deletion
120
- const step = await prisma.templateStep.findUnique({
121
- where: { id: templateStepId },
122
- select: { templateStepGroupId: true },
123
- })
124
- groupId = step?.templateStepGroupId || null
125
- } else {
126
- // For create/update operations, get the current group ID
127
- const step = await prisma.templateStep.findUnique({
128
- where: { id: templateStepId },
129
- select: { templateStepGroupId: true },
130
- })
131
- groupId = step?.templateStepGroupId || null
132
- }
133
-
134
- if (groupId) {
135
- // Regenerate the file for the affected group
136
- await regenerateTemplateStepGroupFile(groupId)
137
- }
138
- } catch (error) {
139
- console.error(`Failed to handle template step change for step ${templateStepId}:`, error)
140
- throw new Error(`File update failed: ${error}`)
141
- }
142
- }
143
-
144
- /**
145
- * Handles file regeneration when a template step is moved between groups
146
- * This is a special case that requires regenerating files for both groups
147
- */
148
- export async function handleTemplateStepGroupChange(
149
- oldGroupId: string | null,
150
- newGroupId: string | null,
151
- ): Promise<void> {
152
- try {
153
- // Regenerate file for the old group (if it exists)
154
- if (oldGroupId) {
155
- await regenerateTemplateStepGroupFile(oldGroupId)
156
- }
157
-
158
- // Regenerate file for the new group (if it exists)
159
- if (newGroupId) {
160
- await regenerateTemplateStepGroupFile(newGroupId)
161
- }
162
- } catch (error) {
163
- console.error(`Failed to handle template step group change:`, error)
164
- throw new Error(`File update failed: ${error}`)
165
- }
166
- }
1
+ import prisma from '@/config/db-config'
2
+ import { writeTemplateStepFile, deleteTemplateStepFile, generateFileContent } from './template-step-file-generator'
3
+ import { TemplateStepGroupType } from '@prisma/client'
4
+
5
+ // TemplateStepGroupType helper - will be available from @prisma/client after migration
6
+ type TemplateStepGroupTypeLocal = 'ACTION' | 'VALIDATION'
7
+
8
+ // Type helper to safely extract type from Prisma templateStepGroup records
9
+ type TemplateStepGroupWithType = {
10
+ id: string
11
+ name: string
12
+ description: string | null
13
+ type?: TemplateStepGroupTypeLocal
14
+ createdAt: Date
15
+ updatedAt: Date
16
+ }
17
+
18
+ function getGroupType(group: unknown): TemplateStepGroupTypeLocal {
19
+ const groupWithType = group as TemplateStepGroupWithType
20
+ const type = groupWithType.type
21
+ if (type === 'VALIDATION' || type === 'ACTION') {
22
+ return type
23
+ }
24
+ return 'ACTION' // default
25
+ }
26
+
27
+ /**
28
+ * Regenerates the file for a specific template step group
29
+ * This function is called whenever template steps in a group change
30
+ */
31
+ export async function regenerateTemplateStepGroupFile(groupId: string): Promise<void> {
32
+ try {
33
+ // Get the template step group with all its template steps
34
+ const group = await prisma.templateStepGroup.findUnique({
35
+ where: { id: groupId },
36
+ include: {
37
+ templateSteps: {
38
+ orderBy: {
39
+ // Order by creation time or any other field you prefer
40
+ createdAt: 'asc',
41
+ },
42
+ },
43
+ },
44
+ })
45
+
46
+ if (!group) {
47
+ throw new Error(`Template step group with ID ${groupId} not found`)
48
+ }
49
+
50
+ // Generate file content from template steps
51
+ const content = generateFileContent(group.templateSteps)
52
+
53
+ // Write the file
54
+ const type = getGroupType(group)
55
+ await writeTemplateStepFile(group.name, content, type)
56
+
57
+ console.log(`File regenerated for template step group: ${group.name}`)
58
+ } catch (error) {
59
+ console.error(`Failed to regenerate file for template step group ${groupId}:`, error)
60
+ throw new Error(`File regeneration failed: ${error}`)
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Creates a placeholder file for a new template step group
66
+ * Called when a new group is created
67
+ * @deprecated Use createTemplateStepGroupFile from template-step-file-manager-intelligent.ts instead
68
+ */
69
+ export async function createTemplateStepGroupFile(
70
+ groupName: string,
71
+ type: TemplateStepGroupType | string = 'ACTION',
72
+ ): Promise<void> {
73
+ try {
74
+ // Create empty placeholder content with required imports
75
+ const placeholderContent =
76
+ '// This file is generated automatically. Add template steps to this group to generate content.'
77
+
78
+ // Write the placeholder file
79
+ await writeTemplateStepFile(groupName, placeholderContent, type)
80
+
81
+ console.log(`Placeholder file created for template step group: ${groupName}`)
82
+ } catch (error) {
83
+ console.error(`Failed to create placeholder file for group "${groupName}":`, error)
84
+ throw new Error(`File creation failed: ${error}`)
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Deletes the file for a template step group
90
+ * Called when a group is deleted
91
+ * @deprecated Use removeTemplateStepGroupFile from template-step-file-manager-intelligent.ts instead
92
+ */
93
+ export async function removeTemplateStepGroupFile(
94
+ groupName: string,
95
+ type: TemplateStepGroupType | string = 'ACTION',
96
+ ): Promise<void> {
97
+ try {
98
+ await deleteTemplateStepFile(groupName, type)
99
+
100
+ console.log(`File deleted for template step group: ${groupName}`)
101
+ } catch (error) {
102
+ console.error(`Failed to delete file for group "${groupName}":`, error)
103
+ throw new Error(`File deletion failed: ${error}`)
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Handles file regeneration when a template step is created, updated, or deleted
109
+ * This function determines which groups need file regeneration
110
+ */
111
+ export async function handleTemplateStepChange(
112
+ templateStepId: string,
113
+ operation: 'create' | 'update' | 'delete',
114
+ ): Promise<void> {
115
+ try {
116
+ let groupId: string | null = null
117
+
118
+ if (operation === 'delete') {
119
+ // For delete operations, we need to get the group ID before deletion
120
+ const step = await prisma.templateStep.findUnique({
121
+ where: { id: templateStepId },
122
+ select: { templateStepGroupId: true },
123
+ })
124
+ groupId = step?.templateStepGroupId || null
125
+ } else {
126
+ // For create/update operations, get the current group ID
127
+ const step = await prisma.templateStep.findUnique({
128
+ where: { id: templateStepId },
129
+ select: { templateStepGroupId: true },
130
+ })
131
+ groupId = step?.templateStepGroupId || null
132
+ }
133
+
134
+ if (groupId) {
135
+ // Regenerate the file for the affected group
136
+ await regenerateTemplateStepGroupFile(groupId)
137
+ }
138
+ } catch (error) {
139
+ console.error(`Failed to handle template step change for step ${templateStepId}:`, error)
140
+ throw new Error(`File update failed: ${error}`)
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Handles file regeneration when a template step is moved between groups
146
+ * This is a special case that requires regenerating files for both groups
147
+ */
148
+ export async function handleTemplateStepGroupChange(
149
+ oldGroupId: string | null,
150
+ newGroupId: string | null,
151
+ ): Promise<void> {
152
+ try {
153
+ // Regenerate file for the old group (if it exists)
154
+ if (oldGroupId) {
155
+ await regenerateTemplateStepGroupFile(oldGroupId)
156
+ }
157
+
158
+ // Regenerate file for the new group (if it exists)
159
+ if (newGroupId) {
160
+ await regenerateTemplateStepGroupFile(newGroupId)
161
+ }
162
+ } catch (error) {
163
+ console.error(`Failed to handle template step group change:`, error)
164
+ throw new Error(`File update failed: ${error}`)
165
+ }
166
+ }
@@ -1,31 +1,31 @@
1
- import { clsx, type ClassValue } from 'clsx'
2
- import { twMerge } from 'tailwind-merge'
3
- export function cn(...inputs: ClassValue[]) {
4
- return twMerge(clsx(inputs))
5
- }
6
-
7
- export function calculateCompletionPercentage(total: number, completed: number) {
8
- return Math.round((completed / total) * 100)
9
- }
10
-
11
- /**
12
- * Formats a date to show only date and time (without seconds/milliseconds)
13
- * @param date - Date string or Date object
14
- * @returns Formatted date string in format: "MM/DD/YYYY, HH:MM AM/PM"
15
- */
16
- export function formatDateTime(date: string | Date | null | undefined): string {
17
- if (!date) return '-'
18
-
19
- const dateObj = typeof date === 'string' ? new Date(date) : date
20
-
21
- if (isNaN(dateObj.getTime())) return '-'
22
-
23
- return dateObj.toLocaleString('en-US', {
24
- year: 'numeric',
25
- month: '2-digit',
26
- day: '2-digit',
27
- hour: '2-digit',
28
- minute: '2-digit',
29
- hour12: true,
30
- })
31
- }
1
+ import { clsx, type ClassValue } from 'clsx'
2
+ import { twMerge } from 'tailwind-merge'
3
+ export function cn(...inputs: ClassValue[]) {
4
+ return twMerge(clsx(inputs))
5
+ }
6
+
7
+ export function calculateCompletionPercentage(total: number, completed: number) {
8
+ return Math.round((completed / total) * 100)
9
+ }
10
+
11
+ /**
12
+ * Formats a date to show only date and time (without seconds/milliseconds)
13
+ * @param date - Date string or Date object
14
+ * @returns Formatted date string in format: "MM/DD/YYYY, HH:MM AM/PM"
15
+ */
16
+ export function formatDateTime(date: string | Date | null | undefined): string {
17
+ if (!date) return '-'
18
+
19
+ const dateObj = typeof date === 'string' ? new Date(date) : date
20
+
21
+ if (isNaN(dateObj.getTime())) return '-'
22
+
23
+ return dateObj.toLocaleString('en-US', {
24
+ year: 'numeric',
25
+ month: '2-digit',
26
+ day: '2-digit',
27
+ hour: '2-digit',
28
+ minute: '2-digit',
29
+ hour12: true,
30
+ })
31
+ }
@@ -1,41 +1,41 @@
1
- import { World, IWorldOptions, setWorldConstructor, setDefaultTimeout } from '@cucumber/cucumber'
2
- import * as chai from 'chai'
3
- import chaiAsPromised from 'chai-as-promised'
4
- import { BrowserContext, Page } from 'playwright'
5
-
6
- setDefaultTimeout(120 * 1000)
7
-
8
- export interface ScenarioData {
9
- token?: string
10
- vars: Record<string, unknown>
11
- }
12
- export class CustomWorld extends World {
13
- context!: BrowserContext
14
- page!: Page
15
- data: ScenarioData = {
16
- vars: {},
17
- }
18
- constructor(options: IWorldOptions) {
19
- super(options)
20
- }
21
-
22
- setVar(key: string, value: unknown): void {
23
- this.data.vars[key] = value
24
- }
25
-
26
- getVar<T = unknown>(key: string): T {
27
- if (!(key in this.data.vars)) {
28
- throw new Error(`Variable ${key} not found`)
29
- }
30
- return this.data.vars[key] as T
31
- }
32
-
33
- clearVars(): void {
34
- this.data.vars = {}
35
- }
36
- }
37
-
38
- setWorldConstructor(CustomWorld)
39
-
40
- chai.use(chaiAsPromised)
41
- export const expect = chai.expect
1
+ import { World, IWorldOptions, setWorldConstructor, setDefaultTimeout } from '@cucumber/cucumber'
2
+ import * as chai from 'chai'
3
+ import chaiAsPromised from 'chai-as-promised'
4
+ import { BrowserContext, Page } from 'playwright'
5
+
6
+ setDefaultTimeout(120 * 1000)
7
+
8
+ export interface ScenarioData {
9
+ token?: string
10
+ vars: Record<string, unknown>
11
+ }
12
+ export class CustomWorld extends World {
13
+ context!: BrowserContext
14
+ page!: Page
15
+ data: ScenarioData = {
16
+ vars: {},
17
+ }
18
+ constructor(options: IWorldOptions) {
19
+ super(options)
20
+ }
21
+
22
+ setVar(key: string, value: unknown): void {
23
+ this.data.vars[key] = value
24
+ }
25
+
26
+ getVar<T = unknown>(key: string): T {
27
+ if (!(key in this.data.vars)) {
28
+ throw new Error(`Variable ${key} not found`)
29
+ }
30
+ return this.data.vars[key] as T
31
+ }
32
+
33
+ clearVars(): void {
34
+ this.data.vars = {}
35
+ }
36
+ }
37
+
38
+ setWorldConstructor(CustomWorld)
39
+
40
+ chai.use(chaiAsPromised)
41
+ export const expect = chai.expect
@@ -1,80 +1,80 @@
1
- import { BrowserName } from '@/types/executor/browser.type'
2
- import { CliOptions, startCli } from '@/tests/utils/cli.util.js'
3
- import { spawnTask, waitForTask } from '@/tests/utils/spawner.util.js'
4
- import { config } from 'dotenv'
5
-
6
- function setEnvironmentVariables(environment: string, headless: boolean, browser: BrowserName) {
7
- process.env.ENVIRONMENT = environment
8
- process.env.HEADLESS = headless.toString()
9
- process.env.BROWSER = browser
10
- }
11
-
12
- /**
13
- * Main entry point for the CLI application
14
- * Handles CLI parsing, error handling, and application lifecycle
15
- */
16
- async function bootstrap(): Promise<void> {
17
- // Load environment variables
18
- config()
19
-
20
- try {
21
- // Parse CLI arguments and get options
22
- const { environment, tags, parallel, browser, headless }: CliOptions = startCli()
23
-
24
- // Log parsed options with better formatting
25
- console.log(
26
- `Running tests in the following configuration\nEnvironment: ${environment}\nTags: ${tags}\nParallel: ${parallel}\nBrowser: ${browser}\nHeadless: ${headless}`,
27
- )
28
-
29
- setEnvironmentVariables(environment, headless as unknown as boolean, browser as unknown as BrowserName)
30
-
31
- // Build the cucumber command with appropriate flags
32
- const cucumberArgs: string[] = []
33
-
34
- if (tags) {
35
- cucumberArgs.push('-t', tags)
36
- }
37
-
38
- if (parallel > 1) {
39
- cucumberArgs.push('--parallel', parallel.toString())
40
- }
41
-
42
- // Spawn the cucumber test process
43
- console.log('🚀 Starting cucumber test process...')
44
- await spawnTask('npm', ['run', 'test', ...cucumberArgs], {
45
- streamLogs: true,
46
- prefixLogs: true,
47
- logPrefix: 'cucumber-test',
48
- captureOutput: true,
49
- })
50
-
51
- // Wait for the test process to complete
52
- const exitCode = await waitForTask('cucumber-test')
53
-
54
- if (exitCode === 0) {
55
- console.log('✅ Tests completed successfully')
56
- } else {
57
- console.log(`❌ Tests failed with exit code: ${exitCode}`)
58
- }
59
-
60
- process.exit(exitCode || 0)
61
- } catch (error) {
62
- console.error('❌ Application failed with error:')
63
- console.error(error instanceof Error ? error.message : 'Unknown error occurred')
64
- process.exit(1)
65
- }
66
- }
67
-
68
- // Handle uncaught exceptions and unhandled rejections
69
- process.on('uncaughtException', error => {
70
- console.error('❌ Uncaught Exception:', error.message)
71
- process.exit(1)
72
- })
73
-
74
- process.on('unhandledRejection', reason => {
75
- console.error('❌ Unhandled Rejection:', reason)
76
- process.exit(1)
77
- })
78
-
79
- // Start the application
80
- bootstrap()
1
+ import { BrowserName } from '@/types/executor/browser.type'
2
+ import { CliOptions, startCli } from '@/tests/utils/cli.util.js'
3
+ import { spawnTask, waitForTask } from '@/tests/utils/spawner.util.js'
4
+ import { config } from 'dotenv'
5
+
6
+ function setEnvironmentVariables(environment: string, headless: boolean, browser: BrowserName) {
7
+ process.env.ENVIRONMENT = environment
8
+ process.env.HEADLESS = headless.toString()
9
+ process.env.BROWSER = browser
10
+ }
11
+
12
+ /**
13
+ * Main entry point for the CLI application
14
+ * Handles CLI parsing, error handling, and application lifecycle
15
+ */
16
+ async function bootstrap(): Promise<void> {
17
+ // Load environment variables
18
+ config()
19
+
20
+ try {
21
+ // Parse CLI arguments and get options
22
+ const { environment, tags, parallel, browser, headless }: CliOptions = startCli()
23
+
24
+ // Log parsed options with better formatting
25
+ console.log(
26
+ `Running tests in the following configuration\nEnvironment: ${environment}\nTags: ${tags}\nParallel: ${parallel}\nBrowser: ${browser}\nHeadless: ${headless}`,
27
+ )
28
+
29
+ setEnvironmentVariables(environment, headless as unknown as boolean, browser as unknown as BrowserName)
30
+
31
+ // Build the cucumber command with appropriate flags
32
+ const cucumberArgs: string[] = []
33
+
34
+ if (tags) {
35
+ cucumberArgs.push('-t', tags)
36
+ }
37
+
38
+ if (parallel > 1) {
39
+ cucumberArgs.push('--parallel', parallel.toString())
40
+ }
41
+
42
+ // Spawn the cucumber test process
43
+ console.log('🚀 Starting cucumber test process...')
44
+ await spawnTask('npm', ['run', 'test', ...cucumberArgs], {
45
+ streamLogs: true,
46
+ prefixLogs: true,
47
+ logPrefix: 'cucumber-test',
48
+ captureOutput: true,
49
+ })
50
+
51
+ // Wait for the test process to complete
52
+ const exitCode = await waitForTask('cucumber-test')
53
+
54
+ if (exitCode === 0) {
55
+ console.log('✅ Tests completed successfully')
56
+ } else {
57
+ console.log(`❌ Tests failed with exit code: ${exitCode}`)
58
+ }
59
+
60
+ process.exit(exitCode || 0)
61
+ } catch (error) {
62
+ console.error('❌ Application failed with error:')
63
+ console.error(error instanceof Error ? error.message : 'Unknown error occurred')
64
+ process.exit(1)
65
+ }
66
+ }
67
+
68
+ // Handle uncaught exceptions and unhandled rejections
69
+ process.on('uncaughtException', error => {
70
+ console.error('❌ Uncaught Exception:', error.message)
71
+ process.exit(1)
72
+ })
73
+
74
+ process.on('unhandledRejection', reason => {
75
+ console.error('❌ Unhandled Rejection:', reason)
76
+ process.exit(1)
77
+ })
78
+
79
+ // Start the application
80
+ bootstrap()