create-appraisejs 0.1.10-alpha.8 → 0.2.0-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 (414) hide show
  1. package/README.md +52 -52
  2. package/dist/cli.e2e.test.d.ts +2 -0
  3. package/dist/cli.e2e.test.d.ts.map +1 -0
  4. package/dist/cli.e2e.test.js +73 -0
  5. package/dist/cli.e2e.test.js.map +1 -0
  6. package/dist/config.test.d.ts +2 -0
  7. package/dist/config.test.d.ts.map +1 -0
  8. package/dist/config.test.js +65 -0
  9. package/dist/config.test.js.map +1 -0
  10. package/dist/copy-template.test.d.ts +2 -0
  11. package/dist/copy-template.test.d.ts.map +1 -0
  12. package/dist/copy-template.test.js +71 -0
  13. package/dist/copy-template.test.js.map +1 -0
  14. package/dist/download-repo.test.d.ts +2 -0
  15. package/dist/download-repo.test.d.ts.map +1 -0
  16. package/dist/download-repo.test.js +14 -0
  17. package/dist/download-repo.test.js.map +1 -0
  18. package/dist/install.test.d.ts +2 -0
  19. package/dist/install.test.d.ts.map +1 -0
  20. package/dist/install.test.js +119 -0
  21. package/dist/install.test.js.map +1 -0
  22. package/dist/prepare-template-utils.d.ts.map +1 -1
  23. package/dist/prepare-template-utils.js +5 -0
  24. package/dist/prepare-template-utils.js.map +1 -1
  25. package/dist/prompts.test.d.ts +2 -0
  26. package/dist/prompts.test.d.ts.map +1 -0
  27. package/dist/prompts.test.js +58 -0
  28. package/dist/prompts.test.js.map +1 -0
  29. package/dist/scaffold-gitignore.d.ts +1 -0
  30. package/dist/scaffold-gitignore.d.ts.map +1 -1
  31. package/dist/scaffold-gitignore.js +3 -0
  32. package/dist/scaffold-gitignore.js.map +1 -1
  33. package/package.json +3 -2
  34. package/templates/default/.appraise-template-meta.json +2 -2
  35. package/templates/default/.env.example +2 -2
  36. package/templates/default/.vscode/settings.json +2 -1
  37. package/templates/default/README.md +53 -53
  38. package/templates/default/automation/mapping/locator-map.json +1 -14
  39. package/templates/default/automation/steps/actions/click.step.ts +58 -58
  40. package/templates/default/automation/steps/actions/hover.step.ts +27 -27
  41. package/templates/default/automation/steps/actions/input.step.ts +84 -84
  42. package/templates/default/automation/steps/actions/navigation.step.ts +70 -70
  43. package/templates/default/automation/steps/actions/random_data.step.ts +142 -142
  44. package/templates/default/automation/steps/actions/store.step.ts +86 -86
  45. package/templates/default/automation/steps/actions/wait.step.ts +90 -90
  46. package/templates/default/automation/steps/validations/active_state_assertion.step.ts +30 -30
  47. package/templates/default/automation/steps/validations/navigation_assertion.step.ts +22 -22
  48. package/templates/default/automation/steps/validations/text_assertion.step.ts +107 -107
  49. package/templates/default/automation/steps/validations/visibility_assertion.step.ts +26 -26
  50. package/templates/default/components.json +24 -24
  51. package/templates/default/cucumber.mjs +16 -16
  52. package/templates/default/eslint.config.mjs +16 -16
  53. package/templates/default/gitignore +3 -0
  54. package/templates/default/next-env.d.ts +6 -6
  55. package/templates/default/next.config.ts +11 -11
  56. package/templates/default/package-lock.json +146 -75
  57. package/templates/default/package.json +2 -1
  58. package/templates/default/packages/cucumber-runtime/package.json +13 -13
  59. package/templates/default/packages/cucumber-runtime/src/cache.util.ts +93 -93
  60. package/templates/default/packages/cucumber-runtime/src/cli.ts +68 -68
  61. package/templates/default/packages/cucumber-runtime/src/environment.util.ts +21 -21
  62. package/templates/default/packages/cucumber-runtime/src/executor.ts +32 -32
  63. package/templates/default/packages/cucumber-runtime/src/hooks.ts +25 -3
  64. package/templates/default/packages/cucumber-runtime/src/index.ts +17 -17
  65. package/templates/default/packages/cucumber-runtime/src/locator.util.ts +234 -234
  66. package/templates/default/packages/cucumber-runtime/src/parameter-types.ts +7 -7
  67. package/templates/default/packages/cucumber-runtime/src/paths.ts +66 -1
  68. package/templates/default/packages/cucumber-runtime/src/random-data.util.ts +35 -35
  69. package/templates/default/packages/cucumber-runtime/src/types.ts +13 -13
  70. package/templates/default/packages/cucumber-runtime/src/world.ts +44 -44
  71. package/templates/default/packages/cucumber-runtime/tsconfig.json +11 -11
  72. package/templates/default/packages/locator-picker-companion/dist/cli.d.ts +1 -0
  73. package/templates/default/packages/locator-picker-companion/dist/cli.js +302 -0
  74. package/templates/default/packages/locator-picker-companion/dist/index.d.ts +3 -0
  75. package/templates/default/packages/locator-picker-companion/dist/index.js +3 -0
  76. package/templates/default/packages/locator-picker-companion/dist/injected-picker-script.d.ts +1 -0
  77. package/templates/default/packages/locator-picker-companion/dist/injected-picker-script.js +615 -0
  78. package/templates/default/packages/locator-picker-companion/dist/launcher.d.ts +11 -0
  79. package/templates/default/packages/locator-picker-companion/dist/launcher.js +59 -0
  80. package/templates/default/packages/locator-picker-companion/dist/selector-generator.d.ts +3 -0
  81. package/templates/default/packages/locator-picker-companion/dist/selector-generator.js +257 -0
  82. package/templates/default/packages/locator-picker-companion/dist/session-file.d.ts +22 -0
  83. package/templates/default/packages/locator-picker-companion/dist/session-file.js +150 -0
  84. package/templates/default/packages/locator-picker-companion/dist/types.d.ts +31 -0
  85. package/templates/default/packages/locator-picker-companion/dist/types.js +1 -0
  86. package/templates/default/packages/locator-picker-companion/package.json +17 -0
  87. package/templates/default/packages/locator-picker-companion/src/cli.ts +428 -0
  88. package/templates/default/packages/locator-picker-companion/src/index.ts +3 -0
  89. package/templates/default/packages/locator-picker-companion/src/injected-picker-script.ts +771 -0
  90. package/templates/default/packages/locator-picker-companion/src/launcher.ts +77 -0
  91. package/templates/default/packages/locator-picker-companion/src/selector-generator.ts +339 -0
  92. package/templates/default/packages/locator-picker-companion/src/session-file.ts +226 -0
  93. package/templates/default/packages/locator-picker-companion/src/types.ts +42 -0
  94. package/templates/default/packages/locator-picker-companion/tsconfig.json +14 -0
  95. package/templates/default/postcss.config.mjs +8 -8
  96. package/templates/default/prisma/dev.db +0 -0
  97. package/templates/default/prisma/migrations/20251104113456_add_type_for_template_step_groups/migration.sql +16 -16
  98. package/templates/default/prisma/migrations/20251104170946_add_tags_to_test_suite_and_test_case/migration.sql +27 -27
  99. package/templates/default/prisma/migrations/20251112190024_add_cascade_delete_to_test_run_test_case/migration.sql +17 -17
  100. package/templates/default/prisma/migrations/20251113181100_add_test_run_log/migration.sql +12 -12
  101. package/templates/default/prisma/migrations/20251119191838_add_tag_type/migration.sql +28 -28
  102. package/templates/default/prisma/migrations/20251121164059_add_conflict_resolution/migration.sql +12 -12
  103. package/templates/default/prisma/migrations/20251223183400_add_report_model_to_db_schema/migration.sql +10 -10
  104. package/templates/default/prisma/migrations/20251223183637_add_report_test_case_entity_for_storing_test_results_for_individual_test_cases/migration.sql +10 -10
  105. package/templates/default/prisma/migrations/20251224083549_add_comprehensive_report_storage/migration.sql +108 -108
  106. package/templates/default/prisma/migrations/20251229194422_migrate_duration_to_string/migration.sql +55 -55
  107. package/templates/default/prisma/migrations/20251230124637_add_unique_constraint_to_test_run_name/migration.sql +27 -27
  108. package/templates/default/prisma/migrations/20260115094436_add_dashboard_metrics/migration.sql +59 -59
  109. package/templates/default/prisma/migrations/20260127172022_add_cascade_delete_to_step_parameters/migration.sql +34 -34
  110. package/templates/default/prisma/migrations/20260313093000_add_report_step_screenshot_path/migration.sql +1 -0
  111. package/templates/default/prisma/migrations/20260318120000_add_test_suite_context_to_test_run_test_case/migration.sql +20 -0
  112. package/templates/default/prisma/migrations/20260318173512_add_support_of_test_suite_level_runs/migration.sql +2 -0
  113. package/templates/default/prisma/schema.prisma +4 -0
  114. package/templates/default/scripts/install-playwright.ts +20 -0
  115. package/templates/default/scripts/protect-seeded-files.ts +38 -38
  116. package/templates/default/scripts/regenerate-features.ts +94 -94
  117. package/templates/default/scripts/setup-env.ts +19 -19
  118. package/templates/default/scripts/sync-all.ts +22 -66
  119. package/templates/default/scripts/sync-appraise-base-template.ts +57 -19
  120. package/templates/default/scripts/sync-environments.ts +40 -21
  121. package/templates/default/scripts/sync-locator-groups.ts +410 -410
  122. package/templates/default/scripts/sync-locators.ts +398 -398
  123. package/templates/default/scripts/sync-modules.ts +341 -341
  124. package/templates/default/scripts/sync-tags.ts +2 -3
  125. package/templates/default/scripts/sync-template-step-groups.ts +0 -3
  126. package/templates/default/scripts/sync-template-steps.ts +37 -11
  127. package/templates/default/scripts/sync-test-cases.ts +68 -16
  128. package/templates/default/scripts/sync-test-suites.ts +7 -5
  129. package/templates/default/src/actions/conflict/conflict.action.ts +33 -33
  130. package/templates/default/src/actions/dashboard/dashboard-actions.ts +240 -240
  131. package/templates/default/src/actions/environments/environment-actions.ts +188 -188
  132. package/templates/default/src/actions/locator/locator-actions.ts +490 -490
  133. package/templates/default/src/actions/locator-groups/locator-group-actions.ts +6 -3
  134. package/templates/default/src/actions/locator-picker/locator-picker-actions.ts +243 -0
  135. package/templates/default/src/actions/modules/module-actions.ts +135 -135
  136. package/templates/default/src/actions/reports/report-actions.ts +51 -49
  137. package/templates/default/src/actions/review/review-actions.ts +147 -147
  138. package/templates/default/src/actions/settings/sync-actions.ts +46 -0
  139. package/templates/default/src/actions/tags/tag-actions.ts +107 -107
  140. package/templates/default/src/actions/template-step/template-step-actions.ts +38 -4
  141. package/templates/default/src/actions/template-step-group/template-step-group-actions.ts +10 -3
  142. package/templates/default/src/actions/template-test-case/template-test-case-actions.ts +238 -238
  143. package/templates/default/src/actions/test-case/test-case-actions.ts +356 -356
  144. package/templates/default/src/actions/test-run/test-run-actions.ts +222 -129
  145. package/templates/default/src/actions/test-suite/test-suite-actions.ts +95 -17
  146. package/templates/default/src/actions/user/user-actions.ts +13 -13
  147. package/templates/default/src/app/(base)/environments/create/page.tsx +28 -28
  148. package/templates/default/src/app/(base)/environments/environment-form.tsx +219 -219
  149. package/templates/default/src/app/(base)/environments/environment-table-columns.tsx +96 -96
  150. package/templates/default/src/app/(base)/environments/environment-table.tsx +24 -24
  151. package/templates/default/src/app/(base)/environments/modify/[id]/page.tsx +46 -46
  152. package/templates/default/src/app/(base)/environments/page.tsx +59 -59
  153. package/templates/default/src/app/(base)/layout.tsx +10 -10
  154. package/templates/default/src/app/(base)/locator-groups/create/page.tsx +44 -44
  155. package/templates/default/src/app/(base)/locator-groups/locator-group-form.tsx +215 -215
  156. package/templates/default/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
  157. package/templates/default/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
  158. package/templates/default/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
  159. package/templates/default/src/app/(base)/locator-groups/page.tsx +20 -8
  160. package/templates/default/src/app/(base)/locators/create/create-locator-workspace.tsx +542 -0
  161. package/templates/default/src/app/(base)/locators/create/page.tsx +32 -19
  162. package/templates/default/src/app/(base)/locators/locator-form.tsx +163 -163
  163. package/templates/default/src/app/(base)/locators/locator-table-columns.tsx +73 -73
  164. package/templates/default/src/app/(base)/locators/locator-table.tsx +28 -28
  165. package/templates/default/src/app/(base)/locators/modify/[id]/page.tsx +56 -27
  166. package/templates/default/src/app/(base)/locators/page.tsx +13 -13
  167. package/templates/default/src/app/(base)/locators/picker/page.tsx +7 -0
  168. package/templates/default/src/app/(base)/locators/sync-locators-button.tsx +66 -66
  169. package/templates/default/src/app/(base)/modules/create/page.tsx +34 -34
  170. package/templates/default/src/app/(base)/modules/modify/[id]/page.tsx +46 -46
  171. package/templates/default/src/app/(base)/modules/module-form.tsx +126 -126
  172. package/templates/default/src/app/(base)/modules/module-table-columns.tsx +85 -85
  173. package/templates/default/src/app/(base)/modules/module-table.tsx +24 -24
  174. package/templates/default/src/app/(base)/modules/page.tsx +59 -59
  175. package/templates/default/src/app/(base)/reports/[id]/page.tsx +40 -33
  176. package/templates/default/src/app/(base)/reports/duration-chart.tsx +33 -33
  177. package/templates/default/src/app/(base)/reports/feature-chart.tsx +78 -78
  178. package/templates/default/src/app/(base)/reports/overview-chart.tsx +49 -46
  179. package/templates/default/src/app/(base)/reports/page.tsx +98 -98
  180. package/templates/default/src/app/(base)/reports/report-metric-card.tsx +78 -16
  181. package/templates/default/src/app/(base)/reports/report-table-columns.tsx +189 -189
  182. package/templates/default/src/app/(base)/reports/report-table.tsx +72 -72
  183. package/templates/default/src/app/(base)/reports/report-view-table-columns.tsx +12 -1
  184. package/templates/default/src/app/(base)/reports/report-view-table.tsx +1 -0
  185. package/templates/default/src/app/(base)/reports/test-cases/page.tsx +40 -42
  186. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +115 -115
  187. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
  188. package/templates/default/src/app/(base)/reports/test-suites/page.tsx +42 -42
  189. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +79 -79
  190. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +27 -27
  191. package/templates/default/src/app/(base)/reports/view-logs-button.tsx +58 -60
  192. package/templates/default/src/app/(base)/reviews/create/page.tsx +26 -26
  193. package/templates/default/src/app/(base)/reviews/created-reviews-table.tsx +15 -15
  194. package/templates/default/src/app/(base)/reviews/modify/[id]/page.tsx +26 -26
  195. package/templates/default/src/app/(base)/reviews/page.tsx +26 -26
  196. package/templates/default/src/app/(base)/reviews/review/[id]/page.tsx +26 -26
  197. package/templates/default/src/app/(base)/reviews/review-form.tsx +11 -11
  198. package/templates/default/src/app/(base)/reviews/review-table-by-creator-columns.tsx +9 -9
  199. package/templates/default/src/app/(base)/reviews/review-table-by-reviewer-columns.tsx +9 -9
  200. package/templates/default/src/app/(base)/reviews/reviewer-reviews-table.tsx +15 -15
  201. package/templates/default/src/app/(base)/settings/page.tsx +30 -0
  202. package/templates/default/src/app/(base)/settings/settings-sync-panel.tsx +261 -0
  203. package/templates/default/src/app/(base)/tags/create/page.tsx +39 -39
  204. package/templates/default/src/app/(base)/tags/modify/[id]/page.tsx +50 -50
  205. package/templates/default/src/app/(base)/tags/page.tsx +58 -58
  206. package/templates/default/src/app/(base)/tags/tag-form.tsx +147 -147
  207. package/templates/default/src/app/(base)/tags/tag-table-columns.tsx +63 -63
  208. package/templates/default/src/app/(base)/tags/tag-table.tsx +29 -29
  209. package/templates/default/src/app/(base)/template-step-groups/create/page.tsx +28 -28
  210. package/templates/default/src/app/(base)/template-step-groups/modify/[id]/page.tsx +45 -45
  211. package/templates/default/src/app/(base)/template-step-groups/page.tsx +60 -60
  212. package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.tsx +167 -167
  213. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table-columns.tsx +89 -89
  214. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table.tsx +32 -32
  215. package/templates/default/src/app/(base)/template-steps/create/page.tsx +37 -37
  216. package/templates/default/src/app/(base)/template-steps/modify/[id]/page.tsx +49 -49
  217. package/templates/default/src/app/(base)/template-steps/page.tsx +58 -58
  218. package/templates/default/src/app/(base)/template-steps/paramChip.tsx +213 -213
  219. package/templates/default/src/app/(base)/template-steps/template-step-form.tsx +384 -384
  220. package/templates/default/src/app/(base)/template-steps/template-step-table-columns.tsx +158 -158
  221. package/templates/default/src/app/(base)/template-steps/template-step-table.tsx +24 -24
  222. package/templates/default/src/app/(base)/template-test-cases/create/page.tsx +56 -56
  223. package/templates/default/src/app/(base)/template-test-cases/modify/[id]/page.tsx +89 -89
  224. package/templates/default/src/app/(base)/template-test-cases/page.tsx +58 -58
  225. package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.tsx +84 -84
  226. package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.tsx +262 -262
  227. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
  228. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
  229. package/templates/default/src/app/(base)/test-cases/create/page.tsx +76 -76
  230. package/templates/default/src/app/(base)/test-cases/create-from-template/generate/[id]/page.tsx +96 -96
  231. package/templates/default/src/app/(base)/test-cases/create-from-template/page.tsx +38 -38
  232. package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.tsx +73 -73
  233. package/templates/default/src/app/(base)/test-cases/modify/[id]/page.tsx +106 -106
  234. package/templates/default/src/app/(base)/test-cases/page.tsx +2 -2
  235. package/templates/default/src/app/(base)/test-cases/test-case-flow.tsx +82 -82
  236. package/templates/default/src/app/(base)/test-cases/test-case-form.tsx +395 -395
  237. package/templates/default/src/app/(base)/test-cases/test-case-table-columns.tsx +6 -71
  238. package/templates/default/src/app/(base)/test-cases/test-case-table.tsx +2 -2
  239. package/templates/default/src/app/(base)/test-runs/[id]/page.tsx +4 -1
  240. package/templates/default/src/app/(base)/test-runs/create/page.tsx +11 -9
  241. package/templates/default/src/app/(base)/test-runs/page.tsx +60 -60
  242. package/templates/default/src/app/(base)/test-runs/test-run-form.tsx +37 -44
  243. package/templates/default/src/app/(base)/test-runs/test-run-table-columns.tsx +229 -229
  244. package/templates/default/src/app/(base)/test-runs/test-run-table.tsx +127 -127
  245. package/templates/default/src/app/(base)/test-suites/create/page.tsx +3 -2
  246. package/templates/default/src/app/(base)/test-suites/modify/[id]/page.tsx +2 -1
  247. package/templates/default/src/app/(base)/test-suites/page.tsx +57 -21
  248. package/templates/default/src/app/(base)/test-suites/test-suite-form.tsx +16 -17
  249. package/templates/default/src/app/(base)/test-suites/test-suite-table-columns.tsx +2 -1
  250. package/templates/default/src/app/(base)/test-suites/test-suite-table.tsx +29 -29
  251. package/templates/default/src/app/(dashboard-components)/app-drawer.tsx +187 -187
  252. package/templates/default/src/app/(dashboard-components)/data-card-grid.tsx +12 -12
  253. package/templates/default/src/app/(dashboard-components)/data-card.tsx +26 -26
  254. package/templates/default/src/app/(dashboard-components)/execution-health-panel.tsx +56 -56
  255. package/templates/default/src/app/(dashboard-components)/ongoing-test-runs-card.tsx +87 -87
  256. package/templates/default/src/app/(dashboard-components)/quick-actions-drawer.tsx +44 -44
  257. package/templates/default/src/app/api/reports/steps/[stepId]/screenshot/route.ts +52 -0
  258. package/templates/default/src/app/api/test-runs/[runId]/download/route.ts +97 -34
  259. package/templates/default/src/app/api/test-runs/[runId]/logs/route.ts +4 -1
  260. package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.ts +146 -147
  261. package/templates/default/src/app/globals.css +147 -147
  262. package/templates/default/src/app/layout.tsx +4 -0
  263. package/templates/default/src/app/page.tsx +2 -0
  264. package/templates/default/src/assets/icons/empty-tube.tsx +23 -23
  265. package/templates/default/src/assets/icons/tube-plus.tsx +29 -29
  266. package/templates/default/src/components/base-node.tsx +21 -21
  267. package/templates/default/src/components/chart/pie-chart.tsx +73 -73
  268. package/templates/default/src/components/data-extraction/locator-inspector.tsx +460 -460
  269. package/templates/default/src/components/data-state/empty-state.tsx +40 -40
  270. package/templates/default/src/components/data-visualization/info-card.tsx +70 -70
  271. package/templates/default/src/components/data-visualization/info-grid.tsx +22 -22
  272. package/templates/default/src/components/diagram/button-edge.tsx +54 -54
  273. package/templates/default/src/components/diagram/dynamic-parameters.tsx +474 -474
  274. package/templates/default/src/components/diagram/edit-header-option.tsx +36 -36
  275. package/templates/default/src/components/diagram/flow-diagram.tsx +470 -470
  276. package/templates/default/src/components/diagram/node-form.tsx +262 -262
  277. package/templates/default/src/components/diagram/options-header-node.tsx +57 -57
  278. package/templates/default/src/components/diagram/template-step-combobox.tsx +155 -155
  279. package/templates/default/src/components/form/error-message.tsx +7 -7
  280. package/templates/default/src/components/kokonutui/smooth-tab.tsx +453 -453
  281. package/templates/default/src/components/loading-skeleton/data-table/data-table-skeleton.tsx +30 -30
  282. package/templates/default/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
  283. package/templates/default/src/components/loading-skeleton/form/icon-button-skeleton.tsx +8 -8
  284. package/templates/default/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
  285. package/templates/default/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
  286. package/templates/default/src/components/logo.tsx +15 -15
  287. package/templates/default/src/components/navigation/command-badge.tsx +34 -34
  288. package/templates/default/src/components/navigation/command-chain-input.tsx +51 -51
  289. package/templates/default/src/components/navigation/entity-search-command.tsx +116 -116
  290. package/templates/default/src/components/navigation/nav-card.tsx +31 -31
  291. package/templates/default/src/components/navigation/nav-command.tsx +13 -0
  292. package/templates/default/src/components/navigation/nav-link.tsx +60 -60
  293. package/templates/default/src/components/navigation/nav-menu-card-deck.tsx +112 -112
  294. package/templates/default/src/components/node-header.tsx +159 -159
  295. package/templates/default/src/components/reports/test-case-logs-modal.tsx +310 -253
  296. package/templates/default/src/components/table/table-actions.tsx +172 -172
  297. package/templates/default/src/components/test-case/test-case-columns.tsx +76 -0
  298. package/templates/default/src/components/test-case/test-case-picker.tsx +244 -0
  299. package/templates/default/src/components/test-run/download-logs-button.tsx +92 -99
  300. package/templates/default/src/components/test-run/log-viewer.tsx +1 -14
  301. package/templates/default/src/components/test-run/test-run-details.tsx +15 -2
  302. package/templates/default/src/components/test-run/test-run-header.tsx +149 -149
  303. package/templates/default/src/components/test-run/view-report-button.tsx +102 -102
  304. package/templates/default/src/components/test-suite/test-suite-picker.tsx +444 -0
  305. package/templates/default/src/components/theme/mode-toggle.tsx +54 -54
  306. package/templates/default/src/components/theme/theme-provider.tsx +8 -8
  307. package/templates/default/src/components/typography/page-header-subtitle.tsx +7 -7
  308. package/templates/default/src/components/typography/page-header.tsx +7 -7
  309. package/templates/default/src/components/ui/alert-dialog.tsx +106 -106
  310. package/templates/default/src/components/ui/alert.tsx +43 -43
  311. package/templates/default/src/components/ui/avatar.tsx +40 -40
  312. package/templates/default/src/components/ui/badge.tsx +29 -29
  313. package/templates/default/src/components/ui/button.tsx +47 -47
  314. package/templates/default/src/components/ui/calendar.tsx +158 -158
  315. package/templates/default/src/components/ui/card.tsx +43 -43
  316. package/templates/default/src/components/ui/checkbox.tsx +28 -28
  317. package/templates/default/src/components/ui/command.tsx +135 -135
  318. package/templates/default/src/components/ui/data-table-column-header.tsx +61 -61
  319. package/templates/default/src/components/ui/data-table-pagination.tsx +87 -87
  320. package/templates/default/src/components/ui/data-table-view-options.tsx +50 -50
  321. package/templates/default/src/components/ui/data-table.tsx +261 -261
  322. package/templates/default/src/components/ui/dialog.tsx +97 -97
  323. package/templates/default/src/components/ui/dropdown-menu.tsx +182 -182
  324. package/templates/default/src/components/ui/input.tsx +22 -22
  325. package/templates/default/src/components/ui/kbd.tsx +28 -28
  326. package/templates/default/src/components/ui/label.tsx +19 -19
  327. package/templates/default/src/components/ui/loading.tsx +12 -12
  328. package/templates/default/src/components/ui/multi-select-with-preview.tsx +116 -116
  329. package/templates/default/src/components/ui/multi-select.tsx +142 -142
  330. package/templates/default/src/components/ui/navigation-menu.tsx +120 -120
  331. package/templates/default/src/components/ui/popover.tsx +33 -33
  332. package/templates/default/src/components/ui/progress.tsx +25 -25
  333. package/templates/default/src/components/ui/radio-group.tsx +44 -44
  334. package/templates/default/src/components/ui/scroll-area.tsx +40 -40
  335. package/templates/default/src/components/ui/select.tsx +151 -151
  336. package/templates/default/src/components/ui/separator.tsx +22 -22
  337. package/templates/default/src/components/ui/skeleton.tsx +7 -7
  338. package/templates/default/src/components/ui/table.tsx +76 -76
  339. package/templates/default/src/components/ui/tabs.tsx +55 -55
  340. package/templates/default/src/components/ui/textarea.tsx +21 -21
  341. package/templates/default/src/components/ui/toast.tsx +113 -113
  342. package/templates/default/src/components/ui/toaster.tsx +26 -26
  343. package/templates/default/src/components/user-prompt/delete-prompt.tsx +87 -87
  344. package/templates/default/src/config/db-config.ts +10 -10
  345. package/templates/default/src/constants/form-opts/diagram/node-form.ts +30 -30
  346. package/templates/default/src/constants/form-opts/environment-form-opts.ts +24 -24
  347. package/templates/default/src/constants/form-opts/locator-form-opts.ts +20 -20
  348. package/templates/default/src/constants/form-opts/locator-group-form-opts.ts +28 -28
  349. package/templates/default/src/constants/form-opts/module-form-opts.ts +21 -21
  350. package/templates/default/src/constants/form-opts/review-form-opts.ts +23 -23
  351. package/templates/default/src/constants/form-opts/tag-form-opts.ts +42 -42
  352. package/templates/default/src/constants/form-opts/template-selection-form-opts.ts +16 -16
  353. package/templates/default/src/constants/form-opts/template-step-group-form-opts.ts +24 -24
  354. package/templates/default/src/constants/form-opts/template-test-case-form-opts.ts +39 -39
  355. package/templates/default/src/constants/form-opts/template-test-step-form-opts.ts +36 -36
  356. package/templates/default/src/constants/form-opts/test-case-form-opts.ts +43 -43
  357. package/templates/default/src/constants/form-opts/test-run-form-opts.ts +5 -3
  358. package/templates/default/src/constants/form-opts/test-suite-form-opts.ts +24 -24
  359. package/templates/default/src/hooks/use-toast.ts +187 -187
  360. package/templates/default/src/lib/automation/paths.ts +42 -12
  361. package/templates/default/src/lib/automation/projection-service.ts +2 -1
  362. package/templates/default/src/lib/bidirectional-sync.ts +432 -432
  363. package/templates/default/src/lib/database-sync.ts +2 -7
  364. package/templates/default/src/lib/environment-file-utils.ts +184 -184
  365. package/templates/default/src/lib/executor/local-executor-adapter.ts +24 -25
  366. package/templates/default/src/lib/executor/types.ts +2 -2
  367. package/templates/default/src/lib/feature-file-generator.ts +5 -66
  368. package/templates/default/src/lib/gherkin-parser.ts +259 -259
  369. package/templates/default/src/lib/locator-group-file-utils.ts +307 -307
  370. package/templates/default/src/lib/locator-picker/session-manager.ts +452 -0
  371. package/templates/default/src/lib/locator-picker/suggestions.ts +124 -0
  372. package/templates/default/src/lib/metrics/metric-calculator.ts +5 -0
  373. package/templates/default/src/lib/module-hierarchy-builder.ts +205 -205
  374. package/templates/default/src/lib/path-helpers/module-path.ts +71 -71
  375. package/templates/default/src/lib/process/task-spawner.ts +39 -2
  376. package/templates/default/src/lib/sync/projected-feature-utils.ts +113 -0
  377. package/templates/default/src/lib/sync/sync-executor.ts +130 -0
  378. package/templates/default/src/lib/sync/sync-pending-counts.test.ts +239 -0
  379. package/templates/default/src/lib/sync/sync-pending-counts.ts +1358 -0
  380. package/templates/default/src/lib/sync/sync-registry.ts +149 -0
  381. package/templates/default/src/lib/tag-utils.ts +28 -0
  382. package/templates/default/src/lib/template-sync-utils.d.ts +6 -6
  383. package/templates/default/src/lib/template-sync-utils.js +46 -46
  384. package/templates/default/src/lib/template-sync-utils.ts +63 -63
  385. package/templates/default/src/lib/test-case-utils.ts +6 -6
  386. package/templates/default/src/lib/test-run/log-formatter.ts +83 -83
  387. package/templates/default/src/lib/test-run/matching.ts +117 -0
  388. package/templates/default/src/lib/test-run/process-manager.ts +2 -0
  389. package/templates/default/src/lib/test-run/report-parser.ts +352 -316
  390. package/templates/default/src/lib/test-run/test-run-executor.ts +13 -15
  391. package/templates/default/src/lib/test-run/winston-logger.ts +64 -66
  392. package/templates/default/src/lib/test-suite-identifier-service.ts +76 -0
  393. package/templates/default/src/lib/test-suite-utils.ts +6 -0
  394. package/templates/default/src/lib/transformers/gherkin-converter.ts +42 -42
  395. package/templates/default/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
  396. package/templates/default/src/lib/transformers/template-test-case-converter.ts +160 -160
  397. package/templates/default/src/lib/utils/node-param-validation.ts +81 -81
  398. package/templates/default/src/lib/utils/template-step-file-generator.ts +104 -104
  399. package/templates/default/src/lib/utils/template-step-file-manager-intelligent.ts +0 -8
  400. package/templates/default/src/lib/utils/template-step-file-manager.ts +166 -166
  401. package/templates/default/src/lib/utils.ts +31 -31
  402. package/templates/default/src/types/diagram/diagram.ts +34 -34
  403. package/templates/default/src/types/diagram/template-step.ts +11 -11
  404. package/templates/default/src/types/executor/browser.type.ts +1 -1
  405. package/templates/default/src/types/form/actionHandler.ts +6 -6
  406. package/templates/default/src/types/locator/locator.type.ts +11 -11
  407. package/templates/default/src/types/locator-picker.ts +65 -0
  408. package/templates/default/src/types/step/step.type.ts +1 -1
  409. package/templates/default/src/types/table/data-table.ts +6 -6
  410. package/templates/default/src/types/test-case-picker.ts +6 -0
  411. package/templates/default/src/types/test-suite-picker.ts +18 -0
  412. package/templates/default/tailwind.config.ts +62 -62
  413. package/templates/default/tsconfig.json +4 -1
  414. package/templates/default/appraisejs.config.json +0 -1
@@ -0,0 +1,149 @@
1
+ type BaseSyncScriptDefinition = {
2
+ id: string
3
+ label: string
4
+ description: string
5
+ orderLabel: string
6
+ scriptFile: string
7
+ dependencies: string[]
8
+ }
9
+
10
+ export const SYNC_ALL_REQUEST_ID = 'sync-all' as const
11
+
12
+ export const syncScriptDefinitions = [
13
+ {
14
+ id: 'sync-modules',
15
+ label: 'Sync Modules',
16
+ description: 'Syncs modules to DB.',
17
+ orderLabel: 'Modules',
18
+ scriptFile: 'sync-modules.ts',
19
+ dependencies: [],
20
+ },
21
+ {
22
+ id: 'sync-environments',
23
+ label: 'Sync Environments',
24
+ description: 'Syncs environments to DB.',
25
+ orderLabel: 'Environments',
26
+ scriptFile: 'sync-environments.ts',
27
+ dependencies: [],
28
+ },
29
+ {
30
+ id: 'sync-tags',
31
+ label: 'Sync Tags',
32
+ description: 'Syncs tags to DB.',
33
+ orderLabel: 'Tags',
34
+ scriptFile: 'sync-tags.ts',
35
+ dependencies: [],
36
+ },
37
+ {
38
+ id: 'sync-template-step-groups',
39
+ label: 'Sync Template Step Groups',
40
+ description: 'Syncs template step groups to DB.',
41
+ orderLabel: 'Template Step Groups',
42
+ scriptFile: 'sync-template-step-groups.ts',
43
+ dependencies: [],
44
+ },
45
+ {
46
+ id: 'sync-template-steps',
47
+ label: 'Sync Template Steps',
48
+ description: 'Syncs template steps to DB.',
49
+ orderLabel: 'Template Steps',
50
+ scriptFile: 'sync-template-steps.ts',
51
+ dependencies: ['sync-template-step-groups'],
52
+ },
53
+ {
54
+ id: 'sync-locator-groups',
55
+ label: 'Sync Locator Groups',
56
+ description: 'Syncs locator groups to DB.',
57
+ orderLabel: 'Locator Groups',
58
+ scriptFile: 'sync-locator-groups.ts',
59
+ dependencies: ['sync-modules'],
60
+ },
61
+ {
62
+ id: 'sync-locators',
63
+ label: 'Sync Locators',
64
+ description: 'Syncs locators to DB.',
65
+ orderLabel: 'Locators',
66
+ scriptFile: 'sync-locators.ts',
67
+ dependencies: ['sync-locator-groups'],
68
+ },
69
+ {
70
+ id: 'sync-test-suites',
71
+ label: 'Sync Test Suites',
72
+ description: 'Syncs test suites to DB.',
73
+ orderLabel: 'Test Suites',
74
+ scriptFile: 'sync-test-suites.ts',
75
+ dependencies: ['sync-modules', 'sync-tags'],
76
+ },
77
+ {
78
+ id: 'sync-test-cases',
79
+ label: 'Sync Test Cases',
80
+ description: 'Syncs test cases to DB.',
81
+ orderLabel: 'Test Cases',
82
+ scriptFile: 'sync-test-cases.ts',
83
+ dependencies: ['sync-test-suites', 'sync-template-steps', 'sync-tags'],
84
+ },
85
+ ] as const satisfies readonly BaseSyncScriptDefinition[]
86
+
87
+ export type SyncScriptId = (typeof syncScriptDefinitions)[number]['id']
88
+ export type SyncRequestId = SyncScriptId | typeof SYNC_ALL_REQUEST_ID
89
+ export type SyncScriptDefinition = (typeof syncScriptDefinitions)[number]
90
+
91
+ const syncScriptDefinitionMap = new Map<SyncScriptId, (typeof syncScriptDefinitions)[number]>(
92
+ syncScriptDefinitions.map(definition => [definition.id, definition]),
93
+ )
94
+
95
+ export function isSyncScriptId(value: string): value is SyncScriptId {
96
+ return syncScriptDefinitionMap.has(value as SyncScriptId)
97
+ }
98
+
99
+ export function isSyncRequestId(value: string): value is SyncRequestId {
100
+ return value === SYNC_ALL_REQUEST_ID || isSyncScriptId(value)
101
+ }
102
+
103
+ export function getSyncScriptDefinition(scriptId: SyncScriptId) {
104
+ const definition = syncScriptDefinitionMap.get(scriptId)
105
+
106
+ if (!definition) {
107
+ throw new Error(`Unknown sync script: ${scriptId}`)
108
+ }
109
+
110
+ return definition
111
+ }
112
+
113
+ export function resolveSyncExecutionOrder(requestedScriptId: SyncScriptId): SyncScriptId[] {
114
+ const visiting = new Set<SyncScriptId>()
115
+ const visited = new Set<SyncScriptId>()
116
+ const executionOrder: SyncScriptId[] = []
117
+
118
+ const visit = (scriptId: SyncScriptId) => {
119
+ if (visited.has(scriptId)) {
120
+ return
121
+ }
122
+
123
+ if (visiting.has(scriptId)) {
124
+ throw new Error(`Circular sync dependency detected for ${scriptId}`)
125
+ }
126
+
127
+ visiting.add(scriptId)
128
+
129
+ for (const dependencyId of getSyncScriptDefinition(scriptId).dependencies) {
130
+ visit(dependencyId as SyncScriptId)
131
+ }
132
+
133
+ visiting.delete(scriptId)
134
+ visited.add(scriptId)
135
+ executionOrder.push(scriptId)
136
+ }
137
+
138
+ visit(requestedScriptId)
139
+
140
+ return executionOrder
141
+ }
142
+
143
+ export function resolveRequestedSyncExecutionOrder(requestedScriptId: SyncRequestId): SyncScriptId[] {
144
+ if (requestedScriptId === SYNC_ALL_REQUEST_ID) {
145
+ return syncScriptDefinitions.map(definition => definition.id)
146
+ }
147
+
148
+ return resolveSyncExecutionOrder(requestedScriptId)
149
+ }
@@ -0,0 +1,28 @@
1
+ import { Tag, TagType } from '@prisma/client'
2
+
3
+ type TagShape = Pick<Tag, 'name' | 'tagExpression' | 'type'>
4
+
5
+ export function isIdentifierTagName(name: string): boolean {
6
+ return name.startsWith('tc_') || name.startsWith('ts_')
7
+ }
8
+
9
+ export function isIdentifierTagExpression(tagExpression: string): boolean {
10
+ const normalized = tagExpression.startsWith('@') ? tagExpression.slice(1) : tagExpression
11
+ return isIdentifierTagName(normalized)
12
+ }
13
+
14
+ export function getTagTypeFromName(name: string): TagType {
15
+ return isIdentifierTagName(name) ? TagType.IDENTIFIER : TagType.FILTER
16
+ }
17
+
18
+ export function getTagTypeFromExpression(tagExpression: string): TagType {
19
+ return isIdentifierTagExpression(tagExpression) ? TagType.IDENTIFIER : TagType.FILTER
20
+ }
21
+
22
+ export function getIdentifierTagByPrefix<T extends TagShape>(tags: T[], prefix: 'tc_' | 'ts_'): T | undefined {
23
+ return tags.find(tag => tag.type === TagType.IDENTIFIER && tag.name.startsWith(prefix))
24
+ }
25
+
26
+ export function getFilterTags<T extends TagShape>(tags: T[]): T[] {
27
+ return tags.filter(tag => tag.type === TagType.FILTER)
28
+ }
@@ -1,7 +1,7 @@
1
- export declare function shouldExcludeTemplatePath(relativePath: string): boolean;
2
- export declare function shouldBackfillLegacyEnvironmentConfig(targetHasEnvironmentsFile: boolean, legacyEnvironmentsDirExists: boolean): boolean;
3
- export declare function getAutomationFeaturesDir(baseDir: string): string;
4
- export declare function getAutomationLocatorsDir(baseDir: string): string;
5
- export declare function getAutomationLocatorMapPath(baseDir: string): string;
6
- export declare function extractModulePathFromAutomationFile(filePath: string, baseDir: string, automationSubdir: 'features' | 'locators'): string;
1
+ export declare function shouldExcludeTemplatePath(relativePath: string): boolean;
2
+ export declare function shouldBackfillLegacyEnvironmentConfig(targetHasEnvironmentsFile: boolean, legacyEnvironmentsDirExists: boolean): boolean;
3
+ export declare function getAutomationFeaturesDir(baseDir: string): string;
4
+ export declare function getAutomationLocatorsDir(baseDir: string): string;
5
+ export declare function getAutomationLocatorMapPath(baseDir: string): string;
6
+ export declare function extractModulePathFromAutomationFile(filePath: string, baseDir: string, automationSubdir: 'features' | 'locators'): string;
7
7
  //# sourceMappingURL=template-sync-utils.d.ts.map
@@ -1,47 +1,47 @@
1
- import { join, relative } from 'path';
2
- const EXCLUDED_DIRS = new Set(['node_modules', '.next', '.git', 'dist']);
3
- const EXCLUDED_EXTENSIONS = new Set(['.db', '.sqlite', '.sqlite3', '.tsbuildinfo']);
4
- const EXCLUDED_PATH_PREFIXES = ['automation/reports/'];
5
- function toPosixPath(value) {
6
- return value.replace(/\\/g, '/');
7
- }
8
- export function shouldExcludeTemplatePath(relativePath) {
9
- const normalizedPath = toPosixPath(relativePath);
10
- const parts = normalizedPath.split('/');
11
- if (parts.some(part => EXCLUDED_DIRS.has(part)))
12
- return true;
13
- if (EXCLUDED_PATH_PREFIXES.some(prefix => normalizedPath.startsWith(prefix)))
14
- return true;
15
- const ext = normalizedPath.endsWith('.sqlite3')
16
- ? '.sqlite3'
17
- : normalizedPath.endsWith('.sqlite')
18
- ? '.sqlite'
19
- : normalizedPath.endsWith('.tsbuildinfo')
20
- ? '.tsbuildinfo'
21
- : normalizedPath.slice(normalizedPath.lastIndexOf('.'));
22
- return EXCLUDED_EXTENSIONS.has(ext);
23
- }
24
- export function shouldBackfillLegacyEnvironmentConfig(targetHasEnvironmentsFile, legacyEnvironmentsDirExists) {
25
- return !targetHasEnvironmentsFile && legacyEnvironmentsDirExists;
26
- }
27
- export function getAutomationFeaturesDir(baseDir) {
28
- return join(baseDir, 'automation', 'features');
29
- }
30
- export function getAutomationLocatorsDir(baseDir) {
31
- return join(baseDir, 'automation', 'locators');
32
- }
33
- export function getAutomationLocatorMapPath(baseDir) {
34
- return join(baseDir, 'automation', 'mapping', 'locator-map.json');
35
- }
36
- export function extractModulePathFromAutomationFile(filePath, baseDir, automationSubdir) {
37
- const automationBaseDir = automationSubdir === 'features' ? getAutomationFeaturesDir(baseDir) : getAutomationLocatorsDir(baseDir);
38
- const normalizedBaseDir = toPosixPath(automationBaseDir).replace(/\/$/, '');
39
- const normalizedFilePath = toPosixPath(filePath);
40
- const relativePath = normalizedFilePath.startsWith(`${normalizedBaseDir}/`)
41
- ? normalizedFilePath.slice(normalizedBaseDir.length + 1)
42
- : toPosixPath(relative(automationBaseDir, filePath));
43
- const pathParts = relativePath.split('/').filter(part => part && part !== '');
44
- const moduleParts = pathParts.slice(0, -1);
45
- return moduleParts.length > 0 ? `/${moduleParts.join('/')}` : '/';
46
- }
1
+ import { join, relative } from 'path';
2
+ const EXCLUDED_DIRS = new Set(['node_modules', '.next', '.git', 'dist']);
3
+ const EXCLUDED_EXTENSIONS = new Set(['.db', '.sqlite', '.sqlite3', '.tsbuildinfo']);
4
+ const EXCLUDED_PATH_PREFIXES = ['automation/reports/'];
5
+ function toPosixPath(value) {
6
+ return value.replace(/\\/g, '/');
7
+ }
8
+ export function shouldExcludeTemplatePath(relativePath) {
9
+ const normalizedPath = toPosixPath(relativePath);
10
+ const parts = normalizedPath.split('/');
11
+ if (parts.some(part => EXCLUDED_DIRS.has(part)))
12
+ return true;
13
+ if (EXCLUDED_PATH_PREFIXES.some(prefix => normalizedPath.startsWith(prefix)))
14
+ return true;
15
+ const ext = normalizedPath.endsWith('.sqlite3')
16
+ ? '.sqlite3'
17
+ : normalizedPath.endsWith('.sqlite')
18
+ ? '.sqlite'
19
+ : normalizedPath.endsWith('.tsbuildinfo')
20
+ ? '.tsbuildinfo'
21
+ : normalizedPath.slice(normalizedPath.lastIndexOf('.'));
22
+ return EXCLUDED_EXTENSIONS.has(ext);
23
+ }
24
+ export function shouldBackfillLegacyEnvironmentConfig(targetHasEnvironmentsFile, legacyEnvironmentsDirExists) {
25
+ return !targetHasEnvironmentsFile && legacyEnvironmentsDirExists;
26
+ }
27
+ export function getAutomationFeaturesDir(baseDir) {
28
+ return join(baseDir, 'automation', 'features');
29
+ }
30
+ export function getAutomationLocatorsDir(baseDir) {
31
+ return join(baseDir, 'automation', 'locators');
32
+ }
33
+ export function getAutomationLocatorMapPath(baseDir) {
34
+ return join(baseDir, 'automation', 'mapping', 'locator-map.json');
35
+ }
36
+ export function extractModulePathFromAutomationFile(filePath, baseDir, automationSubdir) {
37
+ const automationBaseDir = automationSubdir === 'features' ? getAutomationFeaturesDir(baseDir) : getAutomationLocatorsDir(baseDir);
38
+ const normalizedBaseDir = toPosixPath(automationBaseDir).replace(/\/$/, '');
39
+ const normalizedFilePath = toPosixPath(filePath);
40
+ const relativePath = normalizedFilePath.startsWith(`${normalizedBaseDir}/`)
41
+ ? normalizedFilePath.slice(normalizedBaseDir.length + 1)
42
+ : toPosixPath(relative(automationBaseDir, filePath));
43
+ const pathParts = relativePath.split('/').filter(part => part && part !== '');
44
+ const moduleParts = pathParts.slice(0, -1);
45
+ return moduleParts.length > 0 ? `/${moduleParts.join('/')}` : '/';
46
+ }
47
47
  //# sourceMappingURL=template-sync-utils.js.map
@@ -1,63 +1,63 @@
1
- import { join, relative } from 'path'
2
-
3
- const EXCLUDED_DIRS = new Set(['node_modules', '.next', '.git', 'dist'])
4
- const EXCLUDED_EXTENSIONS = new Set(['.db', '.sqlite', '.sqlite3', '.tsbuildinfo'])
5
- const EXCLUDED_PATH_PREFIXES = ['automation/reports/']
6
-
7
- function toPosixPath(value: string): string {
8
- return value.replace(/\\/g, '/')
9
- }
10
-
11
- export function shouldExcludeTemplatePath(relativePath: string): boolean {
12
- const normalizedPath = toPosixPath(relativePath)
13
- const parts = normalizedPath.split('/')
14
-
15
- if (parts.some(part => EXCLUDED_DIRS.has(part))) return true
16
- if (EXCLUDED_PATH_PREFIXES.some(prefix => normalizedPath.startsWith(prefix))) return true
17
-
18
- const ext = normalizedPath.endsWith('.sqlite3')
19
- ? '.sqlite3'
20
- : normalizedPath.endsWith('.sqlite')
21
- ? '.sqlite'
22
- : normalizedPath.endsWith('.tsbuildinfo')
23
- ? '.tsbuildinfo'
24
- : normalizedPath.slice(normalizedPath.lastIndexOf('.'))
25
-
26
- return EXCLUDED_EXTENSIONS.has(ext)
27
- }
28
-
29
- export function shouldBackfillLegacyEnvironmentConfig(
30
- targetHasEnvironmentsFile: boolean,
31
- legacyEnvironmentsDirExists: boolean,
32
- ): boolean {
33
- return !targetHasEnvironmentsFile && legacyEnvironmentsDirExists
34
- }
35
-
36
- export function getAutomationFeaturesDir(baseDir: string): string {
37
- return join(baseDir, 'automation', 'features')
38
- }
39
-
40
- export function getAutomationLocatorsDir(baseDir: string): string {
41
- return join(baseDir, 'automation', 'locators')
42
- }
43
-
44
- export function getAutomationLocatorMapPath(baseDir: string): string {
45
- return join(baseDir, 'automation', 'mapping', 'locator-map.json')
46
- }
47
-
48
- export function extractModulePathFromAutomationFile(
49
- filePath: string,
50
- baseDir: string,
51
- automationSubdir: 'features' | 'locators',
52
- ): string {
53
- const automationBaseDir =
54
- automationSubdir === 'features' ? getAutomationFeaturesDir(baseDir) : getAutomationLocatorsDir(baseDir)
55
- const normalizedBaseDir = toPosixPath(automationBaseDir).replace(/\/$/, '')
56
- const normalizedFilePath = toPosixPath(filePath)
57
- const relativePath = normalizedFilePath.startsWith(`${normalizedBaseDir}/`)
58
- ? normalizedFilePath.slice(normalizedBaseDir.length + 1)
59
- : toPosixPath(relative(automationBaseDir, filePath))
60
- const pathParts = relativePath.split('/').filter(part => part && part !== '')
61
- const moduleParts = pathParts.slice(0, -1)
62
- return moduleParts.length > 0 ? `/${moduleParts.join('/')}` : '/'
63
- }
1
+ import { join, relative } from 'path'
2
+
3
+ const EXCLUDED_DIRS = new Set(['node_modules', '.next', '.git', 'dist'])
4
+ const EXCLUDED_EXTENSIONS = new Set(['.db', '.sqlite', '.sqlite3', '.tsbuildinfo'])
5
+ const EXCLUDED_PATH_PREFIXES = ['automation/reports/']
6
+
7
+ function toPosixPath(value: string): string {
8
+ return value.replace(/\\/g, '/')
9
+ }
10
+
11
+ export function shouldExcludeTemplatePath(relativePath: string): boolean {
12
+ const normalizedPath = toPosixPath(relativePath)
13
+ const parts = normalizedPath.split('/')
14
+
15
+ if (parts.some(part => EXCLUDED_DIRS.has(part))) return true
16
+ if (EXCLUDED_PATH_PREFIXES.some(prefix => normalizedPath.startsWith(prefix))) return true
17
+
18
+ const ext = normalizedPath.endsWith('.sqlite3')
19
+ ? '.sqlite3'
20
+ : normalizedPath.endsWith('.sqlite')
21
+ ? '.sqlite'
22
+ : normalizedPath.endsWith('.tsbuildinfo')
23
+ ? '.tsbuildinfo'
24
+ : normalizedPath.slice(normalizedPath.lastIndexOf('.'))
25
+
26
+ return EXCLUDED_EXTENSIONS.has(ext)
27
+ }
28
+
29
+ export function shouldBackfillLegacyEnvironmentConfig(
30
+ targetHasEnvironmentsFile: boolean,
31
+ legacyEnvironmentsDirExists: boolean,
32
+ ): boolean {
33
+ return !targetHasEnvironmentsFile && legacyEnvironmentsDirExists
34
+ }
35
+
36
+ export function getAutomationFeaturesDir(baseDir: string): string {
37
+ return join(baseDir, 'automation', 'features')
38
+ }
39
+
40
+ export function getAutomationLocatorsDir(baseDir: string): string {
41
+ return join(baseDir, 'automation', 'locators')
42
+ }
43
+
44
+ export function getAutomationLocatorMapPath(baseDir: string): string {
45
+ return join(baseDir, 'automation', 'mapping', 'locator-map.json')
46
+ }
47
+
48
+ export function extractModulePathFromAutomationFile(
49
+ filePath: string,
50
+ baseDir: string,
51
+ automationSubdir: 'features' | 'locators',
52
+ ): string {
53
+ const automationBaseDir =
54
+ automationSubdir === 'features' ? getAutomationFeaturesDir(baseDir) : getAutomationLocatorsDir(baseDir)
55
+ const normalizedBaseDir = toPosixPath(automationBaseDir).replace(/\/$/, '')
56
+ const normalizedFilePath = toPosixPath(filePath)
57
+ const relativePath = normalizedFilePath.startsWith(`${normalizedBaseDir}/`)
58
+ ? normalizedFilePath.slice(normalizedBaseDir.length + 1)
59
+ : toPosixPath(relative(automationBaseDir, filePath))
60
+ const pathParts = relativePath.split('/').filter(part => part && part !== '')
61
+ const moduleParts = pathParts.slice(0, -1)
62
+ return moduleParts.length > 0 ? `/${moduleParts.join('/')}` : '/'
63
+ }
@@ -1,6 +1,6 @@
1
- import crypto from 'crypto'
2
-
3
- export function generateUniqueTestCaseIdentifier(): string {
4
- const id = crypto.randomBytes(8).toString('hex')
5
- return `tc_${id}`
6
- }
1
+ import crypto from 'crypto'
2
+
3
+ export function generateUniqueTestCaseIdentifier(): string {
4
+ const id = crypto.randomBytes(8).toString('hex')
5
+ return `tc_${id}`
6
+ }
@@ -1,83 +1,83 @@
1
- /**
2
- * Log formatting utilities for storing and retrieving test run logs
3
- */
4
-
5
- export interface LogEntry {
6
- type: 'stdout' | 'stderr' | 'status'
7
- message: string
8
- timestamp: Date
9
- }
10
-
11
- /**
12
- * Formats log entries into a single text string for storage in the database
13
- * Format: [timestamp] [TYPE] message
14
- *
15
- * @param logs - Array of log entries to format
16
- * @returns Formatted log string
17
- */
18
- export function formatLogsForStorage(logs: LogEntry[]): string {
19
- return logs
20
- .map(log => {
21
- const timestamp = log.timestamp.toISOString()
22
- const type = log.type.toUpperCase()
23
- // Escape newlines in message to preserve them in the formatted string
24
- const escapedMessage = log.message.replace(/\n/g, '\\n')
25
- return `[${timestamp}] [${type}] ${escapedMessage}`
26
- })
27
- .join('\n')
28
- }
29
-
30
- /**
31
- * Parses formatted log text back into an array of LogEntry objects
32
- *
33
- * @param formattedLogs - Formatted log string from database
34
- * @returns Array of log entries
35
- */
36
- export function parseLogsFromStorage(formattedLogs: string): LogEntry[] {
37
- if (!formattedLogs || formattedLogs.trim() === '') {
38
- return []
39
- }
40
-
41
- const lines = formattedLogs.split('\n')
42
- const parsedLogs: LogEntry[] = []
43
-
44
- for (const line of lines) {
45
- if (!line.trim()) continue
46
-
47
- try {
48
- // Match format: [timestamp] [TYPE] message
49
- const match = line.match(/^\[([^\]]+)\] \[([^\]]+)\] (.+)$/)
50
-
51
- if (match) {
52
- const [, timestampStr, typeStr, message] = match
53
- const timestamp = new Date(timestampStr)
54
- const type = typeStr.toLowerCase() as 'stdout' | 'stderr' | 'status'
55
-
56
- // Unescape newlines in message
57
- const unescapedMessage = message.replace(/\\n/g, '\n')
58
-
59
- // Validate type
60
- if (type === 'stdout' || type === 'stderr' || type === 'status') {
61
- parsedLogs.push({
62
- type,
63
- message: unescapedMessage,
64
- timestamp: isNaN(timestamp.getTime()) ? new Date() : timestamp,
65
- })
66
- }
67
- } else {
68
- // Fallback: treat as stdout if format doesn't match
69
- parsedLogs.push({
70
- type: 'stdout',
71
- message: line,
72
- timestamp: new Date(),
73
- })
74
- }
75
- } catch (error) {
76
- // Skip malformed lines
77
- console.error('[LogFormatter] Error parsing log line:', line, error)
78
- }
79
- }
80
-
81
- return parsedLogs
82
- }
83
-
1
+ /**
2
+ * Log formatting utilities for storing and retrieving test run logs
3
+ */
4
+
5
+ export interface LogEntry {
6
+ type: 'stdout' | 'stderr' | 'status'
7
+ message: string
8
+ timestamp: Date
9
+ }
10
+
11
+ /**
12
+ * Formats log entries into a single text string for storage in the database
13
+ * Format: [timestamp] [TYPE] message
14
+ *
15
+ * @param logs - Array of log entries to format
16
+ * @returns Formatted log string
17
+ */
18
+ export function formatLogsForStorage(logs: LogEntry[]): string {
19
+ return logs
20
+ .map(log => {
21
+ const timestamp = log.timestamp.toISOString()
22
+ const type = log.type.toUpperCase()
23
+ // Escape newlines in message to preserve them in the formatted string
24
+ const escapedMessage = log.message.replace(/\n/g, '\\n')
25
+ return `[${timestamp}] [${type}] ${escapedMessage}`
26
+ })
27
+ .join('\n')
28
+ }
29
+
30
+ /**
31
+ * Parses formatted log text back into an array of LogEntry objects
32
+ *
33
+ * @param formattedLogs - Formatted log string from database
34
+ * @returns Array of log entries
35
+ */
36
+ export function parseLogsFromStorage(formattedLogs: string): LogEntry[] {
37
+ if (!formattedLogs || formattedLogs.trim() === '') {
38
+ return []
39
+ }
40
+
41
+ const lines = formattedLogs.split('\n')
42
+ const parsedLogs: LogEntry[] = []
43
+
44
+ for (const line of lines) {
45
+ if (!line.trim()) continue
46
+
47
+ try {
48
+ // Match format: [timestamp] [TYPE] message
49
+ const match = line.match(/^\[([^\]]+)\] \[([^\]]+)\] (.+)$/)
50
+
51
+ if (match) {
52
+ const [, timestampStr, typeStr, message] = match
53
+ const timestamp = new Date(timestampStr)
54
+ const type = typeStr.toLowerCase() as 'stdout' | 'stderr' | 'status'
55
+
56
+ // Unescape newlines in message
57
+ const unescapedMessage = message.replace(/\\n/g, '\n')
58
+
59
+ // Validate type
60
+ if (type === 'stdout' || type === 'stderr' || type === 'status') {
61
+ parsedLogs.push({
62
+ type,
63
+ message: unescapedMessage,
64
+ timestamp: isNaN(timestamp.getTime()) ? new Date() : timestamp,
65
+ })
66
+ }
67
+ } else {
68
+ // Fallback: treat as stdout if format doesn't match
69
+ parsedLogs.push({
70
+ type: 'stdout',
71
+ message: line,
72
+ timestamp: new Date(),
73
+ })
74
+ }
75
+ } catch (error) {
76
+ // Skip malformed lines
77
+ console.error('[LogFormatter] Error parsing log line:', line, error)
78
+ }
79
+ }
80
+
81
+ return parsedLogs
82
+ }
83
+