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,316 +1,316 @@
|
|
|
1
|
-
import { readFile } from 'fs/promises'
|
|
2
|
-
import { StepStatus, StepKeyword } from '@prisma/client'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Parsed report structure matching cucumber.json format
|
|
6
|
-
*/
|
|
7
|
-
export interface ParsedReport {
|
|
8
|
-
features: Array<{
|
|
9
|
-
name: string
|
|
10
|
-
description: string
|
|
11
|
-
uri: string
|
|
12
|
-
line: number
|
|
13
|
-
keyword: string
|
|
14
|
-
tags: Array<{ name: string; line: number }>
|
|
15
|
-
scenarios: Array<{
|
|
16
|
-
name: string
|
|
17
|
-
description: string
|
|
18
|
-
line: number
|
|
19
|
-
keyword: string
|
|
20
|
-
type: string
|
|
21
|
-
cucumberId: string
|
|
22
|
-
tags: Array<{ name: string; line: number }>
|
|
23
|
-
steps: Array<{
|
|
24
|
-
keyword: string
|
|
25
|
-
line: number | null
|
|
26
|
-
name: string
|
|
27
|
-
matchLocation?: string
|
|
28
|
-
status: string
|
|
29
|
-
duration: number
|
|
30
|
-
errorMessage?: string
|
|
31
|
-
errorTrace?: string
|
|
32
|
-
hidden: boolean
|
|
33
|
-
order: number
|
|
34
|
-
}>
|
|
35
|
-
hooks: Array<{
|
|
36
|
-
keyword: string
|
|
37
|
-
status: string
|
|
38
|
-
duration: number
|
|
39
|
-
errorMessage?: string
|
|
40
|
-
errorTrace?: string
|
|
41
|
-
hidden: boolean
|
|
42
|
-
}>
|
|
43
|
-
}>
|
|
44
|
-
}>
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Cucumber JSON report structure (as received from cucumber-js)
|
|
49
|
-
*/
|
|
50
|
-
interface CucumberJsonFeature {
|
|
51
|
-
description: string
|
|
52
|
-
elements: Array<{
|
|
53
|
-
description: string
|
|
54
|
-
id: string
|
|
55
|
-
keyword: string
|
|
56
|
-
line: number
|
|
57
|
-
name: string
|
|
58
|
-
steps: Array<{
|
|
59
|
-
keyword: string
|
|
60
|
-
line?: number
|
|
61
|
-
name?: string
|
|
62
|
-
hidden?: boolean
|
|
63
|
-
match?: {
|
|
64
|
-
location: string
|
|
65
|
-
}
|
|
66
|
-
result?: {
|
|
67
|
-
status: string
|
|
68
|
-
duration?: number
|
|
69
|
-
error_message?: string
|
|
70
|
-
}
|
|
71
|
-
}>
|
|
72
|
-
tags: Array<{
|
|
73
|
-
name: string
|
|
74
|
-
line: number
|
|
75
|
-
}>
|
|
76
|
-
type: string
|
|
77
|
-
}>
|
|
78
|
-
id: string
|
|
79
|
-
line: number
|
|
80
|
-
keyword: string
|
|
81
|
-
name: string
|
|
82
|
-
tags: Array<{
|
|
83
|
-
name: string
|
|
84
|
-
line: number
|
|
85
|
-
}>
|
|
86
|
-
uri: string
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Maps cucumber step status to Prisma StepStatus enum
|
|
91
|
-
*/
|
|
92
|
-
function mapStepStatus(status: string): StepStatus {
|
|
93
|
-
const upperStatus = status.toUpperCase()
|
|
94
|
-
switch (upperStatus) {
|
|
95
|
-
case 'PASSED':
|
|
96
|
-
return StepStatus.PASSED
|
|
97
|
-
case 'FAILED':
|
|
98
|
-
return StepStatus.FAILED
|
|
99
|
-
case 'SKIPPED':
|
|
100
|
-
return StepStatus.SKIPPED
|
|
101
|
-
case 'PENDING':
|
|
102
|
-
return StepStatus.PENDING
|
|
103
|
-
case 'UNDEFINED':
|
|
104
|
-
return StepStatus.UNDEFINED
|
|
105
|
-
default:
|
|
106
|
-
return StepStatus.PENDING
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Maps cucumber step keyword to Prisma StepKeyword enum
|
|
112
|
-
*/
|
|
113
|
-
function mapStepKeyword(keyword: string): StepKeyword {
|
|
114
|
-
const trimmedKeyword = keyword.trim()
|
|
115
|
-
const upperKeyword = trimmedKeyword.toUpperCase()
|
|
116
|
-
switch (upperKeyword) {
|
|
117
|
-
case 'GIVEN':
|
|
118
|
-
return StepKeyword.GIVEN
|
|
119
|
-
case 'WHEN':
|
|
120
|
-
return StepKeyword.WHEN
|
|
121
|
-
case 'THEN':
|
|
122
|
-
return StepKeyword.THEN
|
|
123
|
-
case 'AND':
|
|
124
|
-
return StepKeyword.AND
|
|
125
|
-
case 'BUT':
|
|
126
|
-
return StepKeyword.BUT
|
|
127
|
-
case 'BEFORE':
|
|
128
|
-
return StepKeyword.BEFORE
|
|
129
|
-
case 'AFTER':
|
|
130
|
-
return StepKeyword.AFTER
|
|
131
|
-
default:
|
|
132
|
-
// Default to GIVEN for unknown keywords
|
|
133
|
-
return StepKeyword.GIVEN
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Separates error message from stack trace
|
|
139
|
-
* Cucumber's error_message typically contains both the error message and stack trace
|
|
140
|
-
* The stack trace usually starts with "at" or contains file paths
|
|
141
|
-
*
|
|
142
|
-
* @param errorMessage - The full error message from Cucumber
|
|
143
|
-
* @returns Object with separated message and trace
|
|
144
|
-
*/
|
|
145
|
-
function separateErrorMessageAndTrace(errorMessage: string | undefined): {
|
|
146
|
-
message: string | undefined
|
|
147
|
-
trace: string | undefined
|
|
148
|
-
} {
|
|
149
|
-
if (!errorMessage) {
|
|
150
|
-
return { message: undefined, trace: undefined }
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Look for common stack trace indicators
|
|
154
|
-
// Stack traces typically start with "at", " at", or contain file paths with line numbers
|
|
155
|
-
const stackTracePatterns = [
|
|
156
|
-
/\n\s*at\s/, // "at" at the start of a line (with optional whitespace)
|
|
157
|
-
/\n\s+at\s/, // "at" with leading whitespace
|
|
158
|
-
/Error:\s*$/m, // Error: at end of line (message ends, trace starts)
|
|
159
|
-
]
|
|
160
|
-
|
|
161
|
-
// Find the first occurrence of a stack trace pattern
|
|
162
|
-
let splitIndex = -1
|
|
163
|
-
for (const pattern of stackTracePatterns) {
|
|
164
|
-
const match = errorMessage.match(pattern)
|
|
165
|
-
if (match && match.index !== undefined) {
|
|
166
|
-
// If we find "at" pattern, split before it (include the newline before "at")
|
|
167
|
-
// If we find "Error:" pattern, split after it
|
|
168
|
-
if (pattern.source.includes('Error:')) {
|
|
169
|
-
splitIndex = match.index + match[0].length
|
|
170
|
-
} else {
|
|
171
|
-
splitIndex = match.index
|
|
172
|
-
}
|
|
173
|
-
break
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// If no stack trace pattern found, check if it looks like just a message (short, no file paths)
|
|
178
|
-
if (splitIndex === -1) {
|
|
179
|
-
// Check if it contains file paths (common in stack traces)
|
|
180
|
-
const hasFilePath = /[\/\\][\w\-\.]+:\d+/.test(errorMessage)
|
|
181
|
-
if (hasFilePath && errorMessage.length > 200) {
|
|
182
|
-
// Likely contains a trace, try to find where message ends
|
|
183
|
-
// Usually the first few lines are the message, rest is trace
|
|
184
|
-
const lines = errorMessage.split('\n')
|
|
185
|
-
// Look for the first line that starts with whitespace and "at" or contains a file path
|
|
186
|
-
for (let i = 0; i < lines.length; i++) {
|
|
187
|
-
if (/^\s*at\s/.test(lines[i]) || /[\/\\][\w\-\.]+:\d+/.test(lines[i])) {
|
|
188
|
-
splitIndex = errorMessage.indexOf(lines[i])
|
|
189
|
-
break
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if (splitIndex > 0) {
|
|
196
|
-
const message = errorMessage.substring(0, splitIndex).trim()
|
|
197
|
-
const trace = errorMessage.substring(splitIndex).trim()
|
|
198
|
-
return {
|
|
199
|
-
message: message || undefined,
|
|
200
|
-
trace: trace || undefined,
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// If we can't separate them, treat the whole thing as the message
|
|
205
|
-
// and leave trace as undefined (better than duplicating)
|
|
206
|
-
return {
|
|
207
|
-
message: errorMessage.trim() || undefined,
|
|
208
|
-
trace: undefined,
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Parses a cucumber.json report file into a structured ParsedReport object
|
|
214
|
-
*
|
|
215
|
-
* @param reportPath - Path to the cucumber.json file
|
|
216
|
-
* @returns Parsed report structure
|
|
217
|
-
* @throws Error if file cannot be read or parsed
|
|
218
|
-
*/
|
|
219
|
-
export async function parseCucumberReport(reportPath: string): Promise<ParsedReport> {
|
|
220
|
-
try {
|
|
221
|
-
// Read the report file
|
|
222
|
-
const fileContent = await readFile(reportPath, 'utf-8')
|
|
223
|
-
const cucumberData: CucumberJsonFeature[] = JSON.parse(fileContent)
|
|
224
|
-
|
|
225
|
-
// Parse features
|
|
226
|
-
const features = cucumberData.map(feature => {
|
|
227
|
-
// Separate steps into regular steps and hooks
|
|
228
|
-
const scenarios = feature.elements.map(element => {
|
|
229
|
-
const steps: ParsedReport['features'][0]['scenarios'][0]['steps'] = []
|
|
230
|
-
const hooks: ParsedReport['features'][0]['scenarios'][0]['hooks'] = []
|
|
231
|
-
|
|
232
|
-
element.steps.forEach((step, index) => {
|
|
233
|
-
const isHook = step.keyword === 'Before' || step.keyword === 'After'
|
|
234
|
-
const stepStatus = step.result?.status || 'pending'
|
|
235
|
-
const duration = step.result?.duration || 0
|
|
236
|
-
|
|
237
|
-
// Separate error message from stack trace
|
|
238
|
-
const { message: errorMessage, trace: errorTrace } = separateErrorMessageAndTrace(step.result?.error_message)
|
|
239
|
-
|
|
240
|
-
if (isHook) {
|
|
241
|
-
hooks.push({
|
|
242
|
-
keyword: step.keyword,
|
|
243
|
-
status: stepStatus,
|
|
244
|
-
duration,
|
|
245
|
-
errorMessage,
|
|
246
|
-
errorTrace,
|
|
247
|
-
hidden: step.hidden || false,
|
|
248
|
-
})
|
|
249
|
-
} else {
|
|
250
|
-
steps.push({
|
|
251
|
-
keyword: step.keyword.trim(),
|
|
252
|
-
line: step.line || null,
|
|
253
|
-
name: step.name || '',
|
|
254
|
-
matchLocation: step.match?.location,
|
|
255
|
-
status: stepStatus,
|
|
256
|
-
duration,
|
|
257
|
-
errorMessage,
|
|
258
|
-
errorTrace,
|
|
259
|
-
hidden: step.hidden || false,
|
|
260
|
-
order: index,
|
|
261
|
-
})
|
|
262
|
-
}
|
|
263
|
-
})
|
|
264
|
-
|
|
265
|
-
return {
|
|
266
|
-
name: element.name,
|
|
267
|
-
description: element.description || '',
|
|
268
|
-
line: element.line,
|
|
269
|
-
keyword: element.keyword,
|
|
270
|
-
type: element.type,
|
|
271
|
-
cucumberId: element.id,
|
|
272
|
-
tags: element.tags.map(tag => ({
|
|
273
|
-
name: tag.name,
|
|
274
|
-
line: tag.line,
|
|
275
|
-
})),
|
|
276
|
-
steps,
|
|
277
|
-
hooks,
|
|
278
|
-
}
|
|
279
|
-
})
|
|
280
|
-
|
|
281
|
-
return {
|
|
282
|
-
name: feature.name,
|
|
283
|
-
description: feature.description || '',
|
|
284
|
-
uri: feature.uri,
|
|
285
|
-
line: feature.line,
|
|
286
|
-
keyword: feature.keyword,
|
|
287
|
-
tags: feature.tags.map(tag => ({
|
|
288
|
-
name: tag.name,
|
|
289
|
-
line: tag.line,
|
|
290
|
-
})),
|
|
291
|
-
scenarios,
|
|
292
|
-
}
|
|
293
|
-
})
|
|
294
|
-
|
|
295
|
-
return { features }
|
|
296
|
-
} catch (error) {
|
|
297
|
-
if (error instanceof Error) {
|
|
298
|
-
throw new Error(`Failed to parse cucumber report at ${reportPath}: ${error.message}`)
|
|
299
|
-
}
|
|
300
|
-
throw new Error(`Failed to parse cucumber report at ${reportPath}: Unknown error`)
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Helper function to convert parsed step status to Prisma enum
|
|
306
|
-
*/
|
|
307
|
-
export function getStepStatusEnum(status: string): StepStatus {
|
|
308
|
-
return mapStepStatus(status)
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Helper function to convert parsed step keyword to Prisma enum
|
|
313
|
-
*/
|
|
314
|
-
export function getStepKeywordEnum(keyword: string): StepKeyword {
|
|
315
|
-
return mapStepKeyword(keyword)
|
|
316
|
-
}
|
|
1
|
+
import { readFile } from 'fs/promises'
|
|
2
|
+
import { StepStatus, StepKeyword } from '@prisma/client'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Parsed report structure matching cucumber.json format
|
|
6
|
+
*/
|
|
7
|
+
export interface ParsedReport {
|
|
8
|
+
features: Array<{
|
|
9
|
+
name: string
|
|
10
|
+
description: string
|
|
11
|
+
uri: string
|
|
12
|
+
line: number
|
|
13
|
+
keyword: string
|
|
14
|
+
tags: Array<{ name: string; line: number }>
|
|
15
|
+
scenarios: Array<{
|
|
16
|
+
name: string
|
|
17
|
+
description: string
|
|
18
|
+
line: number
|
|
19
|
+
keyword: string
|
|
20
|
+
type: string
|
|
21
|
+
cucumberId: string
|
|
22
|
+
tags: Array<{ name: string; line: number }>
|
|
23
|
+
steps: Array<{
|
|
24
|
+
keyword: string
|
|
25
|
+
line: number | null
|
|
26
|
+
name: string
|
|
27
|
+
matchLocation?: string
|
|
28
|
+
status: string
|
|
29
|
+
duration: number
|
|
30
|
+
errorMessage?: string
|
|
31
|
+
errorTrace?: string
|
|
32
|
+
hidden: boolean
|
|
33
|
+
order: number
|
|
34
|
+
}>
|
|
35
|
+
hooks: Array<{
|
|
36
|
+
keyword: string
|
|
37
|
+
status: string
|
|
38
|
+
duration: number
|
|
39
|
+
errorMessage?: string
|
|
40
|
+
errorTrace?: string
|
|
41
|
+
hidden: boolean
|
|
42
|
+
}>
|
|
43
|
+
}>
|
|
44
|
+
}>
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Cucumber JSON report structure (as received from cucumber-js)
|
|
49
|
+
*/
|
|
50
|
+
interface CucumberJsonFeature {
|
|
51
|
+
description: string
|
|
52
|
+
elements: Array<{
|
|
53
|
+
description: string
|
|
54
|
+
id: string
|
|
55
|
+
keyword: string
|
|
56
|
+
line: number
|
|
57
|
+
name: string
|
|
58
|
+
steps: Array<{
|
|
59
|
+
keyword: string
|
|
60
|
+
line?: number
|
|
61
|
+
name?: string
|
|
62
|
+
hidden?: boolean
|
|
63
|
+
match?: {
|
|
64
|
+
location: string
|
|
65
|
+
}
|
|
66
|
+
result?: {
|
|
67
|
+
status: string
|
|
68
|
+
duration?: number
|
|
69
|
+
error_message?: string
|
|
70
|
+
}
|
|
71
|
+
}>
|
|
72
|
+
tags: Array<{
|
|
73
|
+
name: string
|
|
74
|
+
line: number
|
|
75
|
+
}>
|
|
76
|
+
type: string
|
|
77
|
+
}>
|
|
78
|
+
id: string
|
|
79
|
+
line: number
|
|
80
|
+
keyword: string
|
|
81
|
+
name: string
|
|
82
|
+
tags: Array<{
|
|
83
|
+
name: string
|
|
84
|
+
line: number
|
|
85
|
+
}>
|
|
86
|
+
uri: string
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Maps cucumber step status to Prisma StepStatus enum
|
|
91
|
+
*/
|
|
92
|
+
function mapStepStatus(status: string): StepStatus {
|
|
93
|
+
const upperStatus = status.toUpperCase()
|
|
94
|
+
switch (upperStatus) {
|
|
95
|
+
case 'PASSED':
|
|
96
|
+
return StepStatus.PASSED
|
|
97
|
+
case 'FAILED':
|
|
98
|
+
return StepStatus.FAILED
|
|
99
|
+
case 'SKIPPED':
|
|
100
|
+
return StepStatus.SKIPPED
|
|
101
|
+
case 'PENDING':
|
|
102
|
+
return StepStatus.PENDING
|
|
103
|
+
case 'UNDEFINED':
|
|
104
|
+
return StepStatus.UNDEFINED
|
|
105
|
+
default:
|
|
106
|
+
return StepStatus.PENDING
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Maps cucumber step keyword to Prisma StepKeyword enum
|
|
112
|
+
*/
|
|
113
|
+
function mapStepKeyword(keyword: string): StepKeyword {
|
|
114
|
+
const trimmedKeyword = keyword.trim()
|
|
115
|
+
const upperKeyword = trimmedKeyword.toUpperCase()
|
|
116
|
+
switch (upperKeyword) {
|
|
117
|
+
case 'GIVEN':
|
|
118
|
+
return StepKeyword.GIVEN
|
|
119
|
+
case 'WHEN':
|
|
120
|
+
return StepKeyword.WHEN
|
|
121
|
+
case 'THEN':
|
|
122
|
+
return StepKeyword.THEN
|
|
123
|
+
case 'AND':
|
|
124
|
+
return StepKeyword.AND
|
|
125
|
+
case 'BUT':
|
|
126
|
+
return StepKeyword.BUT
|
|
127
|
+
case 'BEFORE':
|
|
128
|
+
return StepKeyword.BEFORE
|
|
129
|
+
case 'AFTER':
|
|
130
|
+
return StepKeyword.AFTER
|
|
131
|
+
default:
|
|
132
|
+
// Default to GIVEN for unknown keywords
|
|
133
|
+
return StepKeyword.GIVEN
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Separates error message from stack trace
|
|
139
|
+
* Cucumber's error_message typically contains both the error message and stack trace
|
|
140
|
+
* The stack trace usually starts with "at" or contains file paths
|
|
141
|
+
*
|
|
142
|
+
* @param errorMessage - The full error message from Cucumber
|
|
143
|
+
* @returns Object with separated message and trace
|
|
144
|
+
*/
|
|
145
|
+
function separateErrorMessageAndTrace(errorMessage: string | undefined): {
|
|
146
|
+
message: string | undefined
|
|
147
|
+
trace: string | undefined
|
|
148
|
+
} {
|
|
149
|
+
if (!errorMessage) {
|
|
150
|
+
return { message: undefined, trace: undefined }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Look for common stack trace indicators
|
|
154
|
+
// Stack traces typically start with "at", " at", or contain file paths with line numbers
|
|
155
|
+
const stackTracePatterns = [
|
|
156
|
+
/\n\s*at\s/, // "at" at the start of a line (with optional whitespace)
|
|
157
|
+
/\n\s+at\s/, // "at" with leading whitespace
|
|
158
|
+
/Error:\s*$/m, // Error: at end of line (message ends, trace starts)
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
// Find the first occurrence of a stack trace pattern
|
|
162
|
+
let splitIndex = -1
|
|
163
|
+
for (const pattern of stackTracePatterns) {
|
|
164
|
+
const match = errorMessage.match(pattern)
|
|
165
|
+
if (match && match.index !== undefined) {
|
|
166
|
+
// If we find "at" pattern, split before it (include the newline before "at")
|
|
167
|
+
// If we find "Error:" pattern, split after it
|
|
168
|
+
if (pattern.source.includes('Error:')) {
|
|
169
|
+
splitIndex = match.index + match[0].length
|
|
170
|
+
} else {
|
|
171
|
+
splitIndex = match.index
|
|
172
|
+
}
|
|
173
|
+
break
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// If no stack trace pattern found, check if it looks like just a message (short, no file paths)
|
|
178
|
+
if (splitIndex === -1) {
|
|
179
|
+
// Check if it contains file paths (common in stack traces)
|
|
180
|
+
const hasFilePath = /[\/\\][\w\-\.]+:\d+/.test(errorMessage)
|
|
181
|
+
if (hasFilePath && errorMessage.length > 200) {
|
|
182
|
+
// Likely contains a trace, try to find where message ends
|
|
183
|
+
// Usually the first few lines are the message, rest is trace
|
|
184
|
+
const lines = errorMessage.split('\n')
|
|
185
|
+
// Look for the first line that starts with whitespace and "at" or contains a file path
|
|
186
|
+
for (let i = 0; i < lines.length; i++) {
|
|
187
|
+
if (/^\s*at\s/.test(lines[i]) || /[\/\\][\w\-\.]+:\d+/.test(lines[i])) {
|
|
188
|
+
splitIndex = errorMessage.indexOf(lines[i])
|
|
189
|
+
break
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (splitIndex > 0) {
|
|
196
|
+
const message = errorMessage.substring(0, splitIndex).trim()
|
|
197
|
+
const trace = errorMessage.substring(splitIndex).trim()
|
|
198
|
+
return {
|
|
199
|
+
message: message || undefined,
|
|
200
|
+
trace: trace || undefined,
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// If we can't separate them, treat the whole thing as the message
|
|
205
|
+
// and leave trace as undefined (better than duplicating)
|
|
206
|
+
return {
|
|
207
|
+
message: errorMessage.trim() || undefined,
|
|
208
|
+
trace: undefined,
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Parses a cucumber.json report file into a structured ParsedReport object
|
|
214
|
+
*
|
|
215
|
+
* @param reportPath - Path to the cucumber.json file
|
|
216
|
+
* @returns Parsed report structure
|
|
217
|
+
* @throws Error if file cannot be read or parsed
|
|
218
|
+
*/
|
|
219
|
+
export async function parseCucumberReport(reportPath: string): Promise<ParsedReport> {
|
|
220
|
+
try {
|
|
221
|
+
// Read the report file
|
|
222
|
+
const fileContent = await readFile(reportPath, 'utf-8')
|
|
223
|
+
const cucumberData: CucumberJsonFeature[] = JSON.parse(fileContent)
|
|
224
|
+
|
|
225
|
+
// Parse features
|
|
226
|
+
const features = cucumberData.map(feature => {
|
|
227
|
+
// Separate steps into regular steps and hooks
|
|
228
|
+
const scenarios = feature.elements.map(element => {
|
|
229
|
+
const steps: ParsedReport['features'][0]['scenarios'][0]['steps'] = []
|
|
230
|
+
const hooks: ParsedReport['features'][0]['scenarios'][0]['hooks'] = []
|
|
231
|
+
|
|
232
|
+
element.steps.forEach((step, index) => {
|
|
233
|
+
const isHook = step.keyword === 'Before' || step.keyword === 'After'
|
|
234
|
+
const stepStatus = step.result?.status || 'pending'
|
|
235
|
+
const duration = step.result?.duration || 0
|
|
236
|
+
|
|
237
|
+
// Separate error message from stack trace
|
|
238
|
+
const { message: errorMessage, trace: errorTrace } = separateErrorMessageAndTrace(step.result?.error_message)
|
|
239
|
+
|
|
240
|
+
if (isHook) {
|
|
241
|
+
hooks.push({
|
|
242
|
+
keyword: step.keyword,
|
|
243
|
+
status: stepStatus,
|
|
244
|
+
duration,
|
|
245
|
+
errorMessage,
|
|
246
|
+
errorTrace,
|
|
247
|
+
hidden: step.hidden || false,
|
|
248
|
+
})
|
|
249
|
+
} else {
|
|
250
|
+
steps.push({
|
|
251
|
+
keyword: step.keyword.trim(),
|
|
252
|
+
line: step.line || null,
|
|
253
|
+
name: step.name || '',
|
|
254
|
+
matchLocation: step.match?.location,
|
|
255
|
+
status: stepStatus,
|
|
256
|
+
duration,
|
|
257
|
+
errorMessage,
|
|
258
|
+
errorTrace,
|
|
259
|
+
hidden: step.hidden || false,
|
|
260
|
+
order: index,
|
|
261
|
+
})
|
|
262
|
+
}
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
name: element.name,
|
|
267
|
+
description: element.description || '',
|
|
268
|
+
line: element.line,
|
|
269
|
+
keyword: element.keyword,
|
|
270
|
+
type: element.type,
|
|
271
|
+
cucumberId: element.id,
|
|
272
|
+
tags: element.tags.map(tag => ({
|
|
273
|
+
name: tag.name,
|
|
274
|
+
line: tag.line,
|
|
275
|
+
})),
|
|
276
|
+
steps,
|
|
277
|
+
hooks,
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
return {
|
|
282
|
+
name: feature.name,
|
|
283
|
+
description: feature.description || '',
|
|
284
|
+
uri: feature.uri,
|
|
285
|
+
line: feature.line,
|
|
286
|
+
keyword: feature.keyword,
|
|
287
|
+
tags: feature.tags.map(tag => ({
|
|
288
|
+
name: tag.name,
|
|
289
|
+
line: tag.line,
|
|
290
|
+
})),
|
|
291
|
+
scenarios,
|
|
292
|
+
}
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
return { features }
|
|
296
|
+
} catch (error) {
|
|
297
|
+
if (error instanceof Error) {
|
|
298
|
+
throw new Error(`Failed to parse cucumber report at ${reportPath}: ${error.message}`)
|
|
299
|
+
}
|
|
300
|
+
throw new Error(`Failed to parse cucumber report at ${reportPath}: Unknown error`)
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Helper function to convert parsed step status to Prisma enum
|
|
306
|
+
*/
|
|
307
|
+
export function getStepStatusEnum(status: string): StepStatus {
|
|
308
|
+
return mapStepStatus(status)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Helper function to convert parsed step keyword to Prisma enum
|
|
313
|
+
*/
|
|
314
|
+
export function getStepKeywordEnum(keyword: string): StepKeyword {
|
|
315
|
+
return mapStepKeyword(keyword)
|
|
316
|
+
}
|