create-appraisejs 0.3.1-alpha.0 → 0.3.1-alpha.1

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 (503) hide show
  1. package/README.md +17 -17
  2. package/dist/cli.e2e.test.d.ts +2 -2
  3. package/dist/cli.e2e.test.js +74 -72
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js.map +1 -1
  6. package/dist/config.test.d.ts +2 -2
  7. package/dist/config.test.js +64 -64
  8. package/dist/copy-template.test.d.ts +2 -2
  9. package/dist/copy-template.test.js +70 -70
  10. package/dist/download-repo.test.d.ts +2 -2
  11. package/dist/download-repo.test.js +15 -13
  12. package/dist/install.test.d.ts +2 -2
  13. package/dist/install.test.js +115 -114
  14. package/dist/prepare-template-utils.d.ts.map +1 -1
  15. package/dist/prepare-template-utils.js.map +1 -1
  16. package/dist/prompts.d.ts.map +1 -1
  17. package/dist/prompts.js +2 -2
  18. package/dist/prompts.js.map +1 -1
  19. package/dist/prompts.test.d.ts +2 -2
  20. package/dist/prompts.test.js +54 -54
  21. package/dist/sync-templates-utils.d.ts.map +1 -1
  22. package/dist/sync-templates-utils.js +1 -5
  23. package/dist/sync-templates-utils.js.map +1 -1
  24. package/package.json +1 -1
  25. package/templates/blank/.editorconfig +11 -0
  26. package/templates/blank/.gitattributes +21 -0
  27. package/templates/blank/.gitconfig.appraise +14 -0
  28. package/templates/blank/.prettierrc +13 -0
  29. package/templates/blank/.vscode/settings.json +2 -0
  30. package/templates/blank/README.md +12 -12
  31. package/templates/blank/components.json +24 -24
  32. package/templates/blank/cucumber.mjs +16 -16
  33. package/templates/blank/e2e/README.md +56 -0
  34. package/templates/blank/e2e/apply-migrations.mjs +76 -0
  35. package/templates/blank/e2e/appraise-smoke.spec.ts +78 -0
  36. package/templates/blank/e2e/authoring.spec.ts +53 -0
  37. package/templates/blank/e2e/crud-configuration.spec.ts +138 -0
  38. package/templates/blank/e2e/crud-tests.spec.ts +76 -0
  39. package/templates/blank/e2e/helpers/forms.ts +186 -0
  40. package/templates/blank/e2e/helpers/navigation.ts +27 -0
  41. package/templates/blank/e2e/helpers/table.ts +45 -0
  42. package/templates/blank/e2e/helpers/test-data.ts +549 -0
  43. package/templates/blank/e2e/helpers/ui.ts +41 -0
  44. package/templates/blank/e2e/navigation.spec.ts +101 -0
  45. package/templates/blank/e2e/runs-and-reports.spec.ts +82 -0
  46. package/templates/blank/e2e/settings-sync.spec.ts +39 -0
  47. package/templates/blank/e2e/start-server.mjs +61 -0
  48. package/templates/blank/eslint.config.mjs +4 -4
  49. package/templates/blank/gitignore +0 -3
  50. package/templates/blank/next-env.d.ts +1 -1
  51. package/templates/blank/package-lock.json +58 -102
  52. package/templates/blank/package.json +10 -9
  53. package/templates/blank/packages/cucumber-runtime/package.json +13 -13
  54. package/templates/blank/packages/cucumber-runtime/src/cache.util.ts +93 -93
  55. package/templates/blank/packages/cucumber-runtime/src/cli.ts +77 -68
  56. package/templates/blank/packages/cucumber-runtime/src/environment.util.ts +21 -21
  57. package/templates/blank/packages/cucumber-runtime/src/executor.ts +32 -32
  58. package/templates/blank/packages/cucumber-runtime/src/index.ts +17 -17
  59. package/templates/blank/packages/cucumber-runtime/src/locator.util.ts +234 -234
  60. package/templates/blank/packages/cucumber-runtime/src/parameter-types.ts +7 -7
  61. package/templates/blank/packages/cucumber-runtime/src/random-data.util.ts +35 -35
  62. package/templates/blank/packages/cucumber-runtime/src/types.ts +13 -13
  63. package/templates/blank/packages/cucumber-runtime/src/world.ts +44 -44
  64. package/templates/blank/packages/cucumber-runtime/tsconfig.json +11 -11
  65. package/templates/blank/packages/locator-picker-companion/dist/cli.js +1 -1
  66. package/templates/blank/packages/locator-picker-companion/dist/index.d.ts +3 -3
  67. package/templates/blank/packages/locator-picker-companion/dist/index.js +3 -3
  68. package/templates/blank/packages/locator-picker-companion/dist/injected-picker-script.js +13 -3
  69. package/templates/blank/packages/locator-picker-companion/dist/selector-generator.d.ts +6 -3
  70. package/templates/blank/packages/locator-picker-companion/dist/selector-generator.js +233 -229
  71. package/templates/blank/packages/locator-picker-companion/src/cli.ts +1 -7
  72. package/templates/blank/packages/locator-picker-companion/src/injected-picker-script.ts +26 -5
  73. package/templates/blank/packages/locator-picker-companion/src/launcher.ts +1 -3
  74. package/templates/blank/packages/locator-picker-companion/src/session-file.ts +4 -15
  75. package/templates/blank/packages/locator-picker-companion/src/types.ts +1 -8
  76. package/templates/blank/playwright.config.ts +46 -0
  77. package/templates/blank/postcss.config.mjs +8 -8
  78. package/templates/blank/prisma/dev.db +0 -0
  79. package/templates/blank/scripts/configure-git-line-endings.mjs +91 -0
  80. package/templates/blank/scripts/install-template-step.ts +5 -1
  81. package/templates/blank/scripts/lib/step-matcher.test.ts +3 -3
  82. package/templates/blank/scripts/lib/step-matcher.ts +5 -1
  83. package/templates/blank/scripts/lib/template-step-installer.test.ts +4 -2
  84. package/templates/blank/scripts/lib/template-step-installer.ts +16 -4
  85. package/templates/blank/scripts/lib/template-step-registry.test.ts +1 -1
  86. package/templates/blank/scripts/lib/template-step-registry.ts +4 -1
  87. package/templates/blank/scripts/run-fallow-commit.mjs +4 -6
  88. package/templates/blank/scripts/sync-all.ts +7 -6
  89. package/templates/blank/scripts/sync-appraise-base-template.ts +84 -77
  90. package/templates/blank/scripts/sync-environments.ts +47 -44
  91. package/templates/blank/scripts/sync-locator-groups.ts +67 -76
  92. package/templates/blank/scripts/sync-locators.ts +50 -53
  93. package/templates/blank/scripts/sync-modules.ts +42 -42
  94. package/templates/blank/scripts/sync-tags.ts +51 -51
  95. package/templates/blank/scripts/sync-template-step-groups.ts +34 -32
  96. package/templates/blank/scripts/sync-template-steps.ts +97 -97
  97. package/templates/blank/scripts/sync-test-cases.ts +65 -74
  98. package/templates/blank/scripts/sync-test-suites.ts +85 -80
  99. package/templates/blank/src/actions/server-action-boundary.test.ts +1 -7
  100. package/templates/blank/src/actions/settings/sync-actions.ts +3 -1
  101. package/templates/blank/src/actions/tags/tag-actions.ts +1 -7
  102. package/templates/blank/src/actions/template-test-case/template-test-case-actions.ts +3 -1
  103. package/templates/blank/src/app/(base)/environments/create/page.tsx +28 -28
  104. package/templates/blank/src/app/(base)/environments/environment-form.tsx +3 -2
  105. package/templates/blank/src/app/(base)/environments/environment-helpers.ts +4 -1
  106. package/templates/blank/src/app/(base)/layout.tsx +10 -10
  107. package/templates/blank/src/app/(base)/locator-groups/locator-group-form.tsx +5 -3
  108. package/templates/blank/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
  109. package/templates/blank/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
  110. package/templates/blank/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
  111. package/templates/blank/src/app/(base)/locator-groups/page.tsx +9 -19
  112. package/templates/blank/src/app/(base)/locators/create/create-locator-workspace-helpers.test.ts +3 -6
  113. package/templates/blank/src/app/(base)/locators/create/create-locator-workspace-response.ts +22 -5
  114. package/templates/blank/src/app/(base)/locators/create/create-locator-workspace-state.ts +5 -1
  115. package/templates/blank/src/app/(base)/locators/create/use-locator-workspace.ts +7 -2
  116. package/templates/blank/src/app/(base)/locators/locator-file-sync.ts +1 -5
  117. package/templates/blank/src/app/(base)/locators/locator-helpers.ts +2 -12
  118. package/templates/blank/src/app/(base)/locators/locator-table-columns.tsx +59 -60
  119. package/templates/blank/src/app/(base)/modules/module-form.tsx +3 -1
  120. package/templates/blank/src/app/(base)/reports/overview-chart.tsx +49 -49
  121. package/templates/blank/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +114 -115
  122. package/templates/blank/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
  123. package/templates/blank/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +80 -79
  124. package/templates/blank/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +29 -27
  125. package/templates/blank/src/app/(base)/settings/settings-sync-panel-helpers.test.tsx +4 -6
  126. package/templates/blank/src/app/(base)/settings/settings-sync-panel.tsx +22 -23
  127. package/templates/blank/src/app/(base)/tags/tag-form.test.tsx +2 -10
  128. package/templates/blank/src/app/(base)/tags/tag-form.tsx +5 -3
  129. package/templates/blank/src/app/(base)/tags/tag-table-columns.tsx +63 -63
  130. package/templates/blank/src/app/(base)/tags/tag-table.tsx +29 -29
  131. package/templates/blank/src/app/(base)/template-step-groups/create/page.tsx +28 -28
  132. package/templates/blank/src/app/(base)/template-step-groups/template-step-group-form.tsx +3 -1
  133. package/templates/blank/src/app/(base)/template-step-groups/template-step-group-helpers.ts +4 -1
  134. package/templates/blank/src/app/(base)/template-steps/paramChip.tsx +6 -10
  135. package/templates/blank/src/app/(base)/template-steps/template-step-form-helpers.ts +4 -2
  136. package/templates/blank/src/app/(base)/template-steps/template-step-helpers.test.ts +19 -1
  137. package/templates/blank/src/app/(base)/template-steps/template-step-helpers.ts +1 -5
  138. package/templates/blank/src/app/(base)/template-steps/template-step-row-guards.ts +1 -5
  139. package/templates/blank/src/app/(base)/template-steps/template-step-types.ts +1 -5
  140. package/templates/blank/src/app/(base)/template-test-cases/create-template-test-case-page-data.test.ts +4 -1
  141. package/templates/blank/src/app/(base)/template-test-cases/create-template-test-case-page-data.ts +1 -2
  142. package/templates/blank/src/app/(base)/template-test-cases/modify/[id]/page.tsx +1 -0
  143. package/templates/blank/src/app/(base)/template-test-cases/template-test-case-flow.test.tsx +0 -1
  144. package/templates/blank/src/app/(base)/template-test-cases/template-test-case-form.tsx +3 -1
  145. package/templates/blank/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
  146. package/templates/blank/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
  147. package/templates/blank/src/app/(base)/test-cases/create/page.tsx +1 -5
  148. package/templates/blank/src/app/(base)/test-cases/create-from-template/create-from-template-selection-helpers.ts +1 -4
  149. package/templates/blank/src/app/(base)/test-cases/create-from-template/page.test.tsx +2 -2
  150. package/templates/blank/src/app/(base)/test-cases/inline-tag-creation-dialog.tsx +1 -7
  151. package/templates/blank/src/app/(base)/test-cases/inline-test-suite-creation-dialog.tsx +1 -7
  152. package/templates/blank/src/app/(base)/test-cases/modify/[id]/page.tsx +1 -5
  153. package/templates/blank/src/app/(base)/test-cases/test-case-form.tsx +63 -78
  154. package/templates/blank/src/app/(base)/test-cases/test-case-route-helpers.test.ts +2 -7
  155. package/templates/blank/src/app/(base)/test-suites/editable-test-suite-helpers.ts +1 -6
  156. package/templates/blank/src/app/(base)/test-suites/test-suite-form.test.tsx +2 -10
  157. package/templates/blank/src/app/(dashboard-components)/data-card-grid.tsx +10 -10
  158. package/templates/blank/src/app/api/test-runs/[runId]/download/route.ts +1 -4
  159. package/templates/blank/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.test.ts +18 -9
  160. package/templates/blank/src/assets/icons/empty-tube.tsx +23 -23
  161. package/templates/blank/src/assets/icons/tube-plus.tsx +29 -29
  162. package/templates/blank/src/components/data-visualization/info-card.tsx +56 -70
  163. package/templates/blank/src/components/data-visualization/info-grid.tsx +22 -22
  164. package/templates/blank/src/components/diagram/add-node-prompt-node.tsx +1 -1
  165. package/templates/blank/src/components/diagram/dynamic-parameters-helpers.ts +4 -3
  166. package/templates/blank/src/components/diagram/dynamic-parameters.test.tsx +4 -1
  167. package/templates/blank/src/components/diagram/dynamic-parameters.tsx +0 -1
  168. package/templates/blank/src/components/diagram/flow-diagram-block-dialog.test.tsx +26 -0
  169. package/templates/blank/src/components/diagram/flow-diagram-block-dialog.tsx +3 -1
  170. package/templates/blank/src/components/diagram/flow-diagram-connection-guards.ts +24 -6
  171. package/templates/blank/src/components/diagram/flow-diagram-helpers.test.ts +27 -0
  172. package/templates/blank/src/components/diagram/flow-diagram-node-search.tsx +65 -65
  173. package/templates/blank/src/components/diagram/flow-diagram-toolbar.tsx +1 -3
  174. package/templates/blank/src/components/diagram/flow-diagram-view.tsx +1 -7
  175. package/templates/blank/src/components/diagram/flow-node-data-helpers.ts +1 -1
  176. package/templates/blank/src/components/diagram/node-form-fields-content.tsx +9 -2
  177. package/templates/blank/src/components/diagram/node-form-helpers.test.ts +3 -1
  178. package/templates/blank/src/components/diagram/node-form-helpers.ts +1 -4
  179. package/templates/blank/src/components/diagram/node-form-template-step-selection.ts +1 -4
  180. package/templates/blank/src/components/diagram/node-form.test.tsx +25 -0
  181. package/templates/blank/src/components/diagram/node-form.tsx +2 -12
  182. package/templates/blank/src/components/diagram/options-header-node.test.tsx +4 -1
  183. package/templates/blank/src/components/diagram/options-header-node.tsx +140 -130
  184. package/templates/blank/src/components/diagram/use-flow-diagram.ts +1 -2
  185. package/templates/blank/src/components/form/error-message.tsx +7 -7
  186. package/templates/blank/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
  187. package/templates/blank/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
  188. package/templates/blank/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
  189. package/templates/blank/src/components/navigation/entity-search-command.tsx +3 -9
  190. package/templates/blank/src/components/navigation/nav-link.tsx +60 -60
  191. package/templates/blank/src/components/test-case/test-case-form-helpers.test.ts +1 -5
  192. package/templates/blank/src/components/test-case/test-case-form-helpers.ts +1 -5
  193. package/templates/blank/src/components/test-case/test-case-picker-helpers.ts +8 -7
  194. package/templates/blank/src/components/test-case/test-case-picker.tsx +2 -6
  195. package/templates/blank/src/components/test-run/log-viewer.test.tsx +25 -0
  196. package/templates/blank/src/components/test-run/log-viewer.tsx +2 -2
  197. package/templates/blank/src/components/test-run/test-run-details-guards.ts +10 -1
  198. package/templates/blank/src/components/test-run/test-run-details.test.tsx +9 -19
  199. package/templates/blank/src/components/test-run/use-log-viewer.ts +2 -8
  200. package/templates/blank/src/components/test-run/use-test-run-header.ts +1 -4
  201. package/templates/blank/src/components/test-suite/test-suite-picker.tsx +1 -1
  202. package/templates/blank/src/components/theme/theme-provider.tsx +7 -1
  203. package/templates/blank/src/components/typography/page-header-subtitle.tsx +7 -7
  204. package/templates/blank/src/components/typography/page-header.tsx +7 -7
  205. package/templates/blank/src/components/ui/chart.tsx +2 -8
  206. package/templates/blank/src/components/ui/command.tsx +2 -5
  207. package/templates/blank/src/components/ui/data-table-column-header.tsx +3 -3
  208. package/templates/blank/src/components/ui/data-table.test.tsx +1 -8
  209. package/templates/blank/src/components/ui/dialog.tsx +1 -4
  210. package/templates/blank/src/components/ui/select.tsx +2 -2
  211. package/templates/blank/src/components/ui/separator.tsx +5 -1
  212. package/templates/blank/src/components/ui/skeleton.tsx +7 -7
  213. package/templates/blank/src/components/ui/table.tsx +1 -1
  214. package/templates/blank/src/components/ui/toaster.tsx +26 -26
  215. package/templates/blank/src/components/ui/tooltip.tsx +1 -1
  216. package/templates/blank/src/constants/form-opts/locator-group-form-opts.ts +1 -1
  217. package/templates/blank/src/lib/locator-group-file-utils.ts +5 -1
  218. package/templates/blank/src/lib/locator-picker/session-manager.ts +1 -2
  219. package/templates/blank/src/lib/metrics/metric-calculator.test.ts +105 -6
  220. package/templates/blank/src/lib/metrics/metric-calculator.ts +39 -40
  221. package/templates/blank/src/lib/sync/sync-executor.ts +1 -4
  222. package/templates/blank/src/lib/sync/sync-pending-counts.test.ts +201 -7
  223. package/templates/blank/src/lib/sync/sync-pending-counts.ts +81 -13
  224. package/templates/blank/src/lib/template-automation-paths.ts +1 -1
  225. package/templates/blank/src/lib/template-sync-utils.d.ts +14 -7
  226. package/templates/blank/src/lib/test-case-utils.ts +6 -6
  227. package/templates/blank/src/lib/test-run/log-formatter.ts +82 -83
  228. package/templates/blank/src/lib/test-run/report-parser.ts +352 -352
  229. package/templates/blank/src/lib/transformers/gherkin-converter.ts +42 -42
  230. package/templates/blank/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
  231. package/templates/blank/src/lib/utils/node-param-validation.ts +81 -81
  232. package/templates/blank/src/lib/utils/template-step-file-generator.ts +5 -3
  233. package/templates/blank/src/lib/utils/template-step-file-manager-intelligent.ts +11 -1
  234. package/templates/blank/src/services/dashboard/dashboard-service.test.ts +28 -1
  235. package/templates/blank/src/services/dashboard/dashboard-service.ts +2 -0
  236. package/templates/blank/src/services/locator/locator-service.test.ts +1 -3
  237. package/templates/blank/src/services/locator/locator-service.ts +3 -1
  238. package/templates/blank/src/services/locator/locator-sync-utils.test.ts +1 -4
  239. package/templates/blank/src/services/module/module-service.ts +1 -4
  240. package/templates/blank/src/services/report/report-service.test.ts +70 -6
  241. package/templates/blank/src/services/report/report-service.ts +52 -9
  242. package/templates/blank/src/services/shared/errors.ts +2 -4
  243. package/templates/blank/src/services/template-step/template-step-service.ts +3 -1
  244. package/templates/blank/src/services/template-step-group/template-step-group-service.ts +3 -1
  245. package/templates/blank/src/services/test-case/test-case-service.ts +0 -5
  246. package/templates/blank/src/services/test-run/test-run-service.test.ts +3 -6
  247. package/templates/blank/src/services/test-run/test-run-service.ts +12 -7
  248. package/templates/blank/src/services/test-suite/test-suite-service.test.ts +1 -5
  249. package/templates/blank/src/services/test-suite/test-suite-service.ts +2 -4
  250. package/templates/blank/src/types/form/actionHandler.ts +1 -5
  251. package/templates/blank/tsconfig.json +8 -8
  252. package/templates/default/packages/locator-picker-companion/dist/cli.d.ts +1 -1
  253. package/templates/default/packages/locator-picker-companion/dist/cli.js +313 -279
  254. package/templates/default/packages/locator-picker-companion/dist/index.d.ts +3 -3
  255. package/templates/default/packages/locator-picker-companion/dist/index.js +3 -3
  256. package/templates/default/packages/locator-picker-companion/dist/injected-picker-script.d.ts +1 -1
  257. package/templates/default/packages/locator-picker-companion/dist/injected-picker-script.js +526 -481
  258. package/templates/default/packages/locator-picker-companion/dist/launcher.d.ts +13 -10
  259. package/templates/default/packages/locator-picker-companion/dist/launcher.js +47 -48
  260. package/templates/default/packages/locator-picker-companion/dist/selector-generator.d.ts +6 -3
  261. package/templates/default/packages/locator-picker-companion/dist/selector-generator.js +233 -229
  262. package/templates/default/packages/locator-picker-companion/dist/session-file.d.ts +30 -22
  263. package/templates/default/packages/locator-picker-companion/dist/session-file.js +116 -104
  264. package/templates/default/packages/locator-picker-companion/dist/types.d.ts +25 -25
  265. package/templates/default/packages/locator-picker-companion/dist/types.js +1 -1
  266. package/templates/starter/.editorconfig +11 -0
  267. package/templates/starter/.gitattributes +21 -0
  268. package/templates/starter/.gitconfig.appraise +14 -0
  269. package/templates/starter/.prettierrc +13 -0
  270. package/templates/starter/.vscode/settings.json +2 -0
  271. package/templates/starter/README.md +12 -12
  272. package/templates/starter/automation/steps/actions/click.step.ts +56 -58
  273. package/templates/starter/automation/steps/actions/hover.step.ts +25 -27
  274. package/templates/starter/automation/steps/actions/input.step.ts +85 -108
  275. package/templates/starter/automation/steps/actions/navigation.step.ts +67 -70
  276. package/templates/starter/automation/steps/actions/random_data.step.ts +149 -143
  277. package/templates/starter/automation/steps/actions/store.step.ts +69 -1
  278. package/templates/starter/automation/steps/actions/wait.step.ts +84 -1
  279. package/templates/starter/automation/steps/validations/active_state_assertion.step.ts +28 -30
  280. package/templates/starter/automation/steps/validations/navigation_assertion.step.ts +20 -22
  281. package/templates/starter/automation/steps/validations/text_assertion.step.ts +67 -107
  282. package/templates/starter/automation/steps/validations/visibility_assertion.step.ts +24 -26
  283. package/templates/starter/components.json +24 -24
  284. package/templates/starter/cucumber.mjs +16 -16
  285. package/templates/starter/e2e/README.md +56 -0
  286. package/templates/starter/e2e/apply-migrations.mjs +76 -0
  287. package/templates/starter/e2e/appraise-smoke.spec.ts +78 -0
  288. package/templates/starter/e2e/authoring.spec.ts +53 -0
  289. package/templates/starter/e2e/crud-configuration.spec.ts +138 -0
  290. package/templates/starter/e2e/crud-tests.spec.ts +76 -0
  291. package/templates/starter/e2e/helpers/forms.ts +186 -0
  292. package/templates/starter/e2e/helpers/navigation.ts +27 -0
  293. package/templates/starter/e2e/helpers/table.ts +45 -0
  294. package/templates/starter/e2e/helpers/test-data.ts +549 -0
  295. package/templates/starter/e2e/helpers/ui.ts +41 -0
  296. package/templates/starter/e2e/navigation.spec.ts +101 -0
  297. package/templates/starter/e2e/runs-and-reports.spec.ts +82 -0
  298. package/templates/starter/e2e/settings-sync.spec.ts +39 -0
  299. package/templates/starter/e2e/start-server.mjs +61 -0
  300. package/templates/starter/eslint.config.mjs +4 -4
  301. package/templates/starter/gitignore +0 -3
  302. package/templates/starter/next-env.d.ts +1 -1
  303. package/templates/starter/package-lock.json +58 -102
  304. package/templates/starter/package.json +10 -9
  305. package/templates/starter/packages/cucumber-runtime/package.json +13 -13
  306. package/templates/starter/packages/cucumber-runtime/src/cache.util.ts +93 -93
  307. package/templates/starter/packages/cucumber-runtime/src/cli.ts +77 -68
  308. package/templates/starter/packages/cucumber-runtime/src/environment.util.ts +21 -21
  309. package/templates/starter/packages/cucumber-runtime/src/executor.ts +32 -32
  310. package/templates/starter/packages/cucumber-runtime/src/index.ts +17 -17
  311. package/templates/starter/packages/cucumber-runtime/src/locator.util.ts +234 -234
  312. package/templates/starter/packages/cucumber-runtime/src/parameter-types.ts +7 -7
  313. package/templates/starter/packages/cucumber-runtime/src/random-data.util.ts +35 -35
  314. package/templates/starter/packages/cucumber-runtime/src/types.ts +13 -13
  315. package/templates/starter/packages/cucumber-runtime/src/world.ts +44 -44
  316. package/templates/starter/packages/cucumber-runtime/tsconfig.json +11 -11
  317. package/templates/starter/packages/locator-picker-companion/dist/cli.js +1 -1
  318. package/templates/starter/packages/locator-picker-companion/dist/index.d.ts +3 -3
  319. package/templates/starter/packages/locator-picker-companion/dist/index.js +3 -3
  320. package/templates/starter/packages/locator-picker-companion/dist/injected-picker-script.js +13 -3
  321. package/templates/starter/packages/locator-picker-companion/dist/selector-generator.d.ts +6 -3
  322. package/templates/starter/packages/locator-picker-companion/dist/selector-generator.js +233 -229
  323. package/templates/starter/packages/locator-picker-companion/src/cli.ts +1 -7
  324. package/templates/starter/packages/locator-picker-companion/src/injected-picker-script.ts +26 -5
  325. package/templates/starter/packages/locator-picker-companion/src/launcher.ts +1 -3
  326. package/templates/starter/packages/locator-picker-companion/src/session-file.ts +4 -15
  327. package/templates/starter/packages/locator-picker-companion/src/types.ts +1 -8
  328. package/templates/starter/playwright.config.ts +46 -0
  329. package/templates/starter/postcss.config.mjs +8 -8
  330. package/templates/starter/prisma/dev.db +0 -0
  331. package/templates/starter/scripts/configure-git-line-endings.mjs +91 -0
  332. package/templates/starter/scripts/install-template-step.ts +5 -1
  333. package/templates/starter/scripts/lib/step-matcher.test.ts +3 -3
  334. package/templates/starter/scripts/lib/step-matcher.ts +5 -1
  335. package/templates/starter/scripts/lib/template-step-installer.test.ts +4 -2
  336. package/templates/starter/scripts/lib/template-step-installer.ts +16 -4
  337. package/templates/starter/scripts/lib/template-step-registry.test.ts +1 -1
  338. package/templates/starter/scripts/lib/template-step-registry.ts +4 -1
  339. package/templates/starter/scripts/run-fallow-commit.mjs +4 -6
  340. package/templates/starter/scripts/sync-all.ts +7 -6
  341. package/templates/starter/scripts/sync-appraise-base-template.ts +84 -77
  342. package/templates/starter/scripts/sync-environments.ts +47 -44
  343. package/templates/starter/scripts/sync-locator-groups.ts +67 -76
  344. package/templates/starter/scripts/sync-locators.ts +50 -53
  345. package/templates/starter/scripts/sync-modules.ts +42 -42
  346. package/templates/starter/scripts/sync-tags.ts +51 -51
  347. package/templates/starter/scripts/sync-template-step-groups.ts +34 -32
  348. package/templates/starter/scripts/sync-template-steps.ts +97 -97
  349. package/templates/starter/scripts/sync-test-cases.ts +65 -74
  350. package/templates/starter/scripts/sync-test-suites.ts +85 -80
  351. package/templates/starter/src/actions/server-action-boundary.test.ts +1 -7
  352. package/templates/starter/src/actions/settings/sync-actions.ts +3 -1
  353. package/templates/starter/src/actions/tags/tag-actions.ts +1 -7
  354. package/templates/starter/src/actions/template-test-case/template-test-case-actions.ts +3 -1
  355. package/templates/starter/src/app/(base)/environments/create/page.tsx +28 -28
  356. package/templates/starter/src/app/(base)/environments/environment-form.tsx +3 -2
  357. package/templates/starter/src/app/(base)/environments/environment-helpers.ts +4 -1
  358. package/templates/starter/src/app/(base)/layout.tsx +10 -10
  359. package/templates/starter/src/app/(base)/locator-groups/locator-group-form.tsx +5 -3
  360. package/templates/starter/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
  361. package/templates/starter/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
  362. package/templates/starter/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
  363. package/templates/starter/src/app/(base)/locator-groups/page.tsx +9 -19
  364. package/templates/starter/src/app/(base)/locators/create/create-locator-workspace-helpers.test.ts +3 -6
  365. package/templates/starter/src/app/(base)/locators/create/create-locator-workspace-response.ts +22 -5
  366. package/templates/starter/src/app/(base)/locators/create/create-locator-workspace-state.ts +5 -1
  367. package/templates/starter/src/app/(base)/locators/create/use-locator-workspace.ts +7 -2
  368. package/templates/starter/src/app/(base)/locators/locator-file-sync.ts +1 -5
  369. package/templates/starter/src/app/(base)/locators/locator-helpers.ts +2 -12
  370. package/templates/starter/src/app/(base)/locators/locator-table-columns.tsx +59 -60
  371. package/templates/starter/src/app/(base)/modules/module-form.tsx +3 -1
  372. package/templates/starter/src/app/(base)/reports/overview-chart.tsx +49 -49
  373. package/templates/starter/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +114 -115
  374. package/templates/starter/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
  375. package/templates/starter/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +80 -79
  376. package/templates/starter/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +29 -27
  377. package/templates/starter/src/app/(base)/settings/settings-sync-panel-helpers.test.tsx +4 -6
  378. package/templates/starter/src/app/(base)/settings/settings-sync-panel.tsx +22 -23
  379. package/templates/starter/src/app/(base)/tags/tag-form.test.tsx +2 -10
  380. package/templates/starter/src/app/(base)/tags/tag-form.tsx +5 -3
  381. package/templates/starter/src/app/(base)/tags/tag-table-columns.tsx +63 -63
  382. package/templates/starter/src/app/(base)/tags/tag-table.tsx +29 -29
  383. package/templates/starter/src/app/(base)/template-step-groups/create/page.tsx +28 -28
  384. package/templates/starter/src/app/(base)/template-step-groups/template-step-group-form.tsx +3 -1
  385. package/templates/starter/src/app/(base)/template-step-groups/template-step-group-helpers.ts +4 -1
  386. package/templates/starter/src/app/(base)/template-steps/paramChip.tsx +6 -10
  387. package/templates/starter/src/app/(base)/template-steps/template-step-form-helpers.ts +4 -2
  388. package/templates/starter/src/app/(base)/template-steps/template-step-helpers.test.ts +19 -1
  389. package/templates/starter/src/app/(base)/template-steps/template-step-helpers.ts +1 -5
  390. package/templates/starter/src/app/(base)/template-steps/template-step-row-guards.ts +1 -5
  391. package/templates/starter/src/app/(base)/template-steps/template-step-types.ts +1 -5
  392. package/templates/starter/src/app/(base)/template-test-cases/create-template-test-case-page-data.test.ts +4 -1
  393. package/templates/starter/src/app/(base)/template-test-cases/create-template-test-case-page-data.ts +1 -2
  394. package/templates/starter/src/app/(base)/template-test-cases/modify/[id]/page.tsx +1 -0
  395. package/templates/starter/src/app/(base)/template-test-cases/template-test-case-flow.test.tsx +0 -1
  396. package/templates/starter/src/app/(base)/template-test-cases/template-test-case-form.tsx +3 -1
  397. package/templates/starter/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
  398. package/templates/starter/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
  399. package/templates/starter/src/app/(base)/test-cases/create/page.tsx +1 -5
  400. package/templates/starter/src/app/(base)/test-cases/create-from-template/create-from-template-selection-helpers.ts +1 -4
  401. package/templates/starter/src/app/(base)/test-cases/create-from-template/page.test.tsx +2 -2
  402. package/templates/starter/src/app/(base)/test-cases/inline-tag-creation-dialog.tsx +1 -7
  403. package/templates/starter/src/app/(base)/test-cases/inline-test-suite-creation-dialog.tsx +1 -7
  404. package/templates/starter/src/app/(base)/test-cases/modify/[id]/page.tsx +1 -5
  405. package/templates/starter/src/app/(base)/test-cases/test-case-form.tsx +63 -78
  406. package/templates/starter/src/app/(base)/test-cases/test-case-route-helpers.test.ts +2 -7
  407. package/templates/starter/src/app/(base)/test-suites/editable-test-suite-helpers.ts +1 -6
  408. package/templates/starter/src/app/(base)/test-suites/test-suite-form.test.tsx +2 -10
  409. package/templates/starter/src/app/(dashboard-components)/data-card-grid.tsx +10 -10
  410. package/templates/starter/src/app/api/test-runs/[runId]/download/route.ts +1 -4
  411. package/templates/starter/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.test.ts +18 -9
  412. package/templates/starter/src/assets/icons/empty-tube.tsx +23 -23
  413. package/templates/starter/src/assets/icons/tube-plus.tsx +29 -29
  414. package/templates/starter/src/components/data-visualization/info-card.tsx +56 -70
  415. package/templates/starter/src/components/data-visualization/info-grid.tsx +22 -22
  416. package/templates/starter/src/components/diagram/add-node-prompt-node.tsx +1 -1
  417. package/templates/starter/src/components/diagram/dynamic-parameters-helpers.ts +4 -3
  418. package/templates/starter/src/components/diagram/dynamic-parameters.test.tsx +4 -1
  419. package/templates/starter/src/components/diagram/dynamic-parameters.tsx +0 -1
  420. package/templates/starter/src/components/diagram/flow-diagram-block-dialog.test.tsx +26 -0
  421. package/templates/starter/src/components/diagram/flow-diagram-block-dialog.tsx +3 -1
  422. package/templates/starter/src/components/diagram/flow-diagram-connection-guards.ts +24 -6
  423. package/templates/starter/src/components/diagram/flow-diagram-helpers.test.ts +27 -0
  424. package/templates/starter/src/components/diagram/flow-diagram-node-search.tsx +65 -65
  425. package/templates/starter/src/components/diagram/flow-diagram-toolbar.tsx +1 -3
  426. package/templates/starter/src/components/diagram/flow-diagram-view.tsx +1 -7
  427. package/templates/starter/src/components/diagram/flow-node-data-helpers.ts +1 -1
  428. package/templates/starter/src/components/diagram/node-form-fields-content.tsx +9 -2
  429. package/templates/starter/src/components/diagram/node-form-helpers.test.ts +3 -1
  430. package/templates/starter/src/components/diagram/node-form-helpers.ts +1 -4
  431. package/templates/starter/src/components/diagram/node-form-template-step-selection.ts +1 -4
  432. package/templates/starter/src/components/diagram/node-form.test.tsx +25 -0
  433. package/templates/starter/src/components/diagram/node-form.tsx +2 -12
  434. package/templates/starter/src/components/diagram/options-header-node.test.tsx +4 -1
  435. package/templates/starter/src/components/diagram/options-header-node.tsx +140 -130
  436. package/templates/starter/src/components/diagram/use-flow-diagram.ts +1 -2
  437. package/templates/starter/src/components/form/error-message.tsx +7 -7
  438. package/templates/starter/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
  439. package/templates/starter/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
  440. package/templates/starter/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
  441. package/templates/starter/src/components/navigation/entity-search-command.tsx +3 -9
  442. package/templates/starter/src/components/navigation/nav-link.tsx +60 -60
  443. package/templates/starter/src/components/test-case/test-case-form-helpers.test.ts +1 -5
  444. package/templates/starter/src/components/test-case/test-case-form-helpers.ts +1 -5
  445. package/templates/starter/src/components/test-case/test-case-picker-helpers.ts +8 -7
  446. package/templates/starter/src/components/test-case/test-case-picker.tsx +2 -6
  447. package/templates/starter/src/components/test-run/log-viewer.test.tsx +25 -0
  448. package/templates/starter/src/components/test-run/log-viewer.tsx +2 -2
  449. package/templates/starter/src/components/test-run/test-run-details-guards.ts +10 -1
  450. package/templates/starter/src/components/test-run/test-run-details.test.tsx +9 -19
  451. package/templates/starter/src/components/test-run/use-log-viewer.ts +2 -8
  452. package/templates/starter/src/components/test-run/use-test-run-header.ts +1 -4
  453. package/templates/starter/src/components/test-suite/test-suite-picker.tsx +1 -1
  454. package/templates/starter/src/components/theme/theme-provider.tsx +7 -1
  455. package/templates/starter/src/components/typography/page-header-subtitle.tsx +7 -7
  456. package/templates/starter/src/components/typography/page-header.tsx +7 -7
  457. package/templates/starter/src/components/ui/chart.tsx +2 -8
  458. package/templates/starter/src/components/ui/command.tsx +2 -5
  459. package/templates/starter/src/components/ui/data-table-column-header.tsx +3 -3
  460. package/templates/starter/src/components/ui/data-table.test.tsx +1 -8
  461. package/templates/starter/src/components/ui/dialog.tsx +1 -4
  462. package/templates/starter/src/components/ui/select.tsx +2 -2
  463. package/templates/starter/src/components/ui/separator.tsx +5 -1
  464. package/templates/starter/src/components/ui/skeleton.tsx +7 -7
  465. package/templates/starter/src/components/ui/table.tsx +1 -1
  466. package/templates/starter/src/components/ui/toaster.tsx +26 -26
  467. package/templates/starter/src/components/ui/tooltip.tsx +1 -1
  468. package/templates/starter/src/constants/form-opts/locator-group-form-opts.ts +1 -1
  469. package/templates/starter/src/lib/locator-group-file-utils.ts +5 -1
  470. package/templates/starter/src/lib/locator-picker/session-manager.ts +1 -2
  471. package/templates/starter/src/lib/metrics/metric-calculator.test.ts +105 -6
  472. package/templates/starter/src/lib/metrics/metric-calculator.ts +39 -40
  473. package/templates/starter/src/lib/sync/sync-executor.ts +1 -4
  474. package/templates/starter/src/lib/sync/sync-pending-counts.test.ts +201 -7
  475. package/templates/starter/src/lib/sync/sync-pending-counts.ts +81 -13
  476. package/templates/starter/src/lib/template-automation-paths.ts +1 -1
  477. package/templates/starter/src/lib/template-sync-utils.d.ts +14 -7
  478. package/templates/starter/src/lib/test-case-utils.ts +6 -6
  479. package/templates/starter/src/lib/test-run/log-formatter.ts +82 -83
  480. package/templates/starter/src/lib/test-run/report-parser.ts +352 -352
  481. package/templates/starter/src/lib/transformers/gherkin-converter.ts +42 -42
  482. package/templates/starter/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
  483. package/templates/starter/src/lib/utils/node-param-validation.ts +81 -81
  484. package/templates/starter/src/lib/utils/template-step-file-generator.ts +5 -3
  485. package/templates/starter/src/lib/utils/template-step-file-manager-intelligent.ts +11 -1
  486. package/templates/starter/src/services/dashboard/dashboard-service.test.ts +28 -1
  487. package/templates/starter/src/services/dashboard/dashboard-service.ts +2 -0
  488. package/templates/starter/src/services/locator/locator-service.test.ts +1 -3
  489. package/templates/starter/src/services/locator/locator-service.ts +3 -1
  490. package/templates/starter/src/services/locator/locator-sync-utils.test.ts +1 -4
  491. package/templates/starter/src/services/module/module-service.ts +1 -4
  492. package/templates/starter/src/services/report/report-service.test.ts +70 -6
  493. package/templates/starter/src/services/report/report-service.ts +52 -9
  494. package/templates/starter/src/services/shared/errors.ts +2 -4
  495. package/templates/starter/src/services/template-step/template-step-service.ts +3 -1
  496. package/templates/starter/src/services/template-step-group/template-step-group-service.ts +3 -1
  497. package/templates/starter/src/services/test-case/test-case-service.ts +0 -5
  498. package/templates/starter/src/services/test-run/test-run-service.test.ts +3 -6
  499. package/templates/starter/src/services/test-run/test-run-service.ts +12 -7
  500. package/templates/starter/src/services/test-suite/test-suite-service.test.ts +1 -5
  501. package/templates/starter/src/services/test-suite/test-suite-service.ts +2 -4
  502. package/templates/starter/src/types/form/actionHandler.ts +1 -5
  503. package/templates/starter/tsconfig.json +8 -8
@@ -49,14 +49,14 @@ type DbTestSuiteWithModule = Prisma.TestSuiteGetPayload<{ include: { module: tru
49
49
  */
50
50
  function extractFeatureLevelTags(parsedFeature: ParsedFeature): string[] {
51
51
  const tags: string[] = []
52
-
52
+
53
53
  for (const tagLine of parsedFeature.tags) {
54
54
  if (tagLine.startsWith('@')) {
55
55
  const splitTags = splitTagLine(tagLine)
56
56
  tags.push(...splitTags)
57
57
  }
58
58
  }
59
-
59
+
60
60
  return tags
61
61
  }
62
62
 
@@ -65,17 +65,17 @@ function extractFeatureLevelTags(parsedFeature: ParsedFeature): string[] {
65
65
  */
66
66
  async function scanTestSuitesFromFilesystem(featuresDir: string): Promise<TestSuiteFromFS[]> {
67
67
  const testSuites: TestSuiteFromFS[] = []
68
-
68
+
69
69
  console.log('📁 Scanning feature files...')
70
70
  const parsedFeatures = await scanFeatureFiles(featuresDir)
71
71
  console.log(` Found ${parsedFeatures.length} feature file(s)`)
72
-
72
+
73
73
  for (const parsedFeature of parsedFeatures) {
74
74
  try {
75
75
  const testSuiteName = extractTestSuiteNameFromFilename(parsedFeature.filePath)
76
76
  const modulePath = extractModulePathFromFilePath(parsedFeature.filePath, featuresDir)
77
77
  const tags = extractFeatureLevelTags(parsedFeature)
78
-
78
+
79
79
  testSuites.push({
80
80
  name: testSuiteName,
81
81
  description: parsedFeature.featureDescription || null,
@@ -87,7 +87,7 @@ async function scanTestSuitesFromFilesystem(featuresDir: string): Promise<TestSu
87
87
  console.error(` ❌ Error processing feature file '${parsedFeature.filePath}': ${error}`)
88
88
  }
89
89
  }
90
-
90
+
91
91
  return testSuites
92
92
  }
93
93
 
@@ -97,13 +97,13 @@ async function scanTestSuitesFromFilesystem(featuresDir: string): Promise<TestSu
97
97
  */
98
98
  async function findTagIdsByExpressions(tagExpressions: string[]): Promise<string[]> {
99
99
  const tagIds: string[] = []
100
-
100
+
101
101
  for (const tagExpression of tagExpressions) {
102
102
  try {
103
103
  const tag = await prisma.tag.findFirst({
104
104
  where: { tagExpression },
105
105
  })
106
-
106
+
107
107
  if (tag) {
108
108
  tagIds.push(tag.id)
109
109
  } else {
@@ -113,7 +113,7 @@ async function findTagIdsByExpressions(tagExpressions: string[]): Promise<string
113
113
  console.error(` ❌ Error finding tag '${tagExpression}': ${error}`)
114
114
  }
115
115
  }
116
-
116
+
117
117
  return tagIds
118
118
  }
119
119
 
@@ -128,7 +128,10 @@ async function resolveModuleId(modulePath: string) {
128
128
  return moduleId
129
129
  }
130
130
 
131
- async function findExistingTestSuite(testSuite: TestSuiteFromFS, moduleId: string): Promise<ExistingTestSuite | undefined> {
131
+ async function findExistingTestSuite(
132
+ testSuite: TestSuiteFromFS,
133
+ moduleId: string,
134
+ ): Promise<ExistingTestSuite | undefined> {
132
135
  const existingTestSuites = await prisma.testSuite.findMany({
133
136
  where: {
134
137
  moduleId,
@@ -150,7 +153,12 @@ function getSortedTagIds(existingTestSuite: ExistingTestSuite, tagIds: string[])
150
153
  }
151
154
  }
152
155
 
153
- function testSuiteNeedsUpdate(existingTestSuite: ExistingTestSuite, testSuite: TestSuiteFromFS, moduleId: string, tagIds: string[]) {
156
+ function testSuiteNeedsUpdate(
157
+ existingTestSuite: ExistingTestSuite,
158
+ testSuite: TestSuiteFromFS,
159
+ moduleId: string,
160
+ tagIds: string[],
161
+ ) {
154
162
  const { currentTagIds, newTagIds } = getSortedTagIds(existingTestSuite, tagIds)
155
163
 
156
164
  return (
@@ -346,15 +354,12 @@ async function deleteOrphanedTestSuites(fsTestSuiteKeys: Set<string>, result: Sy
346
354
  /**
347
355
  * Syncs test suites from filesystem to database
348
356
  */
349
- async function syncTestSuitesToDatabase(
350
- testSuitesFromFS: TestSuiteFromFS[],
351
- result: SyncResult,
352
- ): Promise<void> {
357
+ async function syncTestSuitesToDatabase(testSuitesFromFS: TestSuiteFromFS[], result: SyncResult): Promise<void> {
353
358
  console.log('\n✅ Syncing test suites to database...')
354
-
359
+
355
360
  // Track test suites from filesystem (by name + modulePath)
356
361
  const fsTestSuiteKeys = new Set<string>()
357
-
362
+
358
363
  for (const testSuite of testSuitesFromFS) {
359
364
  try {
360
365
  await syncFilesystemTestSuite(testSuite, fsTestSuiteKeys, result)
@@ -372,69 +377,69 @@ async function syncTestSuitesToDatabase(
372
377
  * Generates and displays sync summary
373
378
  */
374
379
  async function main(): Promise<SyncResult | void> {
375
- console.log('🔄 Starting test suites sync...')
376
- console.log('This will scan feature files and sync test suites to database.')
377
- console.log('Filesystem is the source of truth - test suites in DB but not in FS will be deleted.')
378
- console.log('Note: Test cases are not synced by this script (they will be handled separately).\n')
379
-
380
- await ensureAutomationWorkspaceReady()
381
- const featuresDir = getAutomationFeaturesDir()
382
-
383
- // Scan test suites from filesystem
384
- const testSuitesFromFS = await scanTestSuitesFromFilesystem(featuresDir)
385
-
386
- if (testSuitesFromFS.length === 0) {
387
- console.log('\n⚠️ No feature files found. Nothing to sync.')
388
- return
389
- }
390
-
391
- console.log(`\n📋 Found ${testSuitesFromFS.length} test suite(s) from feature files:`)
392
- for (const ts of testSuitesFromFS) {
393
- console.log(` - ${ts.name} (${ts.modulePath})`)
394
- }
395
-
396
- // Initialize result
397
- const result: SyncResult = {
398
- testSuitesScanned: testSuitesFromFS.length,
399
- testSuitesExisting: 0,
400
- testSuitesCreated: 0,
401
- testSuitesUpdated: 0,
402
- testSuitesDeleted: 0,
403
- errors: [],
404
- createdTestSuites: [],
405
- updatedTestSuites: [],
406
- deletedTestSuites: [],
407
- }
408
-
409
- // Sync to database
410
- await syncTestSuitesToDatabase(testSuitesFromFS, result)
411
-
412
- printSyncSummary(
413
- [
414
- { label: '📁 Test suites scanned', value: result.testSuitesScanned },
415
- { label: '✅ Test suites existing', value: result.testSuitesExisting },
416
- { label: '➕ Test suites created', value: result.testSuitesCreated },
417
- { label: '🔄 Test suites updated', value: result.testSuitesUpdated },
418
- { label: '🗑️ Test suites deleted', value: result.testSuitesDeleted },
419
- { label: '❌ Errors', value: result.errors.length },
420
- ],
421
- [
422
- {
423
- title: 'Created test suites',
424
- items: result.createdTestSuites.map(ts => `${ts.name} (${ts.modulePath})`),
425
- },
426
- {
427
- title: 'Updated test suites',
428
- items: result.updatedTestSuites.map(ts => `${ts.name} (${ts.modulePath})`),
429
- },
430
- {
431
- title: 'Deleted test suites',
432
- items: result.deletedTestSuites.map(ts => `${ts.name} (${ts.modulePath})`),
433
- },
434
- { title: 'Errors', items: result.errors },
435
- ],
436
- )
437
- return result
380
+ console.log('🔄 Starting test suites sync...')
381
+ console.log('This will scan feature files and sync test suites to database.')
382
+ console.log('Filesystem is the source of truth - test suites in DB but not in FS will be deleted.')
383
+ console.log('Note: Test cases are not synced by this script (they will be handled separately).\n')
384
+
385
+ await ensureAutomationWorkspaceReady()
386
+ const featuresDir = getAutomationFeaturesDir()
387
+
388
+ // Scan test suites from filesystem
389
+ const testSuitesFromFS = await scanTestSuitesFromFilesystem(featuresDir)
390
+
391
+ if (testSuitesFromFS.length === 0) {
392
+ console.log('\n⚠️ No feature files found. Nothing to sync.')
393
+ return
394
+ }
395
+
396
+ console.log(`\n📋 Found ${testSuitesFromFS.length} test suite(s) from feature files:`)
397
+ for (const ts of testSuitesFromFS) {
398
+ console.log(` - ${ts.name} (${ts.modulePath})`)
399
+ }
400
+
401
+ // Initialize result
402
+ const result: SyncResult = {
403
+ testSuitesScanned: testSuitesFromFS.length,
404
+ testSuitesExisting: 0,
405
+ testSuitesCreated: 0,
406
+ testSuitesUpdated: 0,
407
+ testSuitesDeleted: 0,
408
+ errors: [],
409
+ createdTestSuites: [],
410
+ updatedTestSuites: [],
411
+ deletedTestSuites: [],
412
+ }
413
+
414
+ // Sync to database
415
+ await syncTestSuitesToDatabase(testSuitesFromFS, result)
416
+
417
+ printSyncSummary(
418
+ [
419
+ { label: '📁 Test suites scanned', value: result.testSuitesScanned },
420
+ { label: '✅ Test suites existing', value: result.testSuitesExisting },
421
+ { label: '➕ Test suites created', value: result.testSuitesCreated },
422
+ { label: '🔄 Test suites updated', value: result.testSuitesUpdated },
423
+ { label: '🗑️ Test suites deleted', value: result.testSuitesDeleted },
424
+ { label: '❌ Errors', value: result.errors.length },
425
+ ],
426
+ [
427
+ {
428
+ title: 'Created test suites',
429
+ items: result.createdTestSuites.map(ts => `${ts.name} (${ts.modulePath})`),
430
+ },
431
+ {
432
+ title: 'Updated test suites',
433
+ items: result.updatedTestSuites.map(ts => `${ts.name} (${ts.modulePath})`),
434
+ },
435
+ {
436
+ title: 'Deleted test suites',
437
+ items: result.deletedTestSuites.map(ts => `${ts.name} (${ts.modulePath})`),
438
+ },
439
+ { title: 'Errors', items: result.errors },
440
+ ],
441
+ )
442
+ return result
438
443
  }
439
444
 
440
445
  runSyncScript(main)
@@ -22,13 +22,7 @@ import {
22
22
  listEnvironments,
23
23
  updateEnvironment,
24
24
  } from '@/services/environment/environment-service'
25
- import {
26
- createTag,
27
- deleteTags,
28
- getTagByIdOrThrow,
29
- listFilterTags,
30
- updateTag,
31
- } from '@/services/tag/tag-service'
25
+ import { createTag, deleteTags, getTagByIdOrThrow, listFilterTags, updateTag } from '@/services/tag/tag-service'
32
26
  import {
33
27
  checkLocatorGroupNameUnique,
34
28
  createLocatorGroup,
@@ -5,7 +5,9 @@ import { runRequestedSync, type SyncExecutionResult } from '@/lib/sync/sync-exec
5
5
  import { getSyncPendingCounts, type SyncPendingCounts } from '@/lib/sync/sync-pending-counts'
6
6
  import { isSyncRequestId } from '@/lib/sync/sync-registry'
7
7
 
8
- export async function runSyncAction(requestedScriptId: string): Promise<SyncExecutionResult | InvalidSyncExecutionResult> {
8
+ export async function runSyncAction(
9
+ requestedScriptId: string,
10
+ ): Promise<SyncExecutionResult | InvalidSyncExecutionResult> {
9
11
  if (!isSyncRequestId(requestedScriptId)) {
10
12
  return {
11
13
  requestedScriptId,
@@ -1,13 +1,7 @@
1
1
  'use server'
2
2
 
3
3
  import { tagSchema } from '@/constants/form-opts/tag-form-opts'
4
- import {
5
- createTag,
6
- deleteTags,
7
- getTagByIdOrThrow,
8
- listFilterTags,
9
- updateTag,
10
- } from '@/services/tag/tag-service'
4
+ import { createTag, deleteTags, getTagByIdOrThrow, listFilterTags, updateTag } from '@/services/tag/tag-service'
11
5
  import { ServiceError, serviceErrorToActionResponse, unknownErrorToActionResponse } from '@/services/shared/errors'
12
6
  import { ActionResponse } from '@/types/form/actionHandler'
13
7
  import { revalidatePath } from 'next/cache'
@@ -40,7 +40,9 @@ export async function deleteTemplateTestCaseAction(id: string[]): Promise<Action
40
40
  }
41
41
  }
42
42
 
43
- export async function createTemplateTestCaseAction(value: z.infer<typeof templateTestCaseSchema>): Promise<ActionResponse> {
43
+ export async function createTemplateTestCaseAction(
44
+ value: z.infer<typeof templateTestCaseSchema>,
45
+ ): Promise<ActionResponse> {
44
46
  try {
45
47
  templateTestCaseSchema.parse(value)
46
48
  const newTemplateTestCase = await createTemplateTestCase(value)
@@ -1,28 +1,28 @@
1
- import { createEnvironmentAction } from '@/actions/environments/environment-actions'
2
- import EnvironmentForm from '../environment-form'
3
- import PageHeader from '@/components/typography/page-header'
4
- import HeaderSubtitle from '@/components/typography/page-header-subtitle'
5
- import { Metadata } from 'next'
6
-
7
- export const metadata: Metadata = {
8
- title: 'Appraise | Create Environment',
9
- description: 'Create a new environment configuration for your test runs',
10
- }
11
-
12
- const CreateEnvironment = async () => {
13
- return (
14
- <>
15
- <div className="mb-8">
16
- <PageHeader>Create Environment</PageHeader>
17
- <HeaderSubtitle>Create a new environment configuration for your test runs.</HeaderSubtitle>
18
- </div>
19
- <EnvironmentForm
20
- successTitle="Environment created"
21
- successMessage="Environment created successfully"
22
- onSubmitAction={createEnvironmentAction}
23
- />
24
- </>
25
- )
26
- }
27
-
28
- export default CreateEnvironment
1
+ import { createEnvironmentAction } from '@/actions/environments/environment-actions'
2
+ import EnvironmentForm from '../environment-form'
3
+ import PageHeader from '@/components/typography/page-header'
4
+ import HeaderSubtitle from '@/components/typography/page-header-subtitle'
5
+ import { Metadata } from 'next'
6
+
7
+ export const metadata: Metadata = {
8
+ title: 'Appraise | Create Environment',
9
+ description: 'Create a new environment configuration for your test runs',
10
+ }
11
+
12
+ const CreateEnvironment = async () => {
13
+ return (
14
+ <>
15
+ <div className="mb-8">
16
+ <PageHeader>Create Environment</PageHeader>
17
+ <HeaderSubtitle>Create a new environment configuration for your test runs.</HeaderSubtitle>
18
+ </div>
19
+ <EnvironmentForm
20
+ successTitle="Environment created"
21
+ successMessage="Environment created successfully"
22
+ onSubmitAction={createEnvironmentAction}
23
+ />
24
+ </>
25
+ )
26
+ }
27
+
28
+ export default CreateEnvironment
@@ -10,7 +10,7 @@ import { useForm } from '@tanstack/react-form'
10
10
  import { TanStackForm } from '@/lib/form/tanstack-form'
11
11
  import { useRouter } from 'next/navigation'
12
12
  import { useState } from 'react'
13
- import { Eye, EyeOff } from 'lucide-react'
13
+ import { Eye, EyeOff, Save } from 'lucide-react'
14
14
  import {
15
15
  environmentFieldValidators,
16
16
  getActionErrorMessage,
@@ -210,7 +210,8 @@ const EnvironmentForm = ({ defaultValues, successTitle, successMessage, id, onSu
210
210
  <form.Subscribe selector={formState => [formState.canSubmit, formState.isSubmitting]}>
211
211
  {([canSubmit, isSubmitting]) => (
212
212
  <Button type="submit" disabled={!canSubmit}>
213
- {isSubmitting ? '...' : 'Save'}
213
+ <Save className="size-4" aria-hidden />
214
+ <span className="font-bold">{isSubmitting ? '...' : 'Save'}</span>
214
215
  </Button>
215
216
  )}
216
217
  </form.Subscribe>
@@ -1,4 +1,7 @@
1
- import { environmentSchema, type Environment as EnvironmentFormValues } from '@/constants/form-opts/environment-form-opts'
1
+ import {
2
+ environmentSchema,
3
+ type Environment as EnvironmentFormValues,
4
+ } from '@/constants/form-opts/environment-form-opts'
2
5
  import type { ActionResponse, ActionResponseData } from '@/types/form/actionHandler'
3
6
 
4
7
  export type EnvironmentTableRow = {
@@ -1,10 +1,10 @@
1
- /**
2
- * All (base) routes depend on server data (Prisma). Force dynamic rendering
3
- * so these pages are not statically generated at build time (e.g. in CI where
4
- * no database is available).
5
- */
6
- export const dynamic = 'force-dynamic'
7
-
8
- export default function BaseLayout({ children }: { children: React.ReactNode }) {
9
- return <>{children}</>
10
- }
1
+ /**
2
+ * All (base) routes depend on server data (Prisma). Force dynamic rendering
3
+ * so these pages are not statically generated at build time (e.g. in CI where
4
+ * no database is available).
5
+ */
6
+ export const dynamic = 'force-dynamic'
7
+
8
+ export default function BaseLayout({ children }: { children: React.ReactNode }) {
9
+ return <>{children}</>
10
+ }
@@ -3,10 +3,11 @@
3
3
  import { Button } from '@/components/ui/button'
4
4
  import { Input } from '@/components/ui/input'
5
5
  import { Label } from '@/components/ui/label'
6
- import { locatorGroupFormOpts, LocatorGroup } from '@/constants/form-opts/locator-group-form-opts'
6
+ import { locatorGroupFormOpts, locatorGroupSchema, LocatorGroup } from '@/constants/form-opts/locator-group-form-opts'
7
7
  import { toast } from '@/hooks/use-toast'
8
8
  import { ActionResponse } from '@/types/form/actionHandler'
9
9
  import { useForm } from '@tanstack/react-form'
10
+ import { Save } from 'lucide-react'
10
11
  import { TanStackForm } from '@/lib/form/tanstack-form'
11
12
  import React, { useCallback, useRef } from 'react'
12
13
  import { z } from 'zod'
@@ -174,7 +175,7 @@ const LocatorGroupForm = ({
174
175
  <form.Field
175
176
  name="route"
176
177
  validators={{
177
- onChange: z.string().optional(),
178
+ onChange: locatorGroupSchema.shape.route,
178
179
  }}
179
180
  >
180
181
  {field => {
@@ -204,7 +205,8 @@ const LocatorGroupForm = ({
204
205
  <form.Subscribe selector={formState => [formState.canSubmit, formState.isSubmitting]}>
205
206
  {([canSubmit, isSubmitting]) => (
206
207
  <Button type="submit" disabled={!canSubmit}>
207
- {isSubmitting ? '...' : 'Save'}
208
+ <Save className="size-4" aria-hidden />
209
+ <span className="font-bold">{isSubmitting ? '...' : 'Save'}</span>
208
210
  </Button>
209
211
  )}
210
212
  </form.Subscribe>
@@ -1,77 +1,77 @@
1
- 'use client'
2
-
3
- import { DataTableColumnHeader } from '@/components/ui/data-table-column-header'
4
- import { ColumnDef } from '@tanstack/react-table'
5
-
6
- import { Checkbox } from '@/components/ui/checkbox'
7
- import TableActions from '@/components/table/table-actions'
8
- import { LocatorGroup, Module } from '@prisma/client'
9
- import { formatDateTime } from '@/lib/utils'
10
- import { deleteLocatorGroupAction } from '@/actions/locator-groups/locator-group-actions'
11
- import { Badge } from '@/components/ui/badge'
12
-
13
- export const locatorGroupTableCols: ColumnDef<LocatorGroup & { module: Module }>[] = [
14
- {
15
- id: 'select',
16
- header: ({ table }) => (
17
- <Checkbox
18
- checked={table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')}
19
- onCheckedChange={value => table.toggleAllPageRowsSelected(!!value)}
20
- aria-label="Select all"
21
- className="mr-2"
22
- />
23
- ),
24
- cell: ({ row }) => (
25
- <Checkbox
26
- checked={row.getIsSelected()}
27
- onCheckedChange={value => row.toggleSelected(!!value)}
28
- aria-label="Select row"
29
- className="mr-2"
30
- />
31
- ),
32
- enableSorting: false,
33
- enableHiding: false,
34
- },
35
- {
36
- accessorKey: 'name',
37
- header: ({ column }) => <DataTableColumnHeader column={column} title="Name" />,
38
- },
39
- {
40
- accessorKey: 'module.name',
41
- header: ({ column }) => <DataTableColumnHeader column={column} title="Module" />,
42
- cell: ({ row }) => {
43
- const locatorGroup = row.original
44
- return <Badge variant="outline">{locatorGroup.module?.name}</Badge>
45
- },
46
- },
47
- {
48
- accessorKey: 'route',
49
- header: ({ column }) => <DataTableColumnHeader column={column} title="Route" />,
50
- },
51
- {
52
- accessorKey: 'createdAt',
53
- header: ({ column }) => <DataTableColumnHeader column={column} title="Created At" />,
54
- cell: ({ row }) => {
55
- return formatDateTime(row.original.createdAt)
56
- },
57
- },
58
- {
59
- accessorKey: 'updatedAt',
60
- header: ({ column }) => <DataTableColumnHeader column={column} title="Updated At" />,
61
- cell: ({ row }) => {
62
- return formatDateTime(row.original.updatedAt)
63
- },
64
- },
65
- {
66
- id: 'actions',
67
- cell: ({ row }) => {
68
- const locatorGroup = row.original
69
- return (
70
- <TableActions
71
- modifyLink={`/locator-groups/modify/${locatorGroup.id}`}
72
- deleteHandler={() => deleteLocatorGroupAction([locatorGroup.id])}
73
- />
74
- )
75
- },
76
- },
77
- ]
1
+ 'use client'
2
+
3
+ import { DataTableColumnHeader } from '@/components/ui/data-table-column-header'
4
+ import { ColumnDef } from '@tanstack/react-table'
5
+
6
+ import { Checkbox } from '@/components/ui/checkbox'
7
+ import TableActions from '@/components/table/table-actions'
8
+ import { LocatorGroup, Module } from '@prisma/client'
9
+ import { formatDateTime } from '@/lib/utils'
10
+ import { deleteLocatorGroupAction } from '@/actions/locator-groups/locator-group-actions'
11
+ import { Badge } from '@/components/ui/badge'
12
+
13
+ export const locatorGroupTableCols: ColumnDef<LocatorGroup & { module: Module }>[] = [
14
+ {
15
+ id: 'select',
16
+ header: ({ table }) => (
17
+ <Checkbox
18
+ checked={table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')}
19
+ onCheckedChange={value => table.toggleAllPageRowsSelected(!!value)}
20
+ aria-label="Select all"
21
+ className="mr-2"
22
+ />
23
+ ),
24
+ cell: ({ row }) => (
25
+ <Checkbox
26
+ checked={row.getIsSelected()}
27
+ onCheckedChange={value => row.toggleSelected(!!value)}
28
+ aria-label="Select row"
29
+ className="mr-2"
30
+ />
31
+ ),
32
+ enableSorting: false,
33
+ enableHiding: false,
34
+ },
35
+ {
36
+ accessorKey: 'name',
37
+ header: ({ column }) => <DataTableColumnHeader column={column} title="Name" />,
38
+ },
39
+ {
40
+ accessorKey: 'module.name',
41
+ header: ({ column }) => <DataTableColumnHeader column={column} title="Module" />,
42
+ cell: ({ row }) => {
43
+ const locatorGroup = row.original
44
+ return <Badge variant="outline">{locatorGroup.module?.name}</Badge>
45
+ },
46
+ },
47
+ {
48
+ accessorKey: 'route',
49
+ header: ({ column }) => <DataTableColumnHeader column={column} title="Route" />,
50
+ },
51
+ {
52
+ accessorKey: 'createdAt',
53
+ header: ({ column }) => <DataTableColumnHeader column={column} title="Created At" />,
54
+ cell: ({ row }) => {
55
+ return formatDateTime(row.original.createdAt)
56
+ },
57
+ },
58
+ {
59
+ accessorKey: 'updatedAt',
60
+ header: ({ column }) => <DataTableColumnHeader column={column} title="Updated At" />,
61
+ cell: ({ row }) => {
62
+ return formatDateTime(row.original.updatedAt)
63
+ },
64
+ },
65
+ {
66
+ id: 'actions',
67
+ cell: ({ row }) => {
68
+ const locatorGroup = row.original
69
+ return (
70
+ <TableActions
71
+ modifyLink={`/locator-groups/modify/${locatorGroup.id}`}
72
+ deleteHandler={() => deleteLocatorGroupAction([locatorGroup.id])}
73
+ />
74
+ )
75
+ },
76
+ },
77
+ ]
@@ -1,28 +1,28 @@
1
- import { deleteLocatorGroupAction, getAllLocatorGroupsAction } from '@/actions/locator-groups/locator-group-actions'
2
- import { DataTable } from '@/components/ui/data-table'
3
- import { LocatorGroup, Module } from '@prisma/client'
4
- import { locatorGroupTableCols } from './locator-group-table-columns'
5
-
6
- const LocatorGroupTable = async () => {
7
- const { data: locatorGroups, error: locatorGroupsError } = await getAllLocatorGroupsAction()
8
-
9
- if (locatorGroupsError) {
10
- return <div>Error: {locatorGroupsError}</div>
11
- }
12
-
13
- return (
14
- <>
15
- <DataTable
16
- columns={locatorGroupTableCols}
17
- data={locatorGroups as (LocatorGroup & { module: Module })[]}
18
- filterColumn="name"
19
- filterPlaceholder="Filter by name..."
20
- createLink="/locator-groups/create"
21
- modifyLink="/locator-groups/modify"
22
- deleteAction={deleteLocatorGroupAction}
23
- />
24
- </>
25
- )
26
- }
27
-
28
- export default LocatorGroupTable
1
+ import { deleteLocatorGroupAction, getAllLocatorGroupsAction } from '@/actions/locator-groups/locator-group-actions'
2
+ import { DataTable } from '@/components/ui/data-table'
3
+ import { LocatorGroup, Module } from '@prisma/client'
4
+ import { locatorGroupTableCols } from './locator-group-table-columns'
5
+
6
+ const LocatorGroupTable = async () => {
7
+ const { data: locatorGroups, error: locatorGroupsError } = await getAllLocatorGroupsAction()
8
+
9
+ if (locatorGroupsError) {
10
+ return <div>Error: {locatorGroupsError}</div>
11
+ }
12
+
13
+ return (
14
+ <>
15
+ <DataTable
16
+ columns={locatorGroupTableCols}
17
+ data={locatorGroups as (LocatorGroup & { module: Module })[]}
18
+ filterColumn="name"
19
+ filterPlaceholder="Filter by name..."
20
+ createLink="/locator-groups/create"
21
+ modifyLink="/locator-groups/modify"
22
+ deleteAction={deleteLocatorGroupAction}
23
+ />
24
+ </>
25
+ )
26
+ }
27
+
28
+ export default LocatorGroupTable