create-appraisejs 0.2.0-alpha.6 → 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 +13 -11
  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,38 +1,51 @@
1
- #!/usr/bin/env tsx
2
-
3
- import fs from 'fs'
4
- import path from 'path'
5
-
6
- const SEEDED_TEMPLATE_PATHS = ['prisma/dev.db', 'automation/config/environments/environments.json']
7
-
8
- function trimTrailingBlankLines(lines: string[]): string[] {
9
- const trimmed = [...lines]
10
- while (trimmed.length > 0 && trimmed[trimmed.length - 1] === '') {
11
- trimmed.pop()
12
- }
13
- return trimmed
14
- }
15
-
16
- function setSeededTemplateFilesTracked(content: string, tracked: boolean): string {
17
- const managedLines = new Set(SEEDED_TEMPLATE_PATHS.flatMap(filePath => [filePath, `!${filePath}`]))
18
- const lines = trimTrailingBlankLines(content.split(/\r?\n/)).filter(line => !managedLines.has(line.trim()))
19
-
20
- for (const filePath of SEEDED_TEMPLATE_PATHS) {
21
- lines.push(tracked ? `!${filePath}` : filePath)
22
- }
23
-
24
- return `${lines.join('\n')}\n`
25
- }
26
-
27
- const gitignorePath = path.join(process.cwd(), '.gitignore')
28
- const packagedGitignorePath = path.join(process.cwd(), 'gitignore')
29
- const sourceGitignorePath = fs.existsSync(gitignorePath) ? gitignorePath : packagedGitignorePath
30
- const currentGitignore = fs.existsSync(sourceGitignorePath) ? fs.readFileSync(sourceGitignorePath, 'utf8') : ''
31
-
32
- fs.writeFileSync(gitignorePath, setSeededTemplateFilesTracked(currentGitignore, false))
33
-
34
- if (sourceGitignorePath === packagedGitignorePath && fs.existsSync(packagedGitignorePath)) {
35
- fs.rmSync(packagedGitignorePath, { force: true })
36
- }
37
-
38
- console.log('Updated .gitignore to ignore seeded local files.')
1
+ #!/usr/bin/env tsx
2
+
3
+ import fs from 'fs'
4
+ import path from 'path'
5
+
6
+ const SEEDED_TEMPLATE_PATHS = ['prisma/dev.db', 'automation/config/environments/environments.json']
7
+
8
+ /**
9
+ * Trims trailing blank lines while preserving internal spacing.
10
+ */
11
+ function trimTrailingBlankLines(lines: string[]): string[] {
12
+ const trimmed = [...lines]
13
+ while (trimmed.length > 0 && trimmed[trimmed.length - 1] === '') {
14
+ trimmed.pop()
15
+ }
16
+ return trimmed
17
+ }
18
+
19
+ /**
20
+ * Rewrites `.gitignore` content to enforce seeded-template tracking rules.
21
+ */
22
+ function setSeededTemplateFilesTracked(content: string, tracked: boolean): string {
23
+ const managedLines = new Set(SEEDED_TEMPLATE_PATHS.flatMap(filePath => [filePath, `!${filePath}`]))
24
+ const lines = trimTrailingBlankLines(content.split(/\r?\n/)).filter(line => !managedLines.has(line.trim()))
25
+
26
+ for (const filePath of SEEDED_TEMPLATE_PATHS) {
27
+ lines.push(tracked ? `!${filePath}` : filePath)
28
+ }
29
+
30
+ return `${lines.join('\n')}\n`
31
+ }
32
+
33
+ /**
34
+ * Updates `.gitignore` so seeded local files stay ignored.
35
+ */
36
+ function main(): void {
37
+ const gitignorePath = path.join(process.cwd(), '.gitignore')
38
+ const packagedGitignorePath = path.join(process.cwd(), 'gitignore')
39
+ const sourceGitignorePath = fs.existsSync(gitignorePath) ? gitignorePath : packagedGitignorePath
40
+ const currentGitignore = fs.existsSync(sourceGitignorePath) ? fs.readFileSync(sourceGitignorePath, 'utf8') : ''
41
+
42
+ fs.writeFileSync(gitignorePath, setSeededTemplateFilesTracked(currentGitignore, false))
43
+
44
+ if (sourceGitignorePath === packagedGitignorePath && fs.existsSync(packagedGitignorePath)) {
45
+ fs.rmSync(packagedGitignorePath, { force: true })
46
+ }
47
+
48
+ console.log('Updated .gitignore to ignore seeded local files.')
49
+ }
50
+
51
+ main()
@@ -1,94 +1,98 @@
1
- #!/usr/bin/env tsx
2
-
3
- /**
4
- * Script to synchronize feature files between database and filesystem
5
- * This performs bidirectional sync - both DB->FS and FS->DB
6
- * Run this after merging changes or database migrations to ensure sync
7
- *
8
- * Usage: npx tsx scripts/regenerate-features.ts [--dry-run]
9
- */
10
-
11
- import { performBidirectionalSync, performDryRunSync } from '../src/lib/bidirectional-sync'
12
- import { join } from 'path'
13
-
14
- async function main() {
15
- try {
16
- const isDryRun = process.argv.includes('--dry-run')
17
- const featuresBaseDir = join(process.cwd(), 'src', 'tests', 'features')
18
-
19
- if (isDryRun) {
20
- console.log('šŸ” Performing dry run of bidirectional sync...')
21
- console.log('This will show what would be changed without making any modifications.\n')
22
-
23
- const dryRunResult = await performDryRunSync(featuresBaseDir)
24
-
25
- console.log('\nšŸ“Š Dry run results:')
26
- console.log(`šŸ“ Would generate ${dryRunResult.wouldGenerate.length} feature files:`)
27
- dryRunResult.wouldGenerate.forEach((filePath, index) => {
28
- const relativePath = filePath.replace(process.cwd(), '.')
29
- console.log(` ${index + 1}. ${relativePath}`)
30
- })
31
-
32
- console.log(`\nšŸ”„ Would update ${dryRunResult.wouldUpdate.length} feature files:`)
33
- dryRunResult.wouldUpdate.forEach((filePath, index) => {
34
- const relativePath = filePath.replace(process.cwd(), '.')
35
- console.log(` ${index + 1}. ${relativePath}`)
36
- })
37
-
38
- console.log(`\nāž• Would create ${dryRunResult.wouldCreate.testSuites.length} test suites:`)
39
- dryRunResult.wouldCreate.testSuites.forEach((item, index) => {
40
- console.log(` ${index + 1}. ${item}`)
41
- })
42
-
43
- console.log(`\nšŸ“ Would create ${dryRunResult.wouldCreate.testCases.length} test cases:`)
44
- dryRunResult.wouldCreate.testCases.forEach((item, index) => {
45
- console.log(` ${index + 1}. ${item}`)
46
- })
47
-
48
- console.log(`\nšŸ”§ Would create ${dryRunResult.wouldCreate.templateSteps.length} template steps:`)
49
- dryRunResult.wouldCreate.templateSteps.forEach((item, index) => {
50
- console.log(` ${index + 1}. ${item}`)
51
- })
52
-
53
- console.log(`\nšŸ·ļø Would create ${dryRunResult.wouldCreate.tags.length} tags:`)
54
- dryRunResult.wouldCreate.tags.forEach((tag, index) => {
55
- console.log(` ${index + 1}. ${tag}`)
56
- })
57
-
58
- console.log('\nšŸ’” To perform the actual sync, run without --dry-run flag')
59
- } else {
60
- console.log('šŸ”„ Starting bidirectional sync between database and feature files...')
61
- console.log('This will sync both directions:')
62
- console.log(' šŸ“ Feature files → Database (create missing test suites/cases)')
63
- console.log(' šŸ—„ļø Database → Feature files (generate/update feature files)')
64
- console.log('')
65
-
66
- const syncResult = await performBidirectionalSync(featuresBaseDir)
67
-
68
- console.log('\nāœ… Bidirectional sync completed successfully!')
69
- console.log(`šŸ“Š Summary:`)
70
- console.log(` šŸ“ Generated feature files: ${syncResult.generatedFeatureFiles}`)
71
- console.log(` šŸ”„ Updated feature files: ${syncResult.updatedFeatureFiles}`)
72
- console.log(` šŸ—„ļø Merged test suites: ${syncResult.mergedTestSuites}`)
73
- console.log(` šŸ“ Added scenarios: ${syncResult.addedScenarios}`)
74
- console.log(` šŸ“Š Total processed: ${syncResult.totalProcessed}`)
75
-
76
- if (syncResult.errors.length > 0) {
77
- console.log(`\nāš ļø Errors encountered: ${syncResult.errors.length}`)
78
- syncResult.errors.forEach((error, index) => {
79
- console.log(` ${index + 1}. ${error}`)
80
- })
81
- }
82
-
83
- console.log('\nšŸ’” Tips:')
84
- console.log(' - Run with --dry-run to see what would be changed')
85
- console.log(' - This script is safe to run multiple times')
86
- console.log(' - Changes are automatically merged, not overwritten')
87
- }
88
- } catch (error) {
89
- console.error('\nāŒ Error during sync:', error)
90
- process.exit(1)
91
- }
92
- }
93
-
94
- main()
1
+ #!/usr/bin/env tsx
2
+
3
+ /**
4
+ * Script to synchronize feature files between database and filesystem
5
+ * This performs bidirectional sync - both DB->FS and FS->DB
6
+ * Run this after merging changes or database migrations to ensure sync
7
+ *
8
+ * Usage: npx tsx scripts/regenerate-features.ts [--dry-run]
9
+ */
10
+
11
+ import { performBidirectionalSync, performDryRunSync } from '../src/lib/bidirectional-sync'
12
+ import { ensureAutomationWorkspaceReady, getAutomationFeaturesDir } from '../src/lib/automation/paths'
13
+
14
+ /**
15
+ * Runs bidirectional feature sync in dry-run or apply mode.
16
+ */
17
+ async function main(): Promise<void> {
18
+ try {
19
+ const isDryRun = process.argv.includes('--dry-run')
20
+ await ensureAutomationWorkspaceReady()
21
+ const featuresBaseDir = getAutomationFeaturesDir()
22
+
23
+ if (isDryRun) {
24
+ console.log('šŸ” Performing dry run of bidirectional sync...')
25
+ console.log('This will show what would be changed without making any modifications.\n')
26
+
27
+ const dryRunResult = await performDryRunSync(featuresBaseDir)
28
+
29
+ console.log('\nšŸ“Š Dry run results:')
30
+ console.log(`šŸ“ Would generate ${dryRunResult.wouldGenerate.length} feature files:`)
31
+ dryRunResult.wouldGenerate.forEach((filePath, index) => {
32
+ const relativePath = filePath.replace(process.cwd(), '.')
33
+ console.log(` ${index + 1}. ${relativePath}`)
34
+ })
35
+
36
+ console.log(`\nšŸ”„ Would update ${dryRunResult.wouldUpdate.length} feature files:`)
37
+ dryRunResult.wouldUpdate.forEach((filePath, index) => {
38
+ const relativePath = filePath.replace(process.cwd(), '.')
39
+ console.log(` ${index + 1}. ${relativePath}`)
40
+ })
41
+
42
+ console.log(`\nāž• Would create ${dryRunResult.wouldCreate.testSuites.length} test suites:`)
43
+ dryRunResult.wouldCreate.testSuites.forEach((item, index) => {
44
+ console.log(` ${index + 1}. ${item}`)
45
+ })
46
+
47
+ console.log(`\nšŸ“ Would create ${dryRunResult.wouldCreate.testCases.length} test cases:`)
48
+ dryRunResult.wouldCreate.testCases.forEach((item, index) => {
49
+ console.log(` ${index + 1}. ${item}`)
50
+ })
51
+
52
+ console.log(`\nšŸ”§ Would create ${dryRunResult.wouldCreate.templateSteps.length} template steps:`)
53
+ dryRunResult.wouldCreate.templateSteps.forEach((item, index) => {
54
+ console.log(` ${index + 1}. ${item}`)
55
+ })
56
+
57
+ console.log(`\nšŸ·ļø Would create ${dryRunResult.wouldCreate.tags.length} tags:`)
58
+ dryRunResult.wouldCreate.tags.forEach((tag, index) => {
59
+ console.log(` ${index + 1}. ${tag}`)
60
+ })
61
+
62
+ console.log('\nšŸ’” To perform the actual sync, run without --dry-run flag')
63
+ } else {
64
+ console.log('šŸ”„ Starting bidirectional sync between database and feature files...')
65
+ console.log('This will sync both directions:')
66
+ console.log(' šŸ“ Feature files → Database (create missing test suites/cases)')
67
+ console.log(' šŸ—„ļø Database → Feature files (generate/update feature files)')
68
+ console.log('')
69
+
70
+ const syncResult = await performBidirectionalSync(featuresBaseDir)
71
+
72
+ console.log('\nāœ… Bidirectional sync completed successfully!')
73
+ console.log(`šŸ“Š Summary:`)
74
+ console.log(` šŸ“ Generated feature files: ${syncResult.generatedFeatureFiles}`)
75
+ console.log(` šŸ”„ Updated feature files: ${syncResult.updatedFeatureFiles}`)
76
+ console.log(` šŸ—„ļø Merged test suites: ${syncResult.mergedTestSuites}`)
77
+ console.log(` šŸ“ Added scenarios: ${syncResult.addedScenarios}`)
78
+ console.log(` šŸ“Š Total processed: ${syncResult.totalProcessed}`)
79
+
80
+ if (syncResult.errors.length > 0) {
81
+ console.log(`\nāš ļø Errors encountered: ${syncResult.errors.length}`)
82
+ syncResult.errors.forEach((error, index) => {
83
+ console.log(` ${index + 1}. ${error}`)
84
+ })
85
+ }
86
+
87
+ console.log('\nšŸ’” Tips:')
88
+ console.log(' - Run with --dry-run to see what would be changed')
89
+ console.log(' - This script is safe to run multiple times')
90
+ console.log(' - Changes are automatically merged, not overwritten')
91
+ }
92
+ } catch (error) {
93
+ console.error('\nāŒ Error during sync:', error)
94
+ process.exit(1)
95
+ }
96
+ }
97
+
98
+ main()
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ import fs from 'node:fs'
4
+ import os from 'node:os'
5
+ import process from 'node:process'
6
+ import { spawnSync } from 'node:child_process'
7
+ import { fileURLToPath } from 'node:url'
8
+
9
+ function isUsableDirectory(directory: string | undefined): directory is string {
10
+ if (!directory) {
11
+ return false
12
+ }
13
+
14
+ try {
15
+ fs.mkdirSync(directory, { recursive: true })
16
+ fs.accessSync(directory, fs.constants.R_OK | fs.constants.W_OK)
17
+ return true
18
+ } catch {
19
+ return false
20
+ }
21
+ }
22
+
23
+ function getTempDirectory(): string | undefined {
24
+ const envCandidates = [process.env.TMPDIR, process.env.TMP, process.env.TEMP]
25
+ const fallbackCandidates =
26
+ process.platform === 'win32' ? [os.tmpdir()] : ['/tmp', os.tmpdir(), '/var/tmp', '/usr/tmp']
27
+
28
+ return [...envCandidates, ...fallbackCandidates].find(isUsableDirectory)
29
+ }
30
+
31
+ function main(): void {
32
+ const tempDirectory = getTempDirectory()
33
+ if (!tempDirectory) {
34
+ console.error('Unable to find a writable temporary directory for Vitest.')
35
+ process.exit(1)
36
+ }
37
+
38
+ const vitestEntry = fileURLToPath(new URL('../node_modules/vitest/vitest.mjs', import.meta.url))
39
+ const env = {
40
+ ...process.env,
41
+ TMPDIR: tempDirectory,
42
+ TMP: tempDirectory,
43
+ TEMP: tempDirectory,
44
+ }
45
+
46
+ const result = spawnSync(process.execPath, [vitestEntry, 'run', ...process.argv.slice(2)], {
47
+ stdio: 'inherit',
48
+ env,
49
+ })
50
+
51
+ if (result.error) {
52
+ console.error(result.error)
53
+ process.exit(1)
54
+ }
55
+
56
+ process.exit(result.status ?? 1)
57
+ }
58
+
59
+ main()
@@ -1,19 +1,26 @@
1
- #!/usr/bin/env tsx
2
-
3
- import fs from 'fs'
4
- import path from 'path'
5
-
6
- const envContent = `# Database configuration for local development
7
- DATABASE_URL="file:./dev.db"
8
- `
9
-
10
- const envPath = path.join(process.cwd(), '.env')
11
-
12
- if (!fs.existsSync(envPath)) {
13
- fs.writeFileSync(envPath, envContent)
14
- console.log('? Created .env file with SQLite configuration')
15
- } else {
16
- console.log('?? .env file already exists, skipping creation')
17
- }
18
-
19
- console.log('?? Environment setup complete!')
1
+ #!/usr/bin/env tsx
2
+
3
+ import fs from 'fs'
4
+ import path from 'path'
5
+
6
+ const envContent = `# Database configuration for local development
7
+ DATABASE_URL="file:./dev.db"
8
+ `
9
+
10
+ /**
11
+ * Ensures local `.env` exists with a default SQLite DATABASE_URL.
12
+ */
13
+ function main(): void {
14
+ const envPath = path.join(process.cwd(), '.env')
15
+
16
+ if (!fs.existsSync(envPath)) {
17
+ fs.writeFileSync(envPath, envContent)
18
+ console.log('Created .env file with SQLite configuration')
19
+ } else {
20
+ console.log('.env file already exists, skipping creation')
21
+ }
22
+
23
+ console.log('Environment setup complete!')
24
+ }
25
+
26
+ main()
@@ -16,7 +16,9 @@ import {
16
16
  SYNC_ALL_REQUEST_ID,
17
17
  type SyncScriptId,
18
18
  } from '../src/lib/sync/sync-registry'
19
+ import { printSyncSummary } from './lib/sync-summary'
19
20
  const SYNC_SCRIPT_IDS = resolveRequestedSyncExecutionOrder(SYNC_ALL_REQUEST_ID)
21
+ const DIVIDER = '='.repeat(80)
20
22
 
21
23
  interface DatabaseChanges {
22
24
  scanned: number
@@ -48,6 +50,15 @@ interface SyncSummary {
48
50
  totalDbChanges: DatabaseChanges
49
51
  }
50
52
 
53
+ const DB_CHANGE_PATTERNS: Array<{ key: keyof DatabaseChanges; regex: RegExp }> = [
54
+ { key: 'scanned', regex: /scanned:\s*(\d+)/i },
55
+ { key: 'existing', regex: /existing:\s*(\d+)/i },
56
+ { key: 'created', regex: /created:\s*(\d+)/i },
57
+ { key: 'updated', regex: /updated:\s*(\d+)/i },
58
+ { key: 'deleted', regex: /deleted:\s*(\d+)/i },
59
+ { key: 'errors', regex: /Errors:\s*(\d+)/i },
60
+ ]
61
+
51
62
  /**
52
63
  * Parses database changes from sync script output
53
64
  * Extracts counts from the "Sync Summary:" section
@@ -62,7 +73,8 @@ function parseDatabaseChanges(stdout: string): DatabaseChanges | undefined {
62
73
  errors: 0,
63
74
  }
64
75
 
65
- // Look for the Sync Summary section
76
+ // Child sync scripts are expected to print a canonical "šŸ“Š Sync Summary:"
77
+ // block. If absent, we skip aggregation for that child.
66
78
  const summaryIndex = stdout.indexOf('šŸ“Š Sync Summary:')
67
79
  if (summaryIndex === -1) {
68
80
  return undefined
@@ -70,17 +82,7 @@ function parseDatabaseChanges(stdout: string): DatabaseChanges | undefined {
70
82
 
71
83
  const summarySection = stdout.substring(summaryIndex)
72
84
 
73
- // Parse patterns like " šŸ“ Modules scanned: 3" or " āœ… Modules existing: 3"
74
- const patterns = [
75
- { key: 'scanned' as const, regex: /scanned:\s*(\d+)/i },
76
- { key: 'existing' as const, regex: /existing:\s*(\d+)/i },
77
- { key: 'created' as const, regex: /created:\s*(\d+)/i },
78
- { key: 'updated' as const, regex: /updated:\s*(\d+)/i },
79
- { key: 'deleted' as const, regex: /deleted:\s*(\d+)/i },
80
- { key: 'errors' as const, regex: /Errors:\s*(\d+)/i },
81
- ]
82
-
83
- for (const pattern of patterns) {
85
+ for (const pattern of DB_CHANGE_PATTERNS) {
84
86
  const match = summarySection.match(pattern.regex)
85
87
  if (match) {
86
88
  changes[pattern.key] = parseInt(match[1], 10) || 0
@@ -103,7 +105,8 @@ async function executeSyncScript(scriptId: SyncScriptId): Promise<ScriptResult>
103
105
  const result = await execa(process.execPath, ['--import', 'tsx', scriptPath], {
104
106
  cwd: process.cwd(),
105
107
  stdio: 'pipe',
106
- reject: false, // Don't throw on non-zero exit codes
108
+ // Non-zero exit codes are reported in summary but should not stop orchestration.
109
+ reject: false,
107
110
  })
108
111
 
109
112
  const duration = Date.now() - startTime
@@ -177,10 +180,14 @@ function aggregateDatabaseChanges(results: ScriptResult[]): DatabaseChanges {
177
180
  /**
178
181
  * Generates and displays a comprehensive summary of the sync operation
179
182
  */
183
+ function hasDatabaseChanges(changes: DatabaseChanges): boolean {
184
+ return Object.values(changes).some(value => value > 0)
185
+ }
186
+
180
187
  function displaySummary(summary: SyncSummary): void {
181
- console.log('\n' + '='.repeat(80))
188
+ console.log('\n' + DIVIDER)
182
189
  console.log('šŸ“Š SYNC ALL - EXECUTION SUMMARY')
183
- console.log('='.repeat(80))
190
+ console.log(DIVIDER)
184
191
 
185
192
  console.log(`\nšŸ“ˆ Overall Statistics:`)
186
193
  console.log(` Total scripts: ${summary.totalScripts}`)
@@ -205,50 +212,34 @@ function displaySummary(summary: SyncSummary): void {
205
212
  }
206
213
  })
207
214
 
208
- // Display database changes summary
209
- const hasChanges = summary.totalDbChanges.created > 0 ||
210
- summary.totalDbChanges.updated > 0 ||
211
- summary.totalDbChanges.deleted > 0 ||
212
- summary.totalDbChanges.existing > 0 ||
213
- summary.totalDbChanges.scanned > 0
214
-
215
- if (hasChanges) {
216
- console.log(`\nšŸ’¾ Database Changes Summary:`)
217
- if (summary.totalDbChanges.scanned > 0) {
218
- console.log(` šŸ“ Total entities scanned: ${summary.totalDbChanges.scanned}`)
219
- }
220
- if (summary.totalDbChanges.existing > 0) {
221
- console.log(` āœ… Total entities existing: ${summary.totalDbChanges.existing}`)
222
- }
223
- if (summary.totalDbChanges.created > 0) {
224
- console.log(` āž• Total entities created: ${summary.totalDbChanges.created}`)
225
- }
226
- if (summary.totalDbChanges.updated > 0) {
227
- console.log(` šŸ”„ Total entities updated: ${summary.totalDbChanges.updated}`)
228
- }
229
- if (summary.totalDbChanges.deleted > 0) {
230
- console.log(` šŸ—‘ļø Total entities deleted: ${summary.totalDbChanges.deleted}`)
231
- }
232
- if (summary.totalDbChanges.errors > 0) {
233
- console.log(` āŒ Total errors encountered: ${summary.totalDbChanges.errors}`)
234
- }
215
+ // Reuse shared summary rendering so aggregate output format remains
216
+ // structurally aligned with individual sync scripts.
217
+ if (hasDatabaseChanges(summary.totalDbChanges)) {
218
+ printSyncSummary([
219
+ { label: 'šŸ“ Total entities scanned', value: summary.totalDbChanges.scanned },
220
+ { label: 'āœ… Total entities existing', value: summary.totalDbChanges.existing },
221
+ { label: 'āž• Total entities created', value: summary.totalDbChanges.created },
222
+ { label: 'šŸ”„ Total entities updated', value: summary.totalDbChanges.updated },
223
+ { label: 'šŸ—‘ļø Total entities deleted', value: summary.totalDbChanges.deleted },
224
+ { label: 'āŒ Total errors encountered', value: summary.totalDbChanges.errors },
225
+ ])
235
226
  }
236
227
 
237
- console.log(`\n${'='.repeat(80)}`)
228
+ console.log(`\n${DIVIDER}`)
238
229
 
239
230
  if (summary.failedScripts === 0) {
240
231
  console.log('āœ… All sync scripts completed successfully!')
241
- console.log('='.repeat(80) + '\n')
232
+ console.log(DIVIDER + '\n')
242
233
  } else {
243
234
  console.log(`āš ļø ${summary.failedScripts} script(s) failed. Please review the errors above.`)
244
- console.log('='.repeat(80) + '\n')
235
+ console.log(DIVIDER + '\n')
245
236
  }
246
237
  }
247
238
 
248
239
  /**
249
240
  * Main function that orchestrates all sync scripts
250
241
  */
251
- async function main(): Promise<void> {
242
+ async function main(): Promise<number> {
252
243
  const startTime = Date.now()
253
244
  const results: ScriptResult[] = []
254
245
 
@@ -256,7 +247,8 @@ async function main(): Promise<void> {
256
247
  console.log('This will sync all entities from filesystem to database in the correct dependency order.')
257
248
  console.log('Execution will continue even if individual scripts fail.\n')
258
249
 
259
- // Execute each script in order
250
+ // Execute in dependency order from registry; we intentionally continue through
251
+ // failures to provide complete visibility of system state in one run.
260
252
  for (const scriptId of SYNC_SCRIPT_IDS) {
261
253
  const result = await executeSyncScript(scriptId)
262
254
  results.push(result)
@@ -282,16 +274,14 @@ async function main(): Promise<void> {
282
274
  // Display comprehensive summary
283
275
  displaySummary(summary)
284
276
 
285
- // Exit with appropriate code
286
- if (failedScripts > 0) {
287
- process.exit(1)
288
- } else {
289
- process.exit(0)
290
- }
277
+ return failedScripts > 0 ? 1 : 0
291
278
  }
292
279
 
293
280
  // Run the main function
294
281
  main().catch(error => {
295
282
  console.error('\nāŒ Fatal error during sync orchestration:', error)
296
- process.exit(1)
283
+ return 1
297
284
  })
285
+ .then(exitCode => {
286
+ process.exit(exitCode)
287
+ })