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
@@ -6,54 +6,19 @@
6
6
  * Filesystem is the source of truth - steps in DB but not in FS will be deleted
7
7
  * Run this after merging changes to ensure template step sync
8
8
  *
9
- * Usage: npx tsx scripts/template-step-sync.ts
9
+ * Usage: npx tsx scripts/sync-template-steps.ts
10
10
  */
11
11
 
12
12
  import { promises as fs } from 'fs'
13
13
  import { join } from 'path'
14
14
  import { glob } from 'glob'
15
- import { parse } from '@babel/parser'
16
- import * as t from '@babel/types'
17
- import _traverse from '@babel/traverse'
18
- import type { NodePath } from '@babel/traverse'
19
15
  import prettier from 'prettier'
20
16
 
21
- // Handle both ESM and CJS exports
22
- const traverse = (_traverse as { default?: typeof _traverse }).default ?? _traverse
23
17
  import prisma from '../src/config/db-config'
24
- import { TemplateStepGroupType, TemplateStepType, TemplateStepIcon, StepParameterType } from '@prisma/client'
25
-
26
- interface StepGroupJSDoc {
27
- name: string
28
- description: string | null
29
- type: TemplateStepGroupType
30
- }
31
-
32
- interface StepJSDoc {
33
- name: string
34
- description: string | null
35
- icon: TemplateStepIcon
36
- }
37
-
38
- interface StepParameter {
39
- name: string
40
- type: StepParameterType
41
- order: number
42
- }
43
-
44
- interface ParsedStep {
45
- jsdoc: StepJSDoc
46
- signature: string
47
- functionDefinition: string
48
- parameters: StepParameter[]
49
- keyword: 'When' | 'Then' | 'Given'
50
- }
51
-
52
- interface StepData {
53
- group: StepGroupJSDoc
54
- steps: ParsedStep[]
55
- filePath: string
56
- }
18
+ import { TemplateStepGroupType, TemplateStepType } from '@prisma/client'
19
+ import { parseStepFile, ParsedStep } from './lib/step-file-parser'
20
+ import { printSyncSummary } from './lib/sync-summary'
21
+ import { runSyncScript } from './lib/sync-script-runner'
57
22
 
58
23
  interface SyncResult {
59
24
  stepsScanned: number
@@ -79,6 +44,8 @@ async function normalizeFunctionDefinition(functionDefinition: string | null | u
79
44
  }
80
45
 
81
46
  try {
47
+ // Persisting a normalized definition avoids false-positive updates caused by
48
+ // formatting-only drift between source files and stored DB representation.
82
49
  return (
83
50
  await prettier.format(source, {
84
51
  parser: 'typescript',
@@ -94,399 +61,6 @@ async function normalizeFunctionDefinition(functionDefinition: string | null | u
94
61
  }
95
62
  }
96
63
 
97
- /**
98
- * Parses JSDoc comment to extract step group metadata
99
- * Reused from template-step-group-sync.ts
100
- */
101
- function parseGroupJSDoc(content: string): StepGroupJSDoc | null {
102
- const lines = content.split('\n')
103
-
104
- if (lines.length === 0) {
105
- return null
106
- }
107
-
108
- let startLine = 0
109
- while (startLine < lines.length) {
110
- const line = lines[startLine].trim()
111
- if (line === '' || line.startsWith('import ')) {
112
- startLine++
113
- continue
114
- }
115
- break
116
- }
117
-
118
- if (startLine >= lines.length || !lines[startLine].trim().startsWith('/**')) {
119
- return null
120
- }
121
-
122
- let hasType = false
123
- let endLine = -1
124
- let name: string | null = null
125
- let description: string | null = null
126
- let type: string | null = null
127
-
128
- const maxLines = Math.min(lines.length, startLine + 50)
129
- for (let i = startLine; i < maxLines; i++) {
130
- const line = lines[i].trim()
131
-
132
- if (line.includes('*/')) {
133
- const beforeClose = line.split('*/')[0].trim()
134
-
135
- if (beforeClose.startsWith('* @name') || beforeClose.startsWith('*@name')) {
136
- const match = beforeClose.match(/@name\s+(.+)/)
137
- if (match) {
138
- name = match[1].trim()
139
- }
140
- } else if (beforeClose.startsWith('* @description') || beforeClose.startsWith('*@description')) {
141
- const match = beforeClose.match(/@description\s+(.+)/)
142
- if (match) {
143
- description = match[1].trim() || null
144
- }
145
- } else if (beforeClose.startsWith('* @type') || beforeClose.startsWith('*@type')) {
146
- hasType = true
147
- const match = beforeClose.match(/@type\s+(.+)/)
148
- if (match) {
149
- type = match[1].trim()
150
- }
151
- }
152
-
153
- endLine = i
154
- break
155
- } else if (line.startsWith('* @name') || line.startsWith('*@name')) {
156
- const match = line.match(/@name\s+(.+)/)
157
- if (match) {
158
- name = match[1].trim()
159
- }
160
- } else if (line.startsWith('* @description') || line.startsWith('*@description')) {
161
- const match = line.match(/@description\s+(.+)/)
162
- if (match) {
163
- description = match[1].trim() || null
164
- }
165
- } else if (line.startsWith('* @type') || line.startsWith('*@type')) {
166
- hasType = true
167
- const match = line.match(/@type\s+(.+)/)
168
- if (match) {
169
- type = match[1].trim()
170
- }
171
- }
172
- }
173
-
174
- if (hasType && endLine >= 0 && name && type) {
175
- const normalizedType = type.toUpperCase()
176
- if (normalizedType !== 'ACTION' && normalizedType !== 'VALIDATION') {
177
- throw new Error(`Invalid @type value: ${type}. Must be ACTION or VALIDATION`)
178
- }
179
-
180
- return {
181
- name: name.trim(),
182
- description: description ? description.trim() : null,
183
- type: normalizedType as TemplateStepGroupType,
184
- }
185
- }
186
-
187
- return null
188
- }
189
-
190
- /**
191
- * Parses JSDoc comment to extract step metadata
192
- */
193
- function parseStepJSDoc(content: string, startLine: number): StepJSDoc | null {
194
- const lines = content.split('\n')
195
-
196
- // Look backwards from startLine for JSDoc comment
197
- // startLine is 0-based (line number - 1)
198
- let jsdocStart = -1
199
- for (let i = startLine - 1; i >= 0 && i >= startLine - 20; i--) {
200
- const line = lines[i]?.trim()
201
- // Check for end of JSDoc (could be on its own line or with content)
202
- if (line?.includes('*/')) {
203
- // Found end, now find start
204
- jsdocStart = i
205
- // Look backwards for the start
206
- for (let j = i - 1; j >= 0 && j >= i - 10; j--) {
207
- const prevLine = lines[j]?.trim()
208
- if (prevLine?.startsWith('/**')) {
209
- jsdocStart = j
210
- break
211
- }
212
- }
213
- break
214
- } else if (line?.startsWith('/**')) {
215
- jsdocStart = i
216
- break
217
- }
218
- }
219
-
220
- if (jsdocStart === -1) {
221
- return null
222
- }
223
-
224
- let name: string | null = null
225
- let description: string | null = null
226
- let icon: string | null = null
227
- let foundJSDoc = false
228
-
229
- for (let i = jsdocStart; i < Math.min(lines.length, jsdocStart + 20); i++) {
230
- const line = lines[i]?.trim()
231
-
232
- if (line?.startsWith('/**')) {
233
- foundJSDoc = true
234
- continue
235
- }
236
-
237
- if (line?.includes('*/')) {
238
- const beforeClose = line.split('*/')[0].trim()
239
- if (beforeClose.startsWith('* @name') || beforeClose.startsWith('*@name')) {
240
- const match = beforeClose.match(/@name\s+(.+)/)
241
- if (match) {
242
- name = match[1].trim()
243
- }
244
- } else if (beforeClose.startsWith('* @description') || beforeClose.startsWith('*@description')) {
245
- const match = beforeClose.match(/@description\s+(.+)/)
246
- if (match) {
247
- description = match[1].trim() || null
248
- }
249
- } else if (beforeClose.startsWith('* @icon') || beforeClose.startsWith('*@icon')) {
250
- const match = beforeClose.match(/@icon\s+(.+)/)
251
- if (match) {
252
- icon = match[1].trim()
253
- }
254
- }
255
- break
256
- }
257
-
258
- if (foundJSDoc) {
259
- if (line?.startsWith('* @name') || line?.startsWith('*@name')) {
260
- const match = line.match(/@name\s+(.+)/)
261
- if (match) {
262
- name = match[1].trim()
263
- }
264
- } else if (line?.startsWith('* @description') || line?.startsWith('*@description')) {
265
- const match = line.match(/@description\s+(.+)/)
266
- if (match) {
267
- description = match[1].trim() || null
268
- }
269
- } else if (line?.startsWith('* @icon') || line?.startsWith('*@icon')) {
270
- const match = line.match(/@icon\s+(.+)/)
271
- if (match) {
272
- icon = match[1].trim()
273
- }
274
- }
275
- }
276
- }
277
-
278
- if (!name || !icon) {
279
- return null
280
- }
281
-
282
- // Validate icon
283
- const iconUpper = icon.toUpperCase()
284
- const validIcons = Object.values(TemplateStepIcon)
285
- if (!validIcons.includes(iconUpper as TemplateStepIcon)) {
286
- throw new Error(`Invalid @icon value: ${icon}. Must be one of: ${validIcons.join(', ')}`)
287
- }
288
-
289
- return {
290
- name: name.trim(),
291
- description: description ? description.trim() : null,
292
- icon: iconUpper as TemplateStepIcon,
293
- }
294
- }
295
-
296
- /**
297
- * Maps TypeScript type to StepParameterType
298
- * Strict mode - throws error for unsupported types
299
- */
300
- function mapTypeToParameterType(typeName: string): StepParameterType {
301
- const normalized = typeName.trim()
302
-
303
- if (normalized === 'SelectorName') {
304
- return StepParameterType.LOCATOR
305
- }
306
- if (normalized === 'string') {
307
- return StepParameterType.STRING
308
- }
309
- if (normalized === 'number' || normalized === 'int') {
310
- return StepParameterType.NUMBER
311
- }
312
- if (normalized === 'boolean') {
313
- return StepParameterType.BOOLEAN
314
- }
315
- if (normalized === 'Date') {
316
- return StepParameterType.DATE
317
- }
318
-
319
- throw new Error(
320
- `Unsupported parameter type: ${typeName}. Supported types: SelectorName, string, number, int, boolean, Date`,
321
- )
322
- }
323
-
324
- /**
325
- * Extracts function definition code from AST node
326
- * Returns the complete When/Then/Given call with function, without JSDoc
327
- * Format: When('pattern', async function(this:CustomWorld, param: type){})
328
- */
329
- function extractFunctionDefinition(callExpr: t.CallExpression, keyword: string, sourceCode: string): string {
330
- // Get the source code for the entire call expression
331
- const start = callExpr.start
332
- const end = callExpr.end
333
-
334
- if (start == null || end == null) {
335
- throw new Error('Cannot extract function definition: missing position information')
336
- }
337
-
338
- // Extract the code - Babel's end position includes the closing parenthesis
339
- // After the null check, TypeScript knows start and end are numbers
340
- let code = sourceCode.slice(start, end).trim()
341
-
342
- // Check if there's a semicolon immediately after (some files have it, some don't)
343
- // Only add if it's clearly there in the source
344
- const afterEnd = sourceCode.slice(end, end + 10).trim()
345
- if (afterEnd.startsWith(';')) {
346
- code += ';'
347
- }
348
-
349
- return code
350
- }
351
-
352
- /**
353
- * Parses a step definition file to extract steps
354
- */
355
- function parseStepFile(content: string, filePath: string): StepData | null {
356
- const group = parseGroupJSDoc(content)
357
- if (!group) {
358
- return null
359
- }
360
-
361
- // Parse TypeScript AST
362
- let ast
363
- try {
364
- ast = parse(content, {
365
- sourceType: 'module',
366
- plugins: ['typescript', 'decorators-legacy'],
367
- })
368
- } catch (error) {
369
- throw new Error(`Failed to parse TypeScript: ${error}`)
370
- }
371
-
372
- const steps: ParsedStep[] = []
373
-
374
- // Traverse the AST to find When/Then/Given calls
375
- traverse(ast, {
376
- CallExpression(path: NodePath<t.CallExpression>) {
377
- const node = path.node
378
- const callee = node.callee
379
-
380
- // Check if this is a When, Then, or Given call
381
- let keyword: 'When' | 'Then' | 'Given' | null = null
382
- if (t.isIdentifier(callee)) {
383
- if (callee.name === 'When' || callee.name === 'Then' || callee.name === 'Given') {
384
- keyword = callee.name as 'When' | 'Then' | 'Given'
385
- }
386
- }
387
-
388
- if (!keyword || node.arguments.length < 2) {
389
- return
390
- }
391
-
392
- // Extract Gherkin pattern (first argument - should be a string)
393
- const patternArg = node.arguments[0]
394
- if (!t.isStringLiteral(patternArg)) {
395
- return
396
- }
397
- const signature = patternArg.value
398
-
399
- // Extract function (second argument)
400
- const funcArg = node.arguments[1]
401
- if (!t.isFunction(funcArg)) {
402
- return
403
- }
404
-
405
- // Get line number for JSDoc lookup (Babel uses 1-based line numbers)
406
- const lineNumber = node.loc?.start?.line
407
- if (lineNumber === undefined) {
408
- return
409
- }
410
-
411
- // Parse step JSDoc (convert to 0-based for array indexing)
412
- const jsdoc = parseStepJSDoc(content, lineNumber - 1)
413
- if (!jsdoc) {
414
- return // Skip steps without JSDoc
415
- }
416
-
417
- // Extract parameters
418
- const parameters: StepParameter[] = []
419
- if (t.isFunction(funcArg) && funcArg.params) {
420
- let order = 0
421
- for (const param of funcArg.params) {
422
- // Skip 'this: CustomWorld' parameter
423
- if (t.isIdentifier(param) && param.name === 'this') {
424
- continue
425
- }
426
- if (t.isObjectPattern(param) && param.properties.length === 1) {
427
- const prop = param.properties[0]
428
- if (t.isObjectProperty(prop) && t.isIdentifier(prop.key) && prop.key.name === 'this') {
429
- continue
430
- }
431
- }
432
-
433
- let paramName: string | null = null
434
- let paramType: string | null = null
435
-
436
- if (t.isIdentifier(param)) {
437
- paramName = param.name
438
- if (param.typeAnnotation && t.isTSTypeAnnotation(param.typeAnnotation)) {
439
- const typeAnnotation = param.typeAnnotation.typeAnnotation
440
- if (t.isTSTypeReference(typeAnnotation) && t.isIdentifier(typeAnnotation.typeName)) {
441
- paramType = typeAnnotation.typeName.name
442
- } else if (t.isTSStringKeyword(typeAnnotation)) {
443
- paramType = 'string'
444
- } else if (t.isTSNumberKeyword(typeAnnotation)) {
445
- paramType = 'number'
446
- } else if (t.isTSBooleanKeyword(typeAnnotation)) {
447
- paramType = 'boolean'
448
- }
449
- }
450
- } else if (t.isObjectPattern(param)) {
451
- // Handle destructured parameters (unlikely but possible)
452
- continue
453
- }
454
-
455
- if (paramName && paramType) {
456
- try {
457
- const mappedType = mapTypeToParameterType(paramType)
458
- parameters.push({
459
- name: paramName,
460
- type: mappedType,
461
- order: order++,
462
- })
463
- } catch (error) {
464
- throw new Error(`Error mapping parameter type in step "${signature}": ${error}`)
465
- }
466
- }
467
- }
468
- }
469
-
470
- // Extract function definition
471
- const functionDefinition = extractFunctionDefinition(node, keyword, content)
472
-
473
- steps.push({
474
- jsdoc,
475
- signature,
476
- functionDefinition,
477
- parameters,
478
- keyword,
479
- })
480
- },
481
- })
482
-
483
- return {
484
- group,
485
- steps,
486
- filePath,
487
- }
488
- }
489
-
490
64
  /**
491
65
  * Scans step definition files
492
66
  */
@@ -522,7 +96,7 @@ async function syncStepsToDatabase(
522
96
  deletedSteps: [],
523
97
  }
524
98
 
525
- // Track signatures from filesystem
99
+ // Signature is treated as the stable sync identity for template steps.
526
100
  const fsSignatures = new Set<string>()
527
101
 
528
102
  // Process each step
@@ -692,49 +266,7 @@ async function syncStepsToDatabase(
692
266
  /**
693
267
  * Generates and displays sync summary
694
268
  */
695
- function generateSummary(result: SyncResult): void {
696
- console.log('\nšŸ“Š Sync Summary:')
697
- console.log(` šŸ“ Steps scanned: ${result.stepsScanned}`)
698
- console.log(` āœ… Steps existing: ${result.stepsExisting}`)
699
- console.log(` āž• Steps created: ${result.stepsCreated}`)
700
- console.log(` šŸ”„ Steps updated: ${result.stepsUpdated}`)
701
- console.log(` šŸ—‘ļø Steps deleted: ${result.stepsDeleted}`)
702
- console.log(` āŒ Errors: ${result.errors.length}`)
703
-
704
- if (result.createdSteps.length > 0) {
705
- console.log('\n Created steps:')
706
- result.createdSteps.forEach((step, index) => {
707
- console.log(` ${index + 1}. ${step.name} (${step.signature}) [${step.group}]`)
708
- })
709
- }
710
-
711
- if (result.updatedSteps.length > 0) {
712
- console.log('\n Updated steps:')
713
- result.updatedSteps.forEach((step, index) => {
714
- console.log(` ${index + 1}. ${step.name} (${step.signature}) [${step.group}]`)
715
- })
716
- }
717
-
718
- if (result.deletedSteps.length > 0) {
719
- console.log('\n Deleted steps:')
720
- result.deletedSteps.forEach((step, index) => {
721
- console.log(` ${index + 1}. ${step.name} (${step.signature}) [${step.group}]`)
722
- })
723
- }
724
-
725
- if (result.errors.length > 0) {
726
- console.log('\n Errors:')
727
- result.errors.forEach((error, index) => {
728
- console.log(` ${index + 1}. ${error}`)
729
- })
730
- }
731
- }
732
-
733
- /**
734
- * Main function
735
- */
736
- async function main() {
737
- try {
269
+ async function main(): Promise<SyncResult | void> {
738
270
  console.log('šŸ”„ Starting template step sync...')
739
271
  console.log('This will scan step definition files and sync template steps to database.')
740
272
  console.log('Filesystem is the source of truth - steps in DB but not in FS will be deleted.\n')
@@ -823,21 +355,32 @@ async function main() {
823
355
  // Add parsing errors to result
824
356
  result.errors.push(...errors)
825
357
 
826
- // Generate summary
827
- generateSummary(result)
828
-
829
- if (result.errors.length === 0) {
830
- console.log('\nāœ… Sync completed successfully!')
831
- } else {
832
- console.log('\nāš ļø Sync completed with errors. Please review the errors above.')
833
- process.exit(1)
834
- }
835
- } catch (error) {
836
- console.error('\nāŒ Error during sync:', error)
837
- process.exit(1)
838
- } finally {
839
- await prisma.$disconnect()
840
- }
358
+ printSyncSummary(
359
+ [
360
+ { label: 'šŸ“ Steps scanned', value: result.stepsScanned },
361
+ { label: 'āœ… Steps existing', value: result.stepsExisting },
362
+ { label: 'āž• Steps created', value: result.stepsCreated },
363
+ { label: 'šŸ”„ Steps updated', value: result.stepsUpdated },
364
+ { label: 'šŸ—‘ļø Steps deleted', value: result.stepsDeleted },
365
+ { label: 'āŒ Errors', value: result.errors.length },
366
+ ],
367
+ [
368
+ {
369
+ title: 'Created steps',
370
+ items: result.createdSteps.map(step => `${step.name} (${step.signature}) [${step.group}]`),
371
+ },
372
+ {
373
+ title: 'Updated steps',
374
+ items: result.updatedSteps.map(step => `${step.name} (${step.signature}) [${step.group}]`),
375
+ },
376
+ {
377
+ title: 'Deleted steps',
378
+ items: result.deletedSteps.map(step => `${step.name} (${step.signature}) [${step.group}]`),
379
+ },
380
+ { title: 'Errors', items: result.errors },
381
+ ],
382
+ )
383
+ return result
841
384
  }
842
385
 
843
- main()
386
+ runSyncScript(main)