create-appraisejs 0.2.0 → 0.3.0-alpha.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 (485) hide show
  1. package/README.md +12 -1
  2. package/package.json +1 -1
  3. package/templates/default/.appraise-template-meta.json +2 -2
  4. package/templates/default/.env.example +2 -2
  5. package/templates/default/README.md +57 -53
  6. package/templates/default/automation/steps/actions/click.step.ts +58 -58
  7. package/templates/default/automation/steps/actions/hover.step.ts +27 -27
  8. package/templates/default/automation/steps/actions/navigation.step.ts +70 -70
  9. package/templates/default/automation/steps/actions/random_data.step.ts +142 -142
  10. package/templates/default/automation/steps/actions/store.step.ts +86 -86
  11. package/templates/default/automation/steps/actions/wait.step.ts +110 -90
  12. package/templates/default/automation/steps/validations/active_state_assertion.step.ts +30 -30
  13. package/templates/default/automation/steps/validations/navigation_assertion.step.ts +22 -22
  14. package/templates/default/automation/steps/validations/text_assertion.step.ts +107 -107
  15. package/templates/default/automation/steps/validations/visibility_assertion.step.ts +26 -26
  16. package/templates/default/components.json +24 -24
  17. package/templates/default/cucumber.mjs +16 -16
  18. package/templates/default/eslint.config.mjs +20 -16
  19. package/templates/default/next-env.d.ts +6 -6
  20. package/templates/default/next.config.ts +20 -11
  21. package/templates/default/package-lock.json +1775 -74
  22. package/templates/default/package.json +8 -1
  23. package/templates/default/packages/cucumber-runtime/package.json +13 -13
  24. package/templates/default/packages/cucumber-runtime/src/cache.util.ts +93 -93
  25. package/templates/default/packages/cucumber-runtime/src/cli.ts +68 -68
  26. package/templates/default/packages/cucumber-runtime/src/environment.util.ts +21 -21
  27. package/templates/default/packages/cucumber-runtime/src/executor.ts +32 -32
  28. package/templates/default/packages/cucumber-runtime/src/index.ts +17 -17
  29. package/templates/default/packages/cucumber-runtime/src/locator.util.ts +234 -234
  30. package/templates/default/packages/cucumber-runtime/src/parameter-types.ts +7 -7
  31. package/templates/default/packages/cucumber-runtime/src/random-data.util.ts +35 -35
  32. package/templates/default/packages/cucumber-runtime/src/types.ts +13 -13
  33. package/templates/default/packages/cucumber-runtime/src/world.ts +44 -44
  34. package/templates/default/packages/cucumber-runtime/tsconfig.json +11 -11
  35. package/templates/default/postcss.config.mjs +8 -8
  36. package/templates/default/prisma/dev.db +0 -0
  37. package/templates/default/prisma/migrations/20251104113456_add_type_for_template_step_groups/migration.sql +16 -16
  38. package/templates/default/prisma/migrations/20251104170946_add_tags_to_test_suite_and_test_case/migration.sql +27 -27
  39. package/templates/default/prisma/migrations/20251112190024_add_cascade_delete_to_test_run_test_case/migration.sql +17 -17
  40. package/templates/default/prisma/migrations/20251113181100_add_test_run_log/migration.sql +12 -12
  41. package/templates/default/prisma/migrations/20251119191838_add_tag_type/migration.sql +28 -28
  42. package/templates/default/prisma/migrations/20251121164059_add_conflict_resolution/migration.sql +12 -12
  43. package/templates/default/prisma/migrations/20251223183400_add_report_model_to_db_schema/migration.sql +10 -10
  44. package/templates/default/prisma/migrations/20251223183637_add_report_test_case_entity_for_storing_test_results_for_individual_test_cases/migration.sql +10 -10
  45. package/templates/default/prisma/migrations/20251224083549_add_comprehensive_report_storage/migration.sql +108 -108
  46. package/templates/default/prisma/migrations/20251229194422_migrate_duration_to_string/migration.sql +55 -55
  47. package/templates/default/prisma/migrations/20251230124637_add_unique_constraint_to_test_run_name/migration.sql +27 -27
  48. package/templates/default/prisma/migrations/20260115094436_add_dashboard_metrics/migration.sql +59 -59
  49. package/templates/default/prisma/migrations/20260127172022_add_cascade_delete_to_step_parameters/migration.sql +34 -34
  50. package/templates/default/prisma/migrations/20260313093000_add_report_step_screenshot_path/migration.sql +1 -1
  51. package/templates/default/scripts/build-step-registry.ts +33 -0
  52. package/templates/default/scripts/install-playwright.ts +17 -8
  53. package/templates/default/scripts/install-template-step.ts +128 -0
  54. package/templates/default/scripts/lib/filename-utils.test.ts +24 -0
  55. package/templates/default/scripts/lib/filename-utils.ts +24 -0
  56. package/templates/default/scripts/lib/jsdoc-parser.test.ts +63 -0
  57. package/templates/default/scripts/lib/jsdoc-parser.ts +88 -0
  58. package/templates/default/scripts/lib/step-file-parser.test.ts +71 -0
  59. package/templates/default/scripts/lib/step-file-parser.ts +315 -0
  60. package/templates/default/scripts/lib/step-matcher.test.ts +86 -0
  61. package/templates/default/scripts/lib/step-matcher.ts +120 -0
  62. package/templates/default/scripts/lib/sync-script-runner.ts +23 -0
  63. package/templates/default/scripts/lib/sync-summary.ts +29 -0
  64. package/templates/default/scripts/lib/tag-parsing.test.ts +20 -0
  65. package/templates/default/scripts/lib/tag-parsing.ts +10 -0
  66. package/templates/default/scripts/lib/template-step-installer.test.ts +225 -0
  67. package/templates/default/scripts/lib/template-step-installer.ts +404 -0
  68. package/templates/default/scripts/lib/template-step-registry.test.ts +118 -0
  69. package/templates/default/scripts/lib/template-step-registry.ts +137 -0
  70. package/templates/default/scripts/protect-seeded-files.ts +51 -38
  71. package/templates/default/scripts/regenerate-features.ts +98 -94
  72. package/templates/default/scripts/run-vitest.ts +59 -0
  73. package/templates/default/scripts/setup-env.ts +26 -19
  74. package/templates/default/scripts/sync-all.ts +44 -54
  75. package/templates/default/scripts/sync-appraise-base-template.ts +44 -16
  76. package/templates/default/scripts/sync-environments.ts +22 -66
  77. package/templates/default/scripts/sync-locator-groups.ts +358 -410
  78. package/templates/default/scripts/sync-locators.ts +348 -398
  79. package/templates/default/scripts/sync-modules.ts +302 -341
  80. package/templates/default/scripts/sync-tags.ts +29 -65
  81. package/templates/default/scripts/sync-template-step-groups.ts +24 -182
  82. package/templates/default/scripts/sync-template-steps.ts +36 -493
  83. package/templates/default/scripts/sync-test-cases.ts +296 -539
  84. package/templates/default/scripts/sync-test-suites.ts +32 -79
  85. package/templates/default/src/actions/dashboard/dashboard-actions.ts +70 -241
  86. package/templates/default/src/actions/environments/environment-actions.ts +102 -188
  87. package/templates/default/src/actions/locator/locator-actions.ts +77 -490
  88. package/templates/default/src/actions/locator-groups/locator-group-actions.ts +34 -212
  89. package/templates/default/src/actions/locator-picker/locator-picker-actions.test.ts +81 -0
  90. package/templates/default/src/actions/locator-picker/locator-picker-actions.ts +20 -161
  91. package/templates/default/src/actions/modules/module-actions.ts +99 -135
  92. package/templates/default/src/actions/reports/report-actions.ts +28 -565
  93. package/templates/default/src/actions/settings/sync-actions.test.ts +58 -0
  94. package/templates/default/src/actions/tags/tag-actions.ts +99 -107
  95. package/templates/default/src/actions/template-step/template-step-actions.ts +33 -194
  96. package/templates/default/src/actions/template-step-group/template-step-group-actions.ts +35 -92
  97. package/templates/default/src/actions/template-test-case/template-test-case-actions.ts +98 -238
  98. package/templates/default/src/actions/test-case/test-case-actions.ts +108 -356
  99. package/templates/default/src/actions/test-run/test-run-actions.ts +74 -1081
  100. package/templates/default/src/actions/test-suite/test-suite-actions.ts +35 -202
  101. package/templates/default/src/app/(base)/environments/create/page.tsx +28 -28
  102. package/templates/default/src/app/(base)/environments/environment-form.test.tsx +92 -0
  103. package/templates/default/src/app/(base)/environments/environment-form.tsx +228 -219
  104. package/templates/default/src/app/(base)/environments/environment-helpers.ts +58 -0
  105. package/templates/default/src/app/(base)/environments/environment-table-columns.tsx +96 -96
  106. package/templates/default/src/app/(base)/environments/environment-table.tsx +25 -24
  107. package/templates/default/src/app/(base)/environments/modify/[id]/page.tsx +49 -46
  108. package/templates/default/src/app/(base)/environments/page.tsx +59 -59
  109. package/templates/default/src/app/(base)/layout.tsx +10 -10
  110. package/templates/default/src/app/(base)/locator-groups/create/page.tsx +44 -44
  111. package/templates/default/src/app/(base)/locator-groups/locator-group-form.tsx +215 -215
  112. package/templates/default/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
  113. package/templates/default/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
  114. package/templates/default/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
  115. package/templates/default/src/app/(base)/locators/create/create-locator-workspace-helpers.test.ts +71 -0
  116. package/templates/default/src/app/(base)/locators/create/create-locator-workspace-helpers.ts +333 -0
  117. package/templates/default/src/app/(base)/locators/create/create-locator-workspace.test.tsx +125 -0
  118. package/templates/default/src/app/(base)/locators/create/create-locator-workspace.tsx +56 -274
  119. package/templates/default/src/app/(base)/locators/create/page.tsx +8 -4
  120. package/templates/default/src/app/(base)/locators/create/use-locator-workspace.ts +183 -0
  121. package/templates/default/src/app/(base)/locators/locator-helpers.test.ts +28 -0
  122. package/templates/default/src/app/(base)/locators/locator-helpers.ts +59 -0
  123. package/templates/default/src/app/(base)/locators/locator-table-columns.tsx +74 -73
  124. package/templates/default/src/app/(base)/locators/locator-table.tsx +30 -28
  125. package/templates/default/src/app/(base)/locators/modify/[id]/page.tsx +20 -8
  126. package/templates/default/src/app/(base)/locators/page.tsx +3 -6
  127. package/templates/default/src/app/(base)/locators/sync-locators-button.tsx +67 -66
  128. package/templates/default/src/app/(base)/modules/create/page.tsx +33 -34
  129. package/templates/default/src/app/(base)/modules/modify/[id]/page.tsx +43 -46
  130. package/templates/default/src/app/(base)/modules/module-form.test.tsx +84 -0
  131. package/templates/default/src/app/(base)/modules/module-form.tsx +159 -126
  132. package/templates/default/src/app/(base)/modules/module-helpers.ts +64 -0
  133. package/templates/default/src/app/(base)/modules/module-table-columns.tsx +81 -85
  134. package/templates/default/src/app/(base)/modules/module-table.tsx +25 -24
  135. package/templates/default/src/app/(base)/modules/page.tsx +59 -59
  136. package/templates/default/src/app/(base)/reports/[id]/page.tsx +20 -260
  137. package/templates/default/src/app/(base)/reports/duration-chart.tsx +33 -33
  138. package/templates/default/src/app/(base)/reports/feature-chart.tsx +79 -78
  139. package/templates/default/src/app/(base)/reports/overview-chart.tsx +49 -49
  140. package/templates/default/src/app/(base)/reports/page.tsx +98 -98
  141. package/templates/default/src/app/(base)/reports/report-detail-helpers.test.ts +109 -0
  142. package/templates/default/src/app/(base)/reports/report-detail-helpers.ts +247 -0
  143. package/templates/default/src/app/(base)/reports/report-metric-card.tsx +78 -78
  144. package/templates/default/src/app/(base)/reports/report-table-columns.tsx +189 -189
  145. package/templates/default/src/app/(base)/reports/report-table.tsx +72 -72
  146. package/templates/default/src/app/(base)/reports/test-cases/page.tsx +40 -40
  147. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +115 -115
  148. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
  149. package/templates/default/src/app/(base)/reports/test-suites/page.tsx +42 -42
  150. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +79 -79
  151. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +27 -27
  152. package/templates/default/src/app/(base)/reports/view-logs-button.tsx +58 -58
  153. package/templates/default/src/app/(base)/settings/settings-sync-panel-helpers.test.tsx +40 -0
  154. package/templates/default/src/app/(base)/settings/settings-sync-panel-helpers.tsx +110 -0
  155. package/templates/default/src/app/(base)/settings/settings-sync-panel.test.tsx +127 -0
  156. package/templates/default/src/app/(base)/settings/settings-sync-panel.tsx +19 -134
  157. package/templates/default/src/app/(base)/settings/use-settings-sync.ts +66 -0
  158. package/templates/default/src/app/(base)/tags/create/page.tsx +39 -39
  159. package/templates/default/src/app/(base)/tags/modify/[id]/page.tsx +50 -50
  160. package/templates/default/src/app/(base)/tags/page.tsx +58 -58
  161. package/templates/default/src/app/(base)/tags/tag-form-helpers.ts +13 -0
  162. package/templates/default/src/app/(base)/tags/tag-form.test.tsx +83 -0
  163. package/templates/default/src/app/(base)/tags/tag-form.tsx +143 -147
  164. package/templates/default/src/app/(base)/tags/tag-table-columns.tsx +63 -63
  165. package/templates/default/src/app/(base)/tags/tag-table.tsx +29 -29
  166. package/templates/default/src/app/(base)/template-step-groups/create/page.tsx +28 -28
  167. package/templates/default/src/app/(base)/template-step-groups/modify/[id]/page.tsx +43 -45
  168. package/templates/default/src/app/(base)/template-step-groups/page.tsx +60 -60
  169. package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.test.tsx +82 -0
  170. package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.tsx +181 -167
  171. package/templates/default/src/app/(base)/template-step-groups/template-step-group-helpers.ts +54 -0
  172. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table-columns.tsx +89 -89
  173. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table.tsx +34 -32
  174. package/templates/default/src/app/(base)/template-steps/create/page.tsx +40 -37
  175. package/templates/default/src/app/(base)/template-steps/modify/[id]/page.tsx +54 -49
  176. package/templates/default/src/app/(base)/template-steps/page.tsx +59 -58
  177. package/templates/default/src/app/(base)/template-steps/paramChip.tsx +233 -213
  178. package/templates/default/src/app/(base)/template-steps/template-step-form.test.tsx +132 -0
  179. package/templates/default/src/app/(base)/template-steps/template-step-form.tsx +342 -384
  180. package/templates/default/src/app/(base)/template-steps/template-step-helpers.test.ts +99 -0
  181. package/templates/default/src/app/(base)/template-steps/template-step-helpers.ts +176 -0
  182. package/templates/default/src/app/(base)/template-steps/template-step-table-columns.tsx +153 -158
  183. package/templates/default/src/app/(base)/template-steps/template-step-table.tsx +26 -24
  184. package/templates/default/src/app/(base)/template-test-cases/create/page.tsx +56 -56
  185. package/templates/default/src/app/(base)/template-test-cases/modify/[id]/page.tsx +89 -89
  186. package/templates/default/src/app/(base)/template-test-cases/page.tsx +58 -58
  187. package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.test.tsx +109 -0
  188. package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.tsx +45 -84
  189. package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.test.tsx +140 -0
  190. package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.tsx +154 -262
  191. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
  192. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
  193. package/templates/default/src/app/(base)/test-cases/create/page.tsx +90 -76
  194. package/templates/default/src/app/(base)/test-cases/create-from-template/create-from-template-helpers.test.ts +94 -0
  195. package/templates/default/src/app/(base)/test-cases/create-from-template/create-from-template-helpers.ts +171 -0
  196. package/templates/default/src/app/(base)/test-cases/create-from-template/generate/[id]/page.tsx +105 -96
  197. package/templates/default/src/app/(base)/test-cases/create-from-template/page.tsx +40 -38
  198. package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.test.tsx +87 -0
  199. package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.tsx +83 -73
  200. package/templates/default/src/app/(base)/test-cases/modify/[id]/page.tsx +106 -106
  201. package/templates/default/src/app/(base)/test-cases/page.tsx +3 -2
  202. package/templates/default/src/app/(base)/test-cases/test-case-flow.test.tsx +108 -0
  203. package/templates/default/src/app/(base)/test-cases/test-case-flow.tsx +43 -82
  204. package/templates/default/src/app/(base)/test-cases/test-case-form.test.tsx +202 -0
  205. package/templates/default/src/app/(base)/test-cases/test-case-form.tsx +263 -395
  206. package/templates/default/src/app/(base)/test-cases/test-case-route-helpers.test.ts +95 -0
  207. package/templates/default/src/app/(base)/test-cases/test-case-route-helpers.ts +147 -0
  208. package/templates/default/src/app/(base)/test-cases/test-case-table.tsx +4 -2
  209. package/templates/default/src/app/(base)/test-runs/[id]/page.tsx +11 -10
  210. package/templates/default/src/app/(base)/test-runs/create/page.tsx +4 -5
  211. package/templates/default/src/app/(base)/test-runs/page.tsx +60 -60
  212. package/templates/default/src/app/(base)/test-runs/test-run-form-helpers.test.ts +50 -0
  213. package/templates/default/src/app/(base)/test-runs/test-run-form-helpers.ts +168 -0
  214. package/templates/default/src/app/(base)/test-runs/test-run-form.test.tsx +138 -0
  215. package/templates/default/src/app/(base)/test-runs/test-run-form.tsx +111 -256
  216. package/templates/default/src/app/(base)/test-runs/test-run-table-columns.tsx +229 -229
  217. package/templates/default/src/app/(base)/test-runs/test-run-table.tsx +127 -127
  218. package/templates/default/src/app/(base)/test-runs/use-test-run-name-validation.ts +74 -0
  219. package/templates/default/src/app/(base)/test-suites/create/page.tsx +17 -12
  220. package/templates/default/src/app/(base)/test-suites/modify/[id]/page.tsx +22 -19
  221. package/templates/default/src/app/(base)/test-suites/page.tsx +14 -56
  222. package/templates/default/src/app/(base)/test-suites/test-suite-form.test.tsx +127 -0
  223. package/templates/default/src/app/(base)/test-suites/test-suite-form.tsx +45 -64
  224. package/templates/default/src/app/(base)/test-suites/test-suite-helpers.test.ts +67 -0
  225. package/templates/default/src/app/(base)/test-suites/test-suite-helpers.ts +215 -0
  226. package/templates/default/src/app/(base)/test-suites/test-suite-table.tsx +32 -29
  227. package/templates/default/src/app/(dashboard-components)/app-drawer.tsx +187 -187
  228. package/templates/default/src/app/(dashboard-components)/data-card-grid.tsx +12 -12
  229. package/templates/default/src/app/(dashboard-components)/data-card.tsx +26 -26
  230. package/templates/default/src/app/(dashboard-components)/execution-health-panel.tsx +56 -56
  231. package/templates/default/src/app/(dashboard-components)/ongoing-test-runs-card.tsx +87 -87
  232. package/templates/default/src/app/(dashboard-components)/quick-actions-drawer.tsx +44 -44
  233. package/templates/default/src/app/api/reports/steps/[stepId]/screenshot/route.test.ts +83 -0
  234. package/templates/default/src/app/api/reports/steps/[stepId]/screenshot/route.ts +52 -52
  235. package/templates/default/src/app/api/test-runs/[runId]/download/route.test.ts +169 -0
  236. package/templates/default/src/app/api/test-runs/[runId]/download/route.ts +1 -1
  237. package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.test.ts +135 -0
  238. package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.ts +146 -146
  239. package/templates/default/src/app/globals.css +147 -147
  240. package/templates/default/src/app/page.tsx +1 -1
  241. package/templates/default/src/assets/icons/empty-tube.tsx +23 -23
  242. package/templates/default/src/assets/icons/tube-plus.tsx +29 -29
  243. package/templates/default/src/components/base-node.tsx +21 -21
  244. package/templates/default/src/components/chart/pie-chart.tsx +73 -73
  245. package/templates/default/src/components/data-extraction/locator-inspector-helpers.test.ts +32 -0
  246. package/templates/default/src/components/data-extraction/locator-inspector-helpers.ts +183 -0
  247. package/templates/default/src/components/data-extraction/locator-inspector.tsx +349 -460
  248. package/templates/default/src/components/data-state/empty-state.tsx +40 -40
  249. package/templates/default/src/components/data-visualization/info-card.tsx +70 -70
  250. package/templates/default/src/components/data-visualization/info-grid.tsx +22 -22
  251. package/templates/default/src/components/diagram/button-edge.tsx +54 -54
  252. package/templates/default/src/components/diagram/dynamic-parameters-helpers.test.ts +83 -0
  253. package/templates/default/src/components/diagram/dynamic-parameters-helpers.ts +158 -0
  254. package/templates/default/src/components/diagram/dynamic-parameters.tsx +350 -474
  255. package/templates/default/src/components/diagram/edit-header-option.tsx +36 -36
  256. package/templates/default/src/components/diagram/flow-diagram-helpers.test.ts +117 -0
  257. package/templates/default/src/components/diagram/flow-diagram-helpers.ts +251 -0
  258. package/templates/default/src/components/diagram/flow-diagram.tsx +247 -470
  259. package/templates/default/src/components/diagram/flow-host-helpers.test.ts +74 -0
  260. package/templates/default/src/components/diagram/flow-host-helpers.ts +51 -0
  261. package/templates/default/src/components/diagram/node-form-helpers.test.ts +92 -0
  262. package/templates/default/src/components/diagram/node-form-helpers.ts +100 -0
  263. package/templates/default/src/components/diagram/node-form.test.tsx +168 -0
  264. package/templates/default/src/components/diagram/node-form.tsx +199 -262
  265. package/templates/default/src/components/diagram/options-header-node.tsx +57 -57
  266. package/templates/default/src/components/diagram/template-step-combobox.tsx +155 -155
  267. package/templates/default/src/components/diagram/use-flow-node-order.ts +49 -0
  268. package/templates/default/src/components/form/error-message.tsx +7 -7
  269. package/templates/default/src/components/kokonutui/smooth-tab.tsx +453 -453
  270. package/templates/default/src/components/loading-skeleton/data-table/data-table-skeleton.tsx +30 -30
  271. package/templates/default/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
  272. package/templates/default/src/components/loading-skeleton/form/icon-button-skeleton.tsx +8 -8
  273. package/templates/default/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
  274. package/templates/default/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
  275. package/templates/default/src/components/navigation/command-badge.tsx +34 -34
  276. package/templates/default/src/components/navigation/command-chain-input.tsx +51 -51
  277. package/templates/default/src/components/navigation/entity-search-command.tsx +118 -116
  278. package/templates/default/src/components/navigation/nav-card.tsx +31 -31
  279. package/templates/default/src/components/navigation/nav-command-helpers.ts +122 -0
  280. package/templates/default/src/components/navigation/nav-command-search.tsx +125 -0
  281. package/templates/default/src/components/navigation/nav-command.test.tsx +106 -0
  282. package/templates/default/src/components/navigation/nav-command.tsx +49 -472
  283. package/templates/default/src/components/navigation/nav-link.tsx +60 -60
  284. package/templates/default/src/components/navigation/nav-menu-card-deck.tsx +112 -112
  285. package/templates/default/src/components/navigation/use-nav-command.ts +58 -0
  286. package/templates/default/src/components/node-header.tsx +159 -159
  287. package/templates/default/src/components/reports/test-case-logs-modal.tsx +310 -310
  288. package/templates/default/src/components/table/table-actions.tsx +174 -172
  289. package/templates/default/src/components/test-case/test-case-form-helpers.test.ts +100 -0
  290. package/templates/default/src/components/test-case/test-case-form-helpers.ts +140 -0
  291. package/templates/default/src/components/test-case/test-case-picker-helpers.test.ts +40 -0
  292. package/templates/default/src/components/test-case/test-case-picker-helpers.ts +41 -0
  293. package/templates/default/src/components/test-case/test-case-picker.test.tsx +44 -0
  294. package/templates/default/src/components/test-case/test-case-picker.tsx +16 -35
  295. package/templates/default/src/components/test-case/test-scenario-preview.tsx +34 -0
  296. package/templates/default/src/components/test-run/download-logs-button.tsx +92 -92
  297. package/templates/default/src/components/test-run/log-viewer-helpers.test.ts +37 -0
  298. package/templates/default/src/components/test-run/log-viewer-helpers.ts +80 -0
  299. package/templates/default/src/components/test-run/log-viewer.test.tsx +118 -0
  300. package/templates/default/src/components/test-run/log-viewer.tsx +51 -350
  301. package/templates/default/src/components/test-run/test-run-details-helpers.test.ts +31 -0
  302. package/templates/default/src/components/test-run/test-run-details-helpers.ts +208 -0
  303. package/templates/default/src/components/test-run/test-run-details.test.tsx +174 -0
  304. package/templates/default/src/components/test-run/test-run-details.tsx +155 -457
  305. package/templates/default/src/components/test-run/test-run-header-helpers.test.ts +31 -0
  306. package/templates/default/src/components/test-run/test-run-header-helpers.ts +23 -0
  307. package/templates/default/src/components/test-run/test-run-header.test.tsx +103 -0
  308. package/templates/default/src/components/test-run/test-run-header.tsx +27 -149
  309. package/templates/default/src/components/test-run/use-log-viewer.ts +213 -0
  310. package/templates/default/src/components/test-run/use-test-run-details.ts +184 -0
  311. package/templates/default/src/components/test-run/use-test-run-header.ts +89 -0
  312. package/templates/default/src/components/test-run/view-report-button.tsx +102 -102
  313. package/templates/default/src/components/test-suite/test-suite-picker-helpers.test.ts +68 -0
  314. package/templates/default/src/components/test-suite/test-suite-picker-helpers.ts +76 -0
  315. package/templates/default/src/components/test-suite/test-suite-picker.test.tsx +65 -0
  316. package/templates/default/src/components/test-suite/test-suite-picker.tsx +4 -72
  317. package/templates/default/src/components/theme/mode-toggle.tsx +54 -54
  318. package/templates/default/src/components/theme/theme-provider.tsx +8 -8
  319. package/templates/default/src/components/typography/page-header-subtitle.tsx +7 -7
  320. package/templates/default/src/components/typography/page-header.tsx +7 -7
  321. package/templates/default/src/components/ui/alert-dialog.tsx +106 -106
  322. package/templates/default/src/components/ui/alert.tsx +43 -43
  323. package/templates/default/src/components/ui/avatar.tsx +40 -40
  324. package/templates/default/src/components/ui/badge.tsx +29 -29
  325. package/templates/default/src/components/ui/button.tsx +47 -47
  326. package/templates/default/src/components/ui/calendar.tsx +158 -158
  327. package/templates/default/src/components/ui/card.tsx +43 -43
  328. package/templates/default/src/components/ui/checkbox.tsx +28 -28
  329. package/templates/default/src/components/ui/command.tsx +135 -135
  330. package/templates/default/src/components/ui/data-table-column-header.tsx +61 -61
  331. package/templates/default/src/components/ui/data-table-pagination.tsx +87 -87
  332. package/templates/default/src/components/ui/data-table-view-options.tsx +50 -50
  333. package/templates/default/src/components/ui/data-table.test.tsx +122 -0
  334. package/templates/default/src/components/ui/data-table.tsx +298 -261
  335. package/templates/default/src/components/ui/dialog.tsx +97 -97
  336. package/templates/default/src/components/ui/dropdown-menu.tsx +182 -182
  337. package/templates/default/src/components/ui/input.tsx +22 -22
  338. package/templates/default/src/components/ui/kbd.tsx +28 -28
  339. package/templates/default/src/components/ui/label.tsx +19 -19
  340. package/templates/default/src/components/ui/loading.tsx +12 -12
  341. package/templates/default/src/components/ui/multi-select-with-preview.tsx +116 -116
  342. package/templates/default/src/components/ui/multi-select.test.tsx +45 -0
  343. package/templates/default/src/components/ui/multi-select.tsx +158 -142
  344. package/templates/default/src/components/ui/navigation-menu.tsx +120 -120
  345. package/templates/default/src/components/ui/popover.tsx +33 -33
  346. package/templates/default/src/components/ui/progress.tsx +25 -25
  347. package/templates/default/src/components/ui/radio-group.tsx +44 -44
  348. package/templates/default/src/components/ui/scroll-area.tsx +40 -40
  349. package/templates/default/src/components/ui/select.tsx +151 -151
  350. package/templates/default/src/components/ui/separator.tsx +22 -22
  351. package/templates/default/src/components/ui/skeleton.tsx +7 -7
  352. package/templates/default/src/components/ui/table.tsx +76 -76
  353. package/templates/default/src/components/ui/tabs.tsx +55 -55
  354. package/templates/default/src/components/ui/textarea.tsx +21 -21
  355. package/templates/default/src/components/ui/toast.tsx +113 -113
  356. package/templates/default/src/components/ui/toaster.tsx +26 -26
  357. package/templates/default/src/components/user-prompt/delete-prompt.test.tsx +60 -0
  358. package/templates/default/src/components/user-prompt/delete-prompt.tsx +118 -87
  359. package/templates/default/src/constants/form-opts/diagram/node-form.ts +30 -30
  360. package/templates/default/src/constants/form-opts/environment-form-opts.ts +24 -24
  361. package/templates/default/src/constants/form-opts/locator-group-form-opts.ts +28 -28
  362. package/templates/default/src/constants/form-opts/module-form-opts.ts +21 -21
  363. package/templates/default/src/constants/form-opts/tag-form-opts.ts +42 -42
  364. package/templates/default/src/constants/form-opts/template-selection-form-opts.ts +16 -16
  365. package/templates/default/src/constants/form-opts/template-step-group-form-opts.ts +24 -24
  366. package/templates/default/src/constants/form-opts/template-test-case-form-opts.ts +39 -39
  367. package/templates/default/src/constants/form-opts/template-test-step-form-opts.ts +36 -36
  368. package/templates/default/src/constants/form-opts/test-case-form-opts.ts +43 -43
  369. package/templates/default/src/constants/form-opts/test-suite-form-opts.ts +24 -24
  370. package/templates/default/src/hooks/use-toast.ts +187 -187
  371. package/templates/default/src/lib/automation/automation-path-roots.ts +95 -0
  372. package/templates/default/src/lib/automation/automation-workspace.ts +147 -0
  373. package/templates/default/src/lib/automation/paths.ts +6 -211
  374. package/templates/default/src/lib/bidirectional-sync.ts +432 -432
  375. package/templates/default/src/lib/environment-file-utils.ts +2 -1
  376. package/templates/default/src/lib/executor/local-executor-adapter.ts +2 -5
  377. package/templates/default/src/lib/feature-file-generator.ts +2 -1
  378. package/templates/default/src/lib/gherkin-parser.ts +0 -2
  379. package/templates/default/src/lib/locator-group-file-utils.ts +304 -307
  380. package/templates/default/src/lib/locator-picker/session-manager.ts +0 -21
  381. package/templates/default/src/lib/locator-picker/suggestions.ts +4 -2
  382. package/templates/default/src/lib/metrics/metric-calculator.ts +2 -6
  383. package/templates/default/src/lib/module-hierarchy-builder.ts +205 -205
  384. package/templates/default/src/lib/path-helpers/module-path.ts +71 -71
  385. package/templates/default/src/lib/sync/sync-executor.test.ts +76 -0
  386. package/templates/default/src/lib/sync/sync-pending-counts.test.ts +227 -226
  387. package/templates/default/src/lib/sync/sync-pending-counts.ts +2 -5
  388. package/templates/default/src/lib/template-sync-utils.d.ts +6 -6
  389. package/templates/default/src/lib/template-sync-utils.js +46 -46
  390. package/templates/default/src/lib/template-sync-utils.ts +63 -63
  391. package/templates/default/src/lib/test-case-utils.ts +6 -6
  392. package/templates/default/src/lib/test-run/log-formatter.ts +83 -83
  393. package/templates/default/src/lib/test-run/report-parser.ts +352 -352
  394. package/templates/default/src/lib/test-run/test-run-executor.ts +13 -13
  395. package/templates/default/src/lib/test-run/winston-logger.ts +65 -64
  396. package/templates/default/src/lib/transformers/gherkin-converter.ts +42 -42
  397. package/templates/default/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
  398. package/templates/default/src/lib/transformers/template-test-case-converter.ts +160 -160
  399. package/templates/default/src/lib/utils/node-param-validation.ts +81 -81
  400. package/templates/default/src/lib/utils/template-step-file-generator.ts +2 -2
  401. package/templates/default/src/lib/utils/template-step-file-manager.ts +166 -166
  402. package/templates/default/src/lib/utils.ts +31 -31
  403. package/templates/default/src/services/dashboard/dashboard-service.test.ts +106 -0
  404. package/templates/default/src/services/dashboard/dashboard-service.ts +173 -0
  405. package/templates/default/src/services/environment/environment-service.test.ts +137 -0
  406. package/templates/default/src/services/environment/environment-service.ts +96 -0
  407. package/templates/default/src/services/locator/locator-path-utils.test.ts +14 -0
  408. package/templates/default/src/services/locator/locator-path-utils.ts +14 -0
  409. package/templates/default/src/services/locator/locator-service.test.ts +63 -0
  410. package/templates/default/src/services/locator/locator-service.ts +479 -0
  411. package/templates/default/src/services/locator/locator-sync-utils.test.ts +19 -0
  412. package/templates/default/src/services/locator/locator-sync-utils.ts +21 -0
  413. package/templates/default/src/services/locator-group/locator-group-service.test.ts +123 -0
  414. package/templates/default/src/services/locator-group/locator-group-service.ts +180 -0
  415. package/templates/default/src/services/module/module-service.test.ts +89 -0
  416. package/templates/default/src/services/module/module-service.ts +66 -0
  417. package/templates/default/src/services/report/report-service.test.ts +244 -0
  418. package/templates/default/src/services/report/report-service.ts +438 -0
  419. package/templates/default/src/services/shared/constants.ts +2 -0
  420. package/templates/default/src/services/shared/errors.test.ts +38 -0
  421. package/templates/default/src/services/shared/errors.ts +44 -0
  422. package/templates/default/src/services/shared/index.ts +7 -0
  423. package/templates/default/src/services/tag/tag-service.test.ts +22 -0
  424. package/templates/default/src/services/tag/tag-service.ts +41 -0
  425. package/templates/default/src/services/template-step/template-step-service.test.ts +22 -0
  426. package/templates/default/src/services/template-step/template-step-service.ts +171 -0
  427. package/templates/default/src/services/template-step-group/template-step-group-service.test.ts +22 -0
  428. package/templates/default/src/services/template-step-group/template-step-group-service.ts +81 -0
  429. package/templates/default/src/services/template-test-case/template-test-case-service.test.ts +22 -0
  430. package/templates/default/src/services/template-test-case/template-test-case-service.ts +128 -0
  431. package/templates/default/src/services/test-case/test-case-service.test.ts +175 -0
  432. package/templates/default/src/services/test-case/test-case-service.ts +298 -0
  433. package/templates/default/src/services/test-run/test-run-helpers.ts +61 -0
  434. package/templates/default/src/services/test-run/test-run-service.test.ts +647 -0
  435. package/templates/default/src/services/test-run/test-run-service.ts +917 -0
  436. package/templates/default/src/services/test-suite/test-suite-service.test.ts +127 -0
  437. package/templates/default/src/services/test-suite/test-suite-service.ts +197 -0
  438. package/templates/default/src/types/diagram/diagram.ts +34 -34
  439. package/templates/default/src/types/diagram/template-step.ts +11 -11
  440. package/templates/default/src/types/executor/browser.type.ts +1 -1
  441. package/templates/default/src/types/form/actionHandler.ts +19 -6
  442. package/templates/default/src/types/locator/locator.type.ts +11 -11
  443. package/templates/default/src/types/step/step.type.ts +1 -1
  444. package/templates/default/src/types/table/data-table.ts +6 -6
  445. package/templates/default/tailwind.config.ts +62 -62
  446. package/templates/default/tsconfig.json +1 -1
  447. package/dist/cli.e2e.test.d.ts +0 -2
  448. package/dist/cli.e2e.test.d.ts.map +0 -1
  449. package/dist/cli.e2e.test.js +0 -73
  450. package/dist/cli.e2e.test.js.map +0 -1
  451. package/dist/config.test.d.ts +0 -2
  452. package/dist/config.test.d.ts.map +0 -1
  453. package/dist/config.test.js +0 -65
  454. package/dist/config.test.js.map +0 -1
  455. package/dist/copy-template.test.d.ts +0 -2
  456. package/dist/copy-template.test.d.ts.map +0 -1
  457. package/dist/copy-template.test.js +0 -71
  458. package/dist/copy-template.test.js.map +0 -1
  459. package/dist/download-repo.test.d.ts +0 -2
  460. package/dist/download-repo.test.d.ts.map +0 -1
  461. package/dist/download-repo.test.js +0 -14
  462. package/dist/download-repo.test.js.map +0 -1
  463. package/dist/install.test.d.ts +0 -2
  464. package/dist/install.test.d.ts.map +0 -1
  465. package/dist/install.test.js +0 -119
  466. package/dist/install.test.js.map +0 -1
  467. package/dist/prompts.test.d.ts +0 -2
  468. package/dist/prompts.test.d.ts.map +0 -1
  469. package/dist/prompts.test.js +0 -58
  470. package/dist/prompts.test.js.map +0 -1
  471. package/templates/default/src/actions/conflict/conflict.action.ts +0 -33
  472. package/templates/default/src/actions/review/review-actions.ts +0 -147
  473. package/templates/default/src/actions/user/user-actions.ts +0 -13
  474. package/templates/default/src/app/(base)/locators/locator-form.tsx +0 -163
  475. package/templates/default/src/app/(base)/reviews/create/page.tsx +0 -26
  476. package/templates/default/src/app/(base)/reviews/created-reviews-table.tsx +0 -15
  477. package/templates/default/src/app/(base)/reviews/modify/[id]/page.tsx +0 -26
  478. package/templates/default/src/app/(base)/reviews/page.tsx +0 -26
  479. package/templates/default/src/app/(base)/reviews/review/[id]/page.tsx +0 -26
  480. package/templates/default/src/app/(base)/reviews/review-form.tsx +0 -11
  481. package/templates/default/src/app/(base)/reviews/review-table-by-creator-columns.tsx +0 -9
  482. package/templates/default/src/app/(base)/reviews/review-table-by-reviewer-columns.tsx +0 -9
  483. package/templates/default/src/app/(base)/reviews/reviewer-reviews-table.tsx +0 -15
  484. package/templates/default/src/constants/form-opts/locator-form-opts.ts +0 -20
  485. package/templates/default/src/constants/form-opts/review-form-opts.ts +0 -23
@@ -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
+ }
@@ -0,0 +1,106 @@
1
+ import { describe, expect, it, vi } from 'vitest'
2
+ import { TestRunTestCaseResult } from '@prisma/client'
3
+ import { getTestSuiteExecutionData } from './dashboard-service'
4
+
5
+ vi.mock('@/config/db-config', () => ({
6
+ default: {
7
+ testRun: { findMany: vi.fn() },
8
+ report: { findMany: vi.fn() },
9
+ },
10
+ }))
11
+
12
+ import prisma from '@/config/db-config'
13
+
14
+ describe('getTestSuiteExecutionData', () => {
15
+ it('returns empty array when no completed test runs', async () => {
16
+ vi.mocked(prisma.testRun.findMany).mockResolvedValue([] as never)
17
+ await expect(getTestSuiteExecutionData()).resolves.toEqual([])
18
+ expect(prisma.report.findMany).not.toHaveBeenCalled()
19
+ })
20
+
21
+ it('aggregates per-suite counts from reports', async () => {
22
+ vi.mocked(prisma.testRun.findMany).mockResolvedValue([{ id: 'run-1' }] as never)
23
+ vi.mocked(prisma.report.findMany).mockResolvedValue([
24
+ {
25
+ id: 'rep-1',
26
+ testCases: [
27
+ {
28
+ testRunTestCase: {
29
+ result: TestRunTestCaseResult.PASSED,
30
+ testCase: {
31
+ TestSuite: [{ id: 'suite-a', name: 'Alpha' }],
32
+ },
33
+ },
34
+ },
35
+ {
36
+ testRunTestCase: {
37
+ result: TestRunTestCaseResult.FAILED,
38
+ testCase: {
39
+ TestSuite: [{ id: 'suite-a', name: 'Alpha' }],
40
+ },
41
+ },
42
+ },
43
+ {
44
+ testRunTestCase: {
45
+ result: TestRunTestCaseResult.UNTESTED,
46
+ testCase: {
47
+ TestSuite: [{ id: 'suite-b', name: 'Beta' }],
48
+ },
49
+ },
50
+ },
51
+ ],
52
+ },
53
+ ] as never)
54
+
55
+ const data = await getTestSuiteExecutionData()
56
+
57
+ expect(data).toHaveLength(2)
58
+ const alpha = data.find(d => d.feature === 'Alpha')
59
+ const beta = data.find(d => d.feature === 'Beta')
60
+ expect(alpha).toMatchObject({
61
+ passed: 1,
62
+ failed: 1,
63
+ cancelled: 0,
64
+ unknown: 0,
65
+ total: 2,
66
+ })
67
+ expect(beta).toMatchObject({
68
+ passed: 0,
69
+ failed: 0,
70
+ cancelled: 1,
71
+ unknown: 0,
72
+ total: 1,
73
+ })
74
+ })
75
+
76
+ it('maps non-pass/fail/untested results to unknown', async () => {
77
+ vi.mocked(prisma.testRun.findMany).mockResolvedValue([{ id: 'run-1' }] as never)
78
+ vi.mocked(prisma.report.findMany).mockResolvedValue([
79
+ {
80
+ id: 'rep-1',
81
+ testCases: [
82
+ {
83
+ testRunTestCase: {
84
+ result: 'OTHER' as TestRunTestCaseResult,
85
+ testCase: {
86
+ TestSuite: [{ id: 'suite-x', name: 'Gamma' }],
87
+ },
88
+ },
89
+ },
90
+ ],
91
+ },
92
+ ] as never)
93
+
94
+ const data = await getTestSuiteExecutionData()
95
+ expect(data).toEqual([
96
+ expect.objectContaining({
97
+ feature: 'Gamma',
98
+ passed: 0,
99
+ failed: 0,
100
+ cancelled: 0,
101
+ unknown: 1,
102
+ total: 1,
103
+ }),
104
+ ])
105
+ })
106
+ })
@@ -0,0 +1,173 @@
1
+ import prisma from '@/config/db-config'
2
+ import { TestRunStatus, TestRunTestCaseResult } from '@prisma/client'
3
+
4
+ /** Stacked bar segments are raw counts; `total` matches passed+failed+cancelled+unknown. */
5
+ export type TestSuiteExecutionData = Array<{
6
+ feature: string
7
+ passed: number
8
+ failed: number
9
+ cancelled: number
10
+ unknown: number
11
+ total: number
12
+ }>
13
+
14
+ export type EntityMetrics = {
15
+ testCasesCount: number
16
+ testSuitesCount: number
17
+ templateStepsCount: number
18
+ runningTestRunsCount: number
19
+ }
20
+
21
+ export async function getDashboardMetrics() {
22
+ return prisma.dashboardMetrics.findFirst()
23
+ }
24
+
25
+ export async function getEntityMetrics(): Promise<EntityMetrics> {
26
+ const testCases = await prisma.testCase.count()
27
+ const testSuites = await prisma.testSuite.count()
28
+ const templateSteps = await prisma.templateStep.count()
29
+ const runningTestRuns = await prisma.testRun.count({
30
+ where: {
31
+ status: {
32
+ in: [TestRunStatus.RUNNING, TestRunStatus.QUEUED, TestRunStatus.CANCELLING],
33
+ },
34
+ },
35
+ })
36
+
37
+ return {
38
+ testCasesCount: testCases,
39
+ testSuitesCount: testSuites,
40
+ templateStepsCount: templateSteps,
41
+ runningTestRunsCount: runningTestRuns,
42
+ }
43
+ }
44
+
45
+ export async function getRunningTestRunsCount(): Promise<number> {
46
+ return prisma.testRun.count({
47
+ where: {
48
+ status: {
49
+ in: [TestRunStatus.RUNNING, TestRunStatus.QUEUED, TestRunStatus.CANCELLING],
50
+ },
51
+ },
52
+ })
53
+ }
54
+
55
+ export async function getTestSuiteExecutionData(): Promise<TestSuiteExecutionData> {
56
+ const testRuns = await prisma.testRun.findMany({
57
+ where: {
58
+ status: TestRunStatus.COMPLETED,
59
+ completedAt: {
60
+ not: null,
61
+ },
62
+ },
63
+ orderBy: {
64
+ completedAt: 'desc',
65
+ },
66
+ take: 10,
67
+ select: {
68
+ id: true,
69
+ },
70
+ })
71
+
72
+ if (testRuns.length === 0) {
73
+ return []
74
+ }
75
+
76
+ const testRunIds = testRuns.map(tr => tr.id)
77
+
78
+ const reports = await prisma.report.findMany({
79
+ where: {
80
+ testRunId: {
81
+ in: testRunIds,
82
+ },
83
+ },
84
+ include: {
85
+ testCases: {
86
+ include: {
87
+ testRunTestCase: {
88
+ include: {
89
+ testCase: {
90
+ include: {
91
+ TestSuite: true,
92
+ },
93
+ },
94
+ },
95
+ },
96
+ },
97
+ },
98
+ },
99
+ })
100
+
101
+ const suiteDataMap = new Map<
102
+ string,
103
+ {
104
+ name: string
105
+ passed: number
106
+ failed: number
107
+ cancelled: number
108
+ unknown: number
109
+ total: number
110
+ }
111
+ >()
112
+
113
+ for (const report of reports) {
114
+ for (const reportTestCase of report.testCases) {
115
+ const testCase = reportTestCase.testRunTestCase.testCase
116
+ const result = reportTestCase.testRunTestCase.result
117
+
118
+ for (const testSuite of testCase.TestSuite) {
119
+ const suiteId = testSuite.id
120
+ const suiteName = testSuite.name
121
+
122
+ if (!suiteDataMap.has(suiteId)) {
123
+ suiteDataMap.set(suiteId, {
124
+ name: suiteName,
125
+ passed: 0,
126
+ failed: 0,
127
+ cancelled: 0,
128
+ unknown: 0,
129
+ total: 0,
130
+ })
131
+ }
132
+
133
+ const suiteData = suiteDataMap.get(suiteId)!
134
+ suiteData.total++
135
+
136
+ switch (result) {
137
+ case TestRunTestCaseResult.PASSED:
138
+ suiteData.passed++
139
+ break
140
+ case TestRunTestCaseResult.FAILED:
141
+ suiteData.failed++
142
+ break
143
+ case TestRunTestCaseResult.UNTESTED:
144
+ suiteData.cancelled++
145
+ break
146
+ default:
147
+ suiteData.unknown++
148
+ break
149
+ }
150
+ }
151
+ }
152
+ }
153
+
154
+ const result: TestSuiteExecutionData = []
155
+
156
+ for (const [, data] of suiteDataMap.entries()) {
157
+ const total = data.total
158
+ if (total === 0) continue
159
+
160
+ result.push({
161
+ feature: data.name,
162
+ passed: data.passed,
163
+ failed: data.failed,
164
+ cancelled: data.cancelled,
165
+ unknown: data.unknown,
166
+ total,
167
+ })
168
+ }
169
+
170
+ result.sort((a, b) => a.feature.localeCompare(b.feature))
171
+
172
+ return result
173
+ }