create-appraisejs 0.3.1-alpha.0 → 0.4.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -17
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/prepare-template-utils.d.ts.map +1 -1
- package/dist/prepare-template-utils.js.map +1 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +2 -2
- package/dist/prompts.js.map +1 -1
- package/dist/sync-templates-utils.d.ts.map +1 -1
- package/dist/sync-templates-utils.js +1 -5
- package/dist/sync-templates-utils.js.map +1 -1
- package/package.json +1 -1
- package/templates/blank/.editorconfig +11 -0
- package/templates/blank/.env.example +2 -2
- package/templates/blank/.gitattributes +21 -0
- package/templates/blank/.gitconfig.appraise +14 -0
- package/templates/blank/.prettierrc +13 -0
- package/templates/blank/.vscode/settings.json +2 -0
- package/templates/blank/README.md +12 -12
- package/templates/blank/components.json +24 -24
- package/templates/blank/cucumber.mjs +27 -16
- package/templates/blank/e2e/README.md +56 -0
- package/templates/blank/e2e/apply-migrations.mjs +76 -0
- package/templates/blank/e2e/appraise-smoke.spec.ts +78 -0
- package/templates/blank/e2e/authoring.spec.ts +53 -0
- package/templates/blank/e2e/crud-configuration.spec.ts +138 -0
- package/templates/blank/e2e/crud-tests.spec.ts +76 -0
- package/templates/blank/e2e/helpers/forms.ts +186 -0
- package/templates/blank/e2e/helpers/navigation.ts +27 -0
- package/templates/blank/e2e/helpers/table.ts +45 -0
- package/templates/blank/e2e/helpers/test-data.ts +559 -0
- package/templates/blank/e2e/helpers/ui.ts +41 -0
- package/templates/blank/e2e/navigation.spec.ts +101 -0
- package/templates/blank/e2e/runs-and-reports.spec.ts +82 -0
- package/templates/blank/e2e/settings-sync.spec.ts +39 -0
- package/templates/blank/e2e/start-server.mjs +61 -0
- package/templates/blank/eslint.config.mjs +4 -4
- package/templates/blank/gitignore +0 -3
- package/templates/blank/next-env.d.ts +6 -6
- package/templates/blank/package-lock.json +60 -104
- package/templates/blank/package.json +11 -10
- package/templates/blank/packages/cucumber-runtime/package.json +14 -13
- package/templates/blank/packages/cucumber-runtime/src/cache.util.ts +93 -93
- package/templates/blank/packages/cucumber-runtime/src/cli.ts +77 -68
- package/templates/blank/packages/cucumber-runtime/src/environment.util.ts +21 -21
- package/templates/blank/packages/cucumber-runtime/src/executor.ts +32 -32
- package/templates/blank/packages/cucumber-runtime/src/index.ts +17 -17
- package/templates/blank/packages/cucumber-runtime/src/locator.util.ts +234 -234
- package/templates/blank/packages/cucumber-runtime/src/parameter-types.ts +7 -7
- package/templates/blank/packages/cucumber-runtime/src/paths.ts +22 -5
- package/templates/blank/packages/cucumber-runtime/src/random-data.util.ts +35 -35
- package/templates/blank/packages/cucumber-runtime/src/types.ts +13 -13
- package/templates/blank/packages/cucumber-runtime/src/world.ts +44 -44
- package/templates/blank/packages/cucumber-runtime/tsconfig.json +11 -11
- package/templates/blank/packages/locator-picker-companion/dist/cli.js +1 -1
- package/templates/blank/packages/locator-picker-companion/dist/index.d.ts +3 -3
- package/templates/blank/packages/locator-picker-companion/dist/index.js +3 -3
- package/templates/blank/packages/locator-picker-companion/dist/injected-picker-script.js +13 -3
- package/templates/blank/packages/locator-picker-companion/dist/selector-generator.d.ts +6 -3
- package/templates/blank/packages/locator-picker-companion/dist/selector-generator.js +233 -229
- package/templates/blank/packages/locator-picker-companion/package.json +2 -1
- package/templates/blank/packages/locator-picker-companion/src/cli.ts +1 -7
- package/templates/blank/packages/locator-picker-companion/src/injected-picker-script.ts +26 -5
- package/templates/blank/packages/locator-picker-companion/src/launcher.ts +1 -3
- package/templates/blank/packages/locator-picker-companion/src/session-file.ts +4 -15
- package/templates/blank/packages/locator-picker-companion/src/types.ts +1 -8
- package/templates/blank/playwright.config.ts +46 -0
- package/templates/blank/postcss.config.mjs +8 -8
- package/templates/blank/prisma/dev.db +0 -0
- package/templates/blank/prisma/migrations/20251104113456_add_type_for_template_step_groups/migration.sql +16 -16
- package/templates/blank/prisma/migrations/20251104170946_add_tags_to_test_suite_and_test_case/migration.sql +27 -27
- package/templates/blank/prisma/migrations/20251112190024_add_cascade_delete_to_test_run_test_case/migration.sql +17 -17
- package/templates/blank/prisma/migrations/20251113181100_add_test_run_log/migration.sql +12 -12
- package/templates/blank/prisma/migrations/20251119191838_add_tag_type/migration.sql +28 -28
- package/templates/blank/prisma/migrations/20251121164059_add_conflict_resolution/migration.sql +12 -12
- package/templates/blank/prisma/migrations/20251223183400_add_report_model_to_db_schema/migration.sql +10 -10
- package/templates/blank/prisma/migrations/20251223183637_add_report_test_case_entity_for_storing_test_results_for_individual_test_cases/migration.sql +10 -10
- package/templates/blank/prisma/migrations/20251224083549_add_comprehensive_report_storage/migration.sql +108 -108
- package/templates/blank/prisma/migrations/20251229194422_migrate_duration_to_string/migration.sql +55 -55
- package/templates/blank/prisma/migrations/20251230124637_add_unique_constraint_to_test_run_name/migration.sql +27 -27
- package/templates/blank/prisma/migrations/20260115094436_add_dashboard_metrics/migration.sql +59 -59
- package/templates/blank/prisma/migrations/20260127172022_add_cascade_delete_to_step_parameters/migration.sql +34 -34
- package/templates/blank/prisma/migrations/20260313093000_add_report_step_screenshot_path/migration.sql +1 -1
- package/templates/blank/scripts/configure-git-line-endings.mjs +91 -0
- package/templates/blank/scripts/install-template-step.ts +5 -1
- package/templates/blank/scripts/lib/step-matcher.test.ts +3 -3
- package/templates/blank/scripts/lib/step-matcher.ts +5 -1
- package/templates/blank/scripts/lib/template-step-installer.test.ts +4 -2
- package/templates/blank/scripts/lib/template-step-installer.ts +16 -4
- package/templates/blank/scripts/lib/template-step-registry.test.ts +1 -1
- package/templates/blank/scripts/lib/template-step-registry.ts +4 -1
- package/templates/blank/scripts/run-fallow-commit.mjs +4 -6
- package/templates/blank/scripts/setup-env.ts +0 -0
- package/templates/blank/scripts/sync-all.ts +7 -6
- package/templates/blank/scripts/sync-appraise-base-template.ts +84 -77
- package/templates/blank/scripts/sync-environments.ts +47 -44
- package/templates/blank/scripts/sync-locator-groups.ts +67 -76
- package/templates/blank/scripts/sync-locators.ts +50 -53
- package/templates/blank/scripts/sync-modules.ts +42 -42
- package/templates/blank/scripts/sync-tags.ts +51 -51
- package/templates/blank/scripts/sync-template-step-groups.ts +34 -32
- package/templates/blank/scripts/sync-template-steps.ts +97 -97
- package/templates/blank/scripts/sync-test-cases.ts +125 -84
- package/templates/blank/scripts/sync-test-suites.ts +85 -80
- package/templates/blank/src/actions/server-action-boundary.test.ts +1 -7
- package/templates/blank/src/actions/settings/sync-actions.ts +3 -1
- package/templates/blank/src/actions/tags/tag-actions.ts +1 -7
- package/templates/blank/src/actions/template-test-case/template-test-case-actions.ts +3 -1
- package/templates/blank/src/app/(base)/environments/create/page.tsx +28 -28
- package/templates/blank/src/app/(base)/environments/environment-form.tsx +3 -2
- package/templates/blank/src/app/(base)/environments/environment-helpers.ts +4 -1
- package/templates/blank/src/app/(base)/layout.tsx +10 -10
- package/templates/blank/src/app/(base)/locator-groups/locator-group-form.tsx +5 -3
- package/templates/blank/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
- package/templates/blank/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
- package/templates/blank/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
- package/templates/blank/src/app/(base)/locator-groups/page.tsx +9 -19
- package/templates/blank/src/app/(base)/locators/create/create-locator-workspace-helpers.test.ts +3 -6
- package/templates/blank/src/app/(base)/locators/create/create-locator-workspace-response.ts +22 -5
- package/templates/blank/src/app/(base)/locators/create/create-locator-workspace-state.ts +5 -1
- package/templates/blank/src/app/(base)/locators/create/use-locator-workspace.ts +7 -2
- package/templates/blank/src/app/(base)/locators/locator-file-sync.ts +1 -5
- package/templates/blank/src/app/(base)/locators/locator-helpers.ts +2 -12
- package/templates/blank/src/app/(base)/locators/locator-table-columns.tsx +59 -60
- package/templates/blank/src/app/(base)/modules/module-form.tsx +3 -1
- package/templates/blank/src/app/(base)/reports/overview-chart.tsx +49 -49
- package/templates/blank/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +114 -115
- package/templates/blank/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
- package/templates/blank/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +80 -79
- package/templates/blank/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +29 -27
- package/templates/blank/src/app/(base)/settings/settings-sync-panel-helpers.test.tsx +4 -6
- package/templates/blank/src/app/(base)/settings/settings-sync-panel.tsx +22 -23
- package/templates/blank/src/app/(base)/tags/tag-form.test.tsx +2 -10
- package/templates/blank/src/app/(base)/tags/tag-form.tsx +5 -3
- package/templates/blank/src/app/(base)/tags/tag-table-columns.tsx +63 -63
- package/templates/blank/src/app/(base)/tags/tag-table.tsx +29 -29
- package/templates/blank/src/app/(base)/template-step-groups/create/page.tsx +28 -28
- package/templates/blank/src/app/(base)/template-step-groups/template-step-group-form.tsx +3 -1
- package/templates/blank/src/app/(base)/template-step-groups/template-step-group-helpers.ts +4 -1
- package/templates/blank/src/app/(base)/template-steps/paramChip.tsx +6 -10
- package/templates/blank/src/app/(base)/template-steps/template-step-form-helpers.ts +4 -2
- package/templates/blank/src/app/(base)/template-steps/template-step-helpers.test.ts +19 -1
- package/templates/blank/src/app/(base)/template-steps/template-step-helpers.ts +1 -5
- package/templates/blank/src/app/(base)/template-steps/template-step-row-guards.ts +1 -5
- package/templates/blank/src/app/(base)/template-steps/template-step-types.ts +1 -5
- package/templates/blank/src/app/(base)/template-test-cases/create-template-test-case-page-data.test.ts +4 -1
- package/templates/blank/src/app/(base)/template-test-cases/create-template-test-case-page-data.ts +1 -2
- package/templates/blank/src/app/(base)/template-test-cases/modify/[id]/page.tsx +1 -0
- package/templates/blank/src/app/(base)/template-test-cases/template-test-case-flow.test.tsx +0 -1
- package/templates/blank/src/app/(base)/template-test-cases/template-test-case-form.tsx +3 -1
- package/templates/blank/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
- package/templates/blank/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
- package/templates/blank/src/app/(base)/test-cases/create/page.tsx +1 -5
- package/templates/blank/src/app/(base)/test-cases/create-from-template/create-from-template-selection-helpers.ts +1 -4
- package/templates/blank/src/app/(base)/test-cases/create-from-template/page.test.tsx +2 -2
- package/templates/blank/src/app/(base)/test-cases/inline-tag-creation-dialog.tsx +1 -7
- package/templates/blank/src/app/(base)/test-cases/inline-test-suite-creation-dialog.tsx +1 -7
- package/templates/blank/src/app/(base)/test-cases/modify/[id]/page.tsx +1 -5
- package/templates/blank/src/app/(base)/test-cases/test-case-form.tsx +63 -78
- package/templates/blank/src/app/(base)/test-cases/test-case-route-helpers.test.ts +2 -7
- package/templates/blank/src/app/(base)/test-suites/editable-test-suite-helpers.ts +1 -6
- package/templates/blank/src/app/(base)/test-suites/test-suite-form.test.tsx +2 -10
- package/templates/blank/src/app/(dashboard-components)/data-card-grid.tsx +10 -10
- package/templates/blank/src/app/api/test-runs/[runId]/download/route.ts +1 -4
- package/templates/blank/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.test.ts +18 -9
- package/templates/blank/src/assets/icons/empty-tube.tsx +23 -23
- package/templates/blank/src/assets/icons/tube-plus.tsx +29 -29
- package/templates/blank/src/components/data-visualization/info-card.tsx +56 -70
- package/templates/blank/src/components/data-visualization/info-grid.tsx +22 -22
- package/templates/blank/src/components/diagram/add-node-prompt-node.tsx +1 -1
- package/templates/blank/src/components/diagram/dynamic-parameters-helpers.ts +4 -3
- package/templates/blank/src/components/diagram/dynamic-parameters.test.tsx +4 -1
- package/templates/blank/src/components/diagram/dynamic-parameters.tsx +0 -1
- package/templates/blank/src/components/diagram/flow-diagram-block-dialog.test.tsx +26 -0
- package/templates/blank/src/components/diagram/flow-diagram-block-dialog.tsx +3 -1
- package/templates/blank/src/components/diagram/flow-diagram-connection-guards.ts +24 -6
- package/templates/blank/src/components/diagram/flow-diagram-helpers.test.ts +27 -0
- package/templates/blank/src/components/diagram/flow-diagram-node-search.tsx +73 -66
- package/templates/blank/src/components/diagram/flow-diagram-toolbar.tsx +35 -3
- package/templates/blank/src/components/diagram/flow-diagram-view.tsx +1 -7
- package/templates/blank/src/components/diagram/flow-diagram.test.tsx +225 -0
- package/templates/blank/src/components/diagram/flow-node-data-helpers.ts +1 -1
- package/templates/blank/src/components/diagram/node-form-fields-content.tsx +9 -2
- package/templates/blank/src/components/diagram/node-form-helpers.test.ts +3 -1
- package/templates/blank/src/components/diagram/node-form-helpers.ts +1 -4
- package/templates/blank/src/components/diagram/node-form-template-step-selection.ts +1 -4
- package/templates/blank/src/components/diagram/node-form.test.tsx +25 -0
- package/templates/blank/src/components/diagram/node-form.tsx +2 -12
- package/templates/blank/src/components/diagram/options-header-node.test.tsx +4 -1
- package/templates/blank/src/components/diagram/options-header-node.tsx +140 -130
- package/templates/blank/src/components/diagram/use-flow-diagram-search.ts +2 -0
- package/templates/blank/src/components/diagram/use-flow-diagram.ts +93 -1
- package/templates/blank/src/components/form/error-message.tsx +7 -7
- package/templates/blank/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
- package/templates/blank/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
- package/templates/blank/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
- package/templates/blank/src/components/navigation/entity-search-command.tsx +3 -9
- package/templates/blank/src/components/navigation/nav-link.tsx +60 -60
- package/templates/blank/src/components/test-case/test-case-form-helpers.test.ts +1 -5
- package/templates/blank/src/components/test-case/test-case-form-helpers.ts +1 -5
- package/templates/blank/src/components/test-case/test-case-picker-helpers.ts +8 -7
- package/templates/blank/src/components/test-case/test-case-picker.tsx +2 -6
- package/templates/blank/src/components/test-run/log-viewer.test.tsx +25 -0
- package/templates/blank/src/components/test-run/log-viewer.tsx +2 -2
- package/templates/blank/src/components/test-run/test-run-details-guards.ts +10 -1
- package/templates/blank/src/components/test-run/test-run-details.test.tsx +9 -19
- package/templates/blank/src/components/test-run/use-log-viewer.ts +2 -8
- package/templates/blank/src/components/test-run/use-test-run-header.ts +1 -4
- package/templates/blank/src/components/test-suite/test-suite-picker.tsx +1 -1
- package/templates/blank/src/components/theme/theme-provider.tsx +7 -1
- package/templates/blank/src/components/typography/page-header-subtitle.tsx +7 -7
- package/templates/blank/src/components/typography/page-header.tsx +7 -7
- package/templates/blank/src/components/ui/chart.tsx +2 -8
- package/templates/blank/src/components/ui/command.tsx +2 -5
- package/templates/blank/src/components/ui/data-table-column-header.tsx +3 -3
- package/templates/blank/src/components/ui/data-table.test.tsx +1 -8
- package/templates/blank/src/components/ui/dialog.tsx +1 -4
- package/templates/blank/src/components/ui/select.tsx +2 -2
- package/templates/blank/src/components/ui/separator.tsx +5 -1
- package/templates/blank/src/components/ui/skeleton.tsx +7 -7
- package/templates/blank/src/components/ui/table.tsx +1 -1
- package/templates/blank/src/components/ui/toaster.tsx +26 -26
- package/templates/blank/src/components/ui/tooltip.tsx +1 -1
- package/templates/blank/src/constants/form-opts/locator-group-form-opts.ts +1 -1
- package/templates/blank/src/lib/appraise-test-case-metadata.test.ts +78 -0
- package/templates/blank/src/lib/appraise-test-case-metadata.ts +220 -0
- package/templates/blank/src/lib/automation/automation-path-roots.test.ts +14 -0
- package/templates/blank/src/lib/automation/automation-path-roots.ts +10 -2
- package/templates/blank/src/lib/database-sync.ts +166 -15
- package/templates/blank/src/lib/executor/local-executor-adapter.ts +6 -2
- package/templates/blank/src/lib/feature-file-generator.ts +54 -10
- package/templates/blank/src/lib/gherkin-parser.test.ts +52 -0
- package/templates/blank/src/lib/gherkin-parser.ts +39 -1
- package/templates/blank/src/lib/locator-group-file-utils.ts +5 -1
- package/templates/blank/src/lib/locator-picker/session-manager.ts +1 -2
- package/templates/blank/src/lib/metrics/metric-calculator.test.ts +105 -6
- package/templates/blank/src/lib/metrics/metric-calculator.ts +39 -40
- package/templates/blank/src/lib/sync/projected-feature-utils.ts +5 -1
- package/templates/blank/src/lib/sync/sync-executor.ts +1 -4
- package/templates/blank/src/lib/sync/sync-pending-counts.test.ts +316 -7
- package/templates/blank/src/lib/sync/sync-pending-counts.ts +189 -26
- package/templates/blank/src/lib/template-automation-paths.ts +1 -1
- package/templates/blank/src/lib/template-sync-utils.d.ts +14 -7
- package/templates/blank/src/lib/test-case-utils.ts +6 -6
- package/templates/blank/src/lib/test-run/log-formatter.ts +82 -83
- package/templates/blank/src/lib/test-run/report-parser.ts +352 -352
- package/templates/blank/src/lib/transformers/gherkin-converter.ts +42 -42
- package/templates/blank/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
- package/templates/blank/src/lib/utils/node-param-validation.ts +81 -81
- package/templates/blank/src/lib/utils/template-step-file-generator.ts +5 -3
- package/templates/blank/src/lib/utils/template-step-file-manager-intelligent.ts +11 -1
- package/templates/blank/src/services/dashboard/dashboard-service.test.ts +28 -1
- package/templates/blank/src/services/dashboard/dashboard-service.ts +2 -0
- package/templates/blank/src/services/locator/locator-service.test.ts +1 -3
- package/templates/blank/src/services/locator/locator-service.ts +3 -1
- package/templates/blank/src/services/locator/locator-sync-utils.test.ts +1 -4
- package/templates/blank/src/services/module/module-service.ts +1 -4
- package/templates/blank/src/services/report/report-service.test.ts +70 -6
- package/templates/blank/src/services/report/report-service.ts +52 -9
- package/templates/blank/src/services/shared/errors.ts +2 -4
- package/templates/blank/src/services/template-step/template-step-service.ts +3 -1
- package/templates/blank/src/services/template-step-group/template-step-group-service.ts +3 -1
- package/templates/blank/src/services/test-case/test-case-service.ts +0 -5
- package/templates/blank/src/services/test-run/test-run-service.test.ts +13 -6
- package/templates/blank/src/services/test-run/test-run-service.ts +53 -8
- package/templates/blank/src/services/test-suite/test-suite-service.test.ts +1 -5
- package/templates/blank/src/services/test-suite/test-suite-service.ts +2 -4
- package/templates/blank/src/types/form/actionHandler.ts +1 -5
- package/templates/blank/tsconfig.json +8 -8
- package/templates/starter/.editorconfig +11 -0
- package/templates/starter/.env.example +2 -2
- package/templates/starter/.gitattributes +21 -0
- package/templates/starter/.gitconfig.appraise +14 -0
- package/templates/starter/.prettierrc +13 -0
- package/templates/starter/.vscode/settings.json +2 -0
- package/templates/starter/README.md +12 -12
- package/templates/starter/automation/steps/actions/click.step.ts +56 -58
- package/templates/starter/automation/steps/actions/hover.step.ts +25 -27
- package/templates/starter/automation/steps/actions/input.step.ts +85 -108
- package/templates/starter/automation/steps/actions/navigation.step.ts +67 -70
- package/templates/starter/automation/steps/actions/random_data.step.ts +149 -143
- package/templates/starter/automation/steps/actions/store.step.ts +69 -1
- package/templates/starter/automation/steps/actions/wait.step.ts +84 -1
- package/templates/starter/automation/steps/validations/active_state_assertion.step.ts +28 -30
- package/templates/starter/automation/steps/validations/navigation_assertion.step.ts +20 -22
- package/templates/starter/automation/steps/validations/text_assertion.step.ts +67 -107
- package/templates/starter/automation/steps/validations/visibility_assertion.step.ts +24 -26
- package/templates/starter/components.json +24 -24
- package/templates/starter/cucumber.mjs +27 -16
- package/templates/starter/e2e/README.md +56 -0
- package/templates/starter/e2e/apply-migrations.mjs +76 -0
- package/templates/starter/e2e/appraise-smoke.spec.ts +78 -0
- package/templates/starter/e2e/authoring.spec.ts +53 -0
- package/templates/starter/e2e/crud-configuration.spec.ts +138 -0
- package/templates/starter/e2e/crud-tests.spec.ts +76 -0
- package/templates/starter/e2e/helpers/forms.ts +186 -0
- package/templates/starter/e2e/helpers/navigation.ts +27 -0
- package/templates/starter/e2e/helpers/table.ts +45 -0
- package/templates/starter/e2e/helpers/test-data.ts +559 -0
- package/templates/starter/e2e/helpers/ui.ts +41 -0
- package/templates/starter/e2e/navigation.spec.ts +101 -0
- package/templates/starter/e2e/runs-and-reports.spec.ts +82 -0
- package/templates/starter/e2e/settings-sync.spec.ts +39 -0
- package/templates/starter/e2e/start-server.mjs +61 -0
- package/templates/starter/eslint.config.mjs +4 -4
- package/templates/starter/gitignore +0 -3
- package/templates/starter/next-env.d.ts +6 -6
- package/templates/starter/package-lock.json +60 -104
- package/templates/starter/package.json +11 -10
- package/templates/starter/packages/cucumber-runtime/package.json +14 -13
- package/templates/starter/packages/cucumber-runtime/src/cache.util.ts +93 -93
- package/templates/starter/packages/cucumber-runtime/src/cli.ts +77 -68
- package/templates/starter/packages/cucumber-runtime/src/environment.util.ts +21 -21
- package/templates/starter/packages/cucumber-runtime/src/executor.ts +32 -32
- package/templates/starter/packages/cucumber-runtime/src/index.ts +17 -17
- package/templates/starter/packages/cucumber-runtime/src/locator.util.ts +234 -234
- package/templates/starter/packages/cucumber-runtime/src/parameter-types.ts +7 -7
- package/templates/starter/packages/cucumber-runtime/src/paths.ts +22 -5
- package/templates/starter/packages/cucumber-runtime/src/random-data.util.ts +35 -35
- package/templates/starter/packages/cucumber-runtime/src/types.ts +13 -13
- package/templates/starter/packages/cucumber-runtime/src/world.ts +44 -44
- package/templates/starter/packages/cucumber-runtime/tsconfig.json +11 -11
- package/templates/starter/packages/locator-picker-companion/dist/cli.js +1 -1
- package/templates/starter/packages/locator-picker-companion/dist/index.d.ts +3 -3
- package/templates/starter/packages/locator-picker-companion/dist/index.js +3 -3
- package/templates/starter/packages/locator-picker-companion/dist/injected-picker-script.js +13 -3
- package/templates/starter/packages/locator-picker-companion/dist/selector-generator.d.ts +6 -3
- package/templates/starter/packages/locator-picker-companion/dist/selector-generator.js +233 -229
- package/templates/starter/packages/locator-picker-companion/package.json +2 -1
- package/templates/starter/packages/locator-picker-companion/src/cli.ts +1 -7
- package/templates/starter/packages/locator-picker-companion/src/injected-picker-script.ts +26 -5
- package/templates/starter/packages/locator-picker-companion/src/launcher.ts +1 -3
- package/templates/starter/packages/locator-picker-companion/src/session-file.ts +4 -15
- package/templates/starter/packages/locator-picker-companion/src/types.ts +1 -8
- package/templates/starter/playwright.config.ts +46 -0
- package/templates/starter/postcss.config.mjs +8 -8
- package/templates/starter/prisma/dev.db +0 -0
- package/templates/starter/prisma/migrations/20251104113456_add_type_for_template_step_groups/migration.sql +16 -16
- package/templates/starter/prisma/migrations/20251104170946_add_tags_to_test_suite_and_test_case/migration.sql +27 -27
- package/templates/starter/prisma/migrations/20251112190024_add_cascade_delete_to_test_run_test_case/migration.sql +17 -17
- package/templates/starter/prisma/migrations/20251113181100_add_test_run_log/migration.sql +12 -12
- package/templates/starter/prisma/migrations/20251119191838_add_tag_type/migration.sql +28 -28
- package/templates/starter/prisma/migrations/20251121164059_add_conflict_resolution/migration.sql +12 -12
- package/templates/starter/prisma/migrations/20251223183400_add_report_model_to_db_schema/migration.sql +10 -10
- package/templates/starter/prisma/migrations/20251223183637_add_report_test_case_entity_for_storing_test_results_for_individual_test_cases/migration.sql +10 -10
- package/templates/starter/prisma/migrations/20251224083549_add_comprehensive_report_storage/migration.sql +108 -108
- package/templates/starter/prisma/migrations/20251229194422_migrate_duration_to_string/migration.sql +55 -55
- package/templates/starter/prisma/migrations/20251230124637_add_unique_constraint_to_test_run_name/migration.sql +27 -27
- package/templates/starter/prisma/migrations/20260115094436_add_dashboard_metrics/migration.sql +59 -59
- package/templates/starter/prisma/migrations/20260127172022_add_cascade_delete_to_step_parameters/migration.sql +34 -34
- package/templates/starter/prisma/migrations/20260313093000_add_report_step_screenshot_path/migration.sql +1 -1
- package/templates/starter/scripts/configure-git-line-endings.mjs +91 -0
- package/templates/starter/scripts/install-template-step.ts +5 -1
- package/templates/starter/scripts/lib/step-matcher.test.ts +3 -3
- package/templates/starter/scripts/lib/step-matcher.ts +5 -1
- package/templates/starter/scripts/lib/template-step-installer.test.ts +4 -2
- package/templates/starter/scripts/lib/template-step-installer.ts +16 -4
- package/templates/starter/scripts/lib/template-step-registry.test.ts +1 -1
- package/templates/starter/scripts/lib/template-step-registry.ts +4 -1
- package/templates/starter/scripts/run-fallow-commit.mjs +4 -6
- package/templates/starter/scripts/setup-env.ts +0 -0
- package/templates/starter/scripts/sync-all.ts +7 -6
- package/templates/starter/scripts/sync-appraise-base-template.ts +84 -77
- package/templates/starter/scripts/sync-environments.ts +47 -44
- package/templates/starter/scripts/sync-locator-groups.ts +67 -76
- package/templates/starter/scripts/sync-locators.ts +50 -53
- package/templates/starter/scripts/sync-modules.ts +42 -42
- package/templates/starter/scripts/sync-tags.ts +51 -51
- package/templates/starter/scripts/sync-template-step-groups.ts +34 -32
- package/templates/starter/scripts/sync-template-steps.ts +97 -97
- package/templates/starter/scripts/sync-test-cases.ts +125 -84
- package/templates/starter/scripts/sync-test-suites.ts +85 -80
- package/templates/starter/src/actions/server-action-boundary.test.ts +1 -7
- package/templates/starter/src/actions/settings/sync-actions.ts +3 -1
- package/templates/starter/src/actions/tags/tag-actions.ts +1 -7
- package/templates/starter/src/actions/template-test-case/template-test-case-actions.ts +3 -1
- package/templates/starter/src/app/(base)/environments/create/page.tsx +28 -28
- package/templates/starter/src/app/(base)/environments/environment-form.tsx +3 -2
- package/templates/starter/src/app/(base)/environments/environment-helpers.ts +4 -1
- package/templates/starter/src/app/(base)/layout.tsx +10 -10
- package/templates/starter/src/app/(base)/locator-groups/locator-group-form.tsx +5 -3
- package/templates/starter/src/app/(base)/locator-groups/locator-group-table-columns.tsx +77 -77
- package/templates/starter/src/app/(base)/locator-groups/locator-group-table.tsx +28 -28
- package/templates/starter/src/app/(base)/locator-groups/modify/[id]/page.tsx +46 -46
- package/templates/starter/src/app/(base)/locator-groups/page.tsx +9 -19
- package/templates/starter/src/app/(base)/locators/create/create-locator-workspace-helpers.test.ts +3 -6
- package/templates/starter/src/app/(base)/locators/create/create-locator-workspace-response.ts +22 -5
- package/templates/starter/src/app/(base)/locators/create/create-locator-workspace-state.ts +5 -1
- package/templates/starter/src/app/(base)/locators/create/use-locator-workspace.ts +7 -2
- package/templates/starter/src/app/(base)/locators/locator-file-sync.ts +1 -5
- package/templates/starter/src/app/(base)/locators/locator-helpers.ts +2 -12
- package/templates/starter/src/app/(base)/locators/locator-table-columns.tsx +59 -60
- package/templates/starter/src/app/(base)/modules/module-form.tsx +3 -1
- package/templates/starter/src/app/(base)/reports/overview-chart.tsx +49 -49
- package/templates/starter/src/app/(base)/reports/test-cases/test-cases-metric-table-columns.tsx +114 -115
- package/templates/starter/src/app/(base)/reports/test-cases/test-cases-metric-table.tsx +27 -27
- package/templates/starter/src/app/(base)/reports/test-suites/test-suites-metric-table-columns.tsx +80 -79
- package/templates/starter/src/app/(base)/reports/test-suites/test-suites-metric-table.tsx +29 -27
- package/templates/starter/src/app/(base)/settings/settings-sync-panel-helpers.test.tsx +4 -6
- package/templates/starter/src/app/(base)/settings/settings-sync-panel.tsx +22 -23
- package/templates/starter/src/app/(base)/tags/tag-form.test.tsx +2 -10
- package/templates/starter/src/app/(base)/tags/tag-form.tsx +5 -3
- package/templates/starter/src/app/(base)/tags/tag-table-columns.tsx +63 -63
- package/templates/starter/src/app/(base)/tags/tag-table.tsx +29 -29
- package/templates/starter/src/app/(base)/template-step-groups/create/page.tsx +28 -28
- package/templates/starter/src/app/(base)/template-step-groups/template-step-group-form.tsx +3 -1
- package/templates/starter/src/app/(base)/template-step-groups/template-step-group-helpers.ts +4 -1
- package/templates/starter/src/app/(base)/template-steps/paramChip.tsx +6 -10
- package/templates/starter/src/app/(base)/template-steps/template-step-form-helpers.ts +4 -2
- package/templates/starter/src/app/(base)/template-steps/template-step-helpers.test.ts +19 -1
- package/templates/starter/src/app/(base)/template-steps/template-step-helpers.ts +1 -5
- package/templates/starter/src/app/(base)/template-steps/template-step-row-guards.ts +1 -5
- package/templates/starter/src/app/(base)/template-steps/template-step-types.ts +1 -5
- package/templates/starter/src/app/(base)/template-test-cases/create-template-test-case-page-data.test.ts +4 -1
- package/templates/starter/src/app/(base)/template-test-cases/create-template-test-case-page-data.ts +1 -2
- package/templates/starter/src/app/(base)/template-test-cases/modify/[id]/page.tsx +1 -0
- package/templates/starter/src/app/(base)/template-test-cases/template-test-case-flow.test.tsx +0 -1
- package/templates/starter/src/app/(base)/template-test-cases/template-test-case-form.tsx +3 -1
- package/templates/starter/src/app/(base)/template-test-cases/template-test-case-table-columns.tsx +76 -76
- package/templates/starter/src/app/(base)/template-test-cases/template-test-case-table.tsx +32 -32
- package/templates/starter/src/app/(base)/test-cases/create/page.tsx +1 -5
- package/templates/starter/src/app/(base)/test-cases/create-from-template/create-from-template-selection-helpers.ts +1 -4
- package/templates/starter/src/app/(base)/test-cases/create-from-template/page.test.tsx +2 -2
- package/templates/starter/src/app/(base)/test-cases/inline-tag-creation-dialog.tsx +1 -7
- package/templates/starter/src/app/(base)/test-cases/inline-test-suite-creation-dialog.tsx +1 -7
- package/templates/starter/src/app/(base)/test-cases/modify/[id]/page.tsx +1 -5
- package/templates/starter/src/app/(base)/test-cases/test-case-form.tsx +63 -78
- package/templates/starter/src/app/(base)/test-cases/test-case-route-helpers.test.ts +2 -7
- package/templates/starter/src/app/(base)/test-suites/editable-test-suite-helpers.ts +1 -6
- package/templates/starter/src/app/(base)/test-suites/test-suite-form.test.tsx +2 -10
- package/templates/starter/src/app/(dashboard-components)/data-card-grid.tsx +10 -10
- package/templates/starter/src/app/api/test-runs/[runId]/download/route.ts +1 -4
- package/templates/starter/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.test.ts +18 -9
- package/templates/starter/src/assets/icons/empty-tube.tsx +23 -23
- package/templates/starter/src/assets/icons/tube-plus.tsx +29 -29
- package/templates/starter/src/components/data-visualization/info-card.tsx +56 -70
- package/templates/starter/src/components/data-visualization/info-grid.tsx +22 -22
- package/templates/starter/src/components/diagram/add-node-prompt-node.tsx +1 -1
- package/templates/starter/src/components/diagram/dynamic-parameters-helpers.ts +4 -3
- package/templates/starter/src/components/diagram/dynamic-parameters.test.tsx +4 -1
- package/templates/starter/src/components/diagram/dynamic-parameters.tsx +0 -1
- package/templates/starter/src/components/diagram/flow-diagram-block-dialog.test.tsx +26 -0
- package/templates/starter/src/components/diagram/flow-diagram-block-dialog.tsx +3 -1
- package/templates/starter/src/components/diagram/flow-diagram-connection-guards.ts +24 -6
- package/templates/starter/src/components/diagram/flow-diagram-helpers.test.ts +27 -0
- package/templates/starter/src/components/diagram/flow-diagram-node-search.tsx +73 -66
- package/templates/starter/src/components/diagram/flow-diagram-toolbar.tsx +35 -3
- package/templates/starter/src/components/diagram/flow-diagram-view.tsx +1 -7
- package/templates/starter/src/components/diagram/flow-diagram.test.tsx +225 -0
- package/templates/starter/src/components/diagram/flow-node-data-helpers.ts +1 -1
- package/templates/starter/src/components/diagram/node-form-fields-content.tsx +9 -2
- package/templates/starter/src/components/diagram/node-form-helpers.test.ts +3 -1
- package/templates/starter/src/components/diagram/node-form-helpers.ts +1 -4
- package/templates/starter/src/components/diagram/node-form-template-step-selection.ts +1 -4
- package/templates/starter/src/components/diagram/node-form.test.tsx +25 -0
- package/templates/starter/src/components/diagram/node-form.tsx +2 -12
- package/templates/starter/src/components/diagram/options-header-node.test.tsx +4 -1
- package/templates/starter/src/components/diagram/options-header-node.tsx +140 -130
- package/templates/starter/src/components/diagram/use-flow-diagram-search.ts +2 -0
- package/templates/starter/src/components/diagram/use-flow-diagram.ts +93 -1
- package/templates/starter/src/components/form/error-message.tsx +7 -7
- package/templates/starter/src/components/loading-skeleton/form/button-skeleton.tsx +8 -8
- package/templates/starter/src/components/loading-skeleton/form/text-input-skeleton.tsx +8 -8
- package/templates/starter/src/components/loading-skeleton/visualization/table-skeleton.tsx +14 -14
- package/templates/starter/src/components/navigation/entity-search-command.tsx +3 -9
- package/templates/starter/src/components/navigation/nav-link.tsx +60 -60
- package/templates/starter/src/components/test-case/test-case-form-helpers.test.ts +1 -5
- package/templates/starter/src/components/test-case/test-case-form-helpers.ts +1 -5
- package/templates/starter/src/components/test-case/test-case-picker-helpers.ts +8 -7
- package/templates/starter/src/components/test-case/test-case-picker.tsx +2 -6
- package/templates/starter/src/components/test-run/log-viewer.test.tsx +25 -0
- package/templates/starter/src/components/test-run/log-viewer.tsx +2 -2
- package/templates/starter/src/components/test-run/test-run-details-guards.ts +10 -1
- package/templates/starter/src/components/test-run/test-run-details.test.tsx +9 -19
- package/templates/starter/src/components/test-run/use-log-viewer.ts +2 -8
- package/templates/starter/src/components/test-run/use-test-run-header.ts +1 -4
- package/templates/starter/src/components/test-suite/test-suite-picker.tsx +1 -1
- package/templates/starter/src/components/theme/theme-provider.tsx +7 -1
- package/templates/starter/src/components/typography/page-header-subtitle.tsx +7 -7
- package/templates/starter/src/components/typography/page-header.tsx +7 -7
- package/templates/starter/src/components/ui/chart.tsx +2 -8
- package/templates/starter/src/components/ui/command.tsx +2 -5
- package/templates/starter/src/components/ui/data-table-column-header.tsx +3 -3
- package/templates/starter/src/components/ui/data-table.test.tsx +1 -8
- package/templates/starter/src/components/ui/dialog.tsx +1 -4
- package/templates/starter/src/components/ui/select.tsx +2 -2
- package/templates/starter/src/components/ui/separator.tsx +5 -1
- package/templates/starter/src/components/ui/skeleton.tsx +7 -7
- package/templates/starter/src/components/ui/table.tsx +1 -1
- package/templates/starter/src/components/ui/toaster.tsx +26 -26
- package/templates/starter/src/components/ui/tooltip.tsx +1 -1
- package/templates/starter/src/constants/form-opts/locator-group-form-opts.ts +1 -1
- package/templates/starter/src/lib/appraise-test-case-metadata.test.ts +78 -0
- package/templates/starter/src/lib/appraise-test-case-metadata.ts +220 -0
- package/templates/starter/src/lib/automation/automation-path-roots.test.ts +14 -0
- package/templates/starter/src/lib/automation/automation-path-roots.ts +10 -2
- package/templates/starter/src/lib/database-sync.ts +166 -15
- package/templates/starter/src/lib/executor/local-executor-adapter.ts +6 -2
- package/templates/starter/src/lib/feature-file-generator.ts +54 -10
- package/templates/starter/src/lib/gherkin-parser.test.ts +52 -0
- package/templates/starter/src/lib/gherkin-parser.ts +39 -1
- package/templates/starter/src/lib/locator-group-file-utils.ts +5 -1
- package/templates/starter/src/lib/locator-picker/session-manager.ts +1 -2
- package/templates/starter/src/lib/metrics/metric-calculator.test.ts +105 -6
- package/templates/starter/src/lib/metrics/metric-calculator.ts +39 -40
- package/templates/starter/src/lib/sync/projected-feature-utils.ts +5 -1
- package/templates/starter/src/lib/sync/sync-executor.ts +1 -4
- package/templates/starter/src/lib/sync/sync-pending-counts.test.ts +316 -7
- package/templates/starter/src/lib/sync/sync-pending-counts.ts +189 -26
- package/templates/starter/src/lib/template-automation-paths.ts +1 -1
- package/templates/starter/src/lib/template-sync-utils.d.ts +14 -7
- package/templates/starter/src/lib/test-case-utils.ts +6 -6
- package/templates/starter/src/lib/test-run/log-formatter.ts +82 -83
- package/templates/starter/src/lib/test-run/report-parser.ts +352 -352
- package/templates/starter/src/lib/transformers/gherkin-converter.ts +42 -42
- package/templates/starter/src/lib/transformers/key-to-icon-transformer.tsx +95 -95
- package/templates/starter/src/lib/utils/node-param-validation.ts +81 -81
- package/templates/starter/src/lib/utils/template-step-file-generator.ts +5 -3
- package/templates/starter/src/lib/utils/template-step-file-manager-intelligent.ts +11 -1
- package/templates/starter/src/services/dashboard/dashboard-service.test.ts +28 -1
- package/templates/starter/src/services/dashboard/dashboard-service.ts +2 -0
- package/templates/starter/src/services/locator/locator-service.test.ts +1 -3
- package/templates/starter/src/services/locator/locator-service.ts +3 -1
- package/templates/starter/src/services/locator/locator-sync-utils.test.ts +1 -4
- package/templates/starter/src/services/module/module-service.ts +1 -4
- package/templates/starter/src/services/report/report-service.test.ts +70 -6
- package/templates/starter/src/services/report/report-service.ts +52 -9
- package/templates/starter/src/services/shared/errors.ts +2 -4
- package/templates/starter/src/services/template-step/template-step-service.ts +3 -1
- package/templates/starter/src/services/template-step-group/template-step-group-service.ts +3 -1
- package/templates/starter/src/services/test-case/test-case-service.ts +0 -5
- package/templates/starter/src/services/test-run/test-run-service.test.ts +13 -6
- package/templates/starter/src/services/test-run/test-run-service.ts +53 -8
- package/templates/starter/src/services/test-suite/test-suite-service.test.ts +1 -5
- package/templates/starter/src/services/test-suite/test-suite-service.ts +2 -4
- package/templates/starter/src/types/form/actionHandler.ts +1 -5
- package/templates/starter/tsconfig.json +8 -8
- package/dist/cli.e2e.test.d.ts +0 -2
- package/dist/cli.e2e.test.d.ts.map +0 -1
- package/dist/cli.e2e.test.js +0 -73
- package/dist/cli.e2e.test.js.map +0 -1
- package/dist/config.test.d.ts +0 -2
- package/dist/config.test.d.ts.map +0 -1
- package/dist/config.test.js +0 -65
- package/dist/config.test.js.map +0 -1
- package/dist/copy-template.test.d.ts +0 -2
- package/dist/copy-template.test.d.ts.map +0 -1
- package/dist/copy-template.test.js +0 -71
- package/dist/copy-template.test.js.map +0 -1
- package/dist/download-repo.test.d.ts +0 -2
- package/dist/download-repo.test.d.ts.map +0 -1
- package/dist/download-repo.test.js +0 -14
- package/dist/download-repo.test.js.map +0 -1
- package/dist/install.test.d.ts +0 -2
- package/dist/install.test.d.ts.map +0 -1
- package/dist/install.test.js +0 -119
- package/dist/install.test.js.map +0 -1
- package/dist/prompts.test.d.ts +0 -2
- package/dist/prompts.test.d.ts.map +0 -1
- package/dist/prompts.test.js +0 -58
- package/dist/prompts.test.js.map +0 -1
- package/templates/default/next-env.d.ts +0 -6
- package/templates/default/packages/locator-picker-companion/dist/cli.d.ts +0 -1
- package/templates/default/packages/locator-picker-companion/dist/cli.js +0 -302
- package/templates/default/packages/locator-picker-companion/dist/index.d.ts +0 -3
- package/templates/default/packages/locator-picker-companion/dist/index.js +0 -3
- package/templates/default/packages/locator-picker-companion/dist/injected-picker-script.d.ts +0 -1
- package/templates/default/packages/locator-picker-companion/dist/injected-picker-script.js +0 -615
- package/templates/default/packages/locator-picker-companion/dist/launcher.d.ts +0 -11
- package/templates/default/packages/locator-picker-companion/dist/launcher.js +0 -59
- package/templates/default/packages/locator-picker-companion/dist/selector-generator.d.ts +0 -3
- package/templates/default/packages/locator-picker-companion/dist/selector-generator.js +0 -257
- package/templates/default/packages/locator-picker-companion/dist/session-file.d.ts +0 -22
- package/templates/default/packages/locator-picker-companion/dist/session-file.js +0 -150
- package/templates/default/packages/locator-picker-companion/dist/types.d.ts +0 -31
- package/templates/default/packages/locator-picker-companion/dist/types.js +0 -1
- package/templates/default/prisma/dev.db +0 -0
|
@@ -27,9 +27,11 @@ import { getTagTypeFromName } from '@/lib/tag-identifiers'
|
|
|
27
27
|
import { extractModulePathFromAutomationFile, getAutomationLocatorMapPath } from '@/lib/template-sync-utils'
|
|
28
28
|
import {
|
|
29
29
|
determineProjectedStepIcon,
|
|
30
|
+
generateProjectedGherkinSteps,
|
|
30
31
|
getTestSuiteSyncIdentity,
|
|
31
32
|
normalizeProjectedDbTestCaseSteps,
|
|
32
33
|
} from '@/lib/sync/projected-feature-utils'
|
|
34
|
+
import type { AppraiseTestCaseMetadataFlowBlock, AppraiseTestCaseMetadataNode } from '@/lib/appraise-test-case-metadata'
|
|
33
35
|
import {
|
|
34
36
|
parseGroupJSDocLenient as parseGroupJSDoc,
|
|
35
37
|
parseStepJSDocLenient as parseStepJSDoc,
|
|
@@ -116,6 +118,13 @@ type TestCaseFromFs = {
|
|
|
116
118
|
modulePath: string
|
|
117
119
|
filterTags: string[]
|
|
118
120
|
steps: ParsedStep[]
|
|
121
|
+
hasAppraiseMetadata?: boolean
|
|
122
|
+
nodes: AppraiseTestCaseMetadataNode[]
|
|
123
|
+
flowBlocks: AppraiseTestCaseMetadataFlowBlock[]
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
type CollapsedTestCaseFromFs = TestCaseFromFs & {
|
|
127
|
+
expectedSuiteIdentities: Set<string>
|
|
119
128
|
}
|
|
120
129
|
|
|
121
130
|
type ParameterMatch = {
|
|
@@ -682,15 +691,18 @@ async function buildFilesystemSnapshot(baseDir: string): Promise<FilesystemSnaps
|
|
|
682
691
|
continue
|
|
683
692
|
}
|
|
684
693
|
|
|
685
|
-
const
|
|
694
|
+
const parsedTitle = parseScenarioTitle(scenario.name, scenario.description)
|
|
686
695
|
testCases.push({
|
|
687
696
|
identifierTag: normalizeTagExpression(identifierTag),
|
|
688
|
-
title,
|
|
689
|
-
description,
|
|
697
|
+
title: scenario.appraiseMetadata?.title ?? parsedTitle.title,
|
|
698
|
+
description: scenario.appraiseMetadata?.description ?? parsedTitle.description,
|
|
690
699
|
testSuiteName,
|
|
691
700
|
modulePath,
|
|
692
701
|
filterTags: flattenedTags.filter(tag => normalizeTagExpression(tag) !== normalizeTagExpression(identifierTag)),
|
|
693
702
|
steps: scenario.steps,
|
|
703
|
+
hasAppraiseMetadata: scenario.appraiseMetadata != null,
|
|
704
|
+
nodes: scenario.appraiseMetadata?.nodes ?? [],
|
|
705
|
+
flowBlocks: scenario.appraiseMetadata?.flowBlocks ?? [],
|
|
694
706
|
})
|
|
695
707
|
}
|
|
696
708
|
}
|
|
@@ -739,14 +751,21 @@ export function countModuleMismatches(
|
|
|
739
751
|
return count
|
|
740
752
|
}
|
|
741
753
|
|
|
742
|
-
function countEnvironmentMismatches(
|
|
754
|
+
export function countEnvironmentMismatches(
|
|
743
755
|
filesystemEnvironments: EnvironmentData[],
|
|
744
|
-
dbEnvironments: Array<{
|
|
756
|
+
dbEnvironments: Array<{
|
|
757
|
+
name: string
|
|
758
|
+
baseUrl: string
|
|
759
|
+
apiBaseUrl: string | null
|
|
760
|
+
username: string | null
|
|
761
|
+
password: string | null
|
|
762
|
+
_count?: { testRuns: number }
|
|
763
|
+
}>,
|
|
745
764
|
): number {
|
|
746
765
|
const fsByNormalizedName = new Map(
|
|
747
766
|
filesystemEnvironments.map(environment => [getEnvironmentIdentityKey(environment.name), environment]),
|
|
748
767
|
)
|
|
749
|
-
const dbByNormalizedName = new Map<string,
|
|
768
|
+
const dbByNormalizedName = new Map<string, (typeof dbEnvironments)[number]>()
|
|
750
769
|
|
|
751
770
|
for (const environment of dbEnvironments) {
|
|
752
771
|
const normalizedName = getEnvironmentIdentityKey(environment.name)
|
|
@@ -760,11 +779,22 @@ function countEnvironmentMismatches(
|
|
|
760
779
|
const existing = dbByNormalizedName.get(getEnvironmentIdentityKey(environment.name))
|
|
761
780
|
if (!existing) {
|
|
762
781
|
count++
|
|
782
|
+
continue
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
if (
|
|
786
|
+
existing.baseUrl !== environment.baseUrl ||
|
|
787
|
+
(existing.apiBaseUrl ?? null) !== environment.apiBaseUrl ||
|
|
788
|
+
(existing.username ?? null) !== environment.username ||
|
|
789
|
+
(existing.password ?? null) !== environment.password
|
|
790
|
+
) {
|
|
791
|
+
count++
|
|
763
792
|
}
|
|
764
793
|
}
|
|
765
794
|
|
|
766
795
|
for (const environment of dbEnvironments) {
|
|
767
|
-
|
|
796
|
+
const canDelete = (environment._count?.testRuns ?? 0) === 0
|
|
797
|
+
if (canDelete && !fsByNormalizedName.has(getEnvironmentIdentityKey(environment.name))) {
|
|
768
798
|
count++
|
|
769
799
|
}
|
|
770
800
|
}
|
|
@@ -822,10 +852,15 @@ export function countTemplateStepMismatches(
|
|
|
822
852
|
parameters: Array<{ name: string; order: number; type: StepParameterType }>
|
|
823
853
|
}>,
|
|
824
854
|
): number {
|
|
855
|
+
const filesystemStepsBySignature = new Map<string, TemplateStepFromFs>()
|
|
825
856
|
const dbBySignature = groupRecordsByKey(dbSteps, step => step.signature)
|
|
826
857
|
let count = 0
|
|
827
858
|
|
|
828
859
|
for (const item of filesystemSteps) {
|
|
860
|
+
filesystemStepsBySignature.set(item.step.signature, item)
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
for (const item of filesystemStepsBySignature.values()) {
|
|
829
864
|
const expectedType =
|
|
830
865
|
item.groupType === TemplateStepGroupType.ACTION ? TemplateStepType.ACTION : TemplateStepType.ASSERTION
|
|
831
866
|
|
|
@@ -849,16 +884,20 @@ export function countTemplateStepMismatches(
|
|
|
849
884
|
return count
|
|
850
885
|
}
|
|
851
886
|
|
|
852
|
-
function countLocatorGroupMismatches(
|
|
887
|
+
export function countLocatorGroupMismatches(
|
|
853
888
|
filesystemGroups: LocatorGroupFromFs[],
|
|
854
889
|
dbGroups: Array<{ name: string; route: string; moduleId: string }>,
|
|
855
890
|
modulePathMap: Map<string, string>,
|
|
856
891
|
): number {
|
|
857
|
-
const fsByName = new Map
|
|
892
|
+
const fsByName = new Map<string, LocatorGroupFromFs>()
|
|
858
893
|
const dbByName = new Map(dbGroups.map(group => [group.name, group]))
|
|
859
894
|
let count = 0
|
|
860
895
|
|
|
861
896
|
for (const group of filesystemGroups) {
|
|
897
|
+
fsByName.set(group.name, group)
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
for (const group of fsByName.values()) {
|
|
862
901
|
const existing = dbByName.get(group.name)
|
|
863
902
|
if (!existing) {
|
|
864
903
|
count++
|
|
@@ -932,10 +971,15 @@ export function countTestSuiteMismatches(
|
|
|
932
971
|
const dbByKey = groupRecordsByKey(dbSuites, suite =>
|
|
933
972
|
getTestSuiteSyncIdentity(suite.name, modulePathMap.get(suite.moduleId) ?? '/'),
|
|
934
973
|
)
|
|
974
|
+
const filesystemSuitesByKey = new Map<string, TestSuiteFromFs>()
|
|
935
975
|
let count = 0
|
|
936
976
|
|
|
937
977
|
for (const suite of filesystemSuites) {
|
|
938
978
|
const suiteKey = getTestSuiteSyncIdentity(suite.name, suite.modulePath)
|
|
979
|
+
filesystemSuitesByKey.set(suiteKey, suite)
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
for (const [suiteKey, suite] of filesystemSuitesByKey) {
|
|
939
983
|
const fsTagExpressions = suite.tags.map(normalizeTagExpression)
|
|
940
984
|
const hasMatch = (dbByKey.get(suiteKey) ?? []).some(existing => {
|
|
941
985
|
const dbTagExpressions = existing.tags.map(tag => normalizeTagExpression(tag.tagExpression))
|
|
@@ -951,11 +995,41 @@ export function countTestSuiteMismatches(
|
|
|
951
995
|
return count
|
|
952
996
|
}
|
|
953
997
|
|
|
998
|
+
type ProjectedTestCaseStep = {
|
|
999
|
+
order: number
|
|
1000
|
+
gherkinStep: string
|
|
1001
|
+
label: string
|
|
1002
|
+
icon: TemplateStepIcon
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
function normalizeProjectedFsTestCaseSteps(stepsFromFs: ParsedStep[]): ProjectedTestCaseStep[] {
|
|
1006
|
+
const storedSteps = stepsFromFs.map(step => ({
|
|
1007
|
+
order: step.order,
|
|
1008
|
+
gherkinStep: `${step.keyword} ${step.text}`,
|
|
1009
|
+
}))
|
|
1010
|
+
const projectedGherkinSteps = generateProjectedGherkinSteps(storedSteps)
|
|
1011
|
+
|
|
1012
|
+
return stepsFromFs.map((step, index) => {
|
|
1013
|
+
const gherkinStep = projectedGherkinSteps[index] ?? ''
|
|
1014
|
+
const [keyword = '', ...textParts] = gherkinStep.split(' ')
|
|
1015
|
+
const label = textParts.join(' ')
|
|
1016
|
+
|
|
1017
|
+
return {
|
|
1018
|
+
order: step.order,
|
|
1019
|
+
gherkinStep,
|
|
1020
|
+
label,
|
|
1021
|
+
icon: determineProjectedStepIcon(keyword),
|
|
1022
|
+
}
|
|
1023
|
+
})
|
|
1024
|
+
}
|
|
1025
|
+
|
|
954
1026
|
function hasProjectedTestCaseStepMismatch(
|
|
955
1027
|
stepsFromFs: ParsedStep[],
|
|
1028
|
+
nodesFromFs: AppraiseTestCaseMetadataNode[] = [],
|
|
956
1029
|
dbSteps: Array<{
|
|
957
1030
|
order: number
|
|
958
1031
|
gherkinStep: string
|
|
1032
|
+
flowNodeId: string | null
|
|
959
1033
|
label: string
|
|
960
1034
|
icon: TemplateStepIcon
|
|
961
1035
|
TemplateStep: { signature: string } | null
|
|
@@ -967,23 +1041,26 @@ function hasProjectedTestCaseStepMismatch(
|
|
|
967
1041
|
}>,
|
|
968
1042
|
): boolean {
|
|
969
1043
|
const projectedDbSteps = normalizeProjectedDbTestCaseSteps(dbSteps)
|
|
1044
|
+
const projectedFsSteps = normalizeProjectedFsTestCaseSteps(stepsFromFs)
|
|
970
1045
|
const dbStepsByOrder = new Map(projectedDbSteps.map(step => [step.order, step]))
|
|
1046
|
+
const fsStepsByOrder = new Map(stepsFromFs.map(step => [step.order, step]))
|
|
1047
|
+
const nodesByOrder = new Map(nodesFromFs.map(node => [node.order, node]))
|
|
971
1048
|
|
|
972
|
-
for (const
|
|
973
|
-
const existing = dbStepsByOrder.get(
|
|
974
|
-
const
|
|
1049
|
+
for (const projectedFsStep of projectedFsSteps) {
|
|
1050
|
+
const existing = dbStepsByOrder.get(projectedFsStep.order)
|
|
1051
|
+
const sourceStep = fsStepsByOrder.get(projectedFsStep.order)
|
|
1052
|
+
const metadataNode = nodesByOrder.get(projectedFsStep.order)
|
|
1053
|
+
const matchedTemplateStep = sourceStep ? matchGherkinStepToTemplateStep(sourceStep, dbTemplateSteps) : null
|
|
975
1054
|
|
|
976
1055
|
if (!existing || !matchedTemplateStep) {
|
|
977
1056
|
return true
|
|
978
1057
|
}
|
|
979
1058
|
|
|
980
|
-
const expectedIcon = determineProjectedStepIcon(step.keyword)
|
|
981
|
-
const expectedGherkinStep = `${step.keyword} ${step.text}`
|
|
982
|
-
|
|
983
1059
|
if (
|
|
984
|
-
existing.gherkinStep !==
|
|
985
|
-
existing.
|
|
986
|
-
existing.
|
|
1060
|
+
existing.gherkinStep !== projectedFsStep.gherkinStep ||
|
|
1061
|
+
existing.flowNodeId !== (metadataNode?.nodeId ?? existing.flowNodeId) ||
|
|
1062
|
+
existing.label !== (metadataNode?.label ?? projectedFsStep.label) ||
|
|
1063
|
+
existing.icon !== projectedFsStep.icon ||
|
|
987
1064
|
existing.templateStepSignature !== matchedTemplateStep.signature ||
|
|
988
1065
|
!sameResolvedParameters(existing.parameters, matchedTemplateStep.parameters)
|
|
989
1066
|
) {
|
|
@@ -995,6 +1072,39 @@ function hasProjectedTestCaseStepMismatch(
|
|
|
995
1072
|
return projectedDbSteps.some(step => !fsOrders.has(step.order))
|
|
996
1073
|
}
|
|
997
1074
|
|
|
1075
|
+
function hasFlowBlockMismatch(
|
|
1076
|
+
flowBlocksFromFs: AppraiseTestCaseMetadataFlowBlock[] = [],
|
|
1077
|
+
hasAppraiseMetadata: boolean | undefined,
|
|
1078
|
+
dbFlowBlocks: Array<{
|
|
1079
|
+
id: string
|
|
1080
|
+
name: string
|
|
1081
|
+
order: number
|
|
1082
|
+
nodes: Array<{ flowNodeId: string }>
|
|
1083
|
+
}>,
|
|
1084
|
+
): boolean {
|
|
1085
|
+
if (!hasAppraiseMetadata) {
|
|
1086
|
+
return false
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
if (flowBlocksFromFs.length !== dbFlowBlocks.length) {
|
|
1090
|
+
return true
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
const dbById = new Map(dbFlowBlocks.map(block => [block.id, block]))
|
|
1094
|
+
|
|
1095
|
+
return flowBlocksFromFs.some(block => {
|
|
1096
|
+
const existing = dbById.get(block.id)
|
|
1097
|
+
if (!existing || existing.name !== block.name || existing.order !== block.order) {
|
|
1098
|
+
return true
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
return !sameStringSet(
|
|
1102
|
+
existing.nodes.map(node => node.flowNodeId),
|
|
1103
|
+
block.nodeIds,
|
|
1104
|
+
)
|
|
1105
|
+
})
|
|
1106
|
+
}
|
|
1107
|
+
|
|
998
1108
|
export function countTestCaseMismatches(
|
|
999
1109
|
filesystemTestCases: TestCaseFromFs[],
|
|
1000
1110
|
dbTestCases: Array<{
|
|
@@ -1005,11 +1115,18 @@ export function countTestCaseMismatches(
|
|
|
1005
1115
|
steps: Array<{
|
|
1006
1116
|
order: number
|
|
1007
1117
|
gherkinStep: string
|
|
1118
|
+
flowNodeId: string | null
|
|
1008
1119
|
label: string
|
|
1009
1120
|
icon: TemplateStepIcon
|
|
1010
1121
|
TemplateStep: { signature: string } | null
|
|
1011
1122
|
parameters: Array<{ name: string; value: string; order: number; type: StepParameterType }>
|
|
1012
1123
|
}>
|
|
1124
|
+
flowBlocks: Array<{
|
|
1125
|
+
id: string
|
|
1126
|
+
name: string
|
|
1127
|
+
order: number
|
|
1128
|
+
nodes: Array<{ flowNodeId: string }>
|
|
1129
|
+
}>
|
|
1013
1130
|
}>,
|
|
1014
1131
|
modulePathMap: Map<string, string>,
|
|
1015
1132
|
dbTemplateSteps: Array<{
|
|
@@ -1017,9 +1134,29 @@ export function countTestCaseMismatches(
|
|
|
1017
1134
|
parameters: Array<{ name: string; order: number; type: StepParameterType }>
|
|
1018
1135
|
}>,
|
|
1019
1136
|
): number {
|
|
1137
|
+
const filesystemTestCasesByIdentifier = new Map<string, CollapsedTestCaseFromFs>()
|
|
1020
1138
|
const dbByIdentifier = new Map<string, Array<(typeof dbTestCases)[number]>>()
|
|
1021
1139
|
let count = 0
|
|
1022
1140
|
|
|
1141
|
+
for (const testCase of filesystemTestCases) {
|
|
1142
|
+
const expectedSuiteIdentity = getTestSuiteSyncIdentity(testCase.testSuiteName, testCase.modulePath)
|
|
1143
|
+
const existing = filesystemTestCasesByIdentifier.get(testCase.identifierTag)
|
|
1144
|
+
|
|
1145
|
+
if (existing) {
|
|
1146
|
+
existing.expectedSuiteIdentities.add(expectedSuiteIdentity)
|
|
1147
|
+
filesystemTestCasesByIdentifier.set(testCase.identifierTag, {
|
|
1148
|
+
...testCase,
|
|
1149
|
+
expectedSuiteIdentities: existing.expectedSuiteIdentities,
|
|
1150
|
+
})
|
|
1151
|
+
continue
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
filesystemTestCasesByIdentifier.set(testCase.identifierTag, {
|
|
1155
|
+
...testCase,
|
|
1156
|
+
expectedSuiteIdentities: new Set([expectedSuiteIdentity]),
|
|
1157
|
+
})
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1023
1160
|
for (const testCase of dbTestCases) {
|
|
1024
1161
|
const identifierTag = testCase.tags.find(tag => tag.type === TagType.IDENTIFIER)
|
|
1025
1162
|
if (!identifierTag) {
|
|
@@ -1036,24 +1173,26 @@ export function countTestCaseMismatches(
|
|
|
1036
1173
|
dbByIdentifier.set(normalizedIdentifier, [testCase])
|
|
1037
1174
|
}
|
|
1038
1175
|
|
|
1039
|
-
for (const testCase of
|
|
1040
|
-
const expectedSuiteIdentity = getTestSuiteSyncIdentity(testCase.testSuiteName, testCase.modulePath)
|
|
1176
|
+
for (const testCase of filesystemTestCasesByIdentifier.values()) {
|
|
1041
1177
|
const normalizedFilterTags = testCase.filterTags.map(normalizeTagExpression)
|
|
1042
1178
|
const hasMatch = (dbByIdentifier.get(testCase.identifierTag) ?? []).some(existing => {
|
|
1043
1179
|
const existingFilterTags = existing.tags
|
|
1044
1180
|
.filter(tag => tag.type === TagType.FILTER)
|
|
1045
1181
|
.map(tag => normalizeTagExpression(tag.tagExpression))
|
|
1046
|
-
const
|
|
1047
|
-
suite =>
|
|
1048
|
-
|
|
1182
|
+
const existingSuiteIdentities = new Set(
|
|
1183
|
+
existing.TestSuite.map(suite => getTestSuiteSyncIdentity(suite.name, modulePathMap.get(suite.moduleId) ?? '/')),
|
|
1184
|
+
)
|
|
1185
|
+
const isLinkedToExpectedSuites = Array.from(testCase.expectedSuiteIdentities).every(identity =>
|
|
1186
|
+
existingSuiteIdentities.has(identity),
|
|
1049
1187
|
)
|
|
1050
1188
|
|
|
1051
1189
|
return (
|
|
1052
1190
|
existing.title === testCase.title &&
|
|
1053
1191
|
existing.description === testCase.description &&
|
|
1054
|
-
|
|
1192
|
+
isLinkedToExpectedSuites &&
|
|
1055
1193
|
sameStringSet(existingFilterTags, normalizedFilterTags) &&
|
|
1056
|
-
!hasProjectedTestCaseStepMismatch(testCase.steps, existing.steps, dbTemplateSteps)
|
|
1194
|
+
!hasProjectedTestCaseStepMismatch(testCase.steps, testCase.nodes, existing.steps, dbTemplateSteps) &&
|
|
1195
|
+
!hasFlowBlockMismatch(testCase.flowBlocks, testCase.hasAppraiseMetadata, existing.flowBlocks ?? [])
|
|
1057
1196
|
)
|
|
1058
1197
|
})
|
|
1059
1198
|
|
|
@@ -1093,7 +1232,18 @@ export async function getSyncPendingCounts(): Promise<SyncPendingCounts> {
|
|
|
1093
1232
|
dbTestCases,
|
|
1094
1233
|
] = await Promise.all([
|
|
1095
1234
|
getAllModulesWithPaths(),
|
|
1096
|
-
prisma.environment.findMany({
|
|
1235
|
+
prisma.environment.findMany({
|
|
1236
|
+
select: {
|
|
1237
|
+
name: true,
|
|
1238
|
+
baseUrl: true,
|
|
1239
|
+
apiBaseUrl: true,
|
|
1240
|
+
username: true,
|
|
1241
|
+
password: true,
|
|
1242
|
+
_count: {
|
|
1243
|
+
select: { testRuns: true },
|
|
1244
|
+
},
|
|
1245
|
+
},
|
|
1246
|
+
}),
|
|
1097
1247
|
prisma.tag.findMany({ select: { name: true, type: true } }),
|
|
1098
1248
|
prisma.templateStepGroup.findMany({ select: { name: true, description: true, type: true } }),
|
|
1099
1249
|
prisma.templateStep.findMany({
|
|
@@ -1148,6 +1298,7 @@ export async function getSyncPendingCounts(): Promise<SyncPendingCounts> {
|
|
|
1148
1298
|
select: {
|
|
1149
1299
|
order: true,
|
|
1150
1300
|
gherkinStep: true,
|
|
1301
|
+
flowNodeId: true,
|
|
1151
1302
|
label: true,
|
|
1152
1303
|
icon: true,
|
|
1153
1304
|
TemplateStep: {
|
|
@@ -1159,6 +1310,18 @@ export async function getSyncPendingCounts(): Promise<SyncPendingCounts> {
|
|
|
1159
1310
|
},
|
|
1160
1311
|
},
|
|
1161
1312
|
},
|
|
1313
|
+
flowBlocks: {
|
|
1314
|
+
select: {
|
|
1315
|
+
id: true,
|
|
1316
|
+
name: true,
|
|
1317
|
+
order: true,
|
|
1318
|
+
nodes: {
|
|
1319
|
+
select: {
|
|
1320
|
+
flowNodeId: true,
|
|
1321
|
+
},
|
|
1322
|
+
},
|
|
1323
|
+
},
|
|
1324
|
+
},
|
|
1162
1325
|
},
|
|
1163
1326
|
}),
|
|
1164
1327
|
])
|
|
@@ -13,7 +13,7 @@ function getAutomationLocatorsDir(baseDir: string): string {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export function getAutomationLocatorMapPath(baseDir: string): string {
|
|
16
|
-
return join(baseDir, 'automation', 'mapping', 'locator-map.json')
|
|
16
|
+
return toPosixPath(join(baseDir, 'automation', 'mapping', 'locator-map.json'))
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export function extractModulePathFromAutomationFile(
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
export declare function shouldExcludeTemplatePath(relativePath: string): boolean
|
|
2
|
-
export declare function shouldBackfillLegacyEnvironmentConfig(
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export declare function
|
|
7
|
-
|
|
1
|
+
export declare function shouldExcludeTemplatePath(relativePath: string): boolean
|
|
2
|
+
export declare function shouldBackfillLegacyEnvironmentConfig(
|
|
3
|
+
targetHasEnvironmentsFile: boolean,
|
|
4
|
+
legacyEnvironmentsDirExists: boolean,
|
|
5
|
+
): boolean
|
|
6
|
+
export declare function getAutomationFeaturesDir(baseDir: string): string
|
|
7
|
+
export declare function getAutomationLocatorsDir(baseDir: string): string
|
|
8
|
+
export declare function getAutomationLocatorMapPath(baseDir: string): string
|
|
9
|
+
export declare function extractModulePathFromAutomationFile(
|
|
10
|
+
filePath: string,
|
|
11
|
+
baseDir: string,
|
|
12
|
+
automationSubdir: 'features' | 'locators',
|
|
13
|
+
): string
|
|
14
|
+
//# sourceMappingURL=template-sync-utils.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import crypto from 'crypto'
|
|
2
|
-
|
|
3
|
-
export function generateUniqueTestCaseIdentifier(): string {
|
|
4
|
-
const id = crypto.randomBytes(8).toString('hex')
|
|
5
|
-
return `tc_${id}`
|
|
6
|
-
}
|
|
1
|
+
import crypto from 'crypto'
|
|
2
|
+
|
|
3
|
+
export function generateUniqueTestCaseIdentifier(): string {
|
|
4
|
+
const id = crypto.randomBytes(8).toString('hex')
|
|
5
|
+
return `tc_${id}`
|
|
6
|
+
}
|
|
@@ -1,83 +1,82 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Log formatting utilities for storing and retrieving test run logs
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export interface LogEntry {
|
|
6
|
-
type: 'stdout' | 'stderr' | 'status'
|
|
7
|
-
message: string
|
|
8
|
-
timestamp: Date
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Formats log entries into a single text string for storage in the database
|
|
13
|
-
* Format: [timestamp] [TYPE] message
|
|
14
|
-
*
|
|
15
|
-
* @param logs - Array of log entries to format
|
|
16
|
-
* @returns Formatted log string
|
|
17
|
-
*/
|
|
18
|
-
export function formatLogsForStorage(logs: LogEntry[]): string {
|
|
19
|
-
return logs
|
|
20
|
-
.map(log => {
|
|
21
|
-
const timestamp = log.timestamp.toISOString()
|
|
22
|
-
const type = log.type.toUpperCase()
|
|
23
|
-
// Escape newlines in message to preserve them in the formatted string
|
|
24
|
-
const escapedMessage = log.message.replace(/\n/g, '\\n')
|
|
25
|
-
return `[${timestamp}] [${type}] ${escapedMessage}`
|
|
26
|
-
})
|
|
27
|
-
.join('\n')
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Parses formatted log text back into an array of LogEntry objects
|
|
32
|
-
*
|
|
33
|
-
* @param formattedLogs - Formatted log string from database
|
|
34
|
-
* @returns Array of log entries
|
|
35
|
-
*/
|
|
36
|
-
export function parseLogsFromStorage(formattedLogs: string): LogEntry[] {
|
|
37
|
-
if (!formattedLogs || formattedLogs.trim() === '') {
|
|
38
|
-
return []
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const lines = formattedLogs.split('\n')
|
|
42
|
-
const parsedLogs: LogEntry[] = []
|
|
43
|
-
|
|
44
|
-
for (const line of lines) {
|
|
45
|
-
if (!line.trim()) continue
|
|
46
|
-
|
|
47
|
-
try {
|
|
48
|
-
// Match format: [timestamp] [TYPE] message
|
|
49
|
-
const match = line.match(/^\[([^\]]+)\] \[([^\]]+)\] (.+)$/)
|
|
50
|
-
|
|
51
|
-
if (match) {
|
|
52
|
-
const [, timestampStr, typeStr, message] = match
|
|
53
|
-
const timestamp = new Date(timestampStr)
|
|
54
|
-
const type = typeStr.toLowerCase() as 'stdout' | 'stderr' | 'status'
|
|
55
|
-
|
|
56
|
-
// Unescape newlines in message
|
|
57
|
-
const unescapedMessage = message.replace(/\\n/g, '\n')
|
|
58
|
-
|
|
59
|
-
// Validate type
|
|
60
|
-
if (type === 'stdout' || type === 'stderr' || type === 'status') {
|
|
61
|
-
parsedLogs.push({
|
|
62
|
-
type,
|
|
63
|
-
message: unescapedMessage,
|
|
64
|
-
timestamp: isNaN(timestamp.getTime()) ? new Date() : timestamp,
|
|
65
|
-
})
|
|
66
|
-
}
|
|
67
|
-
} else {
|
|
68
|
-
// Fallback: treat as stdout if format doesn't match
|
|
69
|
-
parsedLogs.push({
|
|
70
|
-
type: 'stdout',
|
|
71
|
-
message: line,
|
|
72
|
-
timestamp: new Date(),
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
} catch (error) {
|
|
76
|
-
// Skip malformed lines
|
|
77
|
-
console.error('[LogFormatter] Error parsing log line:', line, error)
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return parsedLogs
|
|
82
|
-
}
|
|
83
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Log formatting utilities for storing and retrieving test run logs
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface LogEntry {
|
|
6
|
+
type: 'stdout' | 'stderr' | 'status'
|
|
7
|
+
message: string
|
|
8
|
+
timestamp: Date
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Formats log entries into a single text string for storage in the database
|
|
13
|
+
* Format: [timestamp] [TYPE] message
|
|
14
|
+
*
|
|
15
|
+
* @param logs - Array of log entries to format
|
|
16
|
+
* @returns Formatted log string
|
|
17
|
+
*/
|
|
18
|
+
export function formatLogsForStorage(logs: LogEntry[]): string {
|
|
19
|
+
return logs
|
|
20
|
+
.map(log => {
|
|
21
|
+
const timestamp = log.timestamp.toISOString()
|
|
22
|
+
const type = log.type.toUpperCase()
|
|
23
|
+
// Escape newlines in message to preserve them in the formatted string
|
|
24
|
+
const escapedMessage = log.message.replace(/\n/g, '\\n')
|
|
25
|
+
return `[${timestamp}] [${type}] ${escapedMessage}`
|
|
26
|
+
})
|
|
27
|
+
.join('\n')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Parses formatted log text back into an array of LogEntry objects
|
|
32
|
+
*
|
|
33
|
+
* @param formattedLogs - Formatted log string from database
|
|
34
|
+
* @returns Array of log entries
|
|
35
|
+
*/
|
|
36
|
+
export function parseLogsFromStorage(formattedLogs: string): LogEntry[] {
|
|
37
|
+
if (!formattedLogs || formattedLogs.trim() === '') {
|
|
38
|
+
return []
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const lines = formattedLogs.split('\n')
|
|
42
|
+
const parsedLogs: LogEntry[] = []
|
|
43
|
+
|
|
44
|
+
for (const line of lines) {
|
|
45
|
+
if (!line.trim()) continue
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
// Match format: [timestamp] [TYPE] message
|
|
49
|
+
const match = line.match(/^\[([^\]]+)\] \[([^\]]+)\] (.+)$/)
|
|
50
|
+
|
|
51
|
+
if (match) {
|
|
52
|
+
const [, timestampStr, typeStr, message] = match
|
|
53
|
+
const timestamp = new Date(timestampStr)
|
|
54
|
+
const type = typeStr.toLowerCase() as 'stdout' | 'stderr' | 'status'
|
|
55
|
+
|
|
56
|
+
// Unescape newlines in message
|
|
57
|
+
const unescapedMessage = message.replace(/\\n/g, '\n')
|
|
58
|
+
|
|
59
|
+
// Validate type
|
|
60
|
+
if (type === 'stdout' || type === 'stderr' || type === 'status') {
|
|
61
|
+
parsedLogs.push({
|
|
62
|
+
type,
|
|
63
|
+
message: unescapedMessage,
|
|
64
|
+
timestamp: isNaN(timestamp.getTime()) ? new Date() : timestamp,
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
// Fallback: treat as stdout if format doesn't match
|
|
69
|
+
parsedLogs.push({
|
|
70
|
+
type: 'stdout',
|
|
71
|
+
message: line,
|
|
72
|
+
timestamp: new Date(),
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
// Skip malformed lines
|
|
77
|
+
console.error('[LogFormatter] Error parsing log line:', line, error)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return parsedLogs
|
|
82
|
+
}
|