create-appraisejs 0.1.10-alpha.9 → 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 (334) 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/README.md +53 -53
  37. package/templates/default/automation/mapping/locator-map.json +1 -18
  38. package/templates/default/automation/steps/actions/click.step.ts +58 -58
  39. package/templates/default/automation/steps/actions/hover.step.ts +27 -27
  40. package/templates/default/automation/steps/actions/input.step.ts +84 -84
  41. package/templates/default/automation/steps/actions/navigation.step.ts +70 -70
  42. package/templates/default/automation/steps/actions/random_data.step.ts +142 -142
  43. package/templates/default/automation/steps/actions/store.step.ts +86 -86
  44. package/templates/default/automation/steps/actions/wait.step.ts +90 -90
  45. package/templates/default/automation/steps/validations/active_state_assertion.step.ts +30 -30
  46. package/templates/default/automation/steps/validations/navigation_assertion.step.ts +22 -22
  47. package/templates/default/automation/steps/validations/text_assertion.step.ts +107 -107
  48. package/templates/default/automation/steps/validations/visibility_assertion.step.ts +26 -26
  49. package/templates/default/components.json +24 -24
  50. package/templates/default/cucumber.mjs +16 -16
  51. package/templates/default/eslint.config.mjs +16 -16
  52. package/templates/default/next-env.d.ts +6 -6
  53. package/templates/default/next.config.ts +11 -11
  54. package/templates/default/package-lock.json +51 -48
  55. package/templates/default/packages/cucumber-runtime/package.json +13 -13
  56. package/templates/default/packages/cucumber-runtime/src/cache.util.ts +93 -93
  57. package/templates/default/packages/cucumber-runtime/src/cli.ts +68 -68
  58. package/templates/default/packages/cucumber-runtime/src/environment.util.ts +21 -21
  59. package/templates/default/packages/cucumber-runtime/src/executor.ts +32 -32
  60. package/templates/default/packages/cucumber-runtime/src/index.ts +17 -17
  61. package/templates/default/packages/cucumber-runtime/src/locator.util.ts +234 -234
  62. package/templates/default/packages/cucumber-runtime/src/parameter-types.ts +7 -7
  63. package/templates/default/packages/cucumber-runtime/src/random-data.util.ts +35 -35
  64. package/templates/default/packages/cucumber-runtime/src/types.ts +13 -13
  65. package/templates/default/packages/cucumber-runtime/src/world.ts +44 -44
  66. package/templates/default/packages/cucumber-runtime/tsconfig.json +11 -11
  67. package/templates/default/packages/locator-picker-companion/dist/session-file.d.ts +1 -0
  68. package/templates/default/packages/locator-picker-companion/dist/session-file.js +10 -10
  69. package/templates/default/packages/locator-picker-companion/src/session-file.ts +26 -11
  70. package/templates/default/postcss.config.mjs +8 -8
  71. package/templates/default/prisma/dev.db +0 -0
  72. package/templates/default/prisma/migrations/20251104113456_add_type_for_template_step_groups/migration.sql +16 -16
  73. package/templates/default/prisma/migrations/20251104170946_add_tags_to_test_suite_and_test_case/migration.sql +27 -27
  74. package/templates/default/prisma/migrations/20251112190024_add_cascade_delete_to_test_run_test_case/migration.sql +17 -17
  75. package/templates/default/prisma/migrations/20251113181100_add_test_run_log/migration.sql +12 -12
  76. package/templates/default/prisma/migrations/20251119191838_add_tag_type/migration.sql +28 -28
  77. package/templates/default/prisma/migrations/20251121164059_add_conflict_resolution/migration.sql +12 -12
  78. package/templates/default/prisma/migrations/20251223183400_add_report_model_to_db_schema/migration.sql +10 -10
  79. package/templates/default/prisma/migrations/20251223183637_add_report_test_case_entity_for_storing_test_results_for_individual_test_cases/migration.sql +10 -10
  80. package/templates/default/prisma/migrations/20251224083549_add_comprehensive_report_storage/migration.sql +108 -108
  81. package/templates/default/prisma/migrations/20251229194422_migrate_duration_to_string/migration.sql +55 -55
  82. package/templates/default/prisma/migrations/20251230124637_add_unique_constraint_to_test_run_name/migration.sql +27 -27
  83. package/templates/default/prisma/migrations/20260115094436_add_dashboard_metrics/migration.sql +59 -59
  84. package/templates/default/prisma/migrations/20260127172022_add_cascade_delete_to_step_parameters/migration.sql +34 -34
  85. package/templates/default/prisma/migrations/20260313093000_add_report_step_screenshot_path/migration.sql +1 -1
  86. package/templates/default/scripts/protect-seeded-files.ts +38 -38
  87. package/templates/default/scripts/regenerate-features.ts +94 -94
  88. package/templates/default/scripts/setup-env.ts +19 -19
  89. package/templates/default/scripts/sync-appraise-base-template.ts +7 -0
  90. package/templates/default/scripts/sync-environments.ts +40 -21
  91. package/templates/default/scripts/sync-locator-groups.ts +410 -410
  92. package/templates/default/scripts/sync-locators.ts +398 -398
  93. package/templates/default/scripts/sync-modules.ts +341 -341
  94. package/templates/default/scripts/sync-template-step-groups.ts +0 -3
  95. package/templates/default/scripts/sync-template-steps.ts +37 -11
  96. package/templates/default/scripts/sync-test-cases.ts +65 -11
  97. package/templates/default/scripts/sync-test-suites.ts +7 -5
  98. package/templates/default/src/actions/conflict/conflict.action.ts +33 -33
  99. package/templates/default/src/actions/dashboard/dashboard-actions.ts +240 -240
  100. package/templates/default/src/actions/environments/environment-actions.ts +188 -188
  101. package/templates/default/src/actions/locator/locator-actions.ts +490 -490
  102. package/templates/default/src/actions/locator-groups/locator-group-actions.ts +6 -3
  103. package/templates/default/src/actions/locator-picker/locator-picker-actions.ts +48 -11
  104. package/templates/default/src/actions/modules/module-actions.ts +135 -135
  105. package/templates/default/src/actions/review/review-actions.ts +147 -147
  106. package/templates/default/src/actions/settings/sync-actions.ts +5 -0
  107. package/templates/default/src/actions/tags/tag-actions.ts +107 -107
  108. package/templates/default/src/actions/template-step/template-step-actions.ts +38 -4
  109. package/templates/default/src/actions/template-step-group/template-step-group-actions.ts +10 -3
  110. package/templates/default/src/actions/template-test-case/template-test-case-actions.ts +238 -238
  111. package/templates/default/src/actions/test-case/test-case-actions.ts +356 -356
  112. package/templates/default/src/actions/user/user-actions.ts +13 -13
  113. package/templates/default/src/app/(base)/environments/create/page.tsx +28 -28
  114. package/templates/default/src/app/(base)/environments/environment-form.tsx +219 -219
  115. package/templates/default/src/app/(base)/environments/environment-table-columns.tsx +96 -96
  116. package/templates/default/src/app/(base)/environments/environment-table.tsx +24 -24
  117. package/templates/default/src/app/(base)/environments/modify/[id]/page.tsx +46 -46
  118. package/templates/default/src/app/(base)/environments/page.tsx +59 -59
  119. package/templates/default/src/app/(base)/layout.tsx +10 -10
  120. package/templates/default/src/app/(base)/locator-groups/create/page.tsx +44 -44
  121. package/templates/default/src/app/(base)/locator-groups/locator-group-form.tsx +215 -215
  122. package/templates/default/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
  123. package/templates/default/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
  124. package/templates/default/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
  125. package/templates/default/src/app/(base)/locators/create/create-locator-workspace.tsx +83 -60
  126. package/templates/default/src/app/(base)/locators/locator-form.tsx +163 -163
  127. package/templates/default/src/app/(base)/locators/locator-table-columns.tsx +73 -73
  128. package/templates/default/src/app/(base)/locators/locator-table.tsx +28 -28
  129. package/templates/default/src/app/(base)/locators/modify/[id]/page.tsx +56 -27
  130. package/templates/default/src/app/(base)/locators/sync-locators-button.tsx +66 -66
  131. package/templates/default/src/app/(base)/modules/create/page.tsx +34 -34
  132. package/templates/default/src/app/(base)/modules/modify/[id]/page.tsx +46 -46
  133. package/templates/default/src/app/(base)/modules/module-form.tsx +126 -126
  134. package/templates/default/src/app/(base)/modules/module-table-columns.tsx +85 -85
  135. package/templates/default/src/app/(base)/modules/module-table.tsx +24 -24
  136. package/templates/default/src/app/(base)/modules/page.tsx +59 -59
  137. package/templates/default/src/app/(base)/reports/duration-chart.tsx +33 -33
  138. package/templates/default/src/app/(base)/reports/feature-chart.tsx +78 -78
  139. package/templates/default/src/app/(base)/reports/overview-chart.tsx +49 -49
  140. package/templates/default/src/app/(base)/reports/page.tsx +98 -98
  141. package/templates/default/src/app/(base)/reports/report-metric-card.tsx +78 -78
  142. package/templates/default/src/app/(base)/reports/report-table-columns.tsx +189 -189
  143. package/templates/default/src/app/(base)/reports/report-table.tsx +72 -72
  144. package/templates/default/src/app/(base)/reports/test-cases/page.tsx +40 -40
  145. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +115 -115
  146. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
  147. package/templates/default/src/app/(base)/reports/test-suites/page.tsx +42 -42
  148. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +79 -79
  149. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +27 -27
  150. package/templates/default/src/app/(base)/reports/view-logs-button.tsx +58 -58
  151. package/templates/default/src/app/(base)/reviews/create/page.tsx +26 -26
  152. package/templates/default/src/app/(base)/reviews/created-reviews-table.tsx +15 -15
  153. package/templates/default/src/app/(base)/reviews/modify/[id]/page.tsx +26 -26
  154. package/templates/default/src/app/(base)/reviews/page.tsx +26 -26
  155. package/templates/default/src/app/(base)/reviews/review/[id]/page.tsx +26 -26
  156. package/templates/default/src/app/(base)/reviews/review-form.tsx +11 -11
  157. package/templates/default/src/app/(base)/reviews/review-table-by-creator-columns.tsx +9 -9
  158. package/templates/default/src/app/(base)/reviews/review-table-by-reviewer-columns.tsx +9 -9
  159. package/templates/default/src/app/(base)/reviews/reviewer-reviews-table.tsx +15 -15
  160. package/templates/default/src/app/(base)/settings/settings-sync-panel.tsx +12 -5
  161. package/templates/default/src/app/(base)/tags/create/page.tsx +39 -39
  162. package/templates/default/src/app/(base)/tags/modify/[id]/page.tsx +50 -50
  163. package/templates/default/src/app/(base)/tags/page.tsx +58 -58
  164. package/templates/default/src/app/(base)/tags/tag-form.tsx +147 -147
  165. package/templates/default/src/app/(base)/tags/tag-table-columns.tsx +63 -63
  166. package/templates/default/src/app/(base)/tags/tag-table.tsx +29 -29
  167. package/templates/default/src/app/(base)/template-step-groups/create/page.tsx +28 -28
  168. package/templates/default/src/app/(base)/template-step-groups/modify/[id]/page.tsx +45 -45
  169. package/templates/default/src/app/(base)/template-step-groups/page.tsx +60 -60
  170. package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.tsx +167 -167
  171. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table-columns.tsx +89 -89
  172. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table.tsx +32 -32
  173. package/templates/default/src/app/(base)/template-steps/create/page.tsx +37 -37
  174. package/templates/default/src/app/(base)/template-steps/modify/[id]/page.tsx +49 -49
  175. package/templates/default/src/app/(base)/template-steps/page.tsx +58 -58
  176. package/templates/default/src/app/(base)/template-steps/paramChip.tsx +213 -213
  177. package/templates/default/src/app/(base)/template-steps/template-step-form.tsx +384 -384
  178. package/templates/default/src/app/(base)/template-steps/template-step-table-columns.tsx +158 -158
  179. package/templates/default/src/app/(base)/template-steps/template-step-table.tsx +24 -24
  180. package/templates/default/src/app/(base)/template-test-cases/create/page.tsx +56 -56
  181. package/templates/default/src/app/(base)/template-test-cases/modify/[id]/page.tsx +89 -89
  182. package/templates/default/src/app/(base)/template-test-cases/page.tsx +58 -58
  183. package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.tsx +84 -84
  184. package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.tsx +262 -262
  185. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
  186. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
  187. package/templates/default/src/app/(base)/test-cases/create/page.tsx +76 -76
  188. package/templates/default/src/app/(base)/test-cases/create-from-template/generate/[id]/page.tsx +96 -96
  189. package/templates/default/src/app/(base)/test-cases/create-from-template/page.tsx +38 -38
  190. package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.tsx +73 -73
  191. package/templates/default/src/app/(base)/test-cases/modify/[id]/page.tsx +106 -106
  192. package/templates/default/src/app/(base)/test-cases/test-case-flow.tsx +82 -82
  193. package/templates/default/src/app/(base)/test-cases/test-case-form.tsx +395 -395
  194. package/templates/default/src/app/(base)/test-runs/page.tsx +60 -60
  195. package/templates/default/src/app/(base)/test-runs/test-run-table-columns.tsx +229 -229
  196. package/templates/default/src/app/(base)/test-runs/test-run-table.tsx +127 -127
  197. package/templates/default/src/app/(base)/test-suites/test-suite-table.tsx +29 -29
  198. package/templates/default/src/app/(dashboard-components)/app-drawer.tsx +187 -187
  199. package/templates/default/src/app/(dashboard-components)/data-card-grid.tsx +12 -12
  200. package/templates/default/src/app/(dashboard-components)/data-card.tsx +26 -26
  201. package/templates/default/src/app/(dashboard-components)/execution-health-panel.tsx +56 -56
  202. package/templates/default/src/app/(dashboard-components)/ongoing-test-runs-card.tsx +87 -87
  203. package/templates/default/src/app/(dashboard-components)/quick-actions-drawer.tsx +44 -44
  204. package/templates/default/src/app/api/reports/steps/[stepId]/screenshot/route.ts +52 -52
  205. package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.ts +146 -146
  206. package/templates/default/src/app/globals.css +147 -147
  207. package/templates/default/src/app/page.tsx +2 -0
  208. package/templates/default/src/assets/icons/empty-tube.tsx +23 -23
  209. package/templates/default/src/assets/icons/tube-plus.tsx +29 -29
  210. package/templates/default/src/components/base-node.tsx +21 -21
  211. package/templates/default/src/components/chart/pie-chart.tsx +73 -73
  212. package/templates/default/src/components/data-extraction/locator-inspector.tsx +460 -460
  213. package/templates/default/src/components/data-state/empty-state.tsx +40 -40
  214. package/templates/default/src/components/data-visualization/info-card.tsx +70 -70
  215. package/templates/default/src/components/data-visualization/info-grid.tsx +22 -22
  216. package/templates/default/src/components/diagram/button-edge.tsx +54 -54
  217. package/templates/default/src/components/diagram/dynamic-parameters.tsx +474 -474
  218. package/templates/default/src/components/diagram/edit-header-option.tsx +36 -36
  219. package/templates/default/src/components/diagram/flow-diagram.tsx +470 -470
  220. package/templates/default/src/components/diagram/node-form.tsx +262 -262
  221. package/templates/default/src/components/diagram/options-header-node.tsx +57 -57
  222. package/templates/default/src/components/diagram/template-step-combobox.tsx +155 -155
  223. package/templates/default/src/components/form/error-message.tsx +7 -7
  224. package/templates/default/src/components/kokonutui/smooth-tab.tsx +453 -453
  225. package/templates/default/src/components/loading-skeleton/data-table/data-table-skeleton.tsx +30 -30
  226. package/templates/default/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
  227. package/templates/default/src/components/loading-skeleton/form/icon-button-skeleton.tsx +8 -8
  228. package/templates/default/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
  229. package/templates/default/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
  230. package/templates/default/src/components/logo.tsx +15 -15
  231. package/templates/default/src/components/navigation/command-badge.tsx +34 -34
  232. package/templates/default/src/components/navigation/command-chain-input.tsx +51 -51
  233. package/templates/default/src/components/navigation/entity-search-command.tsx +116 -116
  234. package/templates/default/src/components/navigation/nav-card.tsx +31 -31
  235. package/templates/default/src/components/navigation/nav-link.tsx +60 -60
  236. package/templates/default/src/components/navigation/nav-menu-card-deck.tsx +112 -112
  237. package/templates/default/src/components/node-header.tsx +159 -159
  238. package/templates/default/src/components/reports/test-case-logs-modal.tsx +310 -310
  239. package/templates/default/src/components/table/table-actions.tsx +172 -172
  240. package/templates/default/src/components/test-run/download-logs-button.tsx +92 -92
  241. package/templates/default/src/components/test-run/test-run-header.tsx +149 -149
  242. package/templates/default/src/components/test-run/view-report-button.tsx +102 -102
  243. package/templates/default/src/components/theme/mode-toggle.tsx +54 -54
  244. package/templates/default/src/components/theme/theme-provider.tsx +8 -8
  245. package/templates/default/src/components/typography/page-header-subtitle.tsx +7 -7
  246. package/templates/default/src/components/typography/page-header.tsx +7 -7
  247. package/templates/default/src/components/ui/alert-dialog.tsx +106 -106
  248. package/templates/default/src/components/ui/alert.tsx +43 -43
  249. package/templates/default/src/components/ui/avatar.tsx +40 -40
  250. package/templates/default/src/components/ui/badge.tsx +29 -29
  251. package/templates/default/src/components/ui/button.tsx +47 -47
  252. package/templates/default/src/components/ui/calendar.tsx +158 -158
  253. package/templates/default/src/components/ui/card.tsx +43 -43
  254. package/templates/default/src/components/ui/checkbox.tsx +28 -28
  255. package/templates/default/src/components/ui/command.tsx +135 -135
  256. package/templates/default/src/components/ui/data-table-column-header.tsx +61 -61
  257. package/templates/default/src/components/ui/data-table-pagination.tsx +87 -87
  258. package/templates/default/src/components/ui/data-table-view-options.tsx +50 -50
  259. package/templates/default/src/components/ui/data-table.tsx +261 -261
  260. package/templates/default/src/components/ui/dialog.tsx +97 -97
  261. package/templates/default/src/components/ui/dropdown-menu.tsx +182 -182
  262. package/templates/default/src/components/ui/input.tsx +22 -22
  263. package/templates/default/src/components/ui/kbd.tsx +28 -28
  264. package/templates/default/src/components/ui/label.tsx +19 -19
  265. package/templates/default/src/components/ui/loading.tsx +12 -12
  266. package/templates/default/src/components/ui/multi-select-with-preview.tsx +116 -116
  267. package/templates/default/src/components/ui/multi-select.tsx +142 -142
  268. package/templates/default/src/components/ui/navigation-menu.tsx +120 -120
  269. package/templates/default/src/components/ui/popover.tsx +33 -33
  270. package/templates/default/src/components/ui/progress.tsx +25 -25
  271. package/templates/default/src/components/ui/radio-group.tsx +44 -44
  272. package/templates/default/src/components/ui/scroll-area.tsx +40 -40
  273. package/templates/default/src/components/ui/select.tsx +151 -151
  274. package/templates/default/src/components/ui/separator.tsx +22 -22
  275. package/templates/default/src/components/ui/skeleton.tsx +7 -7
  276. package/templates/default/src/components/ui/table.tsx +76 -76
  277. package/templates/default/src/components/ui/tabs.tsx +55 -55
  278. package/templates/default/src/components/ui/textarea.tsx +21 -21
  279. package/templates/default/src/components/ui/toast.tsx +113 -113
  280. package/templates/default/src/components/ui/toaster.tsx +26 -26
  281. package/templates/default/src/components/user-prompt/delete-prompt.tsx +87 -87
  282. package/templates/default/src/config/db-config.ts +10 -10
  283. package/templates/default/src/constants/form-opts/diagram/node-form.ts +30 -30
  284. package/templates/default/src/constants/form-opts/environment-form-opts.ts +24 -24
  285. package/templates/default/src/constants/form-opts/locator-form-opts.ts +20 -20
  286. package/templates/default/src/constants/form-opts/locator-group-form-opts.ts +28 -28
  287. package/templates/default/src/constants/form-opts/module-form-opts.ts +21 -21
  288. package/templates/default/src/constants/form-opts/review-form-opts.ts +23 -23
  289. package/templates/default/src/constants/form-opts/tag-form-opts.ts +42 -42
  290. package/templates/default/src/constants/form-opts/template-selection-form-opts.ts +16 -16
  291. package/templates/default/src/constants/form-opts/template-step-group-form-opts.ts +24 -24
  292. package/templates/default/src/constants/form-opts/template-test-case-form-opts.ts +39 -39
  293. package/templates/default/src/constants/form-opts/template-test-step-form-opts.ts +36 -36
  294. package/templates/default/src/constants/form-opts/test-case-form-opts.ts +43 -43
  295. package/templates/default/src/constants/form-opts/test-suite-form-opts.ts +24 -24
  296. package/templates/default/src/hooks/use-toast.ts +187 -187
  297. package/templates/default/src/lib/automation/paths.ts +4 -3
  298. package/templates/default/src/lib/automation/projection-service.ts +2 -1
  299. package/templates/default/src/lib/bidirectional-sync.ts +432 -432
  300. package/templates/default/src/lib/environment-file-utils.ts +184 -184
  301. package/templates/default/src/lib/feature-file-generator.ts +5 -66
  302. package/templates/default/src/lib/gherkin-parser.ts +259 -259
  303. package/templates/default/src/lib/locator-group-file-utils.ts +307 -307
  304. package/templates/default/src/lib/locator-picker/session-manager.ts +4 -1
  305. package/templates/default/src/lib/module-hierarchy-builder.ts +205 -205
  306. package/templates/default/src/lib/path-helpers/module-path.ts +71 -71
  307. package/templates/default/src/lib/sync/projected-feature-utils.ts +113 -0
  308. package/templates/default/src/lib/sync/sync-pending-counts.test.ts +239 -0
  309. package/templates/default/src/lib/sync/sync-pending-counts.ts +153 -138
  310. package/templates/default/src/lib/template-sync-utils.d.ts +6 -6
  311. package/templates/default/src/lib/template-sync-utils.js +46 -46
  312. package/templates/default/src/lib/template-sync-utils.ts +63 -63
  313. package/templates/default/src/lib/test-case-utils.ts +6 -6
  314. package/templates/default/src/lib/test-run/log-formatter.ts +83 -83
  315. package/templates/default/src/lib/test-run/report-parser.ts +352 -352
  316. package/templates/default/src/lib/test-run/test-run-executor.ts +13 -13
  317. package/templates/default/src/lib/test-run/winston-logger.ts +64 -64
  318. package/templates/default/src/lib/transformers/gherkin-converter.ts +42 -42
  319. package/templates/default/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
  320. package/templates/default/src/lib/transformers/template-test-case-converter.ts +160 -160
  321. package/templates/default/src/lib/utils/node-param-validation.ts +81 -81
  322. package/templates/default/src/lib/utils/template-step-file-generator.ts +104 -104
  323. package/templates/default/src/lib/utils/template-step-file-manager-intelligent.ts +0 -8
  324. package/templates/default/src/lib/utils/template-step-file-manager.ts +166 -166
  325. package/templates/default/src/lib/utils.ts +31 -31
  326. package/templates/default/src/types/diagram/diagram.ts +34 -34
  327. package/templates/default/src/types/diagram/template-step.ts +11 -11
  328. package/templates/default/src/types/executor/browser.type.ts +1 -1
  329. package/templates/default/src/types/form/actionHandler.ts +6 -6
  330. package/templates/default/src/types/locator/locator.type.ts +11 -11
  331. package/templates/default/src/types/locator-picker.ts +1 -0
  332. package/templates/default/src/types/step/step.type.ts +1 -1
  333. package/templates/default/src/types/table/data-table.ts +6 -6
  334. package/templates/default/tailwind.config.ts +62 -62
@@ -0,0 +1,58 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+ import os from 'os';
5
+ import { runPrompts } from './prompts.js';
6
+ vi.mock('@inquirer/prompts', () => ({
7
+ input: vi.fn(),
8
+ select: vi.fn(),
9
+ confirm: vi.fn(),
10
+ }));
11
+ async function getMocks() {
12
+ const { input, select, confirm } = await import('@inquirer/prompts');
13
+ return { input: input, select: select, confirm: confirm };
14
+ }
15
+ describe('runPrompts', () => {
16
+ let cwd;
17
+ let tempDir;
18
+ beforeEach(() => {
19
+ cwd = process.cwd();
20
+ tempDir = path.join(os.tmpdir(), `create-appraisejs-prompts-${Date.now()}`);
21
+ });
22
+ afterEach(async () => {
23
+ if (tempDir && fs.existsSync(tempDir)) {
24
+ fs.rmSync(tempDir, { recursive: true, force: true });
25
+ }
26
+ vi.clearAllMocks();
27
+ });
28
+ it('returns directory, packageManager, and runInstall from mocked prompts', async () => {
29
+ fs.mkdirSync(tempDir, { recursive: true });
30
+ const { input, select, confirm } = await getMocks();
31
+ input.mockResolvedValue(tempDir);
32
+ select.mockResolvedValue('pnpm');
33
+ confirm.mockResolvedValue(false);
34
+ const result = await runPrompts(cwd);
35
+ expect(result.directory).toBe(path.resolve(cwd, tempDir));
36
+ expect(result.packageManager).toBe('pnpm');
37
+ expect(result.runInstall).toBe(false);
38
+ });
39
+ it('throws when target directory exists and is non-empty', async () => {
40
+ fs.mkdirSync(tempDir, { recursive: true });
41
+ fs.writeFileSync(path.join(tempDir, 'file.txt'), 'x');
42
+ const { input } = await getMocks();
43
+ input.mockResolvedValue(tempDir);
44
+ await expect(runPrompts(cwd)).rejects.toThrow(/Directory must be empty/);
45
+ });
46
+ it('accepts when target directory does not exist', async () => {
47
+ const newPath = path.join(tempDir, 'new-app');
48
+ const { input, select, confirm } = await getMocks();
49
+ input.mockResolvedValue(newPath);
50
+ select.mockResolvedValue('npm');
51
+ confirm.mockResolvedValue(true);
52
+ const result = await runPrompts(cwd);
53
+ expect(result.directory).toBe(path.resolve(cwd, newPath));
54
+ expect(result.packageManager).toBe('npm');
55
+ expect(result.runInstall).toBe(true);
56
+ });
57
+ });
58
+ //# sourceMappingURL=prompts.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.test.js","sourceRoot":"","sources":["../src/prompts.test.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  export declare const SEEDED_TEMPLATE_PATHS: readonly ["prisma/dev.db", "automation/config/environments/environments.json"];
2
2
  export declare function setSeededTemplateFilesTracked(content: string, tracked: boolean): string;
3
3
  export declare function getEmptyEnvironmentsFileContent(): string;
4
+ export declare function getEmptyLocatorMapFileContent(): string;
4
5
  //# sourceMappingURL=scaffold-gitignore.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold-gitignore.d.ts","sourceRoot":"","sources":["../src/scaffold-gitignore.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,gFAAiF,CAAA;AAUnH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CASvF;AAED,wBAAgB,+BAA+B,IAAI,MAAM,CAExD"}
1
+ {"version":3,"file":"scaffold-gitignore.d.ts","sourceRoot":"","sources":["../src/scaffold-gitignore.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,gFAAiF,CAAA;AAUnH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CASvF;AAED,wBAAgB,+BAA+B,IAAI,MAAM,CAExD;AAED,wBAAgB,6BAA6B,IAAI,MAAM,CAEtD"}
@@ -17,4 +17,7 @@ export function setSeededTemplateFilesTracked(content, tracked) {
17
17
  export function getEmptyEnvironmentsFileContent() {
18
18
  return '{}\n';
19
19
  }
20
+ export function getEmptyLocatorMapFileContent() {
21
+ return '[]\n';
22
+ }
20
23
  //# sourceMappingURL=scaffold-gitignore.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold-gitignore.js","sourceRoot":"","sources":["../src/scaffold-gitignore.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,eAAe,EAAE,kDAAkD,CAAU,CAAA;AAEnH,SAAS,sBAAsB,CAAC,KAAe;IAC7C,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,CAAA;IAC1B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QAChE,OAAO,CAAC,GAAG,EAAE,CAAA;IACf,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,OAAe,EAAE,OAAgB;IAC7E,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,qBAAqB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAA;IACnG,MAAM,KAAK,GAAG,sBAAsB,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAE3G,KAAK,MAAM,QAAQ,IAAI,qBAAqB,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;IACjD,CAAC;IAED,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA;AAChC,CAAC;AAED,MAAM,UAAU,+BAA+B;IAC7C,OAAO,MAAM,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"scaffold-gitignore.js","sourceRoot":"","sources":["../src/scaffold-gitignore.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,eAAe,EAAE,kDAAkD,CAAU,CAAA;AAEnH,SAAS,sBAAsB,CAAC,KAAe;IAC7C,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,CAAA;IAC1B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QAChE,OAAO,CAAC,GAAG,EAAE,CAAA;IACf,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,OAAe,EAAE,OAAgB;IAC7E,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,qBAAqB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAA;IACnG,MAAM,KAAK,GAAG,sBAAsB,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAE3G,KAAK,MAAM,QAAQ,IAAI,qBAAqB,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;IACjD,CAAC;IAED,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA;AAChC,CAAC;AAED,MAAM,UAAU,+BAA+B;IAC7C,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,6BAA6B;IAC3C,OAAO,MAAM,CAAA;AACf,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-appraisejs",
3
- "version": "0.1.10-alpha.9",
3
+ "version": "0.2.0-alpha.1",
4
4
  "description": "Scaffold a new AppraiseJS app in your directory",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Hasnat Jamil",
@@ -46,7 +46,8 @@
46
46
  "test:e2e": "vitest run --config vitest.e2e.config.ts",
47
47
  "publish": "npm run build && npm publish",
48
48
  "publish:alpha": "npm run build && npm publish --tag alpha",
49
- "publish:beta": "npm run build && npm publish --tag beta"
49
+ "publish:beta": "npm run build && npm publish --tag beta",
50
+ "bump:alpha": "npm version prerelease --preid alpha"
50
51
  },
51
52
  "dependencies": {
52
53
  "@inquirer/prompts": "^7.2.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "preparedAt": "2026-03-18T19:58:09.000Z",
3
- "inputHash": "bd64681031e377dbc9b3c9fbc9d0e6dedb17afc7158dc7b55a0f02aed1d45e2f",
2
+ "preparedAt": "2026-03-23T05:51:28.888Z",
3
+ "inputHash": "538288241ebcec3d1c8efa09eaaba4e5aec5611c00011ab1ec6c2c6c31341fb5",
4
4
  "databasePath": "prisma/dev.db"
5
5
  }
@@ -1,2 +1,2 @@
1
- # Database configuration for local development
2
- DATABASE_URL="file:./dev.db"
1
+ # Database configuration for local development
2
+ DATABASE_URL="file:./dev.db"
@@ -1,53 +1,53 @@
1
- # Appraise Starter Template
2
-
3
- This is a production-first Appraise starter project. Copy this folder into a new directory to start a new project.
4
-
5
- ## Prerequisites
6
-
7
- - Node.js 18+
8
- - npm, pnpm, yarn, or bun
9
-
10
- ## Quick start
11
-
12
- ```bash
13
- # 1. Install dependencies, create .env, and build the production app
14
- npm run setup
15
-
16
- # 2. Optional: install Playwright browsers when you need test execution
17
- npm run install-playwright -- chromium
18
-
19
- # 3. Start the local production server
20
- npm run start
21
- ```
22
-
23
- ## What you get
24
-
25
- - **URL**: Open [http://localhost:3000](http://localhost:3000) in your browser.
26
- - **Runtime**: A seeded local SQLite database at `prisma/dev.db`.
27
- - **Automation**: Starter automation assets under `automation/`, including features, locators, environments, and reusable steps.
28
- - **UI**: The full Appraise dashboard and UI, ready to run from a production build.
29
-
30
- ## Scripts
31
-
32
- | Script | Description |
33
- | --- | --- |
34
- | `npm run setup` | Install deps, create `.env`, and build the cucumber runtime plus the local production app |
35
- | `npm run build:local` | Build the cucumber runtime and the local production app |
36
- | `npm run start` | Start the local production server |
37
- | `npm run dev` | Start the Next.js development server |
38
- | `npm run install-playwright -- <browser...>` | Install selected Playwright browsers |
39
- | `npm run setup:db` | Recreate the local SQLite database from migrations and rerun `sync-all` |
40
- | `npm run setup:full` | Reinstall dependencies, rebuild the DB, rerun `sync-all`, and rebuild the production app |
41
- | `npm run sync-all` | Sync all starter entities from the bundled automation workspace into the database |
42
- | `npm run appraisejs:sync` | Alias for `sync-all` |
43
-
44
- ## Configuration
45
-
46
- - Copy `.env.example` to `.env` before running, or let `npm run setup` create it.
47
- - Default local database URL: `DATABASE_URL="file:./dev.db"`.
48
- - The database file is created at `prisma/dev.db`.
49
-
50
- ## Notes
51
-
52
- - `npm run setup` does not install Playwright browsers automatically. Install them only when you need browser-based test execution.
53
- - `npm run dev` is still available for development workflows, but `npm run start` is the primary path for day-to-day local usage.
1
+ # Appraise Starter Template
2
+
3
+ This is a production-first Appraise starter project. Copy this folder into a new directory to start a new project.
4
+
5
+ ## Prerequisites
6
+
7
+ - Node.js 18+
8
+ - npm, pnpm, yarn, or bun
9
+
10
+ ## Quick start
11
+
12
+ ```bash
13
+ # 1. Install dependencies, create .env, and build the production app
14
+ npm run setup
15
+
16
+ # 2. Optional: install Playwright browsers when you need test execution
17
+ npm run install-playwright -- chromium
18
+
19
+ # 3. Start the local production server
20
+ npm run start
21
+ ```
22
+
23
+ ## What you get
24
+
25
+ - **URL**: Open [http://localhost:3000](http://localhost:3000) in your browser.
26
+ - **Runtime**: A seeded local SQLite database at `prisma/dev.db`.
27
+ - **Automation**: Starter automation assets under `automation/`, including features, locators, environments, and reusable steps.
28
+ - **UI**: The full Appraise dashboard and UI, ready to run from a production build.
29
+
30
+ ## Scripts
31
+
32
+ | Script | Description |
33
+ | --- | --- |
34
+ | `npm run setup` | Install deps, create `.env`, and build the cucumber runtime plus the local production app |
35
+ | `npm run build:local` | Build the cucumber runtime and the local production app |
36
+ | `npm run start` | Start the local production server |
37
+ | `npm run dev` | Start the Next.js development server |
38
+ | `npm run install-playwright -- <browser...>` | Install selected Playwright browsers |
39
+ | `npm run setup:db` | Recreate the local SQLite database from migrations and rerun `sync-all` |
40
+ | `npm run setup:full` | Reinstall dependencies, rebuild the DB, rerun `sync-all`, and rebuild the production app |
41
+ | `npm run sync-all` | Sync all starter entities from the bundled automation workspace into the database |
42
+ | `npm run appraisejs:sync` | Alias for `sync-all` |
43
+
44
+ ## Configuration
45
+
46
+ - Copy `.env.example` to `.env` before running, or let `npm run setup` create it.
47
+ - Default local database URL: `DATABASE_URL="file:./dev.db"`.
48
+ - The database file is created at `prisma/dev.db`.
49
+
50
+ ## Notes
51
+
52
+ - `npm run setup` does not install Playwright browsers automatically. Install them only when you need browser-based test execution.
53
+ - `npm run dev` is still available for development workflows, but `npm run start` is the primary path for day-to-day local usage.
@@ -1,18 +1 @@
1
- [
2
- {
3
- "name": "login",
4
- "path": "/login"
5
- },
6
- {
7
- "name": "home",
8
- "path": "/home"
9
- },
10
- {
11
- "name": "test",
12
- "path": "/test"
13
- },
14
- {
15
- "name": "testload",
16
- "path": "/login"
17
- }
18
- ]
1
+ []
@@ -1,59 +1,59 @@
1
1
  import { When, Then, CustomWorld, expect, SelectorName, resolveLocator, getEnvironment, generateRandomData, RandomDataType } from '../../../packages/cucumber-runtime/src/index.js'
2
- /**
3
- * @name click
4
- * @description Template step for handling element click
5
- * @type ACTION
6
- */
7
-
8
- // This file is generated automatically. Add template steps to this group to generate content.
9
-
10
- /**
11
- * @name click
12
- * @description Template step for clicking on an element
13
- * @icon MOUSE
14
- */
15
- When('the user clicks on the {string} element', async function (this: CustomWorld, elementName: SelectorName) {
16
- const selector = await resolveLocator(this.page, elementName)
17
- if (!selector) {
18
- throw new Error(`Selector ${elementName} not found. Current url: ${this.page.url()}`)
19
- }
20
- try {
21
- await this.page.locator(selector).click()
22
- } catch (error) {
23
- throw new Error(`Failed to click on the ${elementName} element: ${error}`)
24
- }
25
- })
26
-
27
- /**
28
- * @name double click
29
- * @description Template step for double clicking on an element
30
- * @icon MOUSE
31
- */
32
- When('the user double clicks on the {string} element', async function (this: CustomWorld, elementName: SelectorName) {
33
- const selector = await resolveLocator(this.page, elementName)
34
- if (!selector) {
35
- throw new Error(`Selector ${elementName} not found. Current url: ${this.page.url()}`)
36
- }
37
- try {
38
- await this.page.locator(selector).dblclick()
39
- } catch (error) {
40
- throw new Error(`Failed to double click on the ${elementName} element: ${error}`)
41
- }
42
- })
43
-
44
- /**
45
- * @name right click
46
- * @description Template step for right clicking on an element
47
- * @icon MOUSE
48
- */
49
- When('the user right clicks on the {string} element', async function (this: CustomWorld, elementName: SelectorName) {
50
- const selector = await resolveLocator(this.page, elementName)
51
- if (!selector) {
52
- throw new Error(`Selector ${elementName} not found. Current url: ${this.page.url()}`)
53
- }
54
- try {
55
- await this.page.locator(selector).click({ button: 'right' })
56
- } catch (error) {
57
- throw new Error(`Failed to right click on the ${elementName} element: ${error}`)
58
- }
59
- })
2
+ /**
3
+ * @name click
4
+ * @description Template step for handling element click
5
+ * @type ACTION
6
+ */
7
+
8
+ // This file is generated automatically. Add template steps to this group to generate content.
9
+
10
+ /**
11
+ * @name click
12
+ * @description Template step for clicking on an element
13
+ * @icon MOUSE
14
+ */
15
+ When('the user clicks on the {string} element', async function (this: CustomWorld, elementName: SelectorName) {
16
+ const selector = await resolveLocator(this.page, elementName)
17
+ if (!selector) {
18
+ throw new Error(`Selector ${elementName} not found. Current url: ${this.page.url()}`)
19
+ }
20
+ try {
21
+ await this.page.locator(selector).click()
22
+ } catch (error) {
23
+ throw new Error(`Failed to click on the ${elementName} element: ${error}`)
24
+ }
25
+ })
26
+
27
+ /**
28
+ * @name double click
29
+ * @description Template step for double clicking on an element
30
+ * @icon MOUSE
31
+ */
32
+ When('the user double clicks on the {string} element', async function (this: CustomWorld, elementName: SelectorName) {
33
+ const selector = await resolveLocator(this.page, elementName)
34
+ if (!selector) {
35
+ throw new Error(`Selector ${elementName} not found. Current url: ${this.page.url()}`)
36
+ }
37
+ try {
38
+ await this.page.locator(selector).dblclick()
39
+ } catch (error) {
40
+ throw new Error(`Failed to double click on the ${elementName} element: ${error}`)
41
+ }
42
+ })
43
+
44
+ /**
45
+ * @name right click
46
+ * @description Template step for right clicking on an element
47
+ * @icon MOUSE
48
+ */
49
+ When('the user right clicks on the {string} element', async function (this: CustomWorld, elementName: SelectorName) {
50
+ const selector = await resolveLocator(this.page, elementName)
51
+ if (!selector) {
52
+ throw new Error(`Selector ${elementName} not found. Current url: ${this.page.url()}`)
53
+ }
54
+ try {
55
+ await this.page.locator(selector).click({ button: 'right' })
56
+ } catch (error) {
57
+ throw new Error(`Failed to right click on the ${elementName} element: ${error}`)
58
+ }
59
+ })
@@ -1,28 +1,28 @@
1
1
  import { When, Then, CustomWorld, expect, SelectorName, resolveLocator, getEnvironment, generateRandomData, RandomDataType } from '../../../packages/cucumber-runtime/src/index.js'
2
- /**
3
- * @name hover
4
- * @description Template steps that handles hover actions
5
- * @type ACTION
6
- */
7
-
8
- // This file is generated automatically. Add template steps to this group to generate content.
9
-
10
- /**
11
- * @name hover
12
- * @description Template step for hovering over an element
13
- * @icon MOUSE
14
- */
15
- When(
16
- 'the user hovers the cursor over the {string} element',
17
- async function (this: CustomWorld, elementName: SelectorName) {
18
- try {
19
- const selector = await resolveLocator(this.page, elementName);
20
- if (!selector) {
21
- throw new Error(`Selector ${elementName} not found`);
22
- }
23
- await this.page.locator(selector).hover();
24
- } catch (error) {
25
- throw new Error(`Failed to hover over the ${elementName} element: ${error}`);
26
- }
27
- }
28
- );
2
+ /**
3
+ * @name hover
4
+ * @description Template steps that handles hover actions
5
+ * @type ACTION
6
+ */
7
+
8
+ // This file is generated automatically. Add template steps to this group to generate content.
9
+
10
+ /**
11
+ * @name hover
12
+ * @description Template step for hovering over an element
13
+ * @icon MOUSE
14
+ */
15
+ When(
16
+ 'the user hovers the cursor over the {string} element',
17
+ async function (this: CustomWorld, elementName: SelectorName) {
18
+ try {
19
+ const selector = await resolveLocator(this.page, elementName);
20
+ if (!selector) {
21
+ throw new Error(`Selector ${elementName} not found`);
22
+ }
23
+ await this.page.locator(selector).hover();
24
+ } catch (error) {
25
+ throw new Error(`Failed to hover over the ${elementName} element: ${error}`);
26
+ }
27
+ }
28
+ );
@@ -13,20 +13,20 @@ import { When, Then, CustomWorld, expect, SelectorName, resolveLocator, getEnvir
13
13
  * @icon INPUT
14
14
  */
15
15
  When(
16
- 'the user fills in the {string} input field with value {string}',
17
- async function (this: CustomWorld, elementName: SelectorName, value: string) {
18
- const selector = await resolveLocator(this.page, elementName);
19
- if (!selector) {
20
- throw new Error(`Selector ${elementName} not found`);
16
+ 'the user fills in the {string} input field with value {string}',
17
+ async function (this: CustomWorld, elementName: SelectorName, value: string) {
18
+ const selector = await resolveLocator(this.page, elementName);
19
+ if (!selector) {
20
+ throw new Error(`Selector ${elementName} not found`);
21
+ }
22
+ try {
23
+ await this.page.locator(selector).fill(value);
24
+ } catch (error) {
25
+ throw new Error(
26
+ `Failed to fill in the ${elementName} input field with value ${value}: ${error}`
27
+ );
28
+ }
21
29
  }
22
- try {
23
- await this.page.locator(selector).fill(value);
24
- } catch (error) {
25
- throw new Error(
26
- `Failed to fill in the ${elementName} input field with value ${value}: ${error}`
27
- );
28
- }
29
- }
30
30
  );
31
31
 
32
32
  /**
@@ -35,18 +35,18 @@ When(
35
35
  * @icon INPUT
36
36
  */
37
37
  When(
38
- 'the user clears the {string} field',
39
- async function (this: CustomWorld, elementName: SelectorName) {
40
- const selector = await resolveLocator(this.page, elementName);
41
- if (!selector) {
42
- throw new Error(`Selector ${elementName} not found`);
43
- }
44
- try {
45
- await this.page.locator(selector).clear();
46
- } catch (error) {
47
- throw new Error(`Failed to clear the ${elementName} field: ${error}`);
38
+ 'the user clears the {string} field',
39
+ async function (this: CustomWorld, elementName: SelectorName) {
40
+ const selector = await resolveLocator(this.page, elementName);
41
+ if (!selector) {
42
+ throw new Error(`Selector ${elementName} not found`);
43
+ }
44
+ try {
45
+ await this.page.locator(selector).clear();
46
+ } catch (error) {
47
+ throw new Error(`Failed to clear the ${elementName} field: ${error}`);
48
+ }
48
49
  }
49
- }
50
50
  );
51
51
 
52
52
  /**
@@ -55,24 +55,24 @@ When(
55
55
  * @icon INPUT
56
56
  */
57
57
  When(
58
- 'the user selects the {string} option of the {string} dropdown',
59
- async function (
60
- this: CustomWorld,
61
- optionName: string,
62
- elementName: SelectorName
63
- ) {
64
- const selector = await resolveLocator(this.page, elementName);
65
- if (!selector) {
66
- throw new Error(`Selector ${elementName} not found`);
58
+ 'the user selects the {string} option of the {string} dropdown',
59
+ async function (
60
+ this: CustomWorld,
61
+ optionName: string,
62
+ elementName: SelectorName
63
+ ) {
64
+ const selector = await resolveLocator(this.page, elementName);
65
+ if (!selector) {
66
+ throw new Error(`Selector ${elementName} not found`);
67
+ }
68
+ try {
69
+ await this.page.locator(selector).selectOption(optionName);
70
+ } catch (error) {
71
+ throw new Error(
72
+ `Failed to select the ${optionName} option of the ${elementName} dropdown: ${error}`
73
+ );
74
+ }
67
75
  }
68
- try {
69
- await this.page.locator(selector).selectOption(optionName);
70
- } catch (error) {
71
- throw new Error(
72
- `Failed to select the ${optionName} option of the ${elementName} dropdown: ${error}`
73
- );
74
- }
75
- }
76
76
  );
77
77
 
78
78
  /**
@@ -81,18 +81,18 @@ When(
81
81
  * @icon INPUT
82
82
  */
83
83
  When(
84
- 'the user checks the {string} checkbox',
85
- async function (this: CustomWorld, elementName: SelectorName) {
86
- const selector = await resolveLocator(this.page, elementName);
87
- if (!selector) {
88
- throw new Error(`Selector ${elementName} not found`);
89
- }
90
- try {
91
- await this.page.locator(selector).check();
92
- } catch (error) {
93
- throw new Error(`Failed to check the ${elementName} checkbox: ${error}`);
84
+ 'the user checks the {string} checkbox',
85
+ async function (this: CustomWorld, elementName: SelectorName) {
86
+ const selector = await resolveLocator(this.page, elementName);
87
+ if (!selector) {
88
+ throw new Error(`Selector ${elementName} not found`);
89
+ }
90
+ try {
91
+ await this.page.locator(selector).check();
92
+ } catch (error) {
93
+ throw new Error(`Failed to check the ${elementName} checkbox: ${error}`);
94
+ }
94
95
  }
95
- }
96
96
  );
97
97
 
98
98
  /**
@@ -101,20 +101,20 @@ When(
101
101
  * @icon INPUT
102
102
  */
103
103
  When(
104
- 'the user unchecks the {string} checkbox',
105
- async function (this: CustomWorld, elementName: SelectorName) {
106
- const selector = await resolveLocator(this.page, elementName);
107
- if (!selector) {
108
- throw new Error(`Selector ${elementName} not found`);
104
+ 'the user unchecks the {string} checkbox',
105
+ async function (this: CustomWorld, elementName: SelectorName) {
106
+ const selector = await resolveLocator(this.page, elementName);
107
+ if (!selector) {
108
+ throw new Error(`Selector ${elementName} not found`);
109
+ }
110
+ try {
111
+ await this.page.locator(selector).uncheck();
112
+ } catch (error) {
113
+ throw new Error(
114
+ `Failed to uncheck the ${elementName} checkbox: ${error}`
115
+ );
116
+ }
109
117
  }
110
- try {
111
- await this.page.locator(selector).uncheck();
112
- } catch (error) {
113
- throw new Error(
114
- `Failed to uncheck the ${elementName} checkbox: ${error}`
115
- );
116
- }
117
- }
118
118
  );
119
119
 
120
120
  /**
@@ -123,24 +123,24 @@ When(
123
123
  * @icon INPUT
124
124
  */
125
125
  When(
126
- 'the user fills in the {string} input with data from the stored variable {string}',
127
- async function (
128
- this: CustomWorld,
129
- fieldName: SelectorName,
130
- variableName: string
131
- ) {
132
- const value = this.getVar<string>(variableName);
133
- if (!value) {
134
- throw new Error(`Variable ${variableName} not found`);
135
- }
136
- const selector = await resolveLocator(this.page, fieldName);
137
- if (!selector) {
138
- throw new Error(`Selector ${fieldName} not found`);
139
- }
140
- try {
141
- await this.page.locator(selector).fill(value);
142
- } catch (error) {
143
- throw new Error(`Failed to fill in the ${fieldName} input field with data from the stored variable ${variableName}: ${error}`);
126
+ 'the user fills in the {string} input with data from the stored variable {string}',
127
+ async function (
128
+ this: CustomWorld,
129
+ fieldName: SelectorName,
130
+ variableName: string
131
+ ) {
132
+ const value = this.getVar<string>(variableName);
133
+ if (!value) {
134
+ throw new Error(`Variable ${variableName} not found`);
135
+ }
136
+ const selector = await resolveLocator(this.page, fieldName);
137
+ if (!selector) {
138
+ throw new Error(`Selector ${fieldName} not found`);
139
+ }
140
+ try {
141
+ await this.page.locator(selector).fill(value);
142
+ } catch (error) {
143
+ throw new Error(`Failed to fill in the ${fieldName} input field with data from the stored variable ${variableName}: ${error}`);
144
+ }
144
145
  }
145
- }
146
146
  );