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
@@ -1,24 +1,24 @@
1
- {
2
- "$schema": "https://ui.shadcn.com/schema.json",
3
- "style": "new-york",
4
- "rsc": true,
5
- "tsx": true,
6
- "tailwind": {
7
- "config": "tailwind.config.ts",
8
- "css": "src/app/globals.css",
9
- "baseColor": "slate",
10
- "cssVariables": true,
11
- "prefix": ""
12
- },
13
- "iconLibrary": "lucide",
14
- "aliases": {
15
- "components": "@/components",
16
- "utils": "@/lib/utils",
17
- "ui": "@/components/ui",
18
- "lib": "@/lib",
19
- "hooks": "@/hooks"
20
- },
21
- "registries": {
22
- "@kokonutui": "https://kokonutui.com/r/{name}.json"
23
- }
24
- }
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "new-york",
4
+ "rsc": true,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "tailwind.config.ts",
8
+ "css": "src/app/globals.css",
9
+ "baseColor": "slate",
10
+ "cssVariables": true,
11
+ "prefix": ""
12
+ },
13
+ "iconLibrary": "lucide",
14
+ "aliases": {
15
+ "components": "@/components",
16
+ "utils": "@/lib/utils",
17
+ "ui": "@/components/ui",
18
+ "lib": "@/lib",
19
+ "hooks": "@/hooks"
20
+ },
21
+ "registries": {
22
+ "@kokonutui": "https://kokonutui.com/r/{name}.json"
23
+ }
24
+ }
@@ -1,16 +1,16 @@
1
- // eslint-disable-next-line import/no-anonymous-default-export
2
- export default {
3
- paths: ['automation/features/**/*.feature'],
4
- import: [
5
- 'packages/cucumber-runtime/src/parameter-types.ts',
6
- 'automation/steps/**/*.ts',
7
- 'packages/cucumber-runtime/src/hooks.ts',
8
- 'packages/cucumber-runtime/src/world.ts',
9
- ],
10
- loader: ['ts-node/esm'],
11
- format: [
12
- 'pretty',
13
- process.env.REPORT_FORMAT ?? `json:${process.env.REPORT_PATH ?? 'automation/reports/cucumber.json'}`,
14
- ],
15
- publishQuiet: true,
16
- }
1
+ // eslint-disable-next-line import/no-anonymous-default-export
2
+ export default {
3
+ paths: ['automation/features/**/*.feature'],
4
+ import: [
5
+ 'packages/cucumber-runtime/src/parameter-types.ts',
6
+ 'automation/steps/**/*.ts',
7
+ 'packages/cucumber-runtime/src/hooks.ts',
8
+ 'packages/cucumber-runtime/src/world.ts',
9
+ ],
10
+ loader: ['ts-node/esm'],
11
+ format: [
12
+ 'pretty',
13
+ process.env.REPORT_FORMAT ?? `json:${process.env.REPORT_PATH ?? 'automation/reports/cucumber.json'}`,
14
+ ],
15
+ publishQuiet: true,
16
+ }
@@ -0,0 +1,56 @@
1
+ # AppraiseJS E2E tests
2
+
3
+ Playwright UI tests run against a local Next.js server with an isolated SQLite database. Data is reset and seeded before each test via Prisma helpers in `e2e/helpers/test-data.ts`.
4
+
5
+ ## Commands
6
+
7
+ - `npm run validate:e2e` — full suite (used in CI)
8
+ - `npm run validate:e2e:smoke` — smoke gate only (`@smoke` tag)
9
+ - `E2E_GREP=@crud npx playwright test` — run a tagged subset locally
10
+
11
+ ## CI and parallelism
12
+
13
+ GitHub Actions runs `npm run validate:e2e` after `npm run build` with `DATABASE_URL=file:./e2e.db`
14
+ and `CI=true`. The Playwright web server starts via `e2e/start-server.mjs`, which recreates the
15
+ E2E database and applies migrations before serving the production build.
16
+
17
+ Keep `workers: 1` and `fullyParallel: false` in `playwright.config.ts` until each worker gets an
18
+ isolated database. Spec files reset and seed the same SQLite file in `beforeEach`, so parallel
19
+ workers cause unique-constraint and foreign-key failures in CI and locally.
20
+
21
+ ## Layout
22
+
23
+ | File | Purpose |
24
+ | --- | --- |
25
+ | `appraise-smoke.spec.ts` | Fast regression gate |
26
+ | `navigation.spec.ts` | Route matrix and dashboard attention links |
27
+ | `crud-configuration.spec.ts` | Configuration entity CRUD |
28
+ | `crud-tests.spec.ts` | Suites, cases, template-based create |
29
+ | `authoring.spec.ts` | Inline dialogs, flow panel, authoring |
30
+ | `runs-and-reports.spec.ts` | Seeded runs, reports, create form (no execution) |
31
+ | `settings-sync.spec.ts` | Per-script sync buttons |
32
+
33
+ Helpers live under `e2e/helpers/` (`ui`, `navigation`, `table`, `forms`, `test-data`).
34
+
35
+ ## Seed model
36
+
37
+ `seedCoreData()` provisions modules, environments, tags, locators, template steps, a test case and suite, a completed run with report, and dashboard metric variants (failed, queued, running runs; attention metrics for drawer links).
38
+
39
+ Seeded IDs are exported as `seededIds` for deep-link tests.
40
+
41
+ ## Scope boundaries
42
+
43
+ **In scope:** UI flows with deterministic Prisma seed data.
44
+
45
+ **Out of scope (covered elsewhere):**
46
+
47
+ - Live `cucumber-js` execution and report JSON ingestion during E2E
48
+ - Locator picker companion / external browser extension flows
49
+ - Bidirectional feature sync CLI unless exposed in Settings UI
50
+
51
+ ## Debugging
52
+
53
+ - Traces: `trace: 'on-first-retry'` in `playwright.config.ts`
54
+ - Videos/screenshots retained on failure
55
+ - Run a single file: `npx playwright test e2e/navigation.spec.ts`
56
+ - UI mode: `npx playwright test --ui`
@@ -0,0 +1,76 @@
1
+ import { createHash, randomUUID } from 'node:crypto'
2
+ import { existsSync, readFileSync, readdirSync } from 'node:fs'
3
+ import { isAbsolute, join, resolve } from 'node:path'
4
+ import { DatabaseSync } from 'node:sqlite'
5
+
6
+ function sqlitePathFromDatabaseUrl(value) {
7
+ if (!value?.startsWith('file:')) {
8
+ throw new Error(`E2E SQLite setup expects a file: DATABASE_URL, received ${value || '<empty>'}`)
9
+ }
10
+
11
+ const sqlitePath = value.replace(/^file:/, '')
12
+ return isAbsolute(sqlitePath) ? sqlitePath : resolve(process.cwd(), 'prisma', sqlitePath)
13
+ }
14
+
15
+ const databaseUrl = process.env.DATABASE_URL ?? 'file:./e2e.db'
16
+ const databasePath = sqlitePathFromDatabaseUrl(databaseUrl)
17
+ const migrationsDir = resolve(process.cwd(), 'prisma', 'migrations')
18
+ const db = new DatabaseSync(databasePath)
19
+
20
+ db.exec(`
21
+ CREATE TABLE IF NOT EXISTS "_prisma_migrations" (
22
+ "id" TEXT PRIMARY KEY NOT NULL,
23
+ "checksum" TEXT NOT NULL,
24
+ "finished_at" DATETIME,
25
+ "migration_name" TEXT NOT NULL,
26
+ "logs" TEXT,
27
+ "rolled_back_at" DATETIME,
28
+ "started_at" DATETIME NOT NULL DEFAULT current_timestamp,
29
+ "applied_steps_count" INTEGER UNSIGNED NOT NULL DEFAULT 0
30
+ );
31
+ `)
32
+
33
+ const appliedRows = db.prepare('SELECT migration_name FROM "_prisma_migrations"').all()
34
+ const appliedMigrations = new Set(appliedRows.map(row => row.migration_name))
35
+ const insertMigration = db.prepare(`
36
+ INSERT INTO "_prisma_migrations" (
37
+ id,
38
+ checksum,
39
+ finished_at,
40
+ migration_name,
41
+ logs,
42
+ rolled_back_at,
43
+ applied_steps_count
44
+ ) VALUES (?, ?, current_timestamp, ?, NULL, NULL, 1)
45
+ `)
46
+
47
+ const migrationNames = readdirSync(migrationsDir, { withFileTypes: true })
48
+ .filter(entry => entry.isDirectory())
49
+ .map(entry => entry.name)
50
+ .sort()
51
+
52
+ for (const migrationName of migrationNames) {
53
+ if (appliedMigrations.has(migrationName)) {
54
+ continue
55
+ }
56
+
57
+ const migrationPath = join(migrationsDir, migrationName, 'migration.sql')
58
+ if (!existsSync(migrationPath)) {
59
+ continue
60
+ }
61
+
62
+ const sql = readFileSync(migrationPath, 'utf8')
63
+ const checksum = createHash('sha256').update(sql).digest('hex')
64
+
65
+ db.exec('BEGIN')
66
+ try {
67
+ db.exec(sql)
68
+ insertMigration.run(randomUUID(), checksum, migrationName)
69
+ db.exec('COMMIT')
70
+ } catch (error) {
71
+ db.exec('ROLLBACK')
72
+ throw error
73
+ }
74
+ }
75
+
76
+ db.close()
@@ -0,0 +1,78 @@
1
+ import { test, expect } from '@playwright/test'
2
+
3
+ import {
4
+ disconnectPrisma,
5
+ findModuleByName,
6
+ generateSeededFeature,
7
+ readGeneratedFeature,
8
+ resetE2eData,
9
+ seedCoreData,
10
+ seededIds,
11
+ } from './helpers/test-data'
12
+ import { createModule, expectPageHeading } from './helpers/ui'
13
+
14
+ test.describe('Smoke @smoke', () => {
15
+ test.beforeEach(async () => {
16
+ await resetE2eData()
17
+ await seedCoreData()
18
+ })
19
+
20
+ test.afterAll(async () => {
21
+ await disconnectPrisma()
22
+ })
23
+
24
+ test('dashboard renders seeded entity metrics', async ({ page }) => {
25
+ await page.goto('/')
26
+ await expectPageHeading(page, 'Dashboard')
27
+ await expect(page.getByText('Test Cases')).toBeVisible()
28
+ await expect(page.getByText('Test Suites')).toBeVisible()
29
+ await expect(page.getByText('Template Steps')).toBeVisible()
30
+ await expect(page.getByText('Attention Needed')).toBeVisible()
31
+ })
32
+
33
+ test('module CRUD path creates edits and deletes a module', async ({ page }) => {
34
+ const moduleName = 'E2E Smoke Module'
35
+ const editedModuleName = 'E2E Smoke Module Edited'
36
+
37
+ await createModule(page, moduleName)
38
+ const createdModule = await findModuleByName(moduleName)
39
+ expect(createdModule).not.toBeNull()
40
+
41
+ await page.goto(`/modules/modify/${createdModule?.id}`)
42
+ await page.getByLabel('Name').fill(editedModuleName)
43
+ await page.getByRole('button', { name: /^Save$/ }).click()
44
+ await expect(page).toHaveURL(/\/modules$/)
45
+ await expect(page.getByText(editedModuleName, { exact: true }).first()).toBeVisible()
46
+ })
47
+
48
+ test('seeded completed run opens report summary', async ({ page }) => {
49
+ await page.goto(`/test-runs/${seededIds.testRun}`)
50
+ await expectPageHeading(page, 'Test Run Details')
51
+ await expect(page.getByText('E2E Completed Run')).toBeVisible()
52
+
53
+ await page.getByRole('link', { name: /View Report/ }).click()
54
+ await expectPageHeading(page, /Test Run Report:/)
55
+ await expect(page.getByText('E2E seeded login works')).toBeVisible()
56
+ })
57
+
58
+ test('settings sync all completes without a fatal error', async ({ page }) => {
59
+ test.setTimeout(120_000)
60
+
61
+ await page.goto('/settings')
62
+ await expectPageHeading(page, 'Settings')
63
+ await page.getByRole('button', { name: 'Sync All' }).click()
64
+ await expect(page.getByText(/Sync completed|Sync failed/).first()).toBeVisible({ timeout: 90_000 })
65
+ await expect(page.getByText(/fatal|uncaught/i)).toHaveCount(0)
66
+ })
67
+
68
+ test('feature generation writes suite-backed feature output', async () => {
69
+ const featurePath = await generateSeededFeature()
70
+ const featureContent = readGeneratedFeature()
71
+
72
+ expect(featurePath.replaceAll('\\', '/')).toContain('automation/features/E2E Auth/e2e-auth-suite.feature')
73
+ expect(featureContent).toContain('Feature: Seeded suite for E2E feature generation')
74
+ expect(featureContent).toContain('@e2e-smoke')
75
+ expect(featureContent).toContain('Scenario: [E2E seeded login works] Seeded login smoke case')
76
+ expect(featureContent).toContain('Given I open the seeded page')
77
+ })
78
+ })
@@ -0,0 +1,53 @@
1
+ import { test, expect } from '@playwright/test'
2
+
3
+ import { disconnectPrisma, resetE2eData, seedCoreData, seededIds } from './helpers/test-data'
4
+ import { createTestCaseWithSeededStep } from './helpers/forms'
5
+ import { expectPageHeading } from './helpers/ui'
6
+
7
+ test.describe('Test authoring @authoring', () => {
8
+ test.beforeEach(async () => {
9
+ await resetE2eData()
10
+ await seedCoreData()
11
+ })
12
+
13
+ test.afterAll(async () => {
14
+ await disconnectPrisma()
15
+ })
16
+
17
+ test('inline tag and test suite dialogs add selectable records', async ({ page }) => {
18
+ await page.goto('/test-cases/create')
19
+ await expectPageHeading(page, 'Create New Test Case')
20
+ await page.getByRole('textbox', { name: 'Title' }).fill('E2E Inline Dialog Case')
21
+
22
+ await page.getByRole('button', { name: 'Create filter tag' }).click()
23
+ await page.getByRole('textbox', { name: 'Name', exact: true }).fill('E2E Inline Tag')
24
+ await page.getByRole('textbox', { name: 'Tag Expression', exact: true }).fill('@e2e-inline')
25
+ await page.getByRole('button', { name: /^Save$/ }).click()
26
+ await expect(page.getByRole('button', { name: 'E2E Inline Tag' })).toBeVisible()
27
+
28
+ await page.getByRole('button', { name: 'Create test suite' }).click()
29
+ await page.getByLabel('Name').fill('E2E Inline Suite')
30
+ await page.getByLabel('Module').click()
31
+ await page.getByRole('option', { name: 'E2E Auth' }).click()
32
+ await page.getByRole('button', { name: /^Save$/ }).click()
33
+ await expect(page.getByRole('button', { name: 'E2E Inline Suite' })).toBeVisible()
34
+ })
35
+
36
+ test('flow panel mounts on modify page and scenario preview shows seeded steps', async ({ page }) => {
37
+ await page.goto(`/test-cases/modify/${seededIds.testCase}`)
38
+ await expectPageHeading(page, 'Modify Test Case')
39
+ await page.getByRole('button', { name: /Continue/ }).click()
40
+ await expect(page.getByText('Test Case Flow', { exact: true }).first()).toBeVisible()
41
+ await expect(page.getByRole('button', { name: 'Search nodes' })).toBeVisible()
42
+
43
+ await page.getByRole('button', { name: 'Show test scenario preview' }).click()
44
+ await expect(page.getByText('Test Scenario(Preview)')).toBeVisible()
45
+ await expect(page.getByText('Given I open the seeded page')).toBeVisible()
46
+ })
47
+
48
+ test('full create flow adds a template-backed step before saving', async ({ page }) => {
49
+ await createTestCaseWithSeededStep(page, 'E2E Authored Case')
50
+ await page.goto('/test-cases')
51
+ await expect(page.getByText('E2E Authored Case', { exact: true }).first()).toBeVisible()
52
+ })
53
+ })
@@ -0,0 +1,138 @@
1
+ import { test, expect } from '@playwright/test'
2
+
3
+ import {
4
+ disconnectPrisma,
5
+ findEnvironmentByName,
6
+ findModuleByName,
7
+ findTagByName,
8
+ resetE2eData,
9
+ seedCoreData,
10
+ seededIds,
11
+ } from './helpers/test-data'
12
+ import {
13
+ createLocator,
14
+ createLocatorGroup,
15
+ createTemplateStep,
16
+ createTemplateStepGroup,
17
+ createTemplateTestCase,
18
+ editEnvironment,
19
+ editTag,
20
+ } from './helpers/forms'
21
+ import { createEnvironment, createModule, createTag, expectPageHeading, saveForm } from './helpers/ui'
22
+ import { deleteRowByName, editRowByName, expectRowHidden, filterTableByName } from './helpers/table'
23
+
24
+ test.describe('Configuration CRUD @crud', () => {
25
+ test.beforeEach(async () => {
26
+ await resetE2eData()
27
+ await seedCoreData()
28
+ })
29
+
30
+ test.afterAll(async () => {
31
+ await disconnectPrisma()
32
+ })
33
+
34
+ test('environment tag and locator entities support create edit and delete', async ({ page }) => {
35
+ const environmentName = 'E2E Config Environment'
36
+ const editedEnvironmentName = 'E2E Config Environment Edited'
37
+ const tagName = 'E2E Config Tag'
38
+ const editedTagName = 'E2E Config Tag Edited'
39
+ const locatorGroupName = 'E2E Config Locator Group'
40
+ const locatorName = 'E2E Config Locator'
41
+
42
+ await createEnvironment(page, environmentName)
43
+ const createdEnvironment = await findEnvironmentByName(environmentName)
44
+ expect(createdEnvironment).not.toBeNull()
45
+ await editEnvironment(page, createdEnvironment!.id, editedEnvironmentName)
46
+ await expect(page.getByText(editedEnvironmentName, { exact: true }).first()).toBeVisible()
47
+
48
+ await createTag(page, tagName, '@e2e-config')
49
+ const createdTag = await findTagByName(tagName)
50
+ expect(createdTag).not.toBeNull()
51
+ await editTag(page, createdTag!.id, editedTagName, '@e2e-config-edited')
52
+ await expect(page.getByText(editedTagName, { exact: true }).first()).toBeVisible()
53
+
54
+ await createLocatorGroup(page, locatorGroupName, 'E2E Auth', '/config-login')
55
+ await createLocator(page, locatorName, 'text=Config button', locatorGroupName)
56
+
57
+ await page.goto(`/locators/modify/${seededIds.locator}`)
58
+ await expect(page.getByRole('button', { name: 'Update Locator' })).toBeVisible()
59
+ await page.getByLabel('Locator Name').fill('E2E Sign In Button Edited')
60
+ await page.getByRole('button', { name: 'Update Locator' }).click()
61
+ await expect(page).toHaveURL(/\/locators$/)
62
+ await expect(page.getByText('E2E Sign In Button Edited', { exact: true }).first()).toBeVisible()
63
+
64
+ await deleteRowByName(page, locatorName)
65
+ await page.reload()
66
+ await expectRowHidden(page, locatorName)
67
+
68
+ await page.goto('/locator-groups')
69
+ await deleteRowByName(page, locatorGroupName)
70
+ await page.reload()
71
+ await expectRowHidden(page, locatorGroupName)
72
+
73
+ await page.goto('/tags')
74
+ await deleteRowByName(page, editedTagName)
75
+ await page.reload()
76
+ await expectRowHidden(page, editedTagName)
77
+
78
+ await page.goto('/environments')
79
+ await deleteRowByName(page, editedEnvironmentName)
80
+ await page.reload()
81
+ await expectRowHidden(page, editedEnvironmentName)
82
+ })
83
+
84
+ test('template catalog entities support create edit and delete', async ({ page }) => {
85
+ const groupName = 'E2E Config Template Group'
86
+ const stepName = 'E2E Config Template Step'
87
+ const templateCaseName = 'E2E Config Template Case'
88
+
89
+ await createTemplateStepGroup(page, groupName)
90
+ await createTemplateStep(page, stepName, groupName)
91
+ await createTemplateTestCase(page, templateCaseName)
92
+
93
+ await page.goto('/template-step-groups')
94
+ await editRowByName(page, groupName)
95
+ await page.getByLabel('Name').fill(`${groupName} Edited`)
96
+ await saveForm(page)
97
+ await expect(page.getByText(`${groupName} Edited`, { exact: true }).first()).toBeVisible()
98
+
99
+ await page.goto('/template-steps')
100
+ await editRowByName(page, stepName)
101
+ await page.getByLabel('Name').fill(`${stepName} Edited`)
102
+ await page.getByRole('button', { name: /^Save$/ }).click()
103
+ await expect(page.getByText(`${stepName} Edited`, { exact: true }).first()).toBeVisible()
104
+
105
+ await page.goto('/template-test-cases')
106
+ await deleteRowByName(page, templateCaseName)
107
+ await page.reload()
108
+ await expectRowHidden(page, templateCaseName)
109
+
110
+ await page.goto('/template-steps')
111
+ await deleteRowByName(page, `${stepName} Edited`)
112
+ await page.reload()
113
+ await expectRowHidden(page, `${stepName} Edited`)
114
+
115
+ await page.goto('/template-step-groups')
116
+ await deleteRowByName(page, `${groupName} Edited`)
117
+ await page.reload()
118
+ await expectRowHidden(page, `${groupName} Edited`)
119
+ })
120
+
121
+ test('module create edit delete remains available for configuration flows', async ({ page }) => {
122
+ const moduleName = 'E2E Config Module'
123
+ const editedModuleName = 'E2E Config Module Edited'
124
+
125
+ await createModule(page, moduleName)
126
+ const createdModule = await findModuleByName(moduleName)
127
+ expect(createdModule).not.toBeNull()
128
+
129
+ await page.goto(`/modules/modify/${createdModule?.id}`)
130
+ await page.getByLabel('Name').fill(editedModuleName)
131
+ await saveForm(page)
132
+ await expect(page.getByText(editedModuleName, { exact: true }).first()).toBeVisible()
133
+
134
+ await deleteRowByName(page, editedModuleName)
135
+ await page.reload()
136
+ await expectRowHidden(page, editedModuleName)
137
+ })
138
+ })
@@ -0,0 +1,76 @@
1
+ import { test, expect } from '@playwright/test'
2
+
3
+ import { disconnectPrisma, findModuleByName, resetE2eData, seedCoreData, seededIds } from './helpers/test-data'
4
+ import { createTestCaseWithSeededStep, createTestSuite } from './helpers/forms'
5
+ import { expectPageHeading, saveForm } from './helpers/ui'
6
+ import { deleteRowByName, editRowByName, expectRowHidden, filterTableByName } from './helpers/table'
7
+ import { selectFilterTags, selectTestSuites } from './helpers/forms'
8
+
9
+ test.describe('Test hierarchy CRUD @crud', () => {
10
+ test.beforeEach(async () => {
11
+ await resetE2eData()
12
+ await seedCoreData()
13
+ })
14
+
15
+ test.afterAll(async () => {
16
+ await disconnectPrisma()
17
+ })
18
+
19
+ test('test suite create edit and delete assign seeded cases', async ({ page }) => {
20
+ const suiteName = 'E2E UI Suite'
21
+ const editedSuiteName = 'E2E UI Suite Edited'
22
+
23
+ await createTestSuite(page, suiteName, 'E2E Auth', 'E2E seeded login works')
24
+
25
+ await editRowByName(page, suiteName)
26
+ await page.getByPlaceholder('Enter name for your test suite').fill(editedSuiteName)
27
+ await saveForm(page)
28
+ await expect(page.getByText(editedSuiteName, { exact: true }).first()).toBeVisible()
29
+
30
+ await deleteRowByName(page, editedSuiteName)
31
+ await page.reload()
32
+ await expectRowHidden(page, editedSuiteName)
33
+ })
34
+
35
+ test('test case create modify preview and delete', async ({ page }) => {
36
+ const caseTitle = 'E2E UI Auth Case'
37
+
38
+ await createTestCaseWithSeededStep(page, caseTitle)
39
+
40
+ await page.goto(`/test-cases/modify/${seededIds.testCase}`)
41
+ await expectPageHeading(page, 'Modify Test Case')
42
+ await page.getByRole('textbox', { name: 'Title' }).fill('E2E seeded login works updated')
43
+ await page.getByRole('button', { name: /Continue/ }).click()
44
+ await page.getByRole('button', { name: 'Show test scenario preview' }).click()
45
+ await expect(page.getByText('Test Scenario(Preview)')).toBeVisible()
46
+
47
+ await page.goto('/test-cases')
48
+ await deleteRowByName(page, caseTitle, 'Filter by title...')
49
+ await page.reload()
50
+ await expectRowHidden(page, caseTitle, 'Filter by title...')
51
+ })
52
+
53
+ test('create test case from template lands on modify with prefilled flow', async ({ page }) => {
54
+ await page.goto('/test-cases/create-from-template')
55
+ await expectPageHeading(page, 'Create Test Case From Template')
56
+ await page.getByLabel('Template Test Case').click()
57
+ await page.getByRole('option', { name: 'E2E Login Template' }).click()
58
+ await page.getByRole('button', { name: /Continue/ }).click()
59
+ await page.getByRole('textbox', { name: 'Title' }).fill('E2E From Template Case')
60
+ await selectTestSuites(page, 'E2E Auth Suite')
61
+ await selectFilterTags(page, 'E2E Smoke')
62
+ await page.getByRole('button', { name: /Continue/ }).click()
63
+ await expect(page.getByText('Test Case Flow', { exact: true }).first()).toBeVisible()
64
+ await page.getByRole('button', { name: 'Save test case' }).click()
65
+ await expect(page).toHaveURL(/\/test-cases$/)
66
+ await expect(page.getByText('E2E From Template Case', { exact: true }).first()).toBeVisible()
67
+ })
68
+
69
+ test('secondary module suite seed is visible for assignment coverage', async ({ page }) => {
70
+ await page.goto('/test-suites')
71
+ await expect(page.getByText('E2E Secondary Suite', { exact: true }).first()).toBeVisible()
72
+
73
+ const secondModule = await findModuleByName('E2E Secondary')
74
+ expect(secondModule).not.toBeNull()
75
+ })
76
+ })