create-appraisejs 0.2.0 → 0.3.0-alpha.0

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 (485) hide show
  1. package/README.md +12 -1
  2. package/package.json +1 -1
  3. package/templates/default/.appraise-template-meta.json +2 -2
  4. package/templates/default/.env.example +2 -2
  5. package/templates/default/README.md +57 -53
  6. package/templates/default/automation/steps/actions/click.step.ts +58 -58
  7. package/templates/default/automation/steps/actions/hover.step.ts +27 -27
  8. package/templates/default/automation/steps/actions/navigation.step.ts +70 -70
  9. package/templates/default/automation/steps/actions/random_data.step.ts +142 -142
  10. package/templates/default/automation/steps/actions/store.step.ts +86 -86
  11. package/templates/default/automation/steps/actions/wait.step.ts +110 -90
  12. package/templates/default/automation/steps/validations/active_state_assertion.step.ts +30 -30
  13. package/templates/default/automation/steps/validations/navigation_assertion.step.ts +22 -22
  14. package/templates/default/automation/steps/validations/text_assertion.step.ts +107 -107
  15. package/templates/default/automation/steps/validations/visibility_assertion.step.ts +26 -26
  16. package/templates/default/components.json +24 -24
  17. package/templates/default/cucumber.mjs +16 -16
  18. package/templates/default/eslint.config.mjs +20 -16
  19. package/templates/default/next-env.d.ts +6 -6
  20. package/templates/default/next.config.ts +20 -11
  21. package/templates/default/package-lock.json +1775 -74
  22. package/templates/default/package.json +8 -1
  23. package/templates/default/packages/cucumber-runtime/package.json +13 -13
  24. package/templates/default/packages/cucumber-runtime/src/cache.util.ts +93 -93
  25. package/templates/default/packages/cucumber-runtime/src/cli.ts +68 -68
  26. package/templates/default/packages/cucumber-runtime/src/environment.util.ts +21 -21
  27. package/templates/default/packages/cucumber-runtime/src/executor.ts +32 -32
  28. package/templates/default/packages/cucumber-runtime/src/index.ts +17 -17
  29. package/templates/default/packages/cucumber-runtime/src/locator.util.ts +234 -234
  30. package/templates/default/packages/cucumber-runtime/src/parameter-types.ts +7 -7
  31. package/templates/default/packages/cucumber-runtime/src/random-data.util.ts +35 -35
  32. package/templates/default/packages/cucumber-runtime/src/types.ts +13 -13
  33. package/templates/default/packages/cucumber-runtime/src/world.ts +44 -44
  34. package/templates/default/packages/cucumber-runtime/tsconfig.json +11 -11
  35. package/templates/default/postcss.config.mjs +8 -8
  36. package/templates/default/prisma/dev.db +0 -0
  37. package/templates/default/prisma/migrations/20251104113456_add_type_for_template_step_groups/migration.sql +16 -16
  38. package/templates/default/prisma/migrations/20251104170946_add_tags_to_test_suite_and_test_case/migration.sql +27 -27
  39. package/templates/default/prisma/migrations/20251112190024_add_cascade_delete_to_test_run_test_case/migration.sql +17 -17
  40. package/templates/default/prisma/migrations/20251113181100_add_test_run_log/migration.sql +12 -12
  41. package/templates/default/prisma/migrations/20251119191838_add_tag_type/migration.sql +28 -28
  42. package/templates/default/prisma/migrations/20251121164059_add_conflict_resolution/migration.sql +12 -12
  43. package/templates/default/prisma/migrations/20251223183400_add_report_model_to_db_schema/migration.sql +10 -10
  44. package/templates/default/prisma/migrations/20251223183637_add_report_test_case_entity_for_storing_test_results_for_individual_test_cases/migration.sql +10 -10
  45. package/templates/default/prisma/migrations/20251224083549_add_comprehensive_report_storage/migration.sql +108 -108
  46. package/templates/default/prisma/migrations/20251229194422_migrate_duration_to_string/migration.sql +55 -55
  47. package/templates/default/prisma/migrations/20251230124637_add_unique_constraint_to_test_run_name/migration.sql +27 -27
  48. package/templates/default/prisma/migrations/20260115094436_add_dashboard_metrics/migration.sql +59 -59
  49. package/templates/default/prisma/migrations/20260127172022_add_cascade_delete_to_step_parameters/migration.sql +34 -34
  50. package/templates/default/prisma/migrations/20260313093000_add_report_step_screenshot_path/migration.sql +1 -1
  51. package/templates/default/scripts/build-step-registry.ts +33 -0
  52. package/templates/default/scripts/install-playwright.ts +17 -8
  53. package/templates/default/scripts/install-template-step.ts +128 -0
  54. package/templates/default/scripts/lib/filename-utils.test.ts +24 -0
  55. package/templates/default/scripts/lib/filename-utils.ts +24 -0
  56. package/templates/default/scripts/lib/jsdoc-parser.test.ts +63 -0
  57. package/templates/default/scripts/lib/jsdoc-parser.ts +88 -0
  58. package/templates/default/scripts/lib/step-file-parser.test.ts +71 -0
  59. package/templates/default/scripts/lib/step-file-parser.ts +315 -0
  60. package/templates/default/scripts/lib/step-matcher.test.ts +86 -0
  61. package/templates/default/scripts/lib/step-matcher.ts +120 -0
  62. package/templates/default/scripts/lib/sync-script-runner.ts +23 -0
  63. package/templates/default/scripts/lib/sync-summary.ts +29 -0
  64. package/templates/default/scripts/lib/tag-parsing.test.ts +20 -0
  65. package/templates/default/scripts/lib/tag-parsing.ts +10 -0
  66. package/templates/default/scripts/lib/template-step-installer.test.ts +225 -0
  67. package/templates/default/scripts/lib/template-step-installer.ts +404 -0
  68. package/templates/default/scripts/lib/template-step-registry.test.ts +118 -0
  69. package/templates/default/scripts/lib/template-step-registry.ts +137 -0
  70. package/templates/default/scripts/protect-seeded-files.ts +51 -38
  71. package/templates/default/scripts/regenerate-features.ts +98 -94
  72. package/templates/default/scripts/run-vitest.ts +59 -0
  73. package/templates/default/scripts/setup-env.ts +26 -19
  74. package/templates/default/scripts/sync-all.ts +44 -54
  75. package/templates/default/scripts/sync-appraise-base-template.ts +44 -16
  76. package/templates/default/scripts/sync-environments.ts +22 -66
  77. package/templates/default/scripts/sync-locator-groups.ts +358 -410
  78. package/templates/default/scripts/sync-locators.ts +348 -398
  79. package/templates/default/scripts/sync-modules.ts +302 -341
  80. package/templates/default/scripts/sync-tags.ts +29 -65
  81. package/templates/default/scripts/sync-template-step-groups.ts +24 -182
  82. package/templates/default/scripts/sync-template-steps.ts +36 -493
  83. package/templates/default/scripts/sync-test-cases.ts +296 -539
  84. package/templates/default/scripts/sync-test-suites.ts +32 -79
  85. package/templates/default/src/actions/dashboard/dashboard-actions.ts +70 -241
  86. package/templates/default/src/actions/environments/environment-actions.ts +102 -188
  87. package/templates/default/src/actions/locator/locator-actions.ts +77 -490
  88. package/templates/default/src/actions/locator-groups/locator-group-actions.ts +34 -212
  89. package/templates/default/src/actions/locator-picker/locator-picker-actions.test.ts +81 -0
  90. package/templates/default/src/actions/locator-picker/locator-picker-actions.ts +20 -161
  91. package/templates/default/src/actions/modules/module-actions.ts +99 -135
  92. package/templates/default/src/actions/reports/report-actions.ts +28 -565
  93. package/templates/default/src/actions/settings/sync-actions.test.ts +58 -0
  94. package/templates/default/src/actions/tags/tag-actions.ts +99 -107
  95. package/templates/default/src/actions/template-step/template-step-actions.ts +33 -194
  96. package/templates/default/src/actions/template-step-group/template-step-group-actions.ts +35 -92
  97. package/templates/default/src/actions/template-test-case/template-test-case-actions.ts +98 -238
  98. package/templates/default/src/actions/test-case/test-case-actions.ts +108 -356
  99. package/templates/default/src/actions/test-run/test-run-actions.ts +74 -1081
  100. package/templates/default/src/actions/test-suite/test-suite-actions.ts +35 -202
  101. package/templates/default/src/app/(base)/environments/create/page.tsx +28 -28
  102. package/templates/default/src/app/(base)/environments/environment-form.test.tsx +92 -0
  103. package/templates/default/src/app/(base)/environments/environment-form.tsx +228 -219
  104. package/templates/default/src/app/(base)/environments/environment-helpers.ts +58 -0
  105. package/templates/default/src/app/(base)/environments/environment-table-columns.tsx +96 -96
  106. package/templates/default/src/app/(base)/environments/environment-table.tsx +25 -24
  107. package/templates/default/src/app/(base)/environments/modify/[id]/page.tsx +49 -46
  108. package/templates/default/src/app/(base)/environments/page.tsx +59 -59
  109. package/templates/default/src/app/(base)/layout.tsx +10 -10
  110. package/templates/default/src/app/(base)/locator-groups/create/page.tsx +44 -44
  111. package/templates/default/src/app/(base)/locator-groups/locator-group-form.tsx +215 -215
  112. package/templates/default/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
  113. package/templates/default/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
  114. package/templates/default/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
  115. package/templates/default/src/app/(base)/locators/create/create-locator-workspace-helpers.test.ts +71 -0
  116. package/templates/default/src/app/(base)/locators/create/create-locator-workspace-helpers.ts +333 -0
  117. package/templates/default/src/app/(base)/locators/create/create-locator-workspace.test.tsx +125 -0
  118. package/templates/default/src/app/(base)/locators/create/create-locator-workspace.tsx +56 -274
  119. package/templates/default/src/app/(base)/locators/create/page.tsx +8 -4
  120. package/templates/default/src/app/(base)/locators/create/use-locator-workspace.ts +183 -0
  121. package/templates/default/src/app/(base)/locators/locator-helpers.test.ts +28 -0
  122. package/templates/default/src/app/(base)/locators/locator-helpers.ts +59 -0
  123. package/templates/default/src/app/(base)/locators/locator-table-columns.tsx +74 -73
  124. package/templates/default/src/app/(base)/locators/locator-table.tsx +30 -28
  125. package/templates/default/src/app/(base)/locators/modify/[id]/page.tsx +20 -8
  126. package/templates/default/src/app/(base)/locators/page.tsx +3 -6
  127. package/templates/default/src/app/(base)/locators/sync-locators-button.tsx +67 -66
  128. package/templates/default/src/app/(base)/modules/create/page.tsx +33 -34
  129. package/templates/default/src/app/(base)/modules/modify/[id]/page.tsx +43 -46
  130. package/templates/default/src/app/(base)/modules/module-form.test.tsx +84 -0
  131. package/templates/default/src/app/(base)/modules/module-form.tsx +159 -126
  132. package/templates/default/src/app/(base)/modules/module-helpers.ts +64 -0
  133. package/templates/default/src/app/(base)/modules/module-table-columns.tsx +81 -85
  134. package/templates/default/src/app/(base)/modules/module-table.tsx +25 -24
  135. package/templates/default/src/app/(base)/modules/page.tsx +59 -59
  136. package/templates/default/src/app/(base)/reports/[id]/page.tsx +20 -260
  137. package/templates/default/src/app/(base)/reports/duration-chart.tsx +33 -33
  138. package/templates/default/src/app/(base)/reports/feature-chart.tsx +79 -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-detail-helpers.test.ts +109 -0
  142. package/templates/default/src/app/(base)/reports/report-detail-helpers.ts +247 -0
  143. package/templates/default/src/app/(base)/reports/report-metric-card.tsx +78 -78
  144. package/templates/default/src/app/(base)/reports/report-table-columns.tsx +189 -189
  145. package/templates/default/src/app/(base)/reports/report-table.tsx +72 -72
  146. package/templates/default/src/app/(base)/reports/test-cases/page.tsx +40 -40
  147. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +115 -115
  148. package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
  149. package/templates/default/src/app/(base)/reports/test-suites/page.tsx +42 -42
  150. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +79 -79
  151. package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +27 -27
  152. package/templates/default/src/app/(base)/reports/view-logs-button.tsx +58 -58
  153. package/templates/default/src/app/(base)/settings/settings-sync-panel-helpers.test.tsx +40 -0
  154. package/templates/default/src/app/(base)/settings/settings-sync-panel-helpers.tsx +110 -0
  155. package/templates/default/src/app/(base)/settings/settings-sync-panel.test.tsx +127 -0
  156. package/templates/default/src/app/(base)/settings/settings-sync-panel.tsx +19 -134
  157. package/templates/default/src/app/(base)/settings/use-settings-sync.ts +66 -0
  158. package/templates/default/src/app/(base)/tags/create/page.tsx +39 -39
  159. package/templates/default/src/app/(base)/tags/modify/[id]/page.tsx +50 -50
  160. package/templates/default/src/app/(base)/tags/page.tsx +58 -58
  161. package/templates/default/src/app/(base)/tags/tag-form-helpers.ts +13 -0
  162. package/templates/default/src/app/(base)/tags/tag-form.test.tsx +83 -0
  163. package/templates/default/src/app/(base)/tags/tag-form.tsx +143 -147
  164. package/templates/default/src/app/(base)/tags/tag-table-columns.tsx +63 -63
  165. package/templates/default/src/app/(base)/tags/tag-table.tsx +29 -29
  166. package/templates/default/src/app/(base)/template-step-groups/create/page.tsx +28 -28
  167. package/templates/default/src/app/(base)/template-step-groups/modify/[id]/page.tsx +43 -45
  168. package/templates/default/src/app/(base)/template-step-groups/page.tsx +60 -60
  169. package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.test.tsx +82 -0
  170. package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.tsx +181 -167
  171. package/templates/default/src/app/(base)/template-step-groups/template-step-group-helpers.ts +54 -0
  172. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table-columns.tsx +89 -89
  173. package/templates/default/src/app/(base)/template-step-groups/template-step-group-table.tsx +34 -32
  174. package/templates/default/src/app/(base)/template-steps/create/page.tsx +40 -37
  175. package/templates/default/src/app/(base)/template-steps/modify/[id]/page.tsx +54 -49
  176. package/templates/default/src/app/(base)/template-steps/page.tsx +59 -58
  177. package/templates/default/src/app/(base)/template-steps/paramChip.tsx +233 -213
  178. package/templates/default/src/app/(base)/template-steps/template-step-form.test.tsx +132 -0
  179. package/templates/default/src/app/(base)/template-steps/template-step-form.tsx +342 -384
  180. package/templates/default/src/app/(base)/template-steps/template-step-helpers.test.ts +99 -0
  181. package/templates/default/src/app/(base)/template-steps/template-step-helpers.ts +176 -0
  182. package/templates/default/src/app/(base)/template-steps/template-step-table-columns.tsx +153 -158
  183. package/templates/default/src/app/(base)/template-steps/template-step-table.tsx +26 -24
  184. package/templates/default/src/app/(base)/template-test-cases/create/page.tsx +56 -56
  185. package/templates/default/src/app/(base)/template-test-cases/modify/[id]/page.tsx +89 -89
  186. package/templates/default/src/app/(base)/template-test-cases/page.tsx +58 -58
  187. package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.test.tsx +109 -0
  188. package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.tsx +45 -84
  189. package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.test.tsx +140 -0
  190. package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.tsx +154 -262
  191. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
  192. package/templates/default/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
  193. package/templates/default/src/app/(base)/test-cases/create/page.tsx +90 -76
  194. package/templates/default/src/app/(base)/test-cases/create-from-template/create-from-template-helpers.test.ts +94 -0
  195. package/templates/default/src/app/(base)/test-cases/create-from-template/create-from-template-helpers.ts +171 -0
  196. package/templates/default/src/app/(base)/test-cases/create-from-template/generate/[id]/page.tsx +105 -96
  197. package/templates/default/src/app/(base)/test-cases/create-from-template/page.tsx +40 -38
  198. package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.test.tsx +87 -0
  199. package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.tsx +83 -73
  200. package/templates/default/src/app/(base)/test-cases/modify/[id]/page.tsx +106 -106
  201. package/templates/default/src/app/(base)/test-cases/page.tsx +3 -2
  202. package/templates/default/src/app/(base)/test-cases/test-case-flow.test.tsx +108 -0
  203. package/templates/default/src/app/(base)/test-cases/test-case-flow.tsx +43 -82
  204. package/templates/default/src/app/(base)/test-cases/test-case-form.test.tsx +202 -0
  205. package/templates/default/src/app/(base)/test-cases/test-case-form.tsx +263 -395
  206. package/templates/default/src/app/(base)/test-cases/test-case-route-helpers.test.ts +95 -0
  207. package/templates/default/src/app/(base)/test-cases/test-case-route-helpers.ts +147 -0
  208. package/templates/default/src/app/(base)/test-cases/test-case-table.tsx +4 -2
  209. package/templates/default/src/app/(base)/test-runs/[id]/page.tsx +11 -10
  210. package/templates/default/src/app/(base)/test-runs/create/page.tsx +4 -5
  211. package/templates/default/src/app/(base)/test-runs/page.tsx +60 -60
  212. package/templates/default/src/app/(base)/test-runs/test-run-form-helpers.test.ts +50 -0
  213. package/templates/default/src/app/(base)/test-runs/test-run-form-helpers.ts +168 -0
  214. package/templates/default/src/app/(base)/test-runs/test-run-form.test.tsx +138 -0
  215. package/templates/default/src/app/(base)/test-runs/test-run-form.tsx +111 -256
  216. package/templates/default/src/app/(base)/test-runs/test-run-table-columns.tsx +229 -229
  217. package/templates/default/src/app/(base)/test-runs/test-run-table.tsx +127 -127
  218. package/templates/default/src/app/(base)/test-runs/use-test-run-name-validation.ts +74 -0
  219. package/templates/default/src/app/(base)/test-suites/create/page.tsx +17 -12
  220. package/templates/default/src/app/(base)/test-suites/modify/[id]/page.tsx +22 -19
  221. package/templates/default/src/app/(base)/test-suites/page.tsx +14 -56
  222. package/templates/default/src/app/(base)/test-suites/test-suite-form.test.tsx +127 -0
  223. package/templates/default/src/app/(base)/test-suites/test-suite-form.tsx +45 -64
  224. package/templates/default/src/app/(base)/test-suites/test-suite-helpers.test.ts +67 -0
  225. package/templates/default/src/app/(base)/test-suites/test-suite-helpers.ts +215 -0
  226. package/templates/default/src/app/(base)/test-suites/test-suite-table.tsx +32 -29
  227. package/templates/default/src/app/(dashboard-components)/app-drawer.tsx +187 -187
  228. package/templates/default/src/app/(dashboard-components)/data-card-grid.tsx +12 -12
  229. package/templates/default/src/app/(dashboard-components)/data-card.tsx +26 -26
  230. package/templates/default/src/app/(dashboard-components)/execution-health-panel.tsx +56 -56
  231. package/templates/default/src/app/(dashboard-components)/ongoing-test-runs-card.tsx +87 -87
  232. package/templates/default/src/app/(dashboard-components)/quick-actions-drawer.tsx +44 -44
  233. package/templates/default/src/app/api/reports/steps/[stepId]/screenshot/route.test.ts +83 -0
  234. package/templates/default/src/app/api/reports/steps/[stepId]/screenshot/route.ts +52 -52
  235. package/templates/default/src/app/api/test-runs/[runId]/download/route.test.ts +169 -0
  236. package/templates/default/src/app/api/test-runs/[runId]/download/route.ts +1 -1
  237. package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.test.ts +135 -0
  238. package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.ts +146 -146
  239. package/templates/default/src/app/globals.css +147 -147
  240. package/templates/default/src/app/page.tsx +1 -1
  241. package/templates/default/src/assets/icons/empty-tube.tsx +23 -23
  242. package/templates/default/src/assets/icons/tube-plus.tsx +29 -29
  243. package/templates/default/src/components/base-node.tsx +21 -21
  244. package/templates/default/src/components/chart/pie-chart.tsx +73 -73
  245. package/templates/default/src/components/data-extraction/locator-inspector-helpers.test.ts +32 -0
  246. package/templates/default/src/components/data-extraction/locator-inspector-helpers.ts +183 -0
  247. package/templates/default/src/components/data-extraction/locator-inspector.tsx +349 -460
  248. package/templates/default/src/components/data-state/empty-state.tsx +40 -40
  249. package/templates/default/src/components/data-visualization/info-card.tsx +70 -70
  250. package/templates/default/src/components/data-visualization/info-grid.tsx +22 -22
  251. package/templates/default/src/components/diagram/button-edge.tsx +54 -54
  252. package/templates/default/src/components/diagram/dynamic-parameters-helpers.test.ts +83 -0
  253. package/templates/default/src/components/diagram/dynamic-parameters-helpers.ts +158 -0
  254. package/templates/default/src/components/diagram/dynamic-parameters.tsx +350 -474
  255. package/templates/default/src/components/diagram/edit-header-option.tsx +36 -36
  256. package/templates/default/src/components/diagram/flow-diagram-helpers.test.ts +117 -0
  257. package/templates/default/src/components/diagram/flow-diagram-helpers.ts +251 -0
  258. package/templates/default/src/components/diagram/flow-diagram.tsx +247 -470
  259. package/templates/default/src/components/diagram/flow-host-helpers.test.ts +74 -0
  260. package/templates/default/src/components/diagram/flow-host-helpers.ts +51 -0
  261. package/templates/default/src/components/diagram/node-form-helpers.test.ts +92 -0
  262. package/templates/default/src/components/diagram/node-form-helpers.ts +100 -0
  263. package/templates/default/src/components/diagram/node-form.test.tsx +168 -0
  264. package/templates/default/src/components/diagram/node-form.tsx +199 -262
  265. package/templates/default/src/components/diagram/options-header-node.tsx +57 -57
  266. package/templates/default/src/components/diagram/template-step-combobox.tsx +155 -155
  267. package/templates/default/src/components/diagram/use-flow-node-order.ts +49 -0
  268. package/templates/default/src/components/form/error-message.tsx +7 -7
  269. package/templates/default/src/components/kokonutui/smooth-tab.tsx +453 -453
  270. package/templates/default/src/components/loading-skeleton/data-table/data-table-skeleton.tsx +30 -30
  271. package/templates/default/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
  272. package/templates/default/src/components/loading-skeleton/form/icon-button-skeleton.tsx +8 -8
  273. package/templates/default/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
  274. package/templates/default/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
  275. package/templates/default/src/components/navigation/command-badge.tsx +34 -34
  276. package/templates/default/src/components/navigation/command-chain-input.tsx +51 -51
  277. package/templates/default/src/components/navigation/entity-search-command.tsx +118 -116
  278. package/templates/default/src/components/navigation/nav-card.tsx +31 -31
  279. package/templates/default/src/components/navigation/nav-command-helpers.ts +122 -0
  280. package/templates/default/src/components/navigation/nav-command-search.tsx +125 -0
  281. package/templates/default/src/components/navigation/nav-command.test.tsx +106 -0
  282. package/templates/default/src/components/navigation/nav-command.tsx +49 -472
  283. package/templates/default/src/components/navigation/nav-link.tsx +60 -60
  284. package/templates/default/src/components/navigation/nav-menu-card-deck.tsx +112 -112
  285. package/templates/default/src/components/navigation/use-nav-command.ts +58 -0
  286. package/templates/default/src/components/node-header.tsx +159 -159
  287. package/templates/default/src/components/reports/test-case-logs-modal.tsx +310 -310
  288. package/templates/default/src/components/table/table-actions.tsx +174 -172
  289. package/templates/default/src/components/test-case/test-case-form-helpers.test.ts +100 -0
  290. package/templates/default/src/components/test-case/test-case-form-helpers.ts +140 -0
  291. package/templates/default/src/components/test-case/test-case-picker-helpers.test.ts +40 -0
  292. package/templates/default/src/components/test-case/test-case-picker-helpers.ts +41 -0
  293. package/templates/default/src/components/test-case/test-case-picker.test.tsx +44 -0
  294. package/templates/default/src/components/test-case/test-case-picker.tsx +16 -35
  295. package/templates/default/src/components/test-case/test-scenario-preview.tsx +34 -0
  296. package/templates/default/src/components/test-run/download-logs-button.tsx +92 -92
  297. package/templates/default/src/components/test-run/log-viewer-helpers.test.ts +37 -0
  298. package/templates/default/src/components/test-run/log-viewer-helpers.ts +80 -0
  299. package/templates/default/src/components/test-run/log-viewer.test.tsx +118 -0
  300. package/templates/default/src/components/test-run/log-viewer.tsx +51 -350
  301. package/templates/default/src/components/test-run/test-run-details-helpers.test.ts +31 -0
  302. package/templates/default/src/components/test-run/test-run-details-helpers.ts +208 -0
  303. package/templates/default/src/components/test-run/test-run-details.test.tsx +174 -0
  304. package/templates/default/src/components/test-run/test-run-details.tsx +155 -457
  305. package/templates/default/src/components/test-run/test-run-header-helpers.test.ts +31 -0
  306. package/templates/default/src/components/test-run/test-run-header-helpers.ts +23 -0
  307. package/templates/default/src/components/test-run/test-run-header.test.tsx +103 -0
  308. package/templates/default/src/components/test-run/test-run-header.tsx +27 -149
  309. package/templates/default/src/components/test-run/use-log-viewer.ts +213 -0
  310. package/templates/default/src/components/test-run/use-test-run-details.ts +184 -0
  311. package/templates/default/src/components/test-run/use-test-run-header.ts +89 -0
  312. package/templates/default/src/components/test-run/view-report-button.tsx +102 -102
  313. package/templates/default/src/components/test-suite/test-suite-picker-helpers.test.ts +68 -0
  314. package/templates/default/src/components/test-suite/test-suite-picker-helpers.ts +76 -0
  315. package/templates/default/src/components/test-suite/test-suite-picker.test.tsx +65 -0
  316. package/templates/default/src/components/test-suite/test-suite-picker.tsx +4 -72
  317. package/templates/default/src/components/theme/mode-toggle.tsx +54 -54
  318. package/templates/default/src/components/theme/theme-provider.tsx +8 -8
  319. package/templates/default/src/components/typography/page-header-subtitle.tsx +7 -7
  320. package/templates/default/src/components/typography/page-header.tsx +7 -7
  321. package/templates/default/src/components/ui/alert-dialog.tsx +106 -106
  322. package/templates/default/src/components/ui/alert.tsx +43 -43
  323. package/templates/default/src/components/ui/avatar.tsx +40 -40
  324. package/templates/default/src/components/ui/badge.tsx +29 -29
  325. package/templates/default/src/components/ui/button.tsx +47 -47
  326. package/templates/default/src/components/ui/calendar.tsx +158 -158
  327. package/templates/default/src/components/ui/card.tsx +43 -43
  328. package/templates/default/src/components/ui/checkbox.tsx +28 -28
  329. package/templates/default/src/components/ui/command.tsx +135 -135
  330. package/templates/default/src/components/ui/data-table-column-header.tsx +61 -61
  331. package/templates/default/src/components/ui/data-table-pagination.tsx +87 -87
  332. package/templates/default/src/components/ui/data-table-view-options.tsx +50 -50
  333. package/templates/default/src/components/ui/data-table.test.tsx +122 -0
  334. package/templates/default/src/components/ui/data-table.tsx +298 -261
  335. package/templates/default/src/components/ui/dialog.tsx +97 -97
  336. package/templates/default/src/components/ui/dropdown-menu.tsx +182 -182
  337. package/templates/default/src/components/ui/input.tsx +22 -22
  338. package/templates/default/src/components/ui/kbd.tsx +28 -28
  339. package/templates/default/src/components/ui/label.tsx +19 -19
  340. package/templates/default/src/components/ui/loading.tsx +12 -12
  341. package/templates/default/src/components/ui/multi-select-with-preview.tsx +116 -116
  342. package/templates/default/src/components/ui/multi-select.test.tsx +45 -0
  343. package/templates/default/src/components/ui/multi-select.tsx +158 -142
  344. package/templates/default/src/components/ui/navigation-menu.tsx +120 -120
  345. package/templates/default/src/components/ui/popover.tsx +33 -33
  346. package/templates/default/src/components/ui/progress.tsx +25 -25
  347. package/templates/default/src/components/ui/radio-group.tsx +44 -44
  348. package/templates/default/src/components/ui/scroll-area.tsx +40 -40
  349. package/templates/default/src/components/ui/select.tsx +151 -151
  350. package/templates/default/src/components/ui/separator.tsx +22 -22
  351. package/templates/default/src/components/ui/skeleton.tsx +7 -7
  352. package/templates/default/src/components/ui/table.tsx +76 -76
  353. package/templates/default/src/components/ui/tabs.tsx +55 -55
  354. package/templates/default/src/components/ui/textarea.tsx +21 -21
  355. package/templates/default/src/components/ui/toast.tsx +113 -113
  356. package/templates/default/src/components/ui/toaster.tsx +26 -26
  357. package/templates/default/src/components/user-prompt/delete-prompt.test.tsx +60 -0
  358. package/templates/default/src/components/user-prompt/delete-prompt.tsx +118 -87
  359. package/templates/default/src/constants/form-opts/diagram/node-form.ts +30 -30
  360. package/templates/default/src/constants/form-opts/environment-form-opts.ts +24 -24
  361. package/templates/default/src/constants/form-opts/locator-group-form-opts.ts +28 -28
  362. package/templates/default/src/constants/form-opts/module-form-opts.ts +21 -21
  363. package/templates/default/src/constants/form-opts/tag-form-opts.ts +42 -42
  364. package/templates/default/src/constants/form-opts/template-selection-form-opts.ts +16 -16
  365. package/templates/default/src/constants/form-opts/template-step-group-form-opts.ts +24 -24
  366. package/templates/default/src/constants/form-opts/template-test-case-form-opts.ts +39 -39
  367. package/templates/default/src/constants/form-opts/template-test-step-form-opts.ts +36 -36
  368. package/templates/default/src/constants/form-opts/test-case-form-opts.ts +43 -43
  369. package/templates/default/src/constants/form-opts/test-suite-form-opts.ts +24 -24
  370. package/templates/default/src/hooks/use-toast.ts +187 -187
  371. package/templates/default/src/lib/automation/automation-path-roots.ts +95 -0
  372. package/templates/default/src/lib/automation/automation-workspace.ts +147 -0
  373. package/templates/default/src/lib/automation/paths.ts +6 -211
  374. package/templates/default/src/lib/bidirectional-sync.ts +432 -432
  375. package/templates/default/src/lib/environment-file-utils.ts +2 -1
  376. package/templates/default/src/lib/executor/local-executor-adapter.ts +2 -5
  377. package/templates/default/src/lib/feature-file-generator.ts +2 -1
  378. package/templates/default/src/lib/gherkin-parser.ts +0 -2
  379. package/templates/default/src/lib/locator-group-file-utils.ts +304 -307
  380. package/templates/default/src/lib/locator-picker/session-manager.ts +0 -21
  381. package/templates/default/src/lib/locator-picker/suggestions.ts +4 -2
  382. package/templates/default/src/lib/metrics/metric-calculator.ts +2 -6
  383. package/templates/default/src/lib/module-hierarchy-builder.ts +205 -205
  384. package/templates/default/src/lib/path-helpers/module-path.ts +71 -71
  385. package/templates/default/src/lib/sync/sync-executor.test.ts +76 -0
  386. package/templates/default/src/lib/sync/sync-pending-counts.test.ts +227 -226
  387. package/templates/default/src/lib/sync/sync-pending-counts.ts +2 -5
  388. package/templates/default/src/lib/template-sync-utils.d.ts +6 -6
  389. package/templates/default/src/lib/template-sync-utils.js +46 -46
  390. package/templates/default/src/lib/template-sync-utils.ts +63 -63
  391. package/templates/default/src/lib/test-case-utils.ts +6 -6
  392. package/templates/default/src/lib/test-run/log-formatter.ts +83 -83
  393. package/templates/default/src/lib/test-run/report-parser.ts +352 -352
  394. package/templates/default/src/lib/test-run/test-run-executor.ts +13 -13
  395. package/templates/default/src/lib/test-run/winston-logger.ts +65 -64
  396. package/templates/default/src/lib/transformers/gherkin-converter.ts +42 -42
  397. package/templates/default/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
  398. package/templates/default/src/lib/transformers/template-test-case-converter.ts +160 -160
  399. package/templates/default/src/lib/utils/node-param-validation.ts +81 -81
  400. package/templates/default/src/lib/utils/template-step-file-generator.ts +2 -2
  401. package/templates/default/src/lib/utils/template-step-file-manager.ts +166 -166
  402. package/templates/default/src/lib/utils.ts +31 -31
  403. package/templates/default/src/services/dashboard/dashboard-service.test.ts +106 -0
  404. package/templates/default/src/services/dashboard/dashboard-service.ts +173 -0
  405. package/templates/default/src/services/environment/environment-service.test.ts +137 -0
  406. package/templates/default/src/services/environment/environment-service.ts +96 -0
  407. package/templates/default/src/services/locator/locator-path-utils.test.ts +14 -0
  408. package/templates/default/src/services/locator/locator-path-utils.ts +14 -0
  409. package/templates/default/src/services/locator/locator-service.test.ts +63 -0
  410. package/templates/default/src/services/locator/locator-service.ts +479 -0
  411. package/templates/default/src/services/locator/locator-sync-utils.test.ts +19 -0
  412. package/templates/default/src/services/locator/locator-sync-utils.ts +21 -0
  413. package/templates/default/src/services/locator-group/locator-group-service.test.ts +123 -0
  414. package/templates/default/src/services/locator-group/locator-group-service.ts +180 -0
  415. package/templates/default/src/services/module/module-service.test.ts +89 -0
  416. package/templates/default/src/services/module/module-service.ts +66 -0
  417. package/templates/default/src/services/report/report-service.test.ts +244 -0
  418. package/templates/default/src/services/report/report-service.ts +438 -0
  419. package/templates/default/src/services/shared/constants.ts +2 -0
  420. package/templates/default/src/services/shared/errors.test.ts +38 -0
  421. package/templates/default/src/services/shared/errors.ts +44 -0
  422. package/templates/default/src/services/shared/index.ts +7 -0
  423. package/templates/default/src/services/tag/tag-service.test.ts +22 -0
  424. package/templates/default/src/services/tag/tag-service.ts +41 -0
  425. package/templates/default/src/services/template-step/template-step-service.test.ts +22 -0
  426. package/templates/default/src/services/template-step/template-step-service.ts +171 -0
  427. package/templates/default/src/services/template-step-group/template-step-group-service.test.ts +22 -0
  428. package/templates/default/src/services/template-step-group/template-step-group-service.ts +81 -0
  429. package/templates/default/src/services/template-test-case/template-test-case-service.test.ts +22 -0
  430. package/templates/default/src/services/template-test-case/template-test-case-service.ts +128 -0
  431. package/templates/default/src/services/test-case/test-case-service.test.ts +175 -0
  432. package/templates/default/src/services/test-case/test-case-service.ts +298 -0
  433. package/templates/default/src/services/test-run/test-run-helpers.ts +61 -0
  434. package/templates/default/src/services/test-run/test-run-service.test.ts +647 -0
  435. package/templates/default/src/services/test-run/test-run-service.ts +917 -0
  436. package/templates/default/src/services/test-suite/test-suite-service.test.ts +127 -0
  437. package/templates/default/src/services/test-suite/test-suite-service.ts +197 -0
  438. package/templates/default/src/types/diagram/diagram.ts +34 -34
  439. package/templates/default/src/types/diagram/template-step.ts +11 -11
  440. package/templates/default/src/types/executor/browser.type.ts +1 -1
  441. package/templates/default/src/types/form/actionHandler.ts +19 -6
  442. package/templates/default/src/types/locator/locator.type.ts +11 -11
  443. package/templates/default/src/types/step/step.type.ts +1 -1
  444. package/templates/default/src/types/table/data-table.ts +6 -6
  445. package/templates/default/tailwind.config.ts +62 -62
  446. package/templates/default/tsconfig.json +1 -1
  447. package/dist/cli.e2e.test.d.ts +0 -2
  448. package/dist/cli.e2e.test.d.ts.map +0 -1
  449. package/dist/cli.e2e.test.js +0 -73
  450. package/dist/cli.e2e.test.js.map +0 -1
  451. package/dist/config.test.d.ts +0 -2
  452. package/dist/config.test.d.ts.map +0 -1
  453. package/dist/config.test.js +0 -65
  454. package/dist/config.test.js.map +0 -1
  455. package/dist/copy-template.test.d.ts +0 -2
  456. package/dist/copy-template.test.d.ts.map +0 -1
  457. package/dist/copy-template.test.js +0 -71
  458. package/dist/copy-template.test.js.map +0 -1
  459. package/dist/download-repo.test.d.ts +0 -2
  460. package/dist/download-repo.test.d.ts.map +0 -1
  461. package/dist/download-repo.test.js +0 -14
  462. package/dist/download-repo.test.js.map +0 -1
  463. package/dist/install.test.d.ts +0 -2
  464. package/dist/install.test.d.ts.map +0 -1
  465. package/dist/install.test.js +0 -119
  466. package/dist/install.test.js.map +0 -1
  467. package/dist/prompts.test.d.ts +0 -2
  468. package/dist/prompts.test.d.ts.map +0 -1
  469. package/dist/prompts.test.js +0 -58
  470. package/dist/prompts.test.js.map +0 -1
  471. package/templates/default/src/actions/conflict/conflict.action.ts +0 -33
  472. package/templates/default/src/actions/review/review-actions.ts +0 -147
  473. package/templates/default/src/actions/user/user-actions.ts +0 -13
  474. package/templates/default/src/app/(base)/locators/locator-form.tsx +0 -163
  475. package/templates/default/src/app/(base)/reviews/create/page.tsx +0 -26
  476. package/templates/default/src/app/(base)/reviews/created-reviews-table.tsx +0 -15
  477. package/templates/default/src/app/(base)/reviews/modify/[id]/page.tsx +0 -26
  478. package/templates/default/src/app/(base)/reviews/page.tsx +0 -26
  479. package/templates/default/src/app/(base)/reviews/review/[id]/page.tsx +0 -26
  480. package/templates/default/src/app/(base)/reviews/review-form.tsx +0 -11
  481. package/templates/default/src/app/(base)/reviews/review-table-by-creator-columns.tsx +0 -9
  482. package/templates/default/src/app/(base)/reviews/review-table-by-reviewer-columns.tsx +0 -9
  483. package/templates/default/src/app/(base)/reviews/reviewer-reviews-table.tsx +0 -15
  484. package/templates/default/src/constants/form-opts/locator-form-opts.ts +0 -20
  485. package/templates/default/src/constants/form-opts/review-form-opts.ts +0 -23
@@ -1,310 +1,310 @@
1
- 'use client'
2
-
3
- import { useState } from 'react'
4
- import Image from 'next/image'
5
- import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'
6
- import { Badge } from '@/components/ui/badge'
7
- import { Separator } from '@/components/ui/separator'
8
- import { StepStatus, ReportScenario } from '@prisma/client'
9
- import { CheckCircle, XCircle, Clock, AlertCircle } from 'lucide-react'
10
- import { ScrollArea } from '../ui/scroll-area'
11
- import { Button } from '@/components/ui/button'
12
-
13
- /** Minimal shape so both full Prisma and report-table select types are accepted */
14
- type ReportScenarioWithDetails = ReportScenario & {
15
- tags: Array<{ tagName: string }>
16
- steps: Array<{
17
- id: string
18
- keyword: string
19
- name: string
20
- status: StepStatus
21
- duration: string
22
- errorMessage: string | null
23
- errorTrace: string | null
24
- screenshotPath?: string | null
25
- order: number
26
- matchLocation?: string | null
27
- }>
28
- hooks: Array<{
29
- id: string
30
- keyword: string
31
- status: StepStatus
32
- duration: string
33
- errorMessage: string | null
34
- errorTrace: string | null
35
- }>
36
- }
37
-
38
- interface TestCaseLogsModalProps {
39
- open: boolean
40
- onOpenChange: (open: boolean) => void
41
- reportScenario: ReportScenarioWithDetails | null
42
- }
43
-
44
- const stepStatusToBadge = (status: StepStatus) => {
45
- switch (status) {
46
- case StepStatus.PASSED:
47
- return (
48
- <Badge
49
- variant="outline"
50
- className="flex items-center gap-1 rounded-xl border-green-700 bg-green-700/10 py-0.5 text-xs text-green-500"
51
- >
52
- <CheckCircle className="h-3 w-3" />
53
- PASSED
54
- </Badge>
55
- )
56
- case StepStatus.FAILED:
57
- return (
58
- <Badge
59
- variant="outline"
60
- className="flex items-center gap-1 rounded-xl border-red-700 bg-red-700/10 py-0.5 text-xs text-red-500"
61
- >
62
- <XCircle className="h-3 w-3" />
63
- FAILED
64
- </Badge>
65
- )
66
- case StepStatus.SKIPPED:
67
- return (
68
- <Badge
69
- variant="outline"
70
- className="flex items-center gap-1 rounded-xl border-gray-700 bg-gray-700/10 py-0.5 text-xs text-gray-500"
71
- >
72
- <Clock className="h-3 w-3" />
73
- SKIPPED
74
- </Badge>
75
- )
76
- default:
77
- return (
78
- <Badge
79
- variant="outline"
80
- className="flex items-center gap-1 rounded-xl border-gray-700 bg-gray-700/10 py-0.5 text-xs text-gray-500"
81
- >
82
- {status}
83
- </Badge>
84
- )
85
- }
86
- }
87
-
88
- const formatDuration = (duration: string) => {
89
- const durationNs = Number(duration)
90
- if (isNaN(durationNs)) return '-'
91
- const durationMs = Math.round(durationNs / 1000000)
92
- if (durationMs < 1000) {
93
- return `${durationMs}ms`
94
- }
95
- const seconds = Math.floor(durationMs / 1000)
96
- const milliseconds = durationMs % 1000
97
- return `${seconds}.${String(milliseconds).padStart(3, '0')}s`
98
- }
99
-
100
- const formatKeyword = (keyword: string) => {
101
- return keyword.charAt(0) + keyword.slice(1).toLowerCase()
102
- }
103
-
104
- export function TestCaseLogsModal({ open, onOpenChange, reportScenario }: TestCaseLogsModalProps) {
105
- const [expandedScreenshot, setExpandedScreenshot] = useState<{ stepId: string; stepName: string } | null>(null)
106
-
107
- if (!reportScenario) {
108
- return null
109
- }
110
-
111
- // Sort steps by order
112
- const sortedSteps = [...reportScenario.steps].sort((a, b) => a.order - b.order)
113
-
114
- return (
115
- <>
116
- <Dialog open={open} onOpenChange={onOpenChange}>
117
- <DialogContent className="flex max-h-[90vh] max-w-4xl flex-col p-0">
118
- <DialogHeader className="flex-shrink-0 px-6 pt-6">
119
- <DialogTitle className="text-xl font-semibold">{reportScenario.name}</DialogTitle>
120
- {reportScenario.description && (
121
- <DialogDescription className="text-sm text-muted-foreground">
122
- {reportScenario.description}
123
- </DialogDescription>
124
- )}
125
- </DialogHeader>
126
-
127
- <ScrollArea className="h-[calc(90vh-120px)] pr-4">
128
- <div className="px-6 pb-6">
129
- <div className="space-y-6">
130
- {/* Tags */}
131
- {reportScenario.tags.length > 0 && (
132
- <div>
133
- <h4 className="mb-2 text-sm font-medium">Tags</h4>
134
- <div className="flex flex-wrap gap-1">
135
- {reportScenario.tags.map(tag => (
136
- <Badge key={tag.tagName} variant="outline">
137
- {tag.tagName}
138
- </Badge>
139
- ))}
140
- </div>
141
- </div>
142
- )}
143
-
144
- {/* Steps */}
145
- <div>
146
- <h4 className="mb-3 text-sm font-medium">Steps</h4>
147
- <div className="space-y-3">
148
- {sortedSteps.length > 0 ? (
149
- sortedSteps.map(step => (
150
- <div key={step.id} className="space-y-2 rounded-lg border p-3">
151
- <div className="flex items-start justify-between gap-2">
152
- <div className="flex-1">
153
- <div className="mb-1 flex items-center gap-2">
154
- <span className="text-sm font-medium text-muted-foreground">
155
- {formatKeyword(step.keyword)}
156
- </span>
157
- <span className="text-sm">{step.name}</span>
158
- </div>
159
- {step.matchLocation && (
160
- <div className="mt-1 text-xs text-muted-foreground">{step.matchLocation}</div>
161
- )}
162
- </div>
163
- <div className="flex items-center gap-2">
164
- {stepStatusToBadge(step.status)}
165
- <span className="text-xs text-muted-foreground">{formatDuration(step.duration)}</span>
166
- </div>
167
- </div>
168
- {step.status === StepStatus.FAILED && (
169
- <div className="mt-2 space-y-2">
170
- {step.errorMessage && (
171
- <div className="rounded border border-red-800/50 bg-red-950/20 p-2">
172
- <div className="mb-1 flex items-center gap-2">
173
- <AlertCircle className="h-4 w-4 text-red-500" />
174
- <span className="text-sm font-medium text-red-400">Error Message</span>
175
- </div>
176
- <pre className="whitespace-pre-wrap break-words text-xs text-red-300">
177
- {step.errorMessage}
178
- </pre>
179
- </div>
180
- )}
181
- {step.errorTrace && (
182
- <div className="rounded border border-red-800/50 bg-red-950/20 p-2">
183
- <div className="mb-1 flex items-center gap-2">
184
- <AlertCircle className="h-4 w-4 text-red-500" />
185
- <span className="text-sm font-medium text-red-400">Error Trace</span>
186
- </div>
187
- <pre className="whitespace-pre-wrap break-words font-mono text-xs text-red-300">
188
- {step.errorTrace}
189
- </pre>
190
- </div>
191
- )}
192
- {step.screenshotPath && (
193
- <div className="rounded border border-red-800/50 bg-red-950/20 p-2">
194
- <div className="mb-2 flex items-center justify-between gap-2">
195
- <span className="text-sm font-medium text-red-400">Failure Screenshot</span>
196
- <Button
197
- type="button"
198
- size="sm"
199
- variant="secondary"
200
- onClick={() => setExpandedScreenshot({ stepId: step.id, stepName: step.name })}
201
- >
202
- Expand
203
- </Button>
204
- </div>
205
- <button
206
- type="button"
207
- className="block w-full overflow-hidden rounded-md border border-red-900/60"
208
- onClick={() => setExpandedScreenshot({ stepId: step.id, stepName: step.name })}
209
- >
210
- <Image
211
- src={`/api/reports/steps/${step.id}/screenshot`}
212
- alt={`Failure screenshot for step ${step.name}`}
213
- width={1280}
214
- height={720}
215
- unoptimized
216
- className="max-h-64 w-full object-cover"
217
- loading="lazy"
218
- />
219
- </button>
220
- </div>
221
- )}
222
- </div>
223
- )}
224
- </div>
225
- ))
226
- ) : (
227
- <div className="text-sm text-muted-foreground">No steps recorded</div>
228
- )}
229
- </div>
230
- </div>
231
-
232
- {/* Hooks */}
233
- {reportScenario.hooks.length > 0 && (
234
- <div>
235
- <Separator className="my-4" />
236
- <h4 className="mb-3 text-sm font-medium">Hooks</h4>
237
- <div className="space-y-3">
238
- {reportScenario.hooks.map(hook => (
239
- <div key={hook.id} className="space-y-2 rounded-lg border p-3">
240
- <div className="flex items-start justify-between gap-2">
241
- <div className="flex-1">
242
- <div className="mb-1 flex items-center gap-2">
243
- <span className="text-sm font-medium text-muted-foreground">
244
- {formatKeyword(hook.keyword)} Hook
245
- </span>
246
- </div>
247
- </div>
248
- <div className="flex items-center gap-2">
249
- {stepStatusToBadge(hook.status)}
250
- <span className="text-xs text-muted-foreground">{formatDuration(hook.duration)}</span>
251
- </div>
252
- </div>
253
- {hook.status === StepStatus.FAILED && (
254
- <div className="mt-2 space-y-2">
255
- {hook.errorMessage && (
256
- <div className="rounded border border-red-800/50 bg-red-950/20 p-2">
257
- <div className="mb-1 flex items-center gap-2">
258
- <AlertCircle className="h-4 w-4 text-red-500" />
259
- <span className="text-sm font-medium text-red-400">Error Message</span>
260
- </div>
261
- <pre className="whitespace-pre-wrap break-words text-xs text-red-300">
262
- {hook.errorMessage}
263
- </pre>
264
- </div>
265
- )}
266
- {hook.errorTrace && (
267
- <div className="rounded border border-red-800/50 bg-red-950/20 p-2">
268
- <div className="mb-1 flex items-center gap-2">
269
- <AlertCircle className="h-4 w-4 text-red-500" />
270
- <span className="text-sm font-medium text-red-400">Error Trace</span>
271
- </div>
272
- <pre className="whitespace-pre-wrap break-words font-mono text-xs text-red-300">
273
- {hook.errorTrace}
274
- </pre>
275
- </div>
276
- )}
277
- </div>
278
- )}
279
- </div>
280
- ))}
281
- </div>
282
- </div>
283
- )}
284
- </div>
285
- </div>
286
- </ScrollArea>
287
- </DialogContent>
288
- </Dialog>
289
-
290
- <Dialog open={!!expandedScreenshot} onOpenChange={nextOpen => !nextOpen && setExpandedScreenshot(null)}>
291
- <DialogContent className="max-w-5xl p-4">
292
- <DialogHeader>
293
- <DialogTitle>{expandedScreenshot?.stepName ?? 'Failure Screenshot'}</DialogTitle>
294
- <DialogDescription>Captured from the failed scenario step.</DialogDescription>
295
- </DialogHeader>
296
- {expandedScreenshot && (
297
- <Image
298
- src={`/api/reports/steps/${expandedScreenshot.stepId}/screenshot`}
299
- alt={`Failure screenshot for step ${expandedScreenshot.stepName}`}
300
- width={1600}
301
- height={900}
302
- unoptimized
303
- className="max-h-[75vh] w-full rounded-md border object-contain"
304
- />
305
- )}
306
- </DialogContent>
307
- </Dialog>
308
- </>
309
- )
310
- }
1
+ 'use client'
2
+
3
+ import { useState } from 'react'
4
+ import Image from 'next/image'
5
+ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'
6
+ import { Badge } from '@/components/ui/badge'
7
+ import { Separator } from '@/components/ui/separator'
8
+ import { StepStatus, ReportScenario } from '@prisma/client'
9
+ import { CheckCircle, XCircle, Clock, AlertCircle } from 'lucide-react'
10
+ import { ScrollArea } from '../ui/scroll-area'
11
+ import { Button } from '@/components/ui/button'
12
+
13
+ /** Minimal shape so both full Prisma and report-table select types are accepted */
14
+ type ReportScenarioWithDetails = ReportScenario & {
15
+ tags: Array<{ tagName: string }>
16
+ steps: Array<{
17
+ id: string
18
+ keyword: string
19
+ name: string
20
+ status: StepStatus
21
+ duration: string
22
+ errorMessage: string | null
23
+ errorTrace: string | null
24
+ screenshotPath?: string | null
25
+ order: number
26
+ matchLocation?: string | null
27
+ }>
28
+ hooks: Array<{
29
+ id: string
30
+ keyword: string
31
+ status: StepStatus
32
+ duration: string
33
+ errorMessage: string | null
34
+ errorTrace: string | null
35
+ }>
36
+ }
37
+
38
+ interface TestCaseLogsModalProps {
39
+ open: boolean
40
+ onOpenChange: (open: boolean) => void
41
+ reportScenario: ReportScenarioWithDetails | null
42
+ }
43
+
44
+ const stepStatusToBadge = (status: StepStatus) => {
45
+ switch (status) {
46
+ case StepStatus.PASSED:
47
+ return (
48
+ <Badge
49
+ variant="outline"
50
+ className="flex items-center gap-1 rounded-xl border-green-700 bg-green-700/10 py-0.5 text-xs text-green-500"
51
+ >
52
+ <CheckCircle className="h-3 w-3" />
53
+ PASSED
54
+ </Badge>
55
+ )
56
+ case StepStatus.FAILED:
57
+ return (
58
+ <Badge
59
+ variant="outline"
60
+ className="flex items-center gap-1 rounded-xl border-red-700 bg-red-700/10 py-0.5 text-xs text-red-500"
61
+ >
62
+ <XCircle className="h-3 w-3" />
63
+ FAILED
64
+ </Badge>
65
+ )
66
+ case StepStatus.SKIPPED:
67
+ return (
68
+ <Badge
69
+ variant="outline"
70
+ className="flex items-center gap-1 rounded-xl border-gray-700 bg-gray-700/10 py-0.5 text-xs text-gray-500"
71
+ >
72
+ <Clock className="h-3 w-3" />
73
+ SKIPPED
74
+ </Badge>
75
+ )
76
+ default:
77
+ return (
78
+ <Badge
79
+ variant="outline"
80
+ className="flex items-center gap-1 rounded-xl border-gray-700 bg-gray-700/10 py-0.5 text-xs text-gray-500"
81
+ >
82
+ {status}
83
+ </Badge>
84
+ )
85
+ }
86
+ }
87
+
88
+ const formatDuration = (duration: string) => {
89
+ const durationNs = Number(duration)
90
+ if (isNaN(durationNs)) return '-'
91
+ const durationMs = Math.round(durationNs / 1000000)
92
+ if (durationMs < 1000) {
93
+ return `${durationMs}ms`
94
+ }
95
+ const seconds = Math.floor(durationMs / 1000)
96
+ const milliseconds = durationMs % 1000
97
+ return `${seconds}.${String(milliseconds).padStart(3, '0')}s`
98
+ }
99
+
100
+ const formatKeyword = (keyword: string) => {
101
+ return keyword.charAt(0) + keyword.slice(1).toLowerCase()
102
+ }
103
+
104
+ export function TestCaseLogsModal({ open, onOpenChange, reportScenario }: TestCaseLogsModalProps) {
105
+ const [expandedScreenshot, setExpandedScreenshot] = useState<{ stepId: string; stepName: string } | null>(null)
106
+
107
+ if (!reportScenario) {
108
+ return null
109
+ }
110
+
111
+ // Sort steps by order
112
+ const sortedSteps = [...reportScenario.steps].sort((a, b) => a.order - b.order)
113
+
114
+ return (
115
+ <>
116
+ <Dialog open={open} onOpenChange={onOpenChange}>
117
+ <DialogContent className="flex max-h-[90vh] max-w-4xl flex-col p-0">
118
+ <DialogHeader className="flex-shrink-0 px-6 pt-6">
119
+ <DialogTitle className="text-xl font-semibold">{reportScenario.name}</DialogTitle>
120
+ {reportScenario.description && (
121
+ <DialogDescription className="text-sm text-muted-foreground">
122
+ {reportScenario.description}
123
+ </DialogDescription>
124
+ )}
125
+ </DialogHeader>
126
+
127
+ <ScrollArea className="h-[calc(90vh-120px)] pr-4">
128
+ <div className="px-6 pb-6">
129
+ <div className="space-y-6">
130
+ {/* Tags */}
131
+ {reportScenario.tags.length > 0 && (
132
+ <div>
133
+ <h4 className="mb-2 text-sm font-medium">Tags</h4>
134
+ <div className="flex flex-wrap gap-1">
135
+ {reportScenario.tags.map(tag => (
136
+ <Badge key={tag.tagName} variant="outline">
137
+ {tag.tagName}
138
+ </Badge>
139
+ ))}
140
+ </div>
141
+ </div>
142
+ )}
143
+
144
+ {/* Steps */}
145
+ <div>
146
+ <h4 className="mb-3 text-sm font-medium">Steps</h4>
147
+ <div className="space-y-3">
148
+ {sortedSteps.length > 0 ? (
149
+ sortedSteps.map(step => (
150
+ <div key={step.id} className="space-y-2 rounded-lg border p-3">
151
+ <div className="flex items-start justify-between gap-2">
152
+ <div className="flex-1">
153
+ <div className="mb-1 flex items-center gap-2">
154
+ <span className="text-sm font-medium text-muted-foreground">
155
+ {formatKeyword(step.keyword)}
156
+ </span>
157
+ <span className="text-sm">{step.name}</span>
158
+ </div>
159
+ {step.matchLocation && (
160
+ <div className="mt-1 text-xs text-muted-foreground">{step.matchLocation}</div>
161
+ )}
162
+ </div>
163
+ <div className="flex items-center gap-2">
164
+ {stepStatusToBadge(step.status)}
165
+ <span className="text-xs text-muted-foreground">{formatDuration(step.duration)}</span>
166
+ </div>
167
+ </div>
168
+ {step.status === StepStatus.FAILED && (
169
+ <div className="mt-2 space-y-2">
170
+ {step.errorMessage && (
171
+ <div className="rounded border border-red-800/50 bg-red-950/20 p-2">
172
+ <div className="mb-1 flex items-center gap-2">
173
+ <AlertCircle className="h-4 w-4 text-red-500" />
174
+ <span className="text-sm font-medium text-red-400">Error Message</span>
175
+ </div>
176
+ <pre className="whitespace-pre-wrap break-words text-xs text-red-300">
177
+ {step.errorMessage}
178
+ </pre>
179
+ </div>
180
+ )}
181
+ {step.errorTrace && (
182
+ <div className="rounded border border-red-800/50 bg-red-950/20 p-2">
183
+ <div className="mb-1 flex items-center gap-2">
184
+ <AlertCircle className="h-4 w-4 text-red-500" />
185
+ <span className="text-sm font-medium text-red-400">Error Trace</span>
186
+ </div>
187
+ <pre className="whitespace-pre-wrap break-words font-mono text-xs text-red-300">
188
+ {step.errorTrace}
189
+ </pre>
190
+ </div>
191
+ )}
192
+ {step.screenshotPath && (
193
+ <div className="rounded border border-red-800/50 bg-red-950/20 p-2">
194
+ <div className="mb-2 flex items-center justify-between gap-2">
195
+ <span className="text-sm font-medium text-red-400">Failure Screenshot</span>
196
+ <Button
197
+ type="button"
198
+ size="sm"
199
+ variant="secondary"
200
+ onClick={() => setExpandedScreenshot({ stepId: step.id, stepName: step.name })}
201
+ >
202
+ Expand
203
+ </Button>
204
+ </div>
205
+ <button
206
+ type="button"
207
+ className="block w-full overflow-hidden rounded-md border border-red-900/60"
208
+ onClick={() => setExpandedScreenshot({ stepId: step.id, stepName: step.name })}
209
+ >
210
+ <Image
211
+ src={`/api/reports/steps/${step.id}/screenshot`}
212
+ alt={`Failure screenshot for step ${step.name}`}
213
+ width={1280}
214
+ height={720}
215
+ unoptimized
216
+ className="max-h-64 w-full object-cover"
217
+ loading="lazy"
218
+ />
219
+ </button>
220
+ </div>
221
+ )}
222
+ </div>
223
+ )}
224
+ </div>
225
+ ))
226
+ ) : (
227
+ <div className="text-sm text-muted-foreground">No steps recorded</div>
228
+ )}
229
+ </div>
230
+ </div>
231
+
232
+ {/* Hooks */}
233
+ {reportScenario.hooks.length > 0 && (
234
+ <div>
235
+ <Separator className="my-4" />
236
+ <h4 className="mb-3 text-sm font-medium">Hooks</h4>
237
+ <div className="space-y-3">
238
+ {reportScenario.hooks.map(hook => (
239
+ <div key={hook.id} className="space-y-2 rounded-lg border p-3">
240
+ <div className="flex items-start justify-between gap-2">
241
+ <div className="flex-1">
242
+ <div className="mb-1 flex items-center gap-2">
243
+ <span className="text-sm font-medium text-muted-foreground">
244
+ {formatKeyword(hook.keyword)} Hook
245
+ </span>
246
+ </div>
247
+ </div>
248
+ <div className="flex items-center gap-2">
249
+ {stepStatusToBadge(hook.status)}
250
+ <span className="text-xs text-muted-foreground">{formatDuration(hook.duration)}</span>
251
+ </div>
252
+ </div>
253
+ {hook.status === StepStatus.FAILED && (
254
+ <div className="mt-2 space-y-2">
255
+ {hook.errorMessage && (
256
+ <div className="rounded border border-red-800/50 bg-red-950/20 p-2">
257
+ <div className="mb-1 flex items-center gap-2">
258
+ <AlertCircle className="h-4 w-4 text-red-500" />
259
+ <span className="text-sm font-medium text-red-400">Error Message</span>
260
+ </div>
261
+ <pre className="whitespace-pre-wrap break-words text-xs text-red-300">
262
+ {hook.errorMessage}
263
+ </pre>
264
+ </div>
265
+ )}
266
+ {hook.errorTrace && (
267
+ <div className="rounded border border-red-800/50 bg-red-950/20 p-2">
268
+ <div className="mb-1 flex items-center gap-2">
269
+ <AlertCircle className="h-4 w-4 text-red-500" />
270
+ <span className="text-sm font-medium text-red-400">Error Trace</span>
271
+ </div>
272
+ <pre className="whitespace-pre-wrap break-words font-mono text-xs text-red-300">
273
+ {hook.errorTrace}
274
+ </pre>
275
+ </div>
276
+ )}
277
+ </div>
278
+ )}
279
+ </div>
280
+ ))}
281
+ </div>
282
+ </div>
283
+ )}
284
+ </div>
285
+ </div>
286
+ </ScrollArea>
287
+ </DialogContent>
288
+ </Dialog>
289
+
290
+ <Dialog open={!!expandedScreenshot} onOpenChange={nextOpen => !nextOpen && setExpandedScreenshot(null)}>
291
+ <DialogContent className="max-w-5xl p-4">
292
+ <DialogHeader>
293
+ <DialogTitle>{expandedScreenshot?.stepName ?? 'Failure Screenshot'}</DialogTitle>
294
+ <DialogDescription>Captured from the failed scenario step.</DialogDescription>
295
+ </DialogHeader>
296
+ {expandedScreenshot && (
297
+ <Image
298
+ src={`/api/reports/steps/${expandedScreenshot.stepId}/screenshot`}
299
+ alt={`Failure screenshot for step ${expandedScreenshot.stepName}`}
300
+ width={1600}
301
+ height={900}
302
+ unoptimized
303
+ className="max-h-[75vh] w-full rounded-md border object-contain"
304
+ />
305
+ )}
306
+ </DialogContent>
307
+ </Dialog>
308
+ </>
309
+ )
310
+ }