create-appraisejs 0.1.10-alpha.8 → 0.2.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -52
- package/dist/cli.e2e.test.d.ts +2 -0
- package/dist/cli.e2e.test.d.ts.map +1 -0
- package/dist/cli.e2e.test.js +73 -0
- package/dist/cli.e2e.test.js.map +1 -0
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/config.test.js +65 -0
- package/dist/config.test.js.map +1 -0
- package/dist/copy-template.test.d.ts +2 -0
- package/dist/copy-template.test.d.ts.map +1 -0
- package/dist/copy-template.test.js +71 -0
- package/dist/copy-template.test.js.map +1 -0
- package/dist/download-repo.test.d.ts +2 -0
- package/dist/download-repo.test.d.ts.map +1 -0
- package/dist/download-repo.test.js +14 -0
- package/dist/download-repo.test.js.map +1 -0
- package/dist/install.test.d.ts +2 -0
- package/dist/install.test.d.ts.map +1 -0
- package/dist/install.test.js +119 -0
- package/dist/install.test.js.map +1 -0
- package/dist/prepare-template-utils.d.ts.map +1 -1
- package/dist/prepare-template-utils.js +5 -0
- package/dist/prepare-template-utils.js.map +1 -1
- package/dist/prompts.test.d.ts +2 -0
- package/dist/prompts.test.d.ts.map +1 -0
- package/dist/prompts.test.js +58 -0
- package/dist/prompts.test.js.map +1 -0
- package/dist/scaffold-gitignore.d.ts +1 -0
- package/dist/scaffold-gitignore.d.ts.map +1 -1
- package/dist/scaffold-gitignore.js +3 -0
- package/dist/scaffold-gitignore.js.map +1 -1
- package/package.json +3 -2
- package/templates/default/.appraise-template-meta.json +2 -2
- package/templates/default/.env.example +2 -2
- package/templates/default/.vscode/settings.json +2 -1
- package/templates/default/README.md +53 -53
- package/templates/default/automation/mapping/locator-map.json +1 -14
- package/templates/default/automation/steps/actions/click.step.ts +58 -58
- package/templates/default/automation/steps/actions/hover.step.ts +27 -27
- package/templates/default/automation/steps/actions/input.step.ts +84 -84
- package/templates/default/automation/steps/actions/navigation.step.ts +70 -70
- package/templates/default/automation/steps/actions/random_data.step.ts +142 -142
- package/templates/default/automation/steps/actions/store.step.ts +86 -86
- package/templates/default/automation/steps/actions/wait.step.ts +90 -90
- package/templates/default/automation/steps/validations/active_state_assertion.step.ts +30 -30
- package/templates/default/automation/steps/validations/navigation_assertion.step.ts +22 -22
- package/templates/default/automation/steps/validations/text_assertion.step.ts +107 -107
- package/templates/default/automation/steps/validations/visibility_assertion.step.ts +26 -26
- package/templates/default/components.json +24 -24
- package/templates/default/cucumber.mjs +16 -16
- package/templates/default/eslint.config.mjs +16 -16
- package/templates/default/gitignore +3 -0
- package/templates/default/next-env.d.ts +6 -6
- package/templates/default/next.config.ts +11 -11
- package/templates/default/package-lock.json +146 -75
- package/templates/default/package.json +2 -1
- package/templates/default/packages/cucumber-runtime/package.json +13 -13
- package/templates/default/packages/cucumber-runtime/src/cache.util.ts +93 -93
- package/templates/default/packages/cucumber-runtime/src/cli.ts +68 -68
- package/templates/default/packages/cucumber-runtime/src/environment.util.ts +21 -21
- package/templates/default/packages/cucumber-runtime/src/executor.ts +32 -32
- package/templates/default/packages/cucumber-runtime/src/hooks.ts +25 -3
- package/templates/default/packages/cucumber-runtime/src/index.ts +17 -17
- package/templates/default/packages/cucumber-runtime/src/locator.util.ts +234 -234
- package/templates/default/packages/cucumber-runtime/src/parameter-types.ts +7 -7
- package/templates/default/packages/cucumber-runtime/src/paths.ts +66 -1
- package/templates/default/packages/cucumber-runtime/src/random-data.util.ts +35 -35
- package/templates/default/packages/cucumber-runtime/src/types.ts +13 -13
- package/templates/default/packages/cucumber-runtime/src/world.ts +44 -44
- package/templates/default/packages/cucumber-runtime/tsconfig.json +11 -11
- package/templates/default/packages/locator-picker-companion/dist/cli.d.ts +1 -0
- package/templates/default/packages/locator-picker-companion/dist/cli.js +302 -0
- package/templates/default/packages/locator-picker-companion/dist/index.d.ts +3 -0
- package/templates/default/packages/locator-picker-companion/dist/index.js +3 -0
- package/templates/default/packages/locator-picker-companion/dist/injected-picker-script.d.ts +1 -0
- package/templates/default/packages/locator-picker-companion/dist/injected-picker-script.js +615 -0
- package/templates/default/packages/locator-picker-companion/dist/launcher.d.ts +11 -0
- package/templates/default/packages/locator-picker-companion/dist/launcher.js +59 -0
- package/templates/default/packages/locator-picker-companion/dist/selector-generator.d.ts +3 -0
- package/templates/default/packages/locator-picker-companion/dist/selector-generator.js +257 -0
- package/templates/default/packages/locator-picker-companion/dist/session-file.d.ts +22 -0
- package/templates/default/packages/locator-picker-companion/dist/session-file.js +150 -0
- package/templates/default/packages/locator-picker-companion/dist/types.d.ts +31 -0
- package/templates/default/packages/locator-picker-companion/dist/types.js +1 -0
- package/templates/default/packages/locator-picker-companion/package.json +17 -0
- package/templates/default/packages/locator-picker-companion/src/cli.ts +428 -0
- package/templates/default/packages/locator-picker-companion/src/index.ts +3 -0
- package/templates/default/packages/locator-picker-companion/src/injected-picker-script.ts +771 -0
- package/templates/default/packages/locator-picker-companion/src/launcher.ts +77 -0
- package/templates/default/packages/locator-picker-companion/src/selector-generator.ts +339 -0
- package/templates/default/packages/locator-picker-companion/src/session-file.ts +226 -0
- package/templates/default/packages/locator-picker-companion/src/types.ts +42 -0
- package/templates/default/packages/locator-picker-companion/tsconfig.json +14 -0
- package/templates/default/postcss.config.mjs +8 -8
- package/templates/default/prisma/dev.db +0 -0
- 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/migrations/20260313093000_add_report_step_screenshot_path/migration.sql +1 -0
- package/templates/default/prisma/migrations/20260318120000_add_test_suite_context_to_test_run_test_case/migration.sql +20 -0
- package/templates/default/prisma/migrations/20260318173512_add_support_of_test_suite_level_runs/migration.sql +2 -0
- package/templates/default/prisma/schema.prisma +4 -0
- package/templates/default/scripts/install-playwright.ts +20 -0
- package/templates/default/scripts/protect-seeded-files.ts +38 -38
- 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 +22 -66
- package/templates/default/scripts/sync-appraise-base-template.ts +57 -19
- package/templates/default/scripts/sync-environments.ts +40 -21
- package/templates/default/scripts/sync-locator-groups.ts +410 -410
- package/templates/default/scripts/sync-locators.ts +398 -398
- package/templates/default/scripts/sync-modules.ts +341 -341
- package/templates/default/scripts/sync-tags.ts +2 -3
- package/templates/default/scripts/sync-template-step-groups.ts +0 -3
- package/templates/default/scripts/sync-template-steps.ts +37 -11
- package/templates/default/scripts/sync-test-cases.ts +68 -16
- package/templates/default/scripts/sync-test-suites.ts +7 -5
- 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 +188 -188
- package/templates/default/src/actions/locator/locator-actions.ts +490 -490
- package/templates/default/src/actions/locator-groups/locator-group-actions.ts +6 -3
- package/templates/default/src/actions/locator-picker/locator-picker-actions.ts +243 -0
- package/templates/default/src/actions/modules/module-actions.ts +135 -135
- package/templates/default/src/actions/reports/report-actions.ts +51 -49
- package/templates/default/src/actions/review/review-actions.ts +147 -147
- package/templates/default/src/actions/settings/sync-actions.ts +46 -0
- package/templates/default/src/actions/tags/tag-actions.ts +107 -107
- package/templates/default/src/actions/template-step/template-step-actions.ts +38 -4
- package/templates/default/src/actions/template-step-group/template-step-group-actions.ts +10 -3
- 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 +356 -356
- package/templates/default/src/actions/test-run/test-run-actions.ts +222 -129
- package/templates/default/src/actions/test-suite/test-suite-actions.ts +95 -17
- 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 +20 -8
- package/templates/default/src/app/(base)/locators/create/create-locator-workspace.tsx +542 -0
- package/templates/default/src/app/(base)/locators/create/page.tsx +32 -19
- package/templates/default/src/app/(base)/locators/locator-form.tsx +163 -163
- package/templates/default/src/app/(base)/locators/locator-table-columns.tsx +73 -73
- package/templates/default/src/app/(base)/locators/locator-table.tsx +28 -28
- package/templates/default/src/app/(base)/locators/modify/[id]/page.tsx +56 -27
- package/templates/default/src/app/(base)/locators/page.tsx +13 -13
- package/templates/default/src/app/(base)/locators/picker/page.tsx +7 -0
- 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 +40 -33
- 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 +49 -46
- package/templates/default/src/app/(base)/reports/page.tsx +98 -98
- package/templates/default/src/app/(base)/reports/report-metric-card.tsx +78 -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 +12 -1
- package/templates/default/src/app/(base)/reports/report-view-table.tsx +1 -0
- package/templates/default/src/app/(base)/reports/test-cases/page.tsx +40 -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 +58 -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)/settings/page.tsx +30 -0
- package/templates/default/src/app/(base)/settings/settings-sync-panel.tsx +261 -0
- 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 +58 -58
- 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 +2 -2
- 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 +6 -71
- package/templates/default/src/app/(base)/test-cases/test-case-table.tsx +2 -2
- package/templates/default/src/app/(base)/test-runs/[id]/page.tsx +4 -1
- package/templates/default/src/app/(base)/test-runs/create/page.tsx +11 -9
- package/templates/default/src/app/(base)/test-runs/page.tsx +60 -60
- package/templates/default/src/app/(base)/test-runs/test-run-form.tsx +37 -44
- 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 +3 -2
- package/templates/default/src/app/(base)/test-suites/modify/[id]/page.tsx +2 -1
- package/templates/default/src/app/(base)/test-suites/page.tsx +57 -21
- package/templates/default/src/app/(base)/test-suites/test-suite-form.tsx +16 -17
- package/templates/default/src/app/(base)/test-suites/test-suite-table-columns.tsx +2 -1
- 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/reports/steps/[stepId]/screenshot/route.ts +52 -0
- package/templates/default/src/app/api/test-runs/[runId]/download/route.ts +97 -34
- package/templates/default/src/app/api/test-runs/[runId]/logs/route.ts +4 -1
- package/templates/default/src/app/api/test-runs/[runId]/trace/[testCaseId]/route.ts +146 -147
- package/templates/default/src/app/globals.css +147 -147
- package/templates/default/src/app/layout.tsx +4 -0
- package/templates/default/src/app/page.tsx +2 -0
- 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/diagram/button-edge.tsx +54 -54
- package/templates/default/src/components/diagram/dynamic-parameters.tsx +474 -474
- 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 +13 -0
- 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 +310 -253
- package/templates/default/src/components/table/table-actions.tsx +172 -172
- package/templates/default/src/components/test-case/test-case-columns.tsx +76 -0
- package/templates/default/src/components/test-case/test-case-picker.tsx +244 -0
- package/templates/default/src/components/test-run/download-logs-button.tsx +92 -99
- package/templates/default/src/components/test-run/log-viewer.tsx +1 -14
- package/templates/default/src/components/test-run/test-run-details.tsx +15 -2
- 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/test-suite/test-suite-picker.tsx +444 -0
- 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 +261 -261
- 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 -151
- 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 +5 -3
- 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/automation/paths.ts +42 -12
- package/templates/default/src/lib/automation/projection-service.ts +2 -1
- package/templates/default/src/lib/bidirectional-sync.ts +432 -432
- package/templates/default/src/lib/database-sync.ts +2 -7
- package/templates/default/src/lib/environment-file-utils.ts +184 -184
- package/templates/default/src/lib/executor/local-executor-adapter.ts +24 -25
- package/templates/default/src/lib/executor/types.ts +2 -2
- package/templates/default/src/lib/feature-file-generator.ts +5 -66
- package/templates/default/src/lib/gherkin-parser.ts +259 -259
- package/templates/default/src/lib/locator-group-file-utils.ts +307 -307
- package/templates/default/src/lib/locator-picker/session-manager.ts +452 -0
- package/templates/default/src/lib/locator-picker/suggestions.ts +124 -0
- package/templates/default/src/lib/metrics/metric-calculator.ts +5 -0
- 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/process/task-spawner.ts +39 -2
- package/templates/default/src/lib/sync/projected-feature-utils.ts +113 -0
- package/templates/default/src/lib/sync/sync-executor.ts +130 -0
- package/templates/default/src/lib/sync/sync-pending-counts.test.ts +239 -0
- package/templates/default/src/lib/sync/sync-pending-counts.ts +1358 -0
- package/templates/default/src/lib/sync/sync-registry.ts +149 -0
- package/templates/default/src/lib/tag-utils.ts +28 -0
- package/templates/default/src/lib/template-sync-utils.d.ts +6 -6
- package/templates/default/src/lib/template-sync-utils.js +46 -46
- package/templates/default/src/lib/template-sync-utils.ts +63 -63
- 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/matching.ts +117 -0
- package/templates/default/src/lib/test-run/process-manager.ts +2 -0
- package/templates/default/src/lib/test-run/report-parser.ts +352 -316
- package/templates/default/src/lib/test-run/test-run-executor.ts +13 -15
- package/templates/default/src/lib/test-run/winston-logger.ts +64 -66
- package/templates/default/src/lib/test-suite-identifier-service.ts +76 -0
- package/templates/default/src/lib/test-suite-utils.ts +6 -0
- 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 +104 -104
- package/templates/default/src/lib/utils/template-step-file-manager-intelligent.ts +0 -8
- 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/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/locator-picker.ts +65 -0
- 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/src/types/test-case-picker.ts +6 -0
- package/templates/default/src/types/test-suite-picker.ts +18 -0
- package/templates/default/tailwind.config.ts +62 -62
- package/templates/default/tsconfig.json +4 -1
- package/templates/default/appraisejs.config.json +0 -1
|
@@ -10,58 +10,13 @@
|
|
|
10
10
|
|
|
11
11
|
import { execa } from 'execa'
|
|
12
12
|
import { join } from 'path'
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
name: 'sync-modules',
|
|
21
|
-
description: 'Sync module hierarchy',
|
|
22
|
-
dependencies: [], // No dependencies - base entity
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
name: 'sync-environments',
|
|
26
|
-
description: 'Sync environments',
|
|
27
|
-
dependencies: [], // No dependencies - standalone
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
name: 'sync-tags',
|
|
31
|
-
description: 'Sync tags',
|
|
32
|
-
dependencies: [], // No dependencies - standalone
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
name: 'sync-template-step-groups',
|
|
36
|
-
description: 'Sync template step groups',
|
|
37
|
-
dependencies: [], // No dependencies - base for template steps
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
name: 'sync-template-steps',
|
|
41
|
-
description: 'Sync template steps',
|
|
42
|
-
dependencies: ['sync-template-step-groups'], // Depends on template-step-groups
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
name: 'sync-locator-groups',
|
|
46
|
-
description: 'Sync locator groups',
|
|
47
|
-
dependencies: ['sync-modules'], // Depends on modules
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
name: 'sync-locators',
|
|
51
|
-
description: 'Sync locators',
|
|
52
|
-
dependencies: ['sync-locator-groups'], // Depends on locator-groups
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: 'sync-test-suites',
|
|
56
|
-
description: 'Sync test suites',
|
|
57
|
-
dependencies: ['sync-modules', 'sync-tags'], // Depends on modules and tags
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
name: 'sync-test-cases',
|
|
61
|
-
description: 'Sync test cases',
|
|
62
|
-
dependencies: ['sync-test-suites', 'sync-template-steps', 'sync-tags'], // Depends on test-suites, template-steps, and tags
|
|
63
|
-
},
|
|
64
|
-
] as const
|
|
13
|
+
import {
|
|
14
|
+
getSyncScriptDefinition,
|
|
15
|
+
resolveRequestedSyncExecutionOrder,
|
|
16
|
+
SYNC_ALL_REQUEST_ID,
|
|
17
|
+
type SyncScriptId,
|
|
18
|
+
} from '../src/lib/sync/sync-registry'
|
|
19
|
+
const SYNC_SCRIPT_IDS = resolveRequestedSyncExecutionOrder(SYNC_ALL_REQUEST_ID)
|
|
65
20
|
|
|
66
21
|
interface DatabaseChanges {
|
|
67
22
|
scanned: number
|
|
@@ -138,13 +93,14 @@ function parseDatabaseChanges(stdout: string): DatabaseChanges | undefined {
|
|
|
138
93
|
/**
|
|
139
94
|
* Executes a single sync script and captures the result
|
|
140
95
|
*/
|
|
141
|
-
async function executeSyncScript(
|
|
142
|
-
const
|
|
96
|
+
async function executeSyncScript(scriptId: SyncScriptId): Promise<ScriptResult> {
|
|
97
|
+
const definition = getSyncScriptDefinition(scriptId)
|
|
98
|
+
const scriptPath = join(process.cwd(), 'scripts', definition.scriptFile)
|
|
143
99
|
const startTime = Date.now()
|
|
144
100
|
|
|
145
101
|
try {
|
|
146
|
-
console.log(`\n🔄 Running ${
|
|
147
|
-
const result = await execa('
|
|
102
|
+
console.log(`\n🔄 Running ${scriptId}...`)
|
|
103
|
+
const result = await execa(process.execPath, ['--import', 'tsx', scriptPath], {
|
|
148
104
|
cwd: process.cwd(),
|
|
149
105
|
stdio: 'pipe',
|
|
150
106
|
reject: false, // Don't throw on non-zero exit codes
|
|
@@ -155,17 +111,17 @@ async function executeSyncScript(scriptName: string): Promise<ScriptResult> {
|
|
|
155
111
|
const dbChanges = parseDatabaseChanges(result.stdout)
|
|
156
112
|
|
|
157
113
|
if (success) {
|
|
158
|
-
console.log(` ✅ ${
|
|
114
|
+
console.log(` ✅ ${scriptId} completed successfully (${duration}ms)`)
|
|
159
115
|
} else {
|
|
160
|
-
console.log(` ❌ ${
|
|
116
|
+
console.log(` ❌ ${scriptId} failed with exit code ${result.exitCode} (${duration}ms)`)
|
|
161
117
|
if (result.stderr) {
|
|
162
118
|
console.log(` Error output: ${result.stderr.substring(0, 200)}...`)
|
|
163
119
|
}
|
|
164
120
|
}
|
|
165
121
|
|
|
166
122
|
return {
|
|
167
|
-
name:
|
|
168
|
-
description:
|
|
123
|
+
name: scriptId,
|
|
124
|
+
description: definition.description,
|
|
169
125
|
success,
|
|
170
126
|
exitCode: result.exitCode ?? null,
|
|
171
127
|
duration,
|
|
@@ -175,12 +131,12 @@ async function executeSyncScript(scriptName: string): Promise<ScriptResult> {
|
|
|
175
131
|
}
|
|
176
132
|
} catch (error) {
|
|
177
133
|
const duration = Date.now() - startTime
|
|
178
|
-
console.log(` ❌ ${
|
|
134
|
+
console.log(` ❌ ${scriptId} threw an error (${duration}ms)`)
|
|
179
135
|
console.error(` Error: ${error}`)
|
|
180
136
|
|
|
181
137
|
return {
|
|
182
|
-
name:
|
|
183
|
-
description:
|
|
138
|
+
name: scriptId,
|
|
139
|
+
description: definition.description,
|
|
184
140
|
success: false,
|
|
185
141
|
exitCode: null,
|
|
186
142
|
duration,
|
|
@@ -301,8 +257,8 @@ async function main(): Promise<void> {
|
|
|
301
257
|
console.log('Execution will continue even if individual scripts fail.\n')
|
|
302
258
|
|
|
303
259
|
// Execute each script in order
|
|
304
|
-
for (const
|
|
305
|
-
const result = await executeSyncScript(
|
|
260
|
+
for (const scriptId of SYNC_SCRIPT_IDS) {
|
|
261
|
+
const result = await executeSyncScript(scriptId)
|
|
306
262
|
results.push(result)
|
|
307
263
|
|
|
308
264
|
// Continue execution even if script failed (as per user requirement)
|
|
@@ -315,7 +271,7 @@ async function main(): Promise<void> {
|
|
|
315
271
|
const totalDbChanges = aggregateDatabaseChanges(results)
|
|
316
272
|
|
|
317
273
|
const summary: SyncSummary = {
|
|
318
|
-
totalScripts:
|
|
274
|
+
totalScripts: SYNC_SCRIPT_IDS.length,
|
|
319
275
|
successfulScripts,
|
|
320
276
|
failedScripts,
|
|
321
277
|
totalDuration,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* Sync the default template from the base app (repo root).
|
|
4
|
-
* Copies src/, automation/, prisma/, public/, scripts/,
|
|
4
|
+
* Copies src/, automation/, prisma/, public/, scripts/, selected internal packages,
|
|
5
5
|
* and root config files into templates/default/ while preserving template-only files.
|
|
6
6
|
*
|
|
7
7
|
* Usage: npx tsx scripts/sync-appraise-base-template.ts
|
|
@@ -20,18 +20,23 @@ function shouldExclude(relativePath: string): boolean {
|
|
|
20
20
|
return shouldExcludeTemplatePath(relativePath)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
function copyDirWithFilter(
|
|
23
|
+
function copyDirWithFilter(
|
|
24
|
+
src: string,
|
|
25
|
+
dest: string,
|
|
26
|
+
options: { base?: string; shouldExcludePath?: (relativePath: string) => boolean } = {},
|
|
27
|
+
): void {
|
|
24
28
|
if (!existsSync(src)) return
|
|
25
29
|
|
|
30
|
+
const { base = src, shouldExcludePath = shouldExclude } = options
|
|
26
31
|
mkdirSync(dest, { recursive: true })
|
|
27
32
|
for (const entry of readdirSync(src, { withFileTypes: true })) {
|
|
28
33
|
const srcPath = join(src, entry.name)
|
|
29
34
|
const relativePath = srcPath.slice(base.length + 1).replace(/\\/g, '/')
|
|
30
|
-
if (
|
|
35
|
+
if (shouldExcludePath(relativePath)) continue
|
|
31
36
|
|
|
32
37
|
const destPath = join(dest, entry.name)
|
|
33
38
|
if (entry.isDirectory()) {
|
|
34
|
-
copyDirWithFilter(srcPath, destPath, base)
|
|
39
|
+
copyDirWithFilter(srcPath, destPath, { base, shouldExcludePath })
|
|
35
40
|
continue
|
|
36
41
|
}
|
|
37
42
|
|
|
@@ -51,6 +56,12 @@ function resetAutomationReports(templateRoot: string): void {
|
|
|
51
56
|
mkdirSync(join(reportsRoot, 'traces'), { recursive: true })
|
|
52
57
|
}
|
|
53
58
|
|
|
59
|
+
function resetAutomationLocatorMap(templateRoot: string): void {
|
|
60
|
+
const locatorMapPath = join(templateRoot, 'automation', 'mapping', 'locator-map.json')
|
|
61
|
+
mkdirSync(dirname(locatorMapPath), { recursive: true })
|
|
62
|
+
writeFileSync(locatorMapPath, '[]\n')
|
|
63
|
+
}
|
|
64
|
+
|
|
54
65
|
function syncLegacyEnvironmentConfig(): void {
|
|
55
66
|
const legacyEnvironmentsDir = join(repoRoot, 'src', 'tests', 'config', 'environments')
|
|
56
67
|
const targetEnvironmentsDir = join(target, 'automation', 'config', 'environments')
|
|
@@ -65,22 +76,46 @@ function syncLegacyEnvironmentConfig(): void {
|
|
|
65
76
|
console.log('Backfilled automation/config/environments from legacy src/tests config.')
|
|
66
77
|
}
|
|
67
78
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
79
|
+
type InternalPackageSyncConfig = {
|
|
80
|
+
name: string
|
|
81
|
+
directories: string[]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const INTERNAL_PACKAGES: InternalPackageSyncConfig[] = [
|
|
85
|
+
{ name: 'cucumber-runtime', directories: ['src'] },
|
|
86
|
+
{ name: 'locator-picker-companion', directories: ['src', 'dist'] },
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
function syncInternalPackage({ name, directories }: InternalPackageSyncConfig): void {
|
|
90
|
+
const packageRoot = join(repoRoot, 'packages', name)
|
|
91
|
+
const packageTarget = join(target, 'packages', name)
|
|
92
|
+
|
|
93
|
+
rmSync(packageTarget, { recursive: true, force: true })
|
|
94
|
+
mkdirSync(packageTarget, { recursive: true })
|
|
95
|
+
|
|
96
|
+
copyFile(join(packageRoot, 'package.json'), join(packageTarget, 'package.json'))
|
|
97
|
+
copyFile(join(packageRoot, 'tsconfig.json'), join(packageTarget, 'tsconfig.json'))
|
|
72
98
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
99
|
+
const shouldExcludeInternalPackagePath = (relativePath: string): boolean => {
|
|
100
|
+
if (relativePath === 'dist' || relativePath.startsWith('dist/')) {
|
|
101
|
+
return false
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return shouldExclude(relativePath)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (const directory of directories) {
|
|
108
|
+
copyDirWithFilter(join(packageRoot, directory), join(packageTarget, directory), {
|
|
109
|
+
base: packageRoot,
|
|
110
|
+
shouldExcludePath: shouldExcludeInternalPackagePath,
|
|
111
|
+
})
|
|
112
|
+
}
|
|
76
113
|
}
|
|
77
114
|
|
|
78
115
|
const readmePath = join(target, 'README.md')
|
|
79
116
|
const appraisejsConfigPath = join(target, 'appraisejs.config.json')
|
|
80
117
|
const savedReadme = existsSync(readmePath) ? readFileSync(readmePath, 'utf8') : null
|
|
81
|
-
const savedAppraisejsConfig = existsSync(appraisejsConfigPath)
|
|
82
|
-
? readFileSync(appraisejsConfigPath, 'utf8')
|
|
83
|
-
: null
|
|
118
|
+
const savedAppraisejsConfig = existsSync(appraisejsConfigPath) ? readFileSync(appraisejsConfigPath, 'utf8') : null
|
|
84
119
|
|
|
85
120
|
rmSync(target, { recursive: true, force: true })
|
|
86
121
|
mkdirSync(target, { recursive: true })
|
|
@@ -92,9 +127,12 @@ console.log('Copying automation/...')
|
|
|
92
127
|
copyDirWithFilter(join(repoRoot, 'automation'), join(target, 'automation'))
|
|
93
128
|
syncLegacyEnvironmentConfig()
|
|
94
129
|
resetAutomationReports(target)
|
|
130
|
+
resetAutomationLocatorMap(target)
|
|
95
131
|
|
|
96
|
-
|
|
97
|
-
|
|
132
|
+
for (const internalPackage of INTERNAL_PACKAGES) {
|
|
133
|
+
console.log(`Copying internal package ${internalPackage.name}...`)
|
|
134
|
+
syncInternalPackage(internalPackage)
|
|
135
|
+
}
|
|
98
136
|
|
|
99
137
|
console.log('Copying prisma/...')
|
|
100
138
|
copyDirWithFilter(join(repoRoot, 'prisma'), join(target, 'prisma'))
|
|
@@ -149,13 +187,13 @@ const rootPkg = JSON.parse(readFileSync(join(repoRoot, 'package.json'), 'utf8'))
|
|
|
149
187
|
rootPkg.scripts = {
|
|
150
188
|
...rootPkg.scripts,
|
|
151
189
|
build: 'npm run build:local',
|
|
152
|
-
'build:local':
|
|
190
|
+
'build:local':
|
|
191
|
+
'npm run generate-db-client && npm run build:cucumber-runtime && npm run build:locator-picker-companion && next build',
|
|
153
192
|
start: 'next start',
|
|
154
193
|
'generate-db-client': 'npx prisma generate --schema prisma/schema.prisma',
|
|
155
194
|
'migrate-db': 'npx prisma migrate deploy',
|
|
156
195
|
'install-playwright': 'npx playwright install',
|
|
157
|
-
setup:
|
|
158
|
-
'npm run install-dependencies && npm run setup:db && npm run build:local && npm run protect-seeded-files',
|
|
196
|
+
setup: 'npm run install-dependencies && npm run setup:db && npm run build:local && npm run protect-seeded-files',
|
|
159
197
|
'setup:db': 'npm run setup-env && npm run generate-db-client && npm run migrate-db && npm run sync-all',
|
|
160
198
|
'setup:full':
|
|
161
199
|
'npm run install-dependencies && npm run setup:db && npm run build:local && npm run protect-seeded-files',
|
|
@@ -69,15 +69,25 @@ async function readEnvironmentsFromFile(): Promise<Record<string, EnvironmentCon
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
/**
|
|
73
|
-
* Normalizes environment name to title case for consistent comparison
|
|
74
|
-
* e.g., "staging" -> "Staging", "STAGING" -> "Staging", "Staging" -> "Staging"
|
|
75
|
-
*/
|
|
76
72
|
function normalizeEnvironmentName(name: string): string {
|
|
77
73
|
if (!name || name.trim() === '') {
|
|
78
74
|
return name
|
|
79
75
|
}
|
|
80
|
-
|
|
76
|
+
|
|
77
|
+
return name
|
|
78
|
+
.trim()
|
|
79
|
+
.replace(/[_\s]+/g, ' ')
|
|
80
|
+
.split(' ')
|
|
81
|
+
.filter(Boolean)
|
|
82
|
+
.map(segment => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase())
|
|
83
|
+
.join(' ')
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function getEnvironmentIdentityKey(name: string): string {
|
|
87
|
+
return name
|
|
88
|
+
.trim()
|
|
89
|
+
.replace(/[_\s]+/g, ' ')
|
|
90
|
+
.toLowerCase()
|
|
81
91
|
}
|
|
82
92
|
|
|
83
93
|
/**
|
|
@@ -135,19 +145,20 @@ async function syncEnvironmentsToDatabase(environments: EnvironmentData[]): Prom
|
|
|
135
145
|
}
|
|
136
146
|
|
|
137
147
|
// Get set of normalized environment names from JSON file (for case-insensitive comparison)
|
|
138
|
-
const jsonEnvironmentNamesNormalized = new Set(
|
|
139
|
-
environments.map(env => normalizeEnvironmentName(env.name))
|
|
140
|
-
)
|
|
148
|
+
const jsonEnvironmentNamesNormalized = new Set(environments.map(env => getEnvironmentIdentityKey(env.name)))
|
|
141
149
|
|
|
142
150
|
// Get all environments from database
|
|
143
151
|
const allDbEnvironments = await prisma.environment.findMany({
|
|
144
|
-
select: { id: true, name: true },
|
|
152
|
+
select: { id: true, name: true, baseUrl: true, apiBaseUrl: true, username: true, password: true },
|
|
145
153
|
})
|
|
146
154
|
|
|
147
155
|
// Create a case-insensitive map: normalized name -> actual DB name
|
|
148
|
-
const dbEnvironmentsByNormalizedName = new Map<
|
|
156
|
+
const dbEnvironmentsByNormalizedName = new Map<
|
|
157
|
+
string,
|
|
158
|
+
{ id: string; name: string; baseUrl: string; apiBaseUrl: string | null; username: string | null; password: string | null }
|
|
159
|
+
>()
|
|
149
160
|
for (const dbEnv of allDbEnvironments) {
|
|
150
|
-
const normalizedName =
|
|
161
|
+
const normalizedName = getEnvironmentIdentityKey(dbEnv.name)
|
|
151
162
|
// If we find a duplicate normalized name, keep the first one
|
|
152
163
|
if (!dbEnvironmentsByNormalizedName.has(normalizedName)) {
|
|
153
164
|
dbEnvironmentsByNormalizedName.set(normalizedName, dbEnv)
|
|
@@ -156,7 +167,7 @@ async function syncEnvironmentsToDatabase(environments: EnvironmentData[]): Prom
|
|
|
156
167
|
|
|
157
168
|
// Delete environments from DB that are not in JSON file (case-insensitive comparison)
|
|
158
169
|
for (const dbEnv of allDbEnvironments) {
|
|
159
|
-
const normalizedDbName =
|
|
170
|
+
const normalizedDbName = getEnvironmentIdentityKey(dbEnv.name)
|
|
160
171
|
if (!jsonEnvironmentNamesNormalized.has(normalizedDbName)) {
|
|
161
172
|
try {
|
|
162
173
|
// Check if environment has test runs (foreign key constraint prevents deletion)
|
|
@@ -187,23 +198,32 @@ async function syncEnvironmentsToDatabase(environments: EnvironmentData[]): Prom
|
|
|
187
198
|
// Create or update environments from JSON file
|
|
188
199
|
for (const env of environments) {
|
|
189
200
|
try {
|
|
190
|
-
const normalizedName =
|
|
201
|
+
const normalizedName = getEnvironmentIdentityKey(env.name)
|
|
191
202
|
// Check if environment already exists by normalized name (case-insensitive)
|
|
192
203
|
const existingDbEnv = dbEnvironmentsByNormalizedName.get(normalizedName)
|
|
193
204
|
|
|
194
205
|
if (existingDbEnv) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
206
|
+
const needsUpdate =
|
|
207
|
+
existingDbEnv.baseUrl !== env.baseUrl ||
|
|
208
|
+
(existingDbEnv.apiBaseUrl ?? null) !== env.apiBaseUrl ||
|
|
209
|
+
(existingDbEnv.username ?? null) !== env.username ||
|
|
210
|
+
(existingDbEnv.password ?? null) !== env.password
|
|
211
|
+
|
|
212
|
+
if (needsUpdate) {
|
|
198
213
|
await prisma.environment.update({
|
|
199
214
|
where: { id: existingDbEnv.id },
|
|
200
|
-
data: {
|
|
215
|
+
data: {
|
|
216
|
+
baseUrl: env.baseUrl,
|
|
217
|
+
apiBaseUrl: env.apiBaseUrl,
|
|
218
|
+
username: env.username,
|
|
219
|
+
password: env.password,
|
|
220
|
+
},
|
|
201
221
|
})
|
|
202
|
-
console.log(` 🔄 Updated environment
|
|
222
|
+
console.log(` 🔄 Updated environment '${existingDbEnv.name}'`)
|
|
203
223
|
}
|
|
204
224
|
result.environmentsExisting++
|
|
205
|
-
result.existingEnvironments.push(
|
|
206
|
-
console.log(` ✓ Environment '${
|
|
225
|
+
result.existingEnvironments.push(existingDbEnv.name)
|
|
226
|
+
console.log(` ✓ Environment '${existingDbEnv.name}' already exists`)
|
|
207
227
|
} else {
|
|
208
228
|
// Create the environment
|
|
209
229
|
await prisma.environment.create({
|
|
@@ -323,4 +343,3 @@ main()
|
|
|
323
343
|
|
|
324
344
|
|
|
325
345
|
|
|
326
|
-
|