create-appraisejs 0.1.6 → 0.1.8-alpha
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.
- package/README.md +45 -45
- package/dist/cli.js +4 -4
- package/dist/cli.js.map +1 -1
- package/dist/copy-template.d.ts +2 -1
- package/dist/copy-template.d.ts.map +1 -1
- package/dist/copy-template.js +10 -7
- package/dist/copy-template.js.map +1 -1
- package/dist/copy-template.test.js +19 -0
- package/dist/copy-template.test.js.map +1 -1
- package/package.json +69 -67
- package/templates/default/.vscode/settings.json +5 -0
- package/templates/default/appraisejs.config.json +1 -1
- package/templates/default/components.json +24 -24
- package/templates/default/cucumber.mjs +16 -0
- package/templates/default/eslint.config.mjs +15 -15
- package/templates/default/next.config.ts +13 -7
- package/templates/default/package-lock.json +13732 -14321
- package/templates/default/package.json +11 -9
- package/templates/default/postcss.config.mjs +8 -8
- package/templates/default/prisma/migrations/20251104113456_add_type_for_template_step_groups/migration.sql +16 -16
- package/templates/default/prisma/migrations/20251104170946_add_tags_to_test_suite_and_test_case/migration.sql +27 -27
- package/templates/default/prisma/migrations/20251112190024_add_cascade_delete_to_test_run_test_case/migration.sql +17 -17
- package/templates/default/prisma/migrations/20251113181100_add_test_run_log/migration.sql +12 -12
- package/templates/default/prisma/migrations/20251119191838_add_tag_type/migration.sql +28 -28
- package/templates/default/prisma/migrations/20251121164059_add_conflict_resolution/migration.sql +12 -12
- package/templates/default/prisma/migrations/20251223183400_add_report_model_to_db_schema/migration.sql +10 -10
- package/templates/default/prisma/migrations/20251223183637_add_report_test_case_entity_for_storing_test_results_for_individual_test_cases/migration.sql +10 -10
- package/templates/default/prisma/migrations/20251224083549_add_comprehensive_report_storage/migration.sql +108 -108
- package/templates/default/prisma/migrations/20251229194422_migrate_duration_to_string/migration.sql +55 -55
- package/templates/default/prisma/migrations/20251230124637_add_unique_constraint_to_test_run_name/migration.sql +27 -27
- package/templates/default/prisma/migrations/20260115094436_add_dashboard_metrics/migration.sql +59 -59
- package/templates/default/prisma/migrations/20260127172022_add_cascade_delete_to_step_parameters/migration.sql +34 -34
- package/templates/default/prisma/schema.prisma +554 -554
- package/templates/default/scripts/regenerate-features.ts +94 -94
- package/templates/default/scripts/setup-env.ts +19 -19
- package/templates/default/scripts/sync-all.ts +341 -341
- package/templates/default/scripts/sync-appraise-base-template.ts +52 -2
- package/templates/default/scripts/sync-environments.ts +323 -323
- package/templates/default/scripts/sync-locator-groups.ts +413 -413
- package/templates/default/scripts/sync-locators.ts +402 -402
- package/templates/default/scripts/sync-modules.ts +349 -349
- package/templates/default/scripts/sync-tags.ts +292 -292
- package/templates/default/scripts/sync-template-step-groups.ts +399 -399
- package/templates/default/scripts/sync-template-steps.ts +806 -806
- package/templates/default/scripts/sync-test-cases.ts +905 -905
- package/templates/default/scripts/sync-test-suites.ts +411 -411
- package/templates/default/src/actions/conflict/conflict.action.ts +33 -33
- package/templates/default/src/actions/dashboard/dashboard-actions.ts +240 -240
- package/templates/default/src/actions/environments/environment-actions.ts +205 -205
- package/templates/default/src/actions/locator/locator-actions.ts +547 -547
- package/templates/default/src/actions/locator-groups/locator-group-actions.ts +344 -344
- package/templates/default/src/actions/modules/module-actions.ts +133 -133
- package/templates/default/src/actions/reports/report-actions.ts +613 -613
- package/templates/default/src/actions/review/review-actions.ts +147 -147
- package/templates/default/src/actions/tags/tag-actions.ts +104 -104
- package/templates/default/src/actions/template-step/template-step-actions.ts +332 -332
- package/templates/default/src/actions/template-step-group/template-step-group-actions.ts +278 -278
- package/templates/default/src/actions/template-test-case/template-test-case-actions.ts +238 -238
- package/templates/default/src/actions/test-case/test-case-actions.ts +419 -419
- package/templates/default/src/actions/test-run/test-run-actions.ts +1185 -1185
- package/templates/default/src/actions/test-suite/test-suite-actions.ts +253 -253
- package/templates/default/src/actions/user/user-actions.ts +13 -13
- package/templates/default/src/app/(base)/environments/create/page.tsx +28 -28
- package/templates/default/src/app/(base)/environments/environment-form.tsx +219 -219
- package/templates/default/src/app/(base)/environments/environment-table-columns.tsx +96 -96
- package/templates/default/src/app/(base)/environments/environment-table.tsx +24 -24
- package/templates/default/src/app/(base)/environments/modify/[id]/page.tsx +46 -46
- package/templates/default/src/app/(base)/environments/page.tsx +59 -59
- package/templates/default/src/app/(base)/layout.tsx +10 -10
- package/templates/default/src/app/(base)/locator-groups/create/page.tsx +44 -44
- package/templates/default/src/app/(base)/locator-groups/locator-group-form.tsx +215 -215
- package/templates/default/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
- package/templates/default/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
- package/templates/default/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
- package/templates/default/src/app/(base)/locator-groups/page.tsx +61 -61
- package/templates/default/src/app/(base)/locators/create/page.tsx +38 -38
- package/templates/default/src/app/(base)/locators/locator-form.tsx +163 -163
- package/templates/default/src/app/(base)/locators/locator-table-columns.tsx +73 -90
- package/templates/default/src/app/(base)/locators/locator-table.tsx +28 -28
- package/templates/default/src/app/(base)/locators/modify/[id]/page.tsx +45 -45
- package/templates/default/src/app/(base)/locators/page.tsx +65 -65
- package/templates/default/src/app/(base)/locators/sync-locators-button.tsx +66 -66
- package/templates/default/src/app/(base)/modules/create/page.tsx +34 -34
- package/templates/default/src/app/(base)/modules/modify/[id]/page.tsx +46 -46
- package/templates/default/src/app/(base)/modules/module-form.tsx +126 -126
- package/templates/default/src/app/(base)/modules/module-table-columns.tsx +85 -85
- package/templates/default/src/app/(base)/modules/module-table.tsx +24 -24
- package/templates/default/src/app/(base)/modules/page.tsx +59 -59
- package/templates/default/src/app/(base)/reports/[id]/page.tsx +517 -517
- package/templates/default/src/app/(base)/reports/duration-chart.tsx +33 -33
- package/templates/default/src/app/(base)/reports/feature-chart.tsx +78 -78
- package/templates/default/src/app/(base)/reports/overview-chart.tsx +46 -46
- package/templates/default/src/app/(base)/reports/page.tsx +98 -98
- package/templates/default/src/app/(base)/reports/report-metric-card.tsx +16 -16
- package/templates/default/src/app/(base)/reports/report-table-columns.tsx +189 -189
- package/templates/default/src/app/(base)/reports/report-table.tsx +72 -72
- package/templates/default/src/app/(base)/reports/report-view-table-columns.tsx +131 -131
- package/templates/default/src/app/(base)/reports/report-view-table.tsx +82 -82
- package/templates/default/src/app/(base)/reports/test-cases/page.tsx +42 -42
- package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +115 -115
- package/templates/default/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
- package/templates/default/src/app/(base)/reports/test-suites/page.tsx +42 -42
- package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +79 -79
- package/templates/default/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +27 -27
- package/templates/default/src/app/(base)/reports/view-logs-button.tsx +60 -60
- package/templates/default/src/app/(base)/reviews/create/page.tsx +26 -26
- package/templates/default/src/app/(base)/reviews/created-reviews-table.tsx +15 -15
- package/templates/default/src/app/(base)/reviews/modify/[id]/page.tsx +26 -26
- package/templates/default/src/app/(base)/reviews/page.tsx +26 -26
- package/templates/default/src/app/(base)/reviews/review/[id]/page.tsx +26 -26
- package/templates/default/src/app/(base)/reviews/review-form.tsx +11 -11
- package/templates/default/src/app/(base)/reviews/review-table-by-creator-columns.tsx +9 -9
- package/templates/default/src/app/(base)/reviews/review-table-by-reviewer-columns.tsx +9 -9
- package/templates/default/src/app/(base)/reviews/reviewer-reviews-table.tsx +15 -15
- package/templates/default/src/app/(base)/tags/create/page.tsx +39 -39
- package/templates/default/src/app/(base)/tags/modify/[id]/page.tsx +50 -50
- package/templates/default/src/app/(base)/tags/page.tsx +58 -58
- package/templates/default/src/app/(base)/tags/tag-form.tsx +147 -147
- package/templates/default/src/app/(base)/tags/tag-table-columns.tsx +63 -63
- package/templates/default/src/app/(base)/tags/tag-table.tsx +29 -29
- package/templates/default/src/app/(base)/template-step-groups/create/page.tsx +28 -28
- package/templates/default/src/app/(base)/template-step-groups/modify/[id]/page.tsx +45 -45
- package/templates/default/src/app/(base)/template-step-groups/page.tsx +60 -60
- package/templates/default/src/app/(base)/template-step-groups/template-step-group-form.tsx +167 -167
- package/templates/default/src/app/(base)/template-step-groups/template-step-group-table-columns.tsx +89 -89
- package/templates/default/src/app/(base)/template-step-groups/template-step-group-table.tsx +32 -32
- package/templates/default/src/app/(base)/template-steps/create/page.tsx +37 -37
- package/templates/default/src/app/(base)/template-steps/modify/[id]/page.tsx +49 -49
- package/templates/default/src/app/(base)/template-steps/page.tsx +59 -59
- package/templates/default/src/app/(base)/template-steps/paramChip.tsx +213 -213
- package/templates/default/src/app/(base)/template-steps/template-step-form.tsx +384 -384
- package/templates/default/src/app/(base)/template-steps/template-step-table-columns.tsx +158 -158
- package/templates/default/src/app/(base)/template-steps/template-step-table.tsx +24 -24
- package/templates/default/src/app/(base)/template-test-cases/create/page.tsx +56 -56
- package/templates/default/src/app/(base)/template-test-cases/modify/[id]/page.tsx +89 -89
- package/templates/default/src/app/(base)/template-test-cases/page.tsx +58 -58
- package/templates/default/src/app/(base)/template-test-cases/template-test-case-flow.tsx +84 -84
- package/templates/default/src/app/(base)/template-test-cases/template-test-case-form.tsx +262 -262
- package/templates/default/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
- package/templates/default/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
- package/templates/default/src/app/(base)/test-cases/create/page.tsx +76 -76
- package/templates/default/src/app/(base)/test-cases/create-from-template/generate/[id]/page.tsx +96 -96
- package/templates/default/src/app/(base)/test-cases/create-from-template/page.tsx +38 -38
- package/templates/default/src/app/(base)/test-cases/create-from-template/template-selection-form.tsx +73 -73
- package/templates/default/src/app/(base)/test-cases/modify/[id]/page.tsx +106 -106
- package/templates/default/src/app/(base)/test-cases/page.tsx +60 -60
- package/templates/default/src/app/(base)/test-cases/test-case-flow.tsx +82 -82
- package/templates/default/src/app/(base)/test-cases/test-case-form.tsx +395 -395
- package/templates/default/src/app/(base)/test-cases/test-case-table-columns.tsx +90 -90
- package/templates/default/src/app/(base)/test-cases/test-case-table.tsx +35 -35
- package/templates/default/src/app/(base)/test-runs/[id]/page.tsx +56 -56
- package/templates/default/src/app/(base)/test-runs/create/page.tsx +47 -47
- package/templates/default/src/app/(base)/test-runs/page.tsx +60 -60
- package/templates/default/src/app/(base)/test-runs/test-run-form.tsx +508 -512
- package/templates/default/src/app/(base)/test-runs/test-run-table-columns.tsx +229 -229
- package/templates/default/src/app/(base)/test-runs/test-run-table.tsx +127 -127
- package/templates/default/src/app/(base)/test-suites/create/page.tsx +45 -45
- package/templates/default/src/app/(base)/test-suites/modify/[id]/page.tsx +55 -55
- package/templates/default/src/app/(base)/test-suites/page.tsx +82 -82
- package/templates/default/src/app/(base)/test-suites/test-suite-form.tsx +269 -269
- package/templates/default/src/app/(base)/test-suites/test-suite-table-columns.tsx +97 -97
- package/templates/default/src/app/(base)/test-suites/test-suite-table.tsx +29 -29
- package/templates/default/src/app/(dashboard-components)/app-drawer.tsx +187 -187
- package/templates/default/src/app/(dashboard-components)/data-card-grid.tsx +12 -12
- package/templates/default/src/app/(dashboard-components)/data-card.tsx +26 -26
- package/templates/default/src/app/(dashboard-components)/execution-health-panel.tsx +56 -56
- package/templates/default/src/app/(dashboard-components)/ongoing-test-runs-card.tsx +87 -87
- package/templates/default/src/app/(dashboard-components)/quick-actions-drawer.tsx +44 -44
- package/templates/default/src/app/api/test-runs/[runId]/download/route.ts +133 -133
- package/templates/default/src/app/api/test-runs/[runId]/logs/route.ts +420 -420
- package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.ts +146 -146
- package/templates/default/src/app/globals.css +147 -147
- package/templates/default/src/app/layout.tsx +171 -171
- package/templates/default/src/app/page.tsx +64 -64
- package/templates/default/src/assets/icons/empty-tube.tsx +23 -23
- package/templates/default/src/assets/icons/tube-plus.tsx +29 -29
- package/templates/default/src/components/base-node.tsx +21 -21
- package/templates/default/src/components/chart/pie-chart.tsx +73 -73
- package/templates/default/src/components/data-extraction/locator-inspector.tsx +460 -460
- package/templates/default/src/components/data-state/empty-state.tsx +40 -40
- package/templates/default/src/components/data-visualization/info-card.tsx +70 -70
- package/templates/default/src/components/data-visualization/info-grid.tsx +22 -22
- package/templates/default/src/components/devtools/providers.tsx +19 -13
- package/templates/default/src/components/diagram/button-edge.tsx +54 -54
- package/templates/default/src/components/diagram/dynamic-parameters.tsx +438 -438
- package/templates/default/src/components/diagram/edit-header-option.tsx +36 -36
- package/templates/default/src/components/diagram/flow-diagram.tsx +470 -470
- package/templates/default/src/components/diagram/node-form.tsx +262 -262
- package/templates/default/src/components/diagram/options-header-node.tsx +57 -57
- package/templates/default/src/components/diagram/template-step-combobox.tsx +155 -155
- package/templates/default/src/components/form/error-message.tsx +7 -7
- package/templates/default/src/components/kokonutui/smooth-tab.tsx +453 -453
- package/templates/default/src/components/loading-skeleton/data-table/data-table-skeleton.tsx +30 -30
- package/templates/default/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
- package/templates/default/src/components/loading-skeleton/form/icon-button-skeleton.tsx +8 -8
- package/templates/default/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
- package/templates/default/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
- package/templates/default/src/components/logo.tsx +15 -15
- package/templates/default/src/components/navigation/command-badge.tsx +34 -34
- package/templates/default/src/components/navigation/command-chain-input.tsx +51 -51
- package/templates/default/src/components/navigation/entity-search-command.tsx +116 -116
- package/templates/default/src/components/navigation/nav-card.tsx +31 -31
- package/templates/default/src/components/navigation/nav-command.tsx +508 -508
- package/templates/default/src/components/navigation/nav-link.tsx +60 -60
- package/templates/default/src/components/navigation/nav-menu-card-deck.tsx +112 -112
- package/templates/default/src/components/node-header.tsx +159 -159
- package/templates/default/src/components/reports/test-case-logs-modal.tsx +253 -253
- package/templates/default/src/components/table/table-actions.tsx +172 -172
- package/templates/default/src/components/test-run/download-logs-button.tsx +99 -99
- package/templates/default/src/components/test-run/log-viewer.tsx +445 -445
- package/templates/default/src/components/test-run/test-run-details.tsx +611 -611
- package/templates/default/src/components/test-run/test-run-header.tsx +149 -149
- package/templates/default/src/components/test-run/view-report-button.tsx +102 -102
- package/templates/default/src/components/theme/mode-toggle.tsx +54 -54
- package/templates/default/src/components/theme/theme-provider.tsx +8 -8
- package/templates/default/src/components/typography/page-header-subtitle.tsx +7 -7
- package/templates/default/src/components/typography/page-header.tsx +7 -7
- package/templates/default/src/components/ui/alert-dialog.tsx +106 -106
- package/templates/default/src/components/ui/alert.tsx +43 -43
- package/templates/default/src/components/ui/avatar.tsx +40 -40
- package/templates/default/src/components/ui/badge.tsx +29 -29
- package/templates/default/src/components/ui/button.tsx +47 -47
- package/templates/default/src/components/ui/calendar.tsx +158 -158
- package/templates/default/src/components/ui/card.tsx +43 -43
- package/templates/default/src/components/ui/checkbox.tsx +28 -28
- package/templates/default/src/components/ui/command.tsx +135 -135
- package/templates/default/src/components/ui/data-table-column-header.tsx +61 -61
- package/templates/default/src/components/ui/data-table-pagination.tsx +87 -87
- package/templates/default/src/components/ui/data-table-view-options.tsx +50 -50
- package/templates/default/src/components/ui/data-table.tsx +267 -267
- package/templates/default/src/components/ui/dialog.tsx +97 -97
- package/templates/default/src/components/ui/dropdown-menu.tsx +182 -182
- package/templates/default/src/components/ui/input.tsx +22 -22
- package/templates/default/src/components/ui/kbd.tsx +28 -28
- package/templates/default/src/components/ui/label.tsx +19 -19
- package/templates/default/src/components/ui/loading.tsx +12 -12
- package/templates/default/src/components/ui/multi-select-with-preview.tsx +116 -116
- package/templates/default/src/components/ui/multi-select.tsx +142 -142
- package/templates/default/src/components/ui/navigation-menu.tsx +120 -120
- package/templates/default/src/components/ui/popover.tsx +33 -33
- package/templates/default/src/components/ui/progress.tsx +25 -25
- package/templates/default/src/components/ui/radio-group.tsx +44 -44
- package/templates/default/src/components/ui/scroll-area.tsx +40 -40
- package/templates/default/src/components/ui/select.tsx +151 -144
- package/templates/default/src/components/ui/separator.tsx +22 -22
- package/templates/default/src/components/ui/skeleton.tsx +7 -7
- package/templates/default/src/components/ui/table.tsx +76 -76
- package/templates/default/src/components/ui/tabs.tsx +55 -55
- package/templates/default/src/components/ui/textarea.tsx +21 -21
- package/templates/default/src/components/ui/toast.tsx +113 -113
- package/templates/default/src/components/ui/toaster.tsx +26 -26
- package/templates/default/src/components/user-prompt/delete-prompt.tsx +87 -87
- package/templates/default/src/config/db-config.ts +10 -10
- package/templates/default/src/constants/form-opts/diagram/node-form.ts +30 -30
- package/templates/default/src/constants/form-opts/environment-form-opts.ts +24 -24
- package/templates/default/src/constants/form-opts/locator-form-opts.ts +20 -20
- package/templates/default/src/constants/form-opts/locator-group-form-opts.ts +28 -28
- package/templates/default/src/constants/form-opts/module-form-opts.ts +21 -21
- package/templates/default/src/constants/form-opts/review-form-opts.ts +23 -23
- package/templates/default/src/constants/form-opts/tag-form-opts.ts +42 -42
- package/templates/default/src/constants/form-opts/template-selection-form-opts.ts +16 -16
- package/templates/default/src/constants/form-opts/template-step-group-form-opts.ts +24 -24
- package/templates/default/src/constants/form-opts/template-test-case-form-opts.ts +39 -39
- package/templates/default/src/constants/form-opts/template-test-step-form-opts.ts +36 -36
- package/templates/default/src/constants/form-opts/test-case-form-opts.ts +43 -43
- package/templates/default/src/constants/form-opts/test-run-form-opts.ts +31 -31
- package/templates/default/src/constants/form-opts/test-suite-form-opts.ts +24 -24
- package/templates/default/src/hooks/use-toast.ts +187 -187
- package/templates/default/src/lib/bidirectional-sync.ts +432 -432
- package/templates/default/src/lib/database-sync.ts +531 -531
- package/templates/default/src/lib/environment-file-utils.ts +221 -221
- package/templates/default/src/lib/feature-file-generator.ts +411 -411
- package/templates/default/src/lib/gherkin-parser.ts +259 -259
- package/templates/default/src/lib/locator-group-file-utils.ts +370 -370
- package/templates/default/src/lib/metrics/metric-calculator.ts +613 -613
- package/templates/default/src/lib/module-hierarchy-builder.ts +205 -205
- package/templates/default/src/lib/path-helpers/module-path.ts +71 -71
- package/templates/default/src/lib/test-case-utils.ts +6 -6
- package/templates/default/src/lib/test-run/log-formatter.ts +83 -83
- package/templates/default/src/lib/test-run/process-manager.ts +191 -191
- package/templates/default/src/lib/test-run/report-parser.ts +316 -316
- package/templates/default/src/lib/test-run/test-run-executor.ts +144 -144
- package/templates/default/src/lib/test-run/winston-logger.ts +95 -95
- package/templates/default/src/lib/transformers/gherkin-converter.ts +42 -42
- package/templates/default/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
- package/templates/default/src/lib/transformers/template-test-case-converter.ts +160 -160
- package/templates/default/src/lib/utils/node-param-validation.ts +81 -81
- package/templates/default/src/lib/utils/template-step-file-generator.ts +167 -167
- package/templates/default/src/lib/utils/template-step-file-manager-intelligent.ts +723 -723
- package/templates/default/src/lib/utils/template-step-file-manager.ts +166 -166
- package/templates/default/src/lib/utils.ts +31 -31
- package/templates/default/src/tests/config/executor/world.ts +41 -41
- package/templates/default/src/tests/executor.ts +80 -80
- package/templates/default/src/tests/hooks/hooks.ts +99 -99
- package/templates/default/src/tests/mapping/locator-map.json +1 -1
- package/templates/default/src/tests/steps/actions/click.step.ts +62 -62
- package/templates/default/src/tests/steps/actions/navigation.step.ts +73 -72
- package/templates/default/src/tests/steps/validations/active_state_assertion.step.ts +34 -34
- package/templates/default/src/tests/steps/validations/navigation_assertion.step.ts +24 -23
- package/templates/default/src/tests/steps/validations/text_assertion.step.ts +111 -111
- package/templates/default/src/tests/steps/validations/visibility_assertion.step.ts +30 -30
- package/templates/default/src/tests/support/parameter-types.ts +12 -12
- package/templates/default/src/tests/utils/cache.util.ts +260 -260
- package/templates/default/src/tests/utils/cli.util.ts +177 -177
- package/templates/default/src/tests/utils/environment.util.ts +65 -65
- package/templates/default/src/tests/utils/locator.util.ts +248 -248
- package/templates/default/src/tests/utils/random-data.util.ts +44 -44
- package/templates/default/src/tests/utils/spawner.util.ts +617 -617
- package/templates/default/src/types/diagram/diagram.ts +34 -34
- package/templates/default/src/types/diagram/template-step.ts +11 -11
- package/templates/default/src/types/executor/browser.type.ts +1 -1
- package/templates/default/src/types/form/actionHandler.ts +6 -6
- package/templates/default/src/types/locator/locator.type.ts +11 -11
- package/templates/default/src/types/step/step.type.ts +1 -1
- package/templates/default/src/types/table/data-table.ts +6 -6
- package/templates/default/tailwind.config.ts +62 -62
- package/templates/default/.env +0 -2
- package/templates/default/next-env.d.ts +0 -6
- package/templates/default/prisma/prisma/dev.db +0 -0
- package/templates/default/src/tests/config/environments/environments.json +0 -14
|
@@ -1,419 +1,419 @@
|
|
|
1
|
-
'use server'
|
|
2
|
-
|
|
3
|
-
import prisma from '@/config/db-config'
|
|
4
|
-
import { ActionResponse } from '@/types/form/actionHandler'
|
|
5
|
-
import { revalidatePath } from 'next/cache'
|
|
6
|
-
import { testCaseSchema } from '@/constants/form-opts/test-case-form-opts'
|
|
7
|
-
import { z } from 'zod'
|
|
8
|
-
import { generateFeatureFile } from '@/lib/feature-file-generator'
|
|
9
|
-
|
|
10
|
-
import { StepParameterType, TagType } from '@prisma/client'
|
|
11
|
-
import { generateUniqueTestCaseIdentifier } from '@/lib/test-case-utils'
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Get all test cases
|
|
15
|
-
* @returns ActionResponse
|
|
16
|
-
*/
|
|
17
|
-
export async function getAllTestCasesAction(): Promise<ActionResponse> {
|
|
18
|
-
try {
|
|
19
|
-
const testCases = await prisma.testCase.findMany({
|
|
20
|
-
include: {
|
|
21
|
-
steps: {
|
|
22
|
-
include: {
|
|
23
|
-
parameters: true,
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
TestSuite: true,
|
|
27
|
-
tags: true,
|
|
28
|
-
},
|
|
29
|
-
})
|
|
30
|
-
return {
|
|
31
|
-
status: 200,
|
|
32
|
-
data: testCases,
|
|
33
|
-
}
|
|
34
|
-
} catch (e) {
|
|
35
|
-
return {
|
|
36
|
-
status: 500,
|
|
37
|
-
error: `Server error occurred: ${e}`,
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Delete a test case
|
|
44
|
-
* @param id - Test case id
|
|
45
|
-
* @returns ActionResponse
|
|
46
|
-
*/
|
|
47
|
-
export async function deleteTestCaseAction(id: string[]): Promise<ActionResponse> {
|
|
48
|
-
try {
|
|
49
|
-
// Get the test suites that will be affected before deletion
|
|
50
|
-
const affectedTestSuites = await prisma.testSuite.findMany({
|
|
51
|
-
where: {
|
|
52
|
-
testCases: {
|
|
53
|
-
some: {
|
|
54
|
-
id: {
|
|
55
|
-
in: id,
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
include: {
|
|
61
|
-
module: true,
|
|
62
|
-
},
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
const testCaseIdentifierTags = await prisma.tag.findMany({
|
|
66
|
-
where: {
|
|
67
|
-
type: TagType.IDENTIFIER,
|
|
68
|
-
testCases: {
|
|
69
|
-
some: {
|
|
70
|
-
id: {
|
|
71
|
-
in: id,
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
select: {
|
|
77
|
-
id: true,
|
|
78
|
-
},
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
await prisma.$transaction(async tx => {
|
|
82
|
-
// Delete all test run test cases associated with the test cases
|
|
83
|
-
// Note: This has RESTRICT constraint in the database, so must be deleted first
|
|
84
|
-
await tx.testRunTestCase.deleteMany({
|
|
85
|
-
where: {
|
|
86
|
-
testCaseId: {
|
|
87
|
-
in: id,
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
// Delete all reviews associated with the test cases
|
|
93
|
-
await tx.review.deleteMany({
|
|
94
|
-
where: {
|
|
95
|
-
testCaseId: {
|
|
96
|
-
in: id,
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
// Delete all linked Jira tickets associated with the test cases
|
|
102
|
-
await tx.linkedJiraTicket.deleteMany({
|
|
103
|
-
where: {
|
|
104
|
-
testCaseId: {
|
|
105
|
-
in: id,
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
// Delete all step parameters associated with the test case steps
|
|
111
|
-
await tx.testCaseStepParameter.deleteMany({
|
|
112
|
-
where: {
|
|
113
|
-
testCaseStep: {
|
|
114
|
-
testCaseId: {
|
|
115
|
-
in: id,
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
// Delete all test case steps
|
|
122
|
-
await tx.testCaseStep.deleteMany({
|
|
123
|
-
where: {
|
|
124
|
-
testCaseId: {
|
|
125
|
-
in: id,
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
// Delete all test case identifier tags associated with the test cases
|
|
131
|
-
await tx.tag.deleteMany({
|
|
132
|
-
where: {
|
|
133
|
-
id: { in: testCaseIdentifierTags.map(tag => tag.id) },
|
|
134
|
-
},
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
// Delete the test cases
|
|
138
|
-
await tx.testCase.deleteMany({
|
|
139
|
-
where: { id: { in: id } },
|
|
140
|
-
})
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
// Regenerate feature files for affected test suites
|
|
144
|
-
for (const testSuite of affectedTestSuites) {
|
|
145
|
-
try {
|
|
146
|
-
await generateFeatureFile(testSuite.id, testSuite.name, testSuite.description || undefined)
|
|
147
|
-
} catch (featureFileError) {
|
|
148
|
-
console.error(`Error regenerating feature file for test suite ${testSuite.name}:`, featureFileError)
|
|
149
|
-
// Don't fail the deletion if feature file regeneration fails
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
revalidatePath('/test-cases')
|
|
154
|
-
return {
|
|
155
|
-
status: 200,
|
|
156
|
-
message: 'Test case(s) deleted successfully',
|
|
157
|
-
}
|
|
158
|
-
} catch (e) {
|
|
159
|
-
console.error('Error deleting test case(s):', e)
|
|
160
|
-
return {
|
|
161
|
-
status: 500,
|
|
162
|
-
error: `Server error occurred: ${e}`,
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Create a test case
|
|
169
|
-
* @param testCase - Test case
|
|
170
|
-
* @returns ActionResponse
|
|
171
|
-
*/
|
|
172
|
-
export async function createTestCaseAction(value: z.infer<typeof testCaseSchema>): Promise<ActionResponse> {
|
|
173
|
-
try {
|
|
174
|
-
testCaseSchema.parse(value)
|
|
175
|
-
const uniqueTestCaseIdentifier = generateUniqueTestCaseIdentifier()
|
|
176
|
-
const testCaseIdentifierTag = await prisma.tag.create({
|
|
177
|
-
data: {
|
|
178
|
-
name: uniqueTestCaseIdentifier,
|
|
179
|
-
type: TagType.IDENTIFIER,
|
|
180
|
-
tagExpression: `@${uniqueTestCaseIdentifier}`,
|
|
181
|
-
},
|
|
182
|
-
})
|
|
183
|
-
const baseData = {
|
|
184
|
-
title: value.title,
|
|
185
|
-
description: value.description ?? '',
|
|
186
|
-
TestSuite: {
|
|
187
|
-
connect: value.testSuiteIds.map(id => ({ id })),
|
|
188
|
-
},
|
|
189
|
-
steps: {
|
|
190
|
-
create: value.steps.map(step => ({
|
|
191
|
-
gherkinStep: step.gherkinStep,
|
|
192
|
-
label: step.label,
|
|
193
|
-
icon: step.icon,
|
|
194
|
-
parameters: {
|
|
195
|
-
create: step.parameters.map(param => ({
|
|
196
|
-
name: param.name,
|
|
197
|
-
value: param.value,
|
|
198
|
-
type: param.type as StepParameterType,
|
|
199
|
-
order: param.order,
|
|
200
|
-
})),
|
|
201
|
-
},
|
|
202
|
-
templateStepId: step.templateStepId,
|
|
203
|
-
order: step.order,
|
|
204
|
-
})),
|
|
205
|
-
},
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Only include tags if there are tagIds provided
|
|
209
|
-
const data =
|
|
210
|
-
value.tagIds && value.tagIds.length > 0
|
|
211
|
-
? {
|
|
212
|
-
...baseData,
|
|
213
|
-
tags: {
|
|
214
|
-
connect: [{ id: testCaseIdentifierTag.id }, ...value.tagIds.map(id => ({ id }))],
|
|
215
|
-
},
|
|
216
|
-
}
|
|
217
|
-
: {
|
|
218
|
-
...baseData,
|
|
219
|
-
tags: {
|
|
220
|
-
connect: [{ id: testCaseIdentifierTag.id }],
|
|
221
|
-
},
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const newTestCase = await prisma.testCase.create({
|
|
225
|
-
data,
|
|
226
|
-
include: {
|
|
227
|
-
TestSuite: {
|
|
228
|
-
include: {
|
|
229
|
-
module: true,
|
|
230
|
-
},
|
|
231
|
-
},
|
|
232
|
-
},
|
|
233
|
-
})
|
|
234
|
-
|
|
235
|
-
// Regenerate feature files for all related test suites
|
|
236
|
-
for (const testSuite of newTestCase.TestSuite) {
|
|
237
|
-
try {
|
|
238
|
-
await generateFeatureFile(testSuite.id, testSuite.name, testSuite.description || undefined)
|
|
239
|
-
} catch (featureFileError) {
|
|
240
|
-
console.error(`Error regenerating feature file for test suite ${testSuite.name}:`, featureFileError)
|
|
241
|
-
// Don't fail the creation if feature file regeneration fails
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
revalidatePath('/test-cases')
|
|
246
|
-
return {
|
|
247
|
-
status: 200,
|
|
248
|
-
message: 'Test case created successfully',
|
|
249
|
-
data: newTestCase,
|
|
250
|
-
}
|
|
251
|
-
} catch (e) {
|
|
252
|
-
return {
|
|
253
|
-
status: 500,
|
|
254
|
-
error: `Server error occurred: ${e}`,
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Get a test case by id
|
|
261
|
-
* @param id - Test case id
|
|
262
|
-
* @returns ActionResponse
|
|
263
|
-
*/
|
|
264
|
-
export async function getTestCaseByIdAction(id: string): Promise<ActionResponse> {
|
|
265
|
-
try {
|
|
266
|
-
const testCase = await prisma.testCase.findUnique({
|
|
267
|
-
where: { id },
|
|
268
|
-
include: {
|
|
269
|
-
steps: {
|
|
270
|
-
include: {
|
|
271
|
-
parameters: true,
|
|
272
|
-
},
|
|
273
|
-
},
|
|
274
|
-
TestSuite: {
|
|
275
|
-
select: {
|
|
276
|
-
id: true,
|
|
277
|
-
},
|
|
278
|
-
},
|
|
279
|
-
tags: {
|
|
280
|
-
select: {
|
|
281
|
-
id: true,
|
|
282
|
-
},
|
|
283
|
-
where: {
|
|
284
|
-
type: TagType.FILTER,
|
|
285
|
-
},
|
|
286
|
-
},
|
|
287
|
-
},
|
|
288
|
-
})
|
|
289
|
-
return {
|
|
290
|
-
status: 200,
|
|
291
|
-
data: {
|
|
292
|
-
...testCase,
|
|
293
|
-
testSuiteIds: testCase?.TestSuite.map(suite => suite.id),
|
|
294
|
-
tagIds: testCase?.tags.map(tag => tag.id) || [],
|
|
295
|
-
},
|
|
296
|
-
}
|
|
297
|
-
} catch (e) {
|
|
298
|
-
return {
|
|
299
|
-
status: 500,
|
|
300
|
-
error: `Server error occurred: ${e}`,
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
export async function updateTestCaseAction(
|
|
306
|
-
value: z.infer<typeof testCaseSchema>,
|
|
307
|
-
id?: string,
|
|
308
|
-
): Promise<ActionResponse> {
|
|
309
|
-
if (!id) {
|
|
310
|
-
throw new Error("updateTestCaseAction: 'id' parameter is required for updating a test case.")
|
|
311
|
-
}
|
|
312
|
-
try {
|
|
313
|
-
// Get the test suites that will be affected before updating
|
|
314
|
-
const affectedTestSuites = await prisma.testSuite.findMany({
|
|
315
|
-
where: {
|
|
316
|
-
testCases: {
|
|
317
|
-
some: {
|
|
318
|
-
id: id,
|
|
319
|
-
},
|
|
320
|
-
},
|
|
321
|
-
},
|
|
322
|
-
include: {
|
|
323
|
-
module: true,
|
|
324
|
-
},
|
|
325
|
-
})
|
|
326
|
-
|
|
327
|
-
// 1. Find all step IDs for the test case
|
|
328
|
-
const steps = await prisma.testCaseStep.findMany({
|
|
329
|
-
where: { testCaseId: id },
|
|
330
|
-
select: { id: true },
|
|
331
|
-
})
|
|
332
|
-
const stepIds = steps.map(step => step.id)
|
|
333
|
-
|
|
334
|
-
// 2. Delete all parameters for those steps
|
|
335
|
-
if (stepIds.length > 0) {
|
|
336
|
-
await prisma.testCaseStepParameter.deleteMany({
|
|
337
|
-
where: { testCaseStepId: { in: stepIds } },
|
|
338
|
-
})
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// 3. Delete all steps for the test case
|
|
342
|
-
await prisma.testCaseStep.deleteMany({
|
|
343
|
-
where: { testCaseId: id },
|
|
344
|
-
})
|
|
345
|
-
|
|
346
|
-
// 4. Get existing IDENTIFIER tags to preserve them
|
|
347
|
-
const existingTestCase = await prisma.testCase.findUnique({
|
|
348
|
-
where: { id },
|
|
349
|
-
include: {
|
|
350
|
-
tags: {
|
|
351
|
-
where: {
|
|
352
|
-
type: TagType.IDENTIFIER,
|
|
353
|
-
},
|
|
354
|
-
select: {
|
|
355
|
-
id: true,
|
|
356
|
-
},
|
|
357
|
-
},
|
|
358
|
-
},
|
|
359
|
-
})
|
|
360
|
-
|
|
361
|
-
// 5. Combine IDENTIFIER tags with FILTER tags from the form
|
|
362
|
-
const identifierTagIds = existingTestCase?.tags.map(tag => tag.id) || []
|
|
363
|
-
const filterTagIds = value.tagIds || []
|
|
364
|
-
const allTagIds = [...identifierTagIds, ...filterTagIds]
|
|
365
|
-
|
|
366
|
-
// 6. Then, update the test case with new steps
|
|
367
|
-
const testCase = await prisma.testCase.update({
|
|
368
|
-
where: { id },
|
|
369
|
-
data: {
|
|
370
|
-
title: value.title,
|
|
371
|
-
description: value.description ?? '',
|
|
372
|
-
tags: {
|
|
373
|
-
set: allTagIds.map(id => ({ id })),
|
|
374
|
-
},
|
|
375
|
-
steps: {
|
|
376
|
-
create: value.steps.map(step => ({
|
|
377
|
-
gherkinStep: step.gherkinStep,
|
|
378
|
-
label: step.label ?? '',
|
|
379
|
-
icon: step.icon ?? '',
|
|
380
|
-
parameters: {
|
|
381
|
-
create: step.parameters.map(param => ({
|
|
382
|
-
name: param.name,
|
|
383
|
-
value: param.value,
|
|
384
|
-
type: param.type as StepParameterType,
|
|
385
|
-
order: param.order,
|
|
386
|
-
})),
|
|
387
|
-
},
|
|
388
|
-
templateStepId: step.templateStepId,
|
|
389
|
-
order: step.order,
|
|
390
|
-
})),
|
|
391
|
-
},
|
|
392
|
-
},
|
|
393
|
-
include: {
|
|
394
|
-
steps: true,
|
|
395
|
-
},
|
|
396
|
-
})
|
|
397
|
-
|
|
398
|
-
// Regenerate feature files for all affected test suites
|
|
399
|
-
for (const testSuite of affectedTestSuites) {
|
|
400
|
-
try {
|
|
401
|
-
await generateFeatureFile(testSuite.id, testSuite.name, testSuite.description || undefined)
|
|
402
|
-
} catch (featureFileError) {
|
|
403
|
-
console.error(`Error regenerating feature file for test suite ${testSuite.name}:`, featureFileError)
|
|
404
|
-
// Don't fail the update if feature file regeneration fails
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
return {
|
|
409
|
-
status: 200,
|
|
410
|
-
message: 'Test case updated successfully',
|
|
411
|
-
data: testCase,
|
|
412
|
-
}
|
|
413
|
-
} catch (e) {
|
|
414
|
-
return {
|
|
415
|
-
status: 500,
|
|
416
|
-
error: `Server error occurred: ${e}`,
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
1
|
+
'use server'
|
|
2
|
+
|
|
3
|
+
import prisma from '@/config/db-config'
|
|
4
|
+
import { ActionResponse } from '@/types/form/actionHandler'
|
|
5
|
+
import { revalidatePath } from 'next/cache'
|
|
6
|
+
import { testCaseSchema } from '@/constants/form-opts/test-case-form-opts'
|
|
7
|
+
import { z } from 'zod'
|
|
8
|
+
import { generateFeatureFile } from '@/lib/feature-file-generator'
|
|
9
|
+
|
|
10
|
+
import { StepParameterType, TagType } from '@prisma/client'
|
|
11
|
+
import { generateUniqueTestCaseIdentifier } from '@/lib/test-case-utils'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Get all test cases
|
|
15
|
+
* @returns ActionResponse
|
|
16
|
+
*/
|
|
17
|
+
export async function getAllTestCasesAction(): Promise<ActionResponse> {
|
|
18
|
+
try {
|
|
19
|
+
const testCases = await prisma.testCase.findMany({
|
|
20
|
+
include: {
|
|
21
|
+
steps: {
|
|
22
|
+
include: {
|
|
23
|
+
parameters: true,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
TestSuite: true,
|
|
27
|
+
tags: true,
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
return {
|
|
31
|
+
status: 200,
|
|
32
|
+
data: testCases,
|
|
33
|
+
}
|
|
34
|
+
} catch (e) {
|
|
35
|
+
return {
|
|
36
|
+
status: 500,
|
|
37
|
+
error: `Server error occurred: ${e}`,
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Delete a test case
|
|
44
|
+
* @param id - Test case id
|
|
45
|
+
* @returns ActionResponse
|
|
46
|
+
*/
|
|
47
|
+
export async function deleteTestCaseAction(id: string[]): Promise<ActionResponse> {
|
|
48
|
+
try {
|
|
49
|
+
// Get the test suites that will be affected before deletion
|
|
50
|
+
const affectedTestSuites = await prisma.testSuite.findMany({
|
|
51
|
+
where: {
|
|
52
|
+
testCases: {
|
|
53
|
+
some: {
|
|
54
|
+
id: {
|
|
55
|
+
in: id,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
include: {
|
|
61
|
+
module: true,
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const testCaseIdentifierTags = await prisma.tag.findMany({
|
|
66
|
+
where: {
|
|
67
|
+
type: TagType.IDENTIFIER,
|
|
68
|
+
testCases: {
|
|
69
|
+
some: {
|
|
70
|
+
id: {
|
|
71
|
+
in: id,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
select: {
|
|
77
|
+
id: true,
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
await prisma.$transaction(async tx => {
|
|
82
|
+
// Delete all test run test cases associated with the test cases
|
|
83
|
+
// Note: This has RESTRICT constraint in the database, so must be deleted first
|
|
84
|
+
await tx.testRunTestCase.deleteMany({
|
|
85
|
+
where: {
|
|
86
|
+
testCaseId: {
|
|
87
|
+
in: id,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
// Delete all reviews associated with the test cases
|
|
93
|
+
await tx.review.deleteMany({
|
|
94
|
+
where: {
|
|
95
|
+
testCaseId: {
|
|
96
|
+
in: id,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
// Delete all linked Jira tickets associated with the test cases
|
|
102
|
+
await tx.linkedJiraTicket.deleteMany({
|
|
103
|
+
where: {
|
|
104
|
+
testCaseId: {
|
|
105
|
+
in: id,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// Delete all step parameters associated with the test case steps
|
|
111
|
+
await tx.testCaseStepParameter.deleteMany({
|
|
112
|
+
where: {
|
|
113
|
+
testCaseStep: {
|
|
114
|
+
testCaseId: {
|
|
115
|
+
in: id,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
// Delete all test case steps
|
|
122
|
+
await tx.testCaseStep.deleteMany({
|
|
123
|
+
where: {
|
|
124
|
+
testCaseId: {
|
|
125
|
+
in: id,
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
// Delete all test case identifier tags associated with the test cases
|
|
131
|
+
await tx.tag.deleteMany({
|
|
132
|
+
where: {
|
|
133
|
+
id: { in: testCaseIdentifierTags.map(tag => tag.id) },
|
|
134
|
+
},
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
// Delete the test cases
|
|
138
|
+
await tx.testCase.deleteMany({
|
|
139
|
+
where: { id: { in: id } },
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
// Regenerate feature files for affected test suites
|
|
144
|
+
for (const testSuite of affectedTestSuites) {
|
|
145
|
+
try {
|
|
146
|
+
await generateFeatureFile(testSuite.id, testSuite.name, testSuite.description || undefined)
|
|
147
|
+
} catch (featureFileError) {
|
|
148
|
+
console.error(`Error regenerating feature file for test suite ${testSuite.name}:`, featureFileError)
|
|
149
|
+
// Don't fail the deletion if feature file regeneration fails
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
revalidatePath('/test-cases')
|
|
154
|
+
return {
|
|
155
|
+
status: 200,
|
|
156
|
+
message: 'Test case(s) deleted successfully',
|
|
157
|
+
}
|
|
158
|
+
} catch (e) {
|
|
159
|
+
console.error('Error deleting test case(s):', e)
|
|
160
|
+
return {
|
|
161
|
+
status: 500,
|
|
162
|
+
error: `Server error occurred: ${e}`,
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Create a test case
|
|
169
|
+
* @param testCase - Test case
|
|
170
|
+
* @returns ActionResponse
|
|
171
|
+
*/
|
|
172
|
+
export async function createTestCaseAction(value: z.infer<typeof testCaseSchema>): Promise<ActionResponse> {
|
|
173
|
+
try {
|
|
174
|
+
testCaseSchema.parse(value)
|
|
175
|
+
const uniqueTestCaseIdentifier = generateUniqueTestCaseIdentifier()
|
|
176
|
+
const testCaseIdentifierTag = await prisma.tag.create({
|
|
177
|
+
data: {
|
|
178
|
+
name: uniqueTestCaseIdentifier,
|
|
179
|
+
type: TagType.IDENTIFIER,
|
|
180
|
+
tagExpression: `@${uniqueTestCaseIdentifier}`,
|
|
181
|
+
},
|
|
182
|
+
})
|
|
183
|
+
const baseData = {
|
|
184
|
+
title: value.title,
|
|
185
|
+
description: value.description ?? '',
|
|
186
|
+
TestSuite: {
|
|
187
|
+
connect: value.testSuiteIds.map(id => ({ id })),
|
|
188
|
+
},
|
|
189
|
+
steps: {
|
|
190
|
+
create: value.steps.map(step => ({
|
|
191
|
+
gherkinStep: step.gherkinStep,
|
|
192
|
+
label: step.label,
|
|
193
|
+
icon: step.icon,
|
|
194
|
+
parameters: {
|
|
195
|
+
create: step.parameters.map(param => ({
|
|
196
|
+
name: param.name,
|
|
197
|
+
value: param.value,
|
|
198
|
+
type: param.type as StepParameterType,
|
|
199
|
+
order: param.order,
|
|
200
|
+
})),
|
|
201
|
+
},
|
|
202
|
+
templateStepId: step.templateStepId,
|
|
203
|
+
order: step.order,
|
|
204
|
+
})),
|
|
205
|
+
},
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Only include tags if there are tagIds provided
|
|
209
|
+
const data =
|
|
210
|
+
value.tagIds && value.tagIds.length > 0
|
|
211
|
+
? {
|
|
212
|
+
...baseData,
|
|
213
|
+
tags: {
|
|
214
|
+
connect: [{ id: testCaseIdentifierTag.id }, ...value.tagIds.map(id => ({ id }))],
|
|
215
|
+
},
|
|
216
|
+
}
|
|
217
|
+
: {
|
|
218
|
+
...baseData,
|
|
219
|
+
tags: {
|
|
220
|
+
connect: [{ id: testCaseIdentifierTag.id }],
|
|
221
|
+
},
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const newTestCase = await prisma.testCase.create({
|
|
225
|
+
data,
|
|
226
|
+
include: {
|
|
227
|
+
TestSuite: {
|
|
228
|
+
include: {
|
|
229
|
+
module: true,
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
// Regenerate feature files for all related test suites
|
|
236
|
+
for (const testSuite of newTestCase.TestSuite) {
|
|
237
|
+
try {
|
|
238
|
+
await generateFeatureFile(testSuite.id, testSuite.name, testSuite.description || undefined)
|
|
239
|
+
} catch (featureFileError) {
|
|
240
|
+
console.error(`Error regenerating feature file for test suite ${testSuite.name}:`, featureFileError)
|
|
241
|
+
// Don't fail the creation if feature file regeneration fails
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
revalidatePath('/test-cases')
|
|
246
|
+
return {
|
|
247
|
+
status: 200,
|
|
248
|
+
message: 'Test case created successfully',
|
|
249
|
+
data: newTestCase,
|
|
250
|
+
}
|
|
251
|
+
} catch (e) {
|
|
252
|
+
return {
|
|
253
|
+
status: 500,
|
|
254
|
+
error: `Server error occurred: ${e}`,
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Get a test case by id
|
|
261
|
+
* @param id - Test case id
|
|
262
|
+
* @returns ActionResponse
|
|
263
|
+
*/
|
|
264
|
+
export async function getTestCaseByIdAction(id: string): Promise<ActionResponse> {
|
|
265
|
+
try {
|
|
266
|
+
const testCase = await prisma.testCase.findUnique({
|
|
267
|
+
where: { id },
|
|
268
|
+
include: {
|
|
269
|
+
steps: {
|
|
270
|
+
include: {
|
|
271
|
+
parameters: true,
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
TestSuite: {
|
|
275
|
+
select: {
|
|
276
|
+
id: true,
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
tags: {
|
|
280
|
+
select: {
|
|
281
|
+
id: true,
|
|
282
|
+
},
|
|
283
|
+
where: {
|
|
284
|
+
type: TagType.FILTER,
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
})
|
|
289
|
+
return {
|
|
290
|
+
status: 200,
|
|
291
|
+
data: {
|
|
292
|
+
...testCase,
|
|
293
|
+
testSuiteIds: testCase?.TestSuite.map(suite => suite.id),
|
|
294
|
+
tagIds: testCase?.tags.map(tag => tag.id) || [],
|
|
295
|
+
},
|
|
296
|
+
}
|
|
297
|
+
} catch (e) {
|
|
298
|
+
return {
|
|
299
|
+
status: 500,
|
|
300
|
+
error: `Server error occurred: ${e}`,
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export async function updateTestCaseAction(
|
|
306
|
+
value: z.infer<typeof testCaseSchema>,
|
|
307
|
+
id?: string,
|
|
308
|
+
): Promise<ActionResponse> {
|
|
309
|
+
if (!id) {
|
|
310
|
+
throw new Error("updateTestCaseAction: 'id' parameter is required for updating a test case.")
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
// Get the test suites that will be affected before updating
|
|
314
|
+
const affectedTestSuites = await prisma.testSuite.findMany({
|
|
315
|
+
where: {
|
|
316
|
+
testCases: {
|
|
317
|
+
some: {
|
|
318
|
+
id: id,
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
include: {
|
|
323
|
+
module: true,
|
|
324
|
+
},
|
|
325
|
+
})
|
|
326
|
+
|
|
327
|
+
// 1. Find all step IDs for the test case
|
|
328
|
+
const steps = await prisma.testCaseStep.findMany({
|
|
329
|
+
where: { testCaseId: id },
|
|
330
|
+
select: { id: true },
|
|
331
|
+
})
|
|
332
|
+
const stepIds = steps.map(step => step.id)
|
|
333
|
+
|
|
334
|
+
// 2. Delete all parameters for those steps
|
|
335
|
+
if (stepIds.length > 0) {
|
|
336
|
+
await prisma.testCaseStepParameter.deleteMany({
|
|
337
|
+
where: { testCaseStepId: { in: stepIds } },
|
|
338
|
+
})
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// 3. Delete all steps for the test case
|
|
342
|
+
await prisma.testCaseStep.deleteMany({
|
|
343
|
+
where: { testCaseId: id },
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
// 4. Get existing IDENTIFIER tags to preserve them
|
|
347
|
+
const existingTestCase = await prisma.testCase.findUnique({
|
|
348
|
+
where: { id },
|
|
349
|
+
include: {
|
|
350
|
+
tags: {
|
|
351
|
+
where: {
|
|
352
|
+
type: TagType.IDENTIFIER,
|
|
353
|
+
},
|
|
354
|
+
select: {
|
|
355
|
+
id: true,
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
},
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
// 5. Combine IDENTIFIER tags with FILTER tags from the form
|
|
362
|
+
const identifierTagIds = existingTestCase?.tags.map(tag => tag.id) || []
|
|
363
|
+
const filterTagIds = value.tagIds || []
|
|
364
|
+
const allTagIds = [...identifierTagIds, ...filterTagIds]
|
|
365
|
+
|
|
366
|
+
// 6. Then, update the test case with new steps
|
|
367
|
+
const testCase = await prisma.testCase.update({
|
|
368
|
+
where: { id },
|
|
369
|
+
data: {
|
|
370
|
+
title: value.title,
|
|
371
|
+
description: value.description ?? '',
|
|
372
|
+
tags: {
|
|
373
|
+
set: allTagIds.map(id => ({ id })),
|
|
374
|
+
},
|
|
375
|
+
steps: {
|
|
376
|
+
create: value.steps.map(step => ({
|
|
377
|
+
gherkinStep: step.gherkinStep,
|
|
378
|
+
label: step.label ?? '',
|
|
379
|
+
icon: step.icon ?? '',
|
|
380
|
+
parameters: {
|
|
381
|
+
create: step.parameters.map(param => ({
|
|
382
|
+
name: param.name,
|
|
383
|
+
value: param.value,
|
|
384
|
+
type: param.type as StepParameterType,
|
|
385
|
+
order: param.order,
|
|
386
|
+
})),
|
|
387
|
+
},
|
|
388
|
+
templateStepId: step.templateStepId,
|
|
389
|
+
order: step.order,
|
|
390
|
+
})),
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
include: {
|
|
394
|
+
steps: true,
|
|
395
|
+
},
|
|
396
|
+
})
|
|
397
|
+
|
|
398
|
+
// Regenerate feature files for all affected test suites
|
|
399
|
+
for (const testSuite of affectedTestSuites) {
|
|
400
|
+
try {
|
|
401
|
+
await generateFeatureFile(testSuite.id, testSuite.name, testSuite.description || undefined)
|
|
402
|
+
} catch (featureFileError) {
|
|
403
|
+
console.error(`Error regenerating feature file for test suite ${testSuite.name}:`, featureFileError)
|
|
404
|
+
// Don't fail the update if feature file regeneration fails
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return {
|
|
409
|
+
status: 200,
|
|
410
|
+
message: 'Test case updated successfully',
|
|
411
|
+
data: testCase,
|
|
412
|
+
}
|
|
413
|
+
} catch (e) {
|
|
414
|
+
return {
|
|
415
|
+
status: 500,
|
|
416
|
+
error: `Server error occurred: ${e}`,
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|