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
@@ -18,9 +18,7 @@ async function getLatestModifiedTime(targetPath: string): Promise<number> {
18
18
  }
19
19
 
20
20
  const entries = await readdir(targetPath, { withFileTypes: true })
21
- const times = await Promise.all(
22
- entries.map(entry => getLatestModifiedTime(path.join(targetPath, entry.name))),
23
- )
21
+ const times = await Promise.all(entries.map(entry => getLatestModifiedTime(path.join(targetPath, entry.name))))
24
22
 
25
23
  return Math.max(stats.mtimeMs, ...times)
26
24
  }
@@ -76,20 +76,14 @@ export function getLocatorPickerCrashLogPath(sessionId: string, repoRoot = proce
76
76
  return path.join(getLocatorPickerLogsDir(repoRoot), `${sessionId}.log`)
77
77
  }
78
78
 
79
- export async function removeLocatorPickerProfileDir(
80
- sessionId: string,
81
- repoRoot = process.cwd(),
82
- ): Promise<void> {
79
+ export async function removeLocatorPickerProfileDir(sessionId: string, repoRoot = process.cwd()): Promise<void> {
83
80
  await rm(getLocatorPickerProfileDir(sessionId, repoRoot), {
84
81
  force: true,
85
82
  recursive: true,
86
83
  }).catch(() => undefined)
87
84
  }
88
85
 
89
- export async function removeLocatorPickerSessionFile(
90
- sessionId: string,
91
- repoRoot = process.cwd(),
92
- ): Promise<void> {
86
+ export async function removeLocatorPickerSessionFile(sessionId: string, repoRoot = process.cwd()): Promise<void> {
93
87
  await unlink(getLocatorPickerSessionFilePath(sessionId, repoRoot)).catch(() => undefined)
94
88
  }
95
89
 
@@ -137,9 +131,7 @@ export async function ensureLocatorPickerDirectories(repoRoot = process.cwd()):
137
131
  await mkdir(localAppDataDir, { recursive: true })
138
132
  }
139
133
 
140
- export async function readLocatorPickerSessionFile(
141
- sessionFilePath: string,
142
- ): Promise<CompanionSessionFile | null> {
134
+ export async function readLocatorPickerSessionFile(sessionFilePath: string): Promise<CompanionSessionFile | null> {
143
135
  try {
144
136
  const raw = await readFile(sessionFilePath, 'utf8')
145
137
  return JSON.parse(raw) as CompanionSessionFile
@@ -148,10 +140,7 @@ export async function readLocatorPickerSessionFile(
148
140
  }
149
141
  }
150
142
 
151
- async function enqueueSessionFileOperation<T>(
152
- sessionFilePath: string,
153
- operation: () => Promise<T>,
154
- ): Promise<T> {
143
+ async function enqueueSessionFileOperation<T>(sessionFilePath: string, operation: () => Promise<T>): Promise<T> {
155
144
  const previousOperation = sessionFileOperationQueue.get(sessionFilePath) ?? Promise.resolve()
156
145
  const nextOperation = previousOperation.catch(() => undefined).then(operation)
157
146
 
@@ -1,13 +1,6 @@
1
1
  export type CompanionSessionStatus = 'starting' | 'ready' | 'picked' | 'saving' | 'closed' | 'error'
2
2
 
3
- export type CompanionPickedLocatorStrategy =
4
- | 'test-id'
5
- | 'role'
6
- | 'label'
7
- | 'placeholder'
8
- | 'id'
9
- | 'css'
10
- | 'xpath'
3
+ export type CompanionPickedLocatorStrategy = 'test-id' | 'role' | 'label' | 'placeholder' | 'id' | 'css' | 'xpath'
11
4
 
12
5
  export interface CompanionLaunchSource {
13
6
  environmentId?: string
@@ -0,0 +1,46 @@
1
+ import { defineConfig, devices } from '@playwright/test'
2
+
3
+ const port = Number(process.env.E2E_PORT ?? 3200)
4
+ const baseURL = process.env.PLAYWRIGHT_BASE_URL ?? `http://127.0.0.1:${port}`
5
+ const databaseUrl = process.env.DATABASE_URL ?? `file:./e2e-${Date.now()}.db`
6
+
7
+ process.env.DATABASE_URL = databaseUrl
8
+
9
+ export default defineConfig({
10
+ testDir: './e2e',
11
+ // Each spec resets and seeds the same SQLite database in beforeEach hooks.
12
+ // Parallel workers or files would race on that shared DB (local and CI).
13
+ fullyParallel: false,
14
+ workers: 1,
15
+ forbidOnly: !!process.env.CI,
16
+ timeout: 60_000,
17
+ grep: process.env.E2E_GREP ? new RegExp(process.env.E2E_GREP) : undefined,
18
+ expect: {
19
+ timeout: 10_000,
20
+ },
21
+ reporter: process.env.CI ? [['github'], ['list']] : 'list',
22
+ use: {
23
+ baseURL,
24
+ trace: 'on-first-retry',
25
+ screenshot: 'only-on-failure',
26
+ video: 'retain-on-failure',
27
+ },
28
+ projects: [
29
+ {
30
+ name: 'chromium',
31
+ use: { ...devices['Desktop Chrome'] },
32
+ },
33
+ ],
34
+ webServer: {
35
+ command: `node e2e/start-server.mjs ${port}`,
36
+ url: baseURL,
37
+ reuseExistingServer: !process.env.CI,
38
+ timeout: 120_000,
39
+ env: {
40
+ ...process.env,
41
+ DATABASE_URL: databaseUrl,
42
+ ENVIRONMENT: 'local',
43
+ NEXT_TELEMETRY_DISABLED: '1',
44
+ },
45
+ },
46
+ })
@@ -1,8 +1,8 @@
1
- /** @type {import('postcss-load-config').Config} */
2
- const config = {
3
- plugins: {
4
- tailwindcss: {},
5
- },
6
- };
7
-
8
- export default config;
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: {
4
+ tailwindcss: {},
5
+ },
6
+ }
7
+
8
+ export default config
Binary file
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Applies repo line-ending policy to the local clone so `git diff` matches
4
+ * .gitattributes / EditorConfig / Prettier (LF everywhere).
5
+ *
6
+ * Usage:
7
+ * node scripts/configure-git-line-endings.mjs
8
+ * node scripts/configure-git-line-endings.mjs --renormalize
9
+ */
10
+
11
+ import { execSync } from 'node:child_process'
12
+ import { existsSync } from 'node:fs'
13
+ import { dirname, join } from 'node:path'
14
+ import { fileURLToPath } from 'node:url'
15
+
16
+ const scriptDir = dirname(fileURLToPath(import.meta.url))
17
+ const repoRoot = join(scriptDir, '..')
18
+ const gitConfigInclude = '../.gitconfig.appraise'
19
+ const quiet = process.argv.includes('--quiet')
20
+
21
+ function log(message) {
22
+ if (!quiet) {
23
+ console.log(message)
24
+ }
25
+ }
26
+
27
+ function runGit(args, options = {}) {
28
+ const stdio = options.stdio ?? ['pipe', 'pipe', 'pipe']
29
+ const result = execSync(['git', ...args].join(' '), {
30
+ cwd: repoRoot,
31
+ encoding: 'utf8',
32
+ stdio,
33
+ ...options,
34
+ })
35
+
36
+ if (stdio !== 'inherit' && result != null) {
37
+ return String(result).trim()
38
+ }
39
+
40
+ return ''
41
+ }
42
+
43
+ function isGitRepository() {
44
+ return existsSync(join(repoRoot, '.git'))
45
+ }
46
+
47
+ function getLocalConfig(key) {
48
+ try {
49
+ return runGit(['config', '--local', '--get', key])
50
+ } catch {
51
+ return null
52
+ }
53
+ }
54
+
55
+ function setLocalConfig(key, value) {
56
+ runGit(['config', '--local', key, value], { stdio: 'inherit' })
57
+ }
58
+
59
+ function ensureGitInclude() {
60
+ const current = getLocalConfig('include.path')
61
+ if (current === gitConfigInclude) {
62
+ return false
63
+ }
64
+
65
+ setLocalConfig('include.path', gitConfigInclude)
66
+ log(`Linked local git config: include.path = ${gitConfigInclude}`)
67
+ return true
68
+ }
69
+
70
+ function main() {
71
+ if (!isGitRepository()) {
72
+ log('Not a git repository; skipping git line-ending configuration.')
73
+ return
74
+ }
75
+
76
+ const updatedInclude = ensureGitInclude()
77
+
78
+ if (!updatedInclude && !quiet) {
79
+ log('Git line-ending settings already use .gitconfig.appraise (LF, autocrlf=false).')
80
+ }
81
+
82
+ if (process.argv.includes('--renormalize')) {
83
+ log('Staging removals so renormalize does not fail on deleted tracked paths...')
84
+ runGit(['add', '-u'], { stdio: 'inherit' })
85
+ log('Renormalizing line endings in the index (may update staged content)...')
86
+ runGit(['add', '--renormalize', '.'], { stdio: 'inherit' })
87
+ log('Renormalize complete. Review with: git status')
88
+ }
89
+ }
90
+
91
+ main()
@@ -65,7 +65,11 @@ function getRunArgs(packageManager: 'npm' | 'pnpm' | 'yarn' | 'bun', scriptName:
65
65
  return ['run', scriptName]
66
66
  }
67
67
 
68
- async function runScript(projectRoot: string, packageManager: 'npm' | 'pnpm' | 'yarn' | 'bun', scriptName: string): Promise<void> {
68
+ async function runScript(
69
+ projectRoot: string,
70
+ packageManager: 'npm' | 'pnpm' | 'yarn' | 'bun',
71
+ scriptName: string,
72
+ ): Promise<void> {
69
73
  await new Promise<void>((resolve, reject) => {
70
74
  const child = spawn(packageManager, getRunArgs(packageManager, scriptName), {
71
75
  cwd: projectRoot,
@@ -79,8 +79,8 @@ describe('sameResolvedParameters', () => {
79
79
  })
80
80
 
81
81
  it('returns false for different values', () => {
82
- expect(
83
- sameResolvedParameters(sample, [{ name: 'x', value: '2', order: 0, type: StepParameterType.NUMBER }]),
84
- ).toBe(false)
82
+ expect(sameResolvedParameters(sample, [{ name: 'x', value: '2', order: 0, type: StepParameterType.NUMBER }])).toBe(
83
+ false,
84
+ )
85
85
  })
86
86
  })
@@ -75,7 +75,11 @@ export function findMatchingTemplateStep(
75
75
  templateSteps: TemplateStepCandidate[],
76
76
  ): TemplateStepMatch | null {
77
77
  for (const templateStep of templateSteps) {
78
- const parameters = extractParametersFromGherkinStep(gherkinStep.text, templateStep.signature, templateStep.parameters)
78
+ const parameters = extractParametersFromGherkinStep(
79
+ gherkinStep.text,
80
+ templateStep.signature,
81
+ templateStep.parameters,
82
+ )
79
83
  if (parameters) {
80
84
  return {
81
85
  templateStepId: templateStep.id,
@@ -116,7 +116,7 @@ When('click {string}', async function () {})`),
116
116
  expect(result.status).toBe('installed')
117
117
  const content = await fs.readFile(path.join(workspace, 'automation/steps/actions/click.step.ts'), 'utf8')
118
118
  expect(content).toContain("import { helper } from './helper'")
119
- expect(content).toContain("// Existing note")
119
+ expect(content).toContain('// Existing note')
120
120
  expect(content).toContain("When('existing click'")
121
121
  expect(content).toContain("When('click {string}'")
122
122
  expect(content).toContain('Then')
@@ -185,7 +185,9 @@ When('click {string}', async function () {
185
185
  await Promise.resolve('new')
186
186
  })`)
187
187
 
188
- await expect(installTemplateStepPayload(payload, { projectRoot: workspace })).rejects.toThrow('Re-run with --overwrite')
188
+ await expect(installTemplateStepPayload(payload, { projectRoot: workspace })).rejects.toThrow(
189
+ 'Re-run with --overwrite',
190
+ )
189
191
 
190
192
  const overwriteResult = await installTemplateStepPayload(payload, {
191
193
  projectRoot: workspace,
@@ -33,7 +33,10 @@ type ExistingStepMatch = {
33
33
  source: string
34
34
  }
35
35
 
36
- const STEP_FILE_PATTERNS = ['automation/steps/actions/**/*.step.ts', 'automation/steps/validations/**/*.step.ts'] as const
36
+ const STEP_FILE_PATTERNS = [
37
+ 'automation/steps/actions/**/*.step.ts',
38
+ 'automation/steps/validations/**/*.step.ts',
39
+ ] as const
37
40
  const RUNTIME_IMPORT_PATH = '../../../packages/cucumber-runtime/src/index.js'
38
41
  const REQUIRED_RUNTIME_IMPORTS = [
39
42
  'When',
@@ -46,7 +49,8 @@ const REQUIRED_RUNTIME_IMPORTS = [
46
49
  'generateRandomData',
47
50
  'RandomDataType',
48
51
  ] as const
49
- const PLACEHOLDER_COMMENT = '// This file is generated automatically. Add template steps to this group to generate content.'
52
+ const PLACEHOLDER_COMMENT =
53
+ '// This file is generated automatically. Add template steps to this group to generate content.'
50
54
 
51
55
  function parseTypeScriptModule(content: string) {
52
56
  return parse(content, {
@@ -68,7 +72,13 @@ function getGroupDirectoryName(type: TemplateStepGroupType): 'actions' | 'valida
68
72
  }
69
73
 
70
74
  function getGroupFilePath(projectRoot: string, groupName: string, type: TemplateStepGroupType): string {
71
- return path.join(projectRoot, 'automation', 'steps', getGroupDirectoryName(type), `${getGroupFileName(groupName)}.step.ts`)
75
+ return path.join(
76
+ projectRoot,
77
+ 'automation',
78
+ 'steps',
79
+ getGroupDirectoryName(type),
80
+ `${getGroupFileName(groupName)}.step.ts`,
81
+ )
72
82
  }
73
83
 
74
84
  function generateGroupJSDoc(name: string, description: string | null, type: TemplateStepGroupType): string {
@@ -289,7 +299,9 @@ async function buildUpdatedGroupFileContent(
289
299
  })
290
300
  }
291
301
 
292
- const sections = [generateGroupJSDoc(payload.step.group.name, payload.step.group.description, payload.step.group.type)]
302
+ const sections = [
303
+ generateGroupJSDoc(payload.step.group.name, payload.step.group.description, payload.step.group.type),
304
+ ]
293
305
  const mergedImports = mergeImports(existingContent)
294
306
  if (mergedImports.trim()) {
295
307
  sections.push(mergedImports)
@@ -73,7 +73,7 @@ When('click {string}', async function (this: CustomWorld, elementName: SelectorN
73
73
  expect(registry.fragments).toEqual([
74
74
  {
75
75
  path: 'fragments/click/click-element.ts',
76
- content: expect.stringContaining("@name click element"),
76
+ content: expect.stringContaining('@name click element'),
77
77
  },
78
78
  ])
79
79
  expect(registry.fragments[0]?.content).toContain("When('click {string}'")
@@ -37,7 +37,10 @@ export type BuiltStepRegistry = {
37
37
  fragments: StepRegistryFragment[]
38
38
  }
39
39
 
40
- const STEP_FILE_PATTERNS = ['automation/steps/actions/**/*.step.ts', 'automation/steps/validations/**/*.step.ts'] as const
40
+ const STEP_FILE_PATTERNS = [
41
+ 'automation/steps/actions/**/*.step.ts',
42
+ 'automation/steps/validations/**/*.step.ts',
43
+ ] as const
41
44
 
42
45
  export function slugifyRegistryName(value: string): string {
43
46
  return value
@@ -4,16 +4,14 @@ import path from 'node:path'
4
4
 
5
5
  const scriptDir = path.dirname(fileURLToPath(import.meta.url))
6
6
  const repoRoot = path.resolve(scriptDir, '..')
7
- const fallowBin = path.join(repoRoot, 'node_modules', '.bin', 'fallow')
7
+ // Invoke the package CLI via node — Windows cannot spawn extensionless .bin shims directly.
8
+ const fallowCli = path.join(repoRoot, 'node_modules', 'fallow', 'bin', 'fallow')
9
+ const fallowArgs = ['audit', '--base', 'HEAD', '--format', 'json', '--quiet', '--explain', '--fail-on-issues']
8
10
 
9
11
  const env = { ...process.env }
10
12
  delete env.GIT_INDEX_FILE
11
13
 
12
- const result = spawnSync(
13
- fallowBin,
14
- ['audit', '--base', 'HEAD', '--format', 'json', '--quiet', '--explain', '--fail-on-issues'],
15
- { cwd: repoRoot, env, stdio: 'inherit' },
16
- )
14
+ const result = spawnSync(process.execPath, [fallowCli, ...fallowArgs], { cwd: repoRoot, env, stdio: 'inherit' })
17
15
 
18
16
  if (result.error) {
19
17
  console.error(result.error)
@@ -200,7 +200,7 @@ function displaySummary(summary: SyncSummary): void {
200
200
  const status = result.success ? '✅' : '❌'
201
201
  const duration = `${(result.duration / 1000).toFixed(2)}s`
202
202
  console.log(` ${index + 1}. ${status} ${result.name} (${result.description}) - ${duration}`)
203
-
203
+
204
204
  if (!result.success) {
205
205
  if (result.exitCode !== null) {
206
206
  console.log(` Exit code: ${result.exitCode}`)
@@ -252,7 +252,7 @@ async function main(): Promise<number> {
252
252
  for (const scriptId of SYNC_SCRIPT_IDS) {
253
253
  const result = await executeSyncScript(scriptId)
254
254
  results.push(result)
255
-
255
+
256
256
  // Continue execution even if script failed (as per user requirement)
257
257
  // The script will log the failure but continue with remaining scripts
258
258
  }
@@ -278,10 +278,11 @@ async function main(): Promise<number> {
278
278
  }
279
279
 
280
280
  // Run the main function
281
- main().catch(error => {
282
- console.error('\n❌ Fatal error during sync orchestration:', error)
283
- return 1
284
- })
281
+ main()
282
+ .catch(error => {
283
+ console.error('\n❌ Fatal error during sync orchestration:', error)
284
+ return 1
285
+ })
285
286
  .then(exitCode => {
286
287
  process.exit(exitCode)
287
288
  })
@@ -145,89 +145,96 @@ function main(): void {
145
145
  console.log('Copying src/...')
146
146
  copyDirWithFilter(join(repoRoot, 'src'), join(target, 'src'))
147
147
 
148
- console.log('Copying automation/...')
149
- copyDirWithFilter(join(repoRoot, 'automation'), join(target, 'automation'))
150
- syncLegacyEnvironmentConfig()
151
- resetAutomationReports(target)
152
- resetAutomationLocatorMap(target)
153
-
154
- for (const internalPackage of INTERNAL_PACKAGES) {
155
- console.log(`Copying internal package ${internalPackage.name}...`)
156
- syncInternalPackage(internalPackage)
157
- }
158
-
159
- console.log('Copying prisma/...')
160
- copyDirWithFilter(join(repoRoot, 'prisma'), join(target, 'prisma'))
161
- console.log('Copying public/...')
162
- copyDirWithFilter(join(repoRoot, 'public'), join(target, 'public'))
163
- console.log('Copying scripts/...')
164
- copyDirWithFilter(join(repoRoot, 'scripts'), join(target, 'scripts'))
148
+ console.log('Copying automation/...')
149
+ copyDirWithFilter(join(repoRoot, 'automation'), join(target, 'automation'))
150
+ syncLegacyEnvironmentConfig()
151
+ resetAutomationReports(target)
152
+ resetAutomationLocatorMap(target)
153
+
154
+ for (const internalPackage of INTERNAL_PACKAGES) {
155
+ console.log(`Copying internal package ${internalPackage.name}...`)
156
+ syncInternalPackage(internalPackage)
157
+ }
165
158
 
166
- const legacyTestsRoot = join(target, 'src', 'tests')
167
- if (existsSync(legacyTestsRoot)) {
168
- rmSync(legacyTestsRoot, { recursive: true, force: true })
169
- }
159
+ console.log('Copying prisma/...')
160
+ copyDirWithFilter(join(repoRoot, 'prisma'), join(target, 'prisma'))
161
+ console.log('Copying public/...')
162
+ copyDirWithFilter(join(repoRoot, 'public'), join(target, 'public'))
163
+ console.log('Copying scripts/...')
164
+ copyDirWithFilter(join(repoRoot, 'scripts'), join(target, 'scripts'))
165
+ console.log('Copying e2e/...')
166
+ copyDirWithFilter(join(repoRoot, 'e2e'), join(target, 'e2e'))
167
+
168
+ const legacyTestsRoot = join(target, 'src', 'tests')
169
+ if (existsSync(legacyTestsRoot)) {
170
+ rmSync(legacyTestsRoot, { recursive: true, force: true })
171
+ }
170
172
 
171
- const configFiles = [
172
- '.gitignore',
173
- 'eslint.config.mjs',
174
- 'tailwind.config.ts',
175
- 'tsconfig.json',
176
- 'postcss.config.mjs',
177
- 'components.json',
178
- 'next.config.ts',
179
- 'next-env.d.ts',
180
- '.env.example',
181
- 'package-lock.json',
182
- 'yarn.lock',
183
- 'pnpm-lock.yaml',
184
- 'bun.lockb',
185
- ]
186
- for (const name of configFiles) {
187
- const src = join(repoRoot, name)
188
- if (existsSync(src)) {
189
- copyFile(src, join(target, name))
173
+ const configFiles = [
174
+ '.gitattributes',
175
+ '.gitconfig.appraise',
176
+ '.editorconfig',
177
+ '.prettierrc',
178
+ '.gitignore',
179
+ 'eslint.config.mjs',
180
+ 'tailwind.config.ts',
181
+ 'tsconfig.json',
182
+ 'postcss.config.mjs',
183
+ 'components.json',
184
+ 'next.config.ts',
185
+ 'next-env.d.ts',
186
+ 'playwright.config.ts',
187
+ '.env.example',
188
+ 'package-lock.json',
189
+ 'yarn.lock',
190
+ 'pnpm-lock.yaml',
191
+ 'bun.lockb',
192
+ ]
193
+ for (const name of configFiles) {
194
+ const src = join(repoRoot, name)
195
+ if (existsSync(src)) {
196
+ copyFile(src, join(target, name))
197
+ }
190
198
  }
191
- }
192
199
 
193
- const cucumberSource = join(repoRoot, 'cucumber.mjs')
194
- if (existsSync(cucumberSource)) {
195
- copyFile(cucumberSource, join(target, 'cucumber.mjs'))
196
- console.log('Synced cucumber.mjs to template')
197
- }
200
+ const cucumberSource = join(repoRoot, 'cucumber.mjs')
201
+ if (existsSync(cucumberSource)) {
202
+ copyFile(cucumberSource, join(target, 'cucumber.mjs'))
203
+ console.log('Synced cucumber.mjs to template')
204
+ }
198
205
 
199
- const vscodeSource = join(repoRoot, '.vscode')
200
- if (existsSync(vscodeSource)) {
201
- cpSync(vscodeSource, join(target, '.vscode'), { recursive: true, force: true })
202
- console.log('Synced .vscode to template')
203
- }
206
+ const vscodeSource = join(repoRoot, '.vscode')
207
+ if (existsSync(vscodeSource)) {
208
+ cpSync(vscodeSource, join(target, '.vscode'), { recursive: true, force: true })
209
+ console.log('Synced .vscode to template')
210
+ }
204
211
 
205
- const rootPkg = JSON.parse(readFileSync(join(repoRoot, 'package.json'), 'utf8')) as {
206
- scripts: Record<string, string>
207
- [key: string]: unknown
208
- }
209
- rootPkg.scripts = {
210
- ...rootPkg.scripts,
211
- build: 'npm run build:local',
212
- 'build:local':
213
- 'npm run generate-db-client && npm run build:cucumber-runtime && npm run build:locator-picker-companion && next build',
214
- start: 'next start',
215
- 'generate-db-client': 'npx prisma generate --schema prisma/schema.prisma',
216
- 'migrate-db': 'npx prisma migrate deploy',
217
- 'install-playwright': 'npx playwright install',
218
- setup: 'npm run install-dependencies && npm run setup:db && npm run build:local && npm run protect-seeded-files',
219
- 'setup:db': 'npm run setup-env && npm run generate-db-client && npm run migrate-db && npm run sync-all',
220
- 'setup:full':
221
- 'npm run install-dependencies && npm run setup:db && npm run build:local && npm run protect-seeded-files',
222
- 'protect-seeded-files': 'npx tsx scripts/protect-seeded-files.ts',
223
- 'appraisejs:setup': 'npm run setup',
224
- 'appraisejs:sync': 'npm run sync-all',
225
- 'appraisejs:install-step': 'npx tsx scripts/install-template-step.ts',
226
- }
227
- delete rootPkg.scripts['build:appraisejs']
228
- delete rootPkg.scripts['build-step-registry']
229
- writeFileSync(join(target, 'package.json'), JSON.stringify(rootPkg, null, 2) + '\n')
230
- console.log('Wrote template package.json with production-first scaffold scripts.')
212
+ const rootPkg = JSON.parse(readFileSync(join(repoRoot, 'package.json'), 'utf8')) as {
213
+ scripts: Record<string, string>
214
+ [key: string]: unknown
215
+ }
216
+ rootPkg.scripts = {
217
+ ...rootPkg.scripts,
218
+ build: 'npm run build:local',
219
+ 'build:local':
220
+ 'npm run generate-db-client && npm run build:cucumber-runtime && npm run build:locator-picker-companion && next build',
221
+ start: 'next start',
222
+ 'generate-db-client': 'npx prisma generate --schema prisma/schema.prisma',
223
+ 'migrate-db': 'npx prisma migrate deploy',
224
+ 'install-playwright': 'npx playwright install',
225
+ setup: 'npm run install-dependencies && npm run setup:db && npm run build:local && npm run protect-seeded-files',
226
+ 'setup:db': 'npm run setup-env && npm run generate-db-client && npm run migrate-db && npm run sync-all',
227
+ 'setup:full':
228
+ 'npm run install-dependencies && npm run setup:db && npm run build:local && npm run protect-seeded-files',
229
+ 'protect-seeded-files': 'npx tsx scripts/protect-seeded-files.ts',
230
+ 'appraisejs:setup': 'npm run setup',
231
+ 'appraisejs:sync': 'npm run sync-all',
232
+ 'appraisejs:install-step': 'npx tsx scripts/install-template-step.ts',
233
+ }
234
+ delete rootPkg.scripts['build:appraisejs']
235
+ delete rootPkg.scripts['build-step-registry']
236
+ writeFileSync(join(target, 'package.json'), JSON.stringify(rootPkg, null, 2) + '\n')
237
+ console.log('Wrote template package.json with production-first scaffold scripts.')
231
238
 
232
239
  if (savedReadme) {
233
240
  writeFileSync(readmePath, savedReadme)