siesa-agents 2.1.40 → 2.1.42
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 +147 -147
- package/bin/install.js +534 -534
- package/bin/prepare-publish.js +26 -26
- package/bin/restore-folders.js +26 -26
- package/bmad/_config/agent-manifest.csv +20 -20
- package/bmad/_config/agents/bmb-agent-builder.customize.yaml +41 -41
- package/bmad/_config/agents/bmb-module-builder.customize.yaml +41 -41
- package/bmad/_config/agents/bmb-workflow-builder.customize.yaml +41 -41
- package/bmad/_config/files-manifest.csv +469 -469
- package/bmad/_config/ides/claude-code.yaml +6 -6
- package/bmad/_config/manifest.yaml +14 -14
- package/bmad/_config/task-manifest.csv +6 -6
- package/bmad/_config/tool-manifest.csv +1 -1
- package/bmad/_config/workflow-manifest.csv +45 -45
- package/bmad/_memory/config.yaml +11 -11
- package/bmad/bmb/README.md +25 -25
- package/bmad/bmb/agents/agent-builder.md +57 -57
- package/bmad/bmb/agents/module-builder.md +60 -60
- package/bmad/bmb/agents/workflow-builder.md +56 -56
- package/bmad/bmb/config.yaml +12 -12
- package/bmad/bmb/docs/workflows/architecture.md +220 -220
- package/bmad/bmb/docs/workflows/common-workflow-tools.csv +18 -18
- package/bmad/bmb/docs/workflows/csv-data-file-standards.md +206 -206
- package/bmad/bmb/docs/workflows/intent-vs-prescriptive-spectrum.md +220 -220
- package/bmad/bmb/docs/workflows/step-file-rules.md +469 -469
- package/bmad/bmb/docs/workflows/templates/step-01-init-continuable-template.md +241 -241
- package/bmad/bmb/docs/workflows/templates/step-1b-template.md +223 -223
- package/bmad/bmb/docs/workflows/templates/step-file.md +139 -139
- package/bmad/bmb/docs/workflows/templates/step-template.md +290 -290
- package/bmad/bmb/docs/workflows/templates/workflow-template.md +104 -104
- package/bmad/bmb/docs/workflows/templates/workflow.md +58 -58
- package/bmad/bmb/docs/workflows/terms.md +97 -97
- package/bmad/bmb/reference/agents/simple-examples/README.md +223 -223
- package/bmad/bmb/reference/readme.md +3 -3
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/data/dietary-restrictions.csv +17 -17
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/data/macro-calculator.csv +15 -15
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/data/recipe-database.csv +27 -27
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-01-init.md +177 -177
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-01b-continue.md +121 -121
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-02-profile.md +165 -165
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-03-assessment.md +154 -154
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-04-strategy.md +183 -183
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md +168 -168
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/steps/step-06-prep-schedule.md +195 -195
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/templates/assessment-section.md +25 -25
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/templates/nutrition-plan.md +68 -68
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/templates/prep-schedule-section.md +29 -29
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/templates/profile-section.md +47 -47
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/templates/shopping-section.md +37 -37
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/templates/strategy-section.md +18 -18
- package/bmad/bmb/reference/workflows/meal-prep-nutrition/workflow.md +59 -59
- package/bmad/bmb/workflows/agent/data/agent-compilation.md +273 -273
- package/bmad/bmb/workflows/agent/data/agent-menu-patterns.md +233 -233
- package/bmad/bmb/workflows/agent/data/agent-metadata.md +208 -208
- package/bmad/bmb/workflows/agent/data/brainstorm-context.md +146 -146
- package/bmad/bmb/workflows/agent/data/communication-presets.csv +61 -61
- package/bmad/bmb/workflows/agent/data/critical-actions.md +120 -120
- package/bmad/bmb/workflows/agent/data/expert-agent-architecture.md +236 -236
- package/bmad/bmb/workflows/agent/data/expert-agent-validation.md +173 -173
- package/bmad/bmb/workflows/agent/data/module-agent-validation.md +124 -124
- package/bmad/bmb/workflows/agent/data/persona-properties.md +266 -266
- package/bmad/bmb/workflows/agent/data/principles-crafting.md +292 -292
- package/bmad/bmb/workflows/agent/data/reference/expert-examples/journal-keeper/journal-keeper-sidecar/entries/yy-mm-dd-entry-template.md +16 -16
- package/bmad/bmb/workflows/agent/data/reference/module-examples/architect.md +68 -68
- package/bmad/bmb/workflows/agent/data/simple-agent-architecture.md +204 -204
- package/bmad/bmb/workflows/agent/data/simple-agent-validation.md +132 -132
- package/bmad/bmb/workflows/agent/data/understanding-agent-types.md +222 -222
- package/bmad/bmb/workflows/agent/steps-c/step-01-brainstorm.md +126 -126
- package/bmad/bmb/workflows/agent/steps-c/step-02-discovery.md +168 -168
- package/bmad/bmb/workflows/agent/steps-c/step-03-type-metadata.md +294 -294
- package/bmad/bmb/workflows/agent/steps-c/step-04-persona.md +210 -210
- package/bmad/bmb/workflows/agent/steps-c/step-05-commands-menu.md +176 -176
- package/bmad/bmb/workflows/agent/steps-c/step-06-activation.md +275 -275
- package/bmad/bmb/workflows/agent/steps-c/step-07a-build-simple.md +185 -185
- package/bmad/bmb/workflows/agent/steps-c/step-07b-build-expert.md +201 -201
- package/bmad/bmb/workflows/agent/steps-c/step-07c-build-module.md +258 -258
- package/bmad/bmb/workflows/agent/steps-c/step-08a-plan-traceability.md +203 -203
- package/bmad/bmb/workflows/agent/steps-c/step-08b-metadata-validation.md +135 -135
- package/bmad/bmb/workflows/agent/steps-c/step-08c-persona-validation.md +161 -161
- package/bmad/bmb/workflows/agent/steps-c/step-08d-menu-validation.md +158 -158
- package/bmad/bmb/workflows/agent/steps-c/step-08e-structure-validation.md +306 -306
- package/bmad/bmb/workflows/agent/steps-c/step-08f-sidecar-validation.md +462 -462
- package/bmad/bmb/workflows/agent/steps-c/step-09-celebrate.md +244 -244
- package/bmad/bmb/workflows/agent/steps-e/e-01-load-existing.md +214 -214
- package/bmad/bmb/workflows/agent/steps-e/e-02-discover-edits.md +191 -191
- package/bmad/bmb/workflows/agent/steps-e/e-03a-validate-metadata.md +78 -78
- package/bmad/bmb/workflows/agent/steps-e/e-03b-validate-persona.md +76 -76
- package/bmad/bmb/workflows/agent/steps-e/e-03c-validate-menu.md +75 -75
- package/bmad/bmb/workflows/agent/steps-e/e-03d-validate-structure.md +75 -75
- package/bmad/bmb/workflows/agent/steps-e/e-03e-validate-sidecar.md +78 -78
- package/bmad/bmb/workflows/agent/steps-e/e-03f-validation-summary.md +119 -119
- package/bmad/bmb/workflows/agent/steps-e/e-04-type-metadata.md +122 -122
- package/bmad/bmb/workflows/agent/steps-e/e-05-persona.md +132 -132
- package/bmad/bmb/workflows/agent/steps-e/e-06-commands-menu.md +120 -120
- package/bmad/bmb/workflows/agent/steps-e/e-07-activation.md +122 -122
- package/bmad/bmb/workflows/agent/steps-e/e-08a-edit-simple.md +134 -134
- package/bmad/bmb/workflows/agent/steps-e/e-08b-edit-expert.md +117 -117
- package/bmad/bmb/workflows/agent/steps-e/e-08c-edit-module.md +120 -120
- package/bmad/bmb/workflows/agent/steps-e/e-09a-validate-metadata.md +70 -70
- package/bmad/bmb/workflows/agent/steps-e/e-09b-validate-persona.md +70 -70
- package/bmad/bmb/workflows/agent/steps-e/e-09c-validate-menu.md +69 -69
- package/bmad/bmb/workflows/agent/steps-e/e-09d-validate-structure.md +69 -69
- package/bmad/bmb/workflows/agent/steps-e/e-09e-validate-sidecar.md +70 -70
- package/bmad/bmb/workflows/agent/steps-e/e-09f-validation-summary.md +111 -111
- package/bmad/bmb/workflows/agent/steps-e/e-10-celebrate.md +150 -150
- package/bmad/bmb/workflows/agent/steps-v/v-01-load-review.md +128 -128
- package/bmad/bmb/workflows/agent/steps-v/v-02a-validate-metadata.md +73 -73
- package/bmad/bmb/workflows/agent/steps-v/v-02b-validate-persona.md +72 -72
- package/bmad/bmb/workflows/agent/steps-v/v-02c-validate-menu.md +71 -71
- package/bmad/bmb/workflows/agent/steps-v/v-02d-validate-structure.md +71 -71
- package/bmad/bmb/workflows/agent/steps-v/v-02e-validate-sidecar.md +76 -76
- package/bmad/bmb/workflows/agent/steps-v/v-03-summary.md +100 -100
- package/bmad/bmb/workflows/agent/templates/agent-plan.template.md +5 -5
- package/bmad/bmb/workflows/agent/templates/expert-agent-template/expert-agent.template.md +76 -76
- package/bmad/bmb/workflows/agent/templates/simple-agent.template.md +71 -71
- package/bmad/bmb/workflows/agent/workflow.md +123 -123
- package/bmad/bmb/workflows/create-module/steps/step-01-init.md +156 -156
- package/bmad/bmb/workflows/create-module/steps/step-01b-continue.md +170 -170
- package/bmad/bmb/workflows/create-module/steps/step-02-concept.md +218 -218
- package/bmad/bmb/workflows/create-module/steps/step-03-components.md +268 -268
- package/bmad/bmb/workflows/create-module/steps/step-04-structure.md +229 -229
- package/bmad/bmb/workflows/create-module/steps/step-05-config.md +234 -234
- package/bmad/bmb/workflows/create-module/steps/step-06-agents.md +297 -297
- package/bmad/bmb/workflows/create-module/steps/step-07-workflows.md +229 -229
- package/bmad/bmb/workflows/create-module/steps/step-08-installer.md +187 -187
- package/bmad/bmb/workflows/create-module/steps/step-09-documentation.md +310 -310
- package/bmad/bmb/workflows/create-module/steps/step-10-roadmap.md +338 -338
- package/bmad/bmb/workflows/create-module/steps/step-11-validate.md +336 -336
- package/bmad/bmb/workflows/create-module/templates/agent.template.md +313 -313
- package/bmad/bmb/workflows/create-module/templates/installer.template.js +47 -47
- package/bmad/bmb/workflows/create-module/templates/module-plan.template.md +5 -5
- package/bmad/bmb/workflows/create-module/templates/module.template.yaml +53 -53
- package/bmad/bmb/workflows/create-module/templates/workflow-plan-template.md +23 -23
- package/bmad/bmb/workflows/create-module/validation.md +126 -126
- package/bmad/bmb/workflows/create-module/workflow.md +56 -56
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/data/dietary-restrictions.csv +17 -17
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/data/macro-calculator.csv +15 -15
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/data/recipe-database.csv +27 -27
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-01-init.md +177 -177
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-01b-continue.md +150 -150
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-02-profile.md +164 -164
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-03-assessment.md +152 -152
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-04-strategy.md +182 -182
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-05-shopping.md +167 -167
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/steps/step-06-prep-schedule.md +194 -194
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/templates/assessment-section.md +25 -25
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/templates/nutrition-plan.md +68 -68
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/templates/prep-schedule-section.md +29 -29
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/templates/profile-section.md +47 -47
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/templates/shopping-section.md +37 -37
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/templates/strategy-section.md +18 -18
- package/bmad/bmb/workflows/create-workflow/data/examples/meal-prep-nutrition/workflow.md +58 -58
- package/bmad/bmb/workflows/create-workflow/steps/step-01-init.md +158 -158
- package/bmad/bmb/workflows/create-workflow/steps/step-02-gather.md +212 -212
- package/bmad/bmb/workflows/create-workflow/steps/step-03-tools-configuration.md +251 -251
- package/bmad/bmb/workflows/create-workflow/steps/step-04-plan-review.md +217 -217
- package/bmad/bmb/workflows/create-workflow/steps/step-05-output-format-design.md +290 -290
- package/bmad/bmb/workflows/create-workflow/steps/step-06-design.md +272 -272
- package/bmad/bmb/workflows/create-workflow/steps/step-07-build.md +323 -323
- package/bmad/bmb/workflows/create-workflow/steps/step-08-review.md +285 -285
- package/bmad/bmb/workflows/create-workflow/steps/step-09-complete.md +188 -188
- package/bmad/bmb/workflows/create-workflow/workflow.md +59 -59
- package/bmad/bmb/workflows/edit-workflow/steps/step-01-analyze.md +217 -217
- package/bmad/bmb/workflows/edit-workflow/steps/step-02-discover.md +254 -254
- package/bmad/bmb/workflows/edit-workflow/steps/step-03-improve.md +218 -218
- package/bmad/bmb/workflows/edit-workflow/steps/step-04-validate.md +194 -194
- package/bmad/bmb/workflows/edit-workflow/steps/step-05-compliance-check.md +246 -246
- package/bmad/bmb/workflows/edit-workflow/templates/completion-summary.md +75 -75
- package/bmad/bmb/workflows/edit-workflow/templates/improvement-goals.md +68 -68
- package/bmad/bmb/workflows/edit-workflow/templates/improvement-log.md +40 -40
- package/bmad/bmb/workflows/edit-workflow/templates/validation-results.md +51 -51
- package/bmad/bmb/workflows/edit-workflow/templates/workflow-analysis.md +56 -56
- package/bmad/bmb/workflows/edit-workflow/workflow.md +59 -59
- package/bmad/bmb/workflows/workflow-compliance-check/steps/step-01-validate-goal.md +153 -153
- package/bmad/bmb/workflows/workflow-compliance-check/steps/step-02-workflow-validation.md +244 -244
- package/bmad/bmb/workflows/workflow-compliance-check/steps/step-03-step-validation.md +275 -275
- package/bmad/bmb/workflows/workflow-compliance-check/steps/step-04-file-validation.md +296 -296
- package/bmad/bmb/workflows/workflow-compliance-check/steps/step-05-intent-spectrum-validation.md +265 -265
- package/bmad/bmb/workflows/workflow-compliance-check/steps/step-06-web-subprocess-validation.md +361 -361
- package/bmad/bmb/workflows/workflow-compliance-check/steps/step-07-holistic-analysis.md +259 -259
- package/bmad/bmb/workflows/workflow-compliance-check/steps/step-08-generate-report.md +302 -302
- package/bmad/bmb/workflows/workflow-compliance-check/templates/compliance-report.md +140 -140
- package/bmad/bmb/workflows/workflow-compliance-check/workflow.md +59 -59
- package/bmad/bmb/workflows-legacy/edit-module/README.md +171 -171
- package/bmad/bmb/workflows-legacy/edit-module/checklist.md +163 -163
- package/bmad/bmb/workflows-legacy/edit-module/instructions.md +340 -340
- package/bmad/bmb/workflows-legacy/edit-module/workflow.yaml +32 -32
- package/bmad/bmb/workflows-legacy/module-brief/README.md +264 -264
- package/bmad/bmb/workflows-legacy/module-brief/checklist.md +116 -116
- package/bmad/bmb/workflows-legacy/module-brief/instructions.md +268 -268
- package/bmad/bmb/workflows-legacy/module-brief/template.md +275 -275
- package/bmad/bmb/workflows-legacy/module-brief/workflow.yaml +34 -34
- package/bmad/bmm/agents/analyst.md +76 -76
- package/bmad/bmm/agents/architect.md +68 -68
- package/bmad/bmm/agents/dev.md +70 -70
- package/bmad/bmm/agents/pm.md +70 -70
- package/bmad/bmm/agents/quick-flow-solo-dev.md +68 -68
- package/bmad/bmm/agents/sm.md +71 -71
- package/bmad/bmm/agents/tea.md +71 -71
- package/bmad/bmm/agents/tech-writer.md +72 -72
- package/bmad/bmm/agents/ux-designer.md +68 -68
- package/bmad/bmm/config.yaml +18 -18
- package/bmad/bmm/data/README.md +29 -29
- package/bmad/bmm/data/documentation-standards.md +262 -262
- package/bmad/bmm/data/project-context-template.md +40 -40
- package/bmad/bmm/teams/default-party.csv +21 -21
- package/bmad/bmm/teams/team-fullstack.yaml +12 -12
- package/bmad/bmm/testarch/knowledge/api-request.md +303 -303
- package/bmad/bmm/testarch/knowledge/auth-session.md +356 -356
- package/bmad/bmm/testarch/knowledge/burn-in.md +273 -273
- package/bmad/bmm/testarch/knowledge/ci-burn-in.md +675 -675
- package/bmad/bmm/testarch/knowledge/component-tdd.md +486 -486
- package/bmad/bmm/testarch/knowledge/contract-testing.md +957 -957
- package/bmad/bmm/testarch/knowledge/data-factories.md +500 -500
- package/bmad/bmm/testarch/knowledge/email-auth.md +721 -721
- package/bmad/bmm/testarch/knowledge/error-handling.md +725 -725
- package/bmad/bmm/testarch/knowledge/feature-flags.md +750 -750
- package/bmad/bmm/testarch/knowledge/file-utils.md +260 -260
- package/bmad/bmm/testarch/knowledge/fixture-architecture.md +401 -401
- package/bmad/bmm/testarch/knowledge/fixtures-composition.md +382 -382
- package/bmad/bmm/testarch/knowledge/intercept-network-call.md +280 -280
- package/bmad/bmm/testarch/knowledge/log.md +294 -294
- package/bmad/bmm/testarch/knowledge/network-error-monitor.md +272 -272
- package/bmad/bmm/testarch/knowledge/network-first.md +486 -486
- package/bmad/bmm/testarch/knowledge/network-recorder.md +265 -265
- package/bmad/bmm/testarch/knowledge/nfr-criteria.md +670 -670
- package/bmad/bmm/testarch/knowledge/overview.md +283 -283
- package/bmad/bmm/testarch/knowledge/playwright-config.md +730 -730
- package/bmad/bmm/testarch/knowledge/probability-impact.md +601 -601
- package/bmad/bmm/testarch/knowledge/recurse.md +296 -296
- package/bmad/bmm/testarch/knowledge/risk-governance.md +615 -615
- package/bmad/bmm/testarch/knowledge/selective-testing.md +732 -732
- package/bmad/bmm/testarch/knowledge/selector-resilience.md +527 -527
- package/bmad/bmm/testarch/knowledge/test-healing-patterns.md +644 -644
- package/bmad/bmm/testarch/knowledge/test-levels-framework.md +473 -473
- package/bmad/bmm/testarch/knowledge/test-priorities-matrix.md +373 -373
- package/bmad/bmm/testarch/knowledge/test-quality.md +664 -664
- package/bmad/bmm/testarch/knowledge/timing-debugging.md +372 -372
- package/bmad/bmm/testarch/knowledge/visual-debugging.md +524 -524
- package/bmad/bmm/testarch/tea-index.csv +33 -33
- package/bmad/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -10
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +182 -182
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +166 -166
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +204 -204
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +207 -207
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +210 -210
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +224 -224
- package/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +199 -199
- package/bmad/bmm/workflows/1-analysis/create-product-brief/workflow.md +58 -58
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -137
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -229
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -238
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -206
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -234
- package/bmad/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +443 -443
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -182
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -237
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +200 -200
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -249
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -259
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -177
- package/bmad/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +475 -475
- package/bmad/bmm/workflows/1-analysis/research/research.template.md +29 -29
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -137
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -239
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -248
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -202
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +239 -239
- package/bmad/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +486 -486
- package/bmad/bmm/workflows/1-analysis/research/workflow.md +173 -173
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -135
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -127
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -190
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -216
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -219
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -234
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -252
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -254
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -224
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -224
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -241
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +332 -248
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -237
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -264
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +228 -228
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -13
- package/bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +59 -43
- package/bmad/bmm/workflows/2-plan-workflows/prd/domain-complexity.csv +12 -12
- package/bmad/bmm/workflows/2-plan-workflows/prd/prd-template.md +11 -11
- package/bmad/bmm/workflows/2-plan-workflows/prd/project-types.csv +10 -10
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-01-init.md +197 -197
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-01b-continue.md +166 -166
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-02-discovery.md +421 -421
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-03-success.md +290 -290
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-04-journeys.md +291 -291
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-05-domain.md +271 -271
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-06-innovation.md +262 -262
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-07-project-type.md +258 -258
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-08-scoping.md +299 -299
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-09-functional.md +270 -270
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-10-nonfunctional.md +294 -294
- package/bmad/bmm/workflows/2-plan-workflows/prd/steps/step-11-complete.md +186 -186
- package/bmad/bmm/workflows/2-plan-workflows/prd/workflow.md +63 -63
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +190 -190
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +178 -178
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +179 -179
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +139 -139
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +252 -252
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +133 -133
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -4
- package/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +55 -55
- package/bmad/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -12
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/architecture-patterns.md +415 -415
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/backend-standards.md +811 -811
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/frontend-standards.md +375 -375
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/technical-preferences-ux.md +422 -422
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/company-standards/technology-stack.md +235 -235
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +10 -10
- package/bmad/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +6 -6
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +166 -166
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +164 -164
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -224
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +342 -342
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +328 -328
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +368 -368
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -379
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +366 -366
- package/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +352 -352
- package/bmad/bmm/workflows/3-solutioning/create-architecture/workflow.md +51 -51
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -259
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -233
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -272
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +145 -145
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -57
- package/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +59 -59
- package/bmad/bmm/workflows/4-implementation/code-review/checklist.md +23 -23
- package/bmad/bmm/workflows/4-implementation/code-review/instructions.xml +224 -224
- package/bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +49 -49
- package/bmad/bmm/workflows/4-implementation/correct-course/checklist.md +279 -279
- package/bmad/bmm/workflows/4-implementation/correct-course/instructions.md +206 -206
- package/bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +58 -58
- package/bmad/bmm/workflows/4-implementation/create-story/checklist.md +358 -358
- package/bmad/bmm/workflows/4-implementation/create-story/steps/step-01-determine-story.md +85 -85
- package/bmad/bmm/workflows/4-implementation/create-story/steps/step-02-analyze.md +67 -67
- package/bmad/bmm/workflows/4-implementation/create-story/steps/step-03-architecture.md +71 -71
- package/bmad/bmm/workflows/4-implementation/create-story/steps/step-04-web-research.md +58 -58
- package/bmad/bmm/workflows/4-implementation/create-story/steps/step-05-create-file.md +76 -76
- package/bmad/bmm/workflows/4-implementation/create-story/steps/step-06-finalize.md +66 -66
- package/bmad/bmm/workflows/4-implementation/create-story/template.md +49 -49
- package/bmad/bmm/workflows/4-implementation/create-story/workflow.md +58 -58
- package/bmad/bmm/workflows/4-implementation/create-story/workflow.yaml.bak +63 -63
- package/bmad/bmm/workflows/4-implementation/dev-story/checklist.md +85 -85
- package/bmad/bmm/workflows/4-implementation/dev-story/instructions.xml +470 -470
- package/bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +25 -25
- package/bmad/bmm/workflows/4-implementation/retrospective/instructions.md +1443 -1443
- package/bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +56 -56
- package/bmad/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -33
- package/bmad/bmm/workflows/4-implementation/sprint-planning/instructions.md +225 -225
- package/bmad/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -55
- package/bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +52 -52
- package/bmad/bmm/workflows/4-implementation/sprint-status/instructions.md +229 -229
- package/bmad/bmm/workflows/4-implementation/sprint-status/workflow.yaml +34 -34
- package/bmad/bmm/workflows/bmad-quick-flow/create-tech-spec/steps/step-01-understand.md +189 -189
- package/bmad/bmm/workflows/bmad-quick-flow/create-tech-spec/steps/step-02-investigate.md +144 -144
- package/bmad/bmm/workflows/bmad-quick-flow/create-tech-spec/steps/step-03-generate.md +128 -128
- package/bmad/bmm/workflows/bmad-quick-flow/create-tech-spec/steps/step-04-review.md +173 -173
- package/bmad/bmm/workflows/bmad-quick-flow/create-tech-spec/tech-spec-template.md +74 -74
- package/bmad/bmm/workflows/bmad-quick-flow/create-tech-spec/workflow.md +79 -79
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +156 -156
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +120 -120
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +113 -113
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +113 -113
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +106 -106
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +140 -140
- package/bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +52 -52
- package/bmad/bmm/workflows/document-project/checklist.md +245 -245
- package/bmad/bmm/workflows/document-project/documentation-requirements.csv +12 -12
- package/bmad/bmm/workflows/document-project/instructions.md +221 -221
- package/bmad/bmm/workflows/document-project/templates/deep-dive-template.md +345 -345
- package/bmad/bmm/workflows/document-project/templates/index-template.md +169 -169
- package/bmad/bmm/workflows/document-project/templates/project-overview-template.md +103 -103
- package/bmad/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -160
- package/bmad/bmm/workflows/document-project/templates/source-tree-template.md +135 -135
- package/bmad/bmm/workflows/document-project/workflow.yaml +28 -28
- package/bmad/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -298
- package/bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -31
- package/bmad/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -1106
- package/bmad/bmm/workflows/document-project/workflows/full-scan.yaml +31 -31
- package/bmad/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-library.json +90 -90
- package/bmad/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-templates.yaml +127 -127
- package/bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/checklist.md +39 -39
- package/bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/instructions.md +130 -130
- package/bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml +25 -25
- package/bmad/bmm/workflows/excalidraw-diagrams/create-diagram/checklist.md +43 -43
- package/bmad/bmm/workflows/excalidraw-diagrams/create-diagram/instructions.md +141 -141
- package/bmad/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml +25 -25
- package/bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/checklist.md +49 -49
- package/bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/instructions.md +241 -241
- package/bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml +25 -25
- package/bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/checklist.md +38 -38
- package/bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/instructions.md +133 -133
- package/bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml +25 -25
- package/bmad/bmm/workflows/generate-project-context/project-context-template.md +21 -21
- package/bmad/bmm/workflows/generate-project-context/steps/step-01-discover.md +218 -218
- package/bmad/bmm/workflows/generate-project-context/steps/step-02-generate.md +318 -318
- package/bmad/bmm/workflows/generate-project-context/steps/step-03-complete.md +278 -278
- package/bmad/bmm/workflows/generate-project-context/workflow.md +50 -50
- package/bmad/bmm/workflows/testarch/atdd/atdd-checklist-template.md +364 -364
- package/bmad/bmm/workflows/testarch/atdd/checklist.md +374 -374
- package/bmad/bmm/workflows/testarch/atdd/instructions.md +806 -806
- package/bmad/bmm/workflows/testarch/atdd/workflow.yaml +45 -45
- package/bmad/bmm/workflows/testarch/automate/checklist.md +582 -582
- package/bmad/bmm/workflows/testarch/automate/instructions.md +1324 -1324
- package/bmad/bmm/workflows/testarch/automate/workflow.yaml +52 -52
- package/bmad/bmm/workflows/testarch/ci/checklist.md +248 -248
- package/bmad/bmm/workflows/testarch/ci/github-actions-template.yaml +198 -198
- package/bmad/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +149 -149
- package/bmad/bmm/workflows/testarch/ci/instructions.md +536 -536
- package/bmad/bmm/workflows/testarch/ci/workflow.yaml +45 -45
- package/bmad/bmm/workflows/testarch/framework/checklist.md +321 -321
- package/bmad/bmm/workflows/testarch/framework/instructions.md +481 -481
- package/bmad/bmm/workflows/testarch/framework/workflow.yaml +47 -47
- package/bmad/bmm/workflows/testarch/nfr-assess/checklist.md +407 -407
- package/bmad/bmm/workflows/testarch/nfr-assess/instructions.md +722 -722
- package/bmad/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +445 -445
- package/bmad/bmm/workflows/testarch/nfr-assess/workflow.yaml +47 -47
- package/bmad/bmm/workflows/testarch/test-design/checklist.md +235 -235
- package/bmad/bmm/workflows/testarch/test-design/instructions.md +788 -788
- package/bmad/bmm/workflows/testarch/test-design/test-design-template.md +294 -294
- package/bmad/bmm/workflows/testarch/test-design/workflow.yaml +54 -54
- package/bmad/bmm/workflows/testarch/test-review/checklist.md +472 -472
- package/bmad/bmm/workflows/testarch/test-review/instructions.md +628 -628
- package/bmad/bmm/workflows/testarch/test-review/test-review-template.md +390 -390
- package/bmad/bmm/workflows/testarch/test-review/workflow.yaml +46 -46
- package/bmad/bmm/workflows/testarch/trace/checklist.md +655 -655
- package/bmad/bmm/workflows/testarch/trace/instructions.md +1047 -1047
- package/bmad/bmm/workflows/testarch/trace/trace-template.md +675 -675
- package/bmad/bmm/workflows/testarch/trace/workflow.yaml +55 -55
- package/bmad/bmm/workflows/workflow-status/init/instructions.md +346 -346
- package/bmad/bmm/workflows/workflow-status/init/workflow.yaml +28 -28
- package/bmad/bmm/workflows/workflow-status/instructions.md +395 -395
- package/bmad/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +103 -103
- package/bmad/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +100 -100
- package/bmad/bmm/workflows/workflow-status/paths/method-brownfield.yaml +103 -103
- package/bmad/bmm/workflows/workflow-status/paths/method-greenfield.yaml +100 -100
- package/bmad/bmm/workflows/workflow-status/project-levels.yaml +59 -59
- package/bmad/bmm/workflows/workflow-status/workflow-status-template.yaml +24 -24
- package/bmad/bmm/workflows/workflow-status/workflow.yaml +30 -30
- package/bmad/cis/agents/brainstorming-coach.md +60 -60
- package/bmad/cis/agents/creative-problem-solver.md +60 -60
- package/bmad/cis/agents/design-thinking-coach.md +60 -60
- package/bmad/cis/agents/innovation-strategist.md +60 -60
- package/bmad/cis/agents/presentation-master.md +66 -66
- package/bmad/cis/agents/storyteller/storyteller.md +57 -57
- package/bmad/cis/config.yaml +11 -11
- package/bmad/cis/teams/creative-squad.yaml +7 -7
- package/bmad/cis/teams/default-party.csv +12 -12
- package/bmad/cis/workflows/README.md +139 -139
- package/bmad/cis/workflows/design-thinking/README.md +56 -56
- package/bmad/cis/workflows/design-thinking/design-methods.csv +30 -30
- package/bmad/cis/workflows/design-thinking/instructions.md +202 -202
- package/bmad/cis/workflows/design-thinking/template.md +111 -111
- package/bmad/cis/workflows/design-thinking/workflow.yaml +27 -27
- package/bmad/cis/workflows/innovation-strategy/README.md +56 -56
- package/bmad/cis/workflows/innovation-strategy/innovation-frameworks.csv +30 -30
- package/bmad/cis/workflows/innovation-strategy/instructions.md +276 -276
- package/bmad/cis/workflows/innovation-strategy/template.md +189 -189
- package/bmad/cis/workflows/innovation-strategy/workflow.yaml +27 -27
- package/bmad/cis/workflows/problem-solving/README.md +56 -56
- package/bmad/cis/workflows/problem-solving/instructions.md +252 -252
- package/bmad/cis/workflows/problem-solving/solving-methods.csv +30 -30
- package/bmad/cis/workflows/problem-solving/template.md +165 -165
- package/bmad/cis/workflows/problem-solving/workflow.yaml +27 -27
- package/bmad/cis/workflows/storytelling/README.md +58 -58
- package/bmad/cis/workflows/storytelling/instructions.md +293 -293
- package/bmad/cis/workflows/storytelling/story-types.csv +25 -25
- package/bmad/cis/workflows/storytelling/template.md +113 -113
- package/bmad/cis/workflows/storytelling/workflow.yaml +27 -27
- package/bmad/core/agents/bmad-master.md +57 -57
- package/bmad/core/config.yaml +9 -9
- package/bmad/core/resources/excalidraw/README.md +160 -160
- package/bmad/core/resources/excalidraw/excalidraw-helpers.md +127 -127
- package/bmad/core/resources/excalidraw/library-loader.md +50 -50
- package/bmad/core/resources/excalidraw/validate-json-instructions.md +79 -79
- package/bmad/core/tasks/index-docs.xml +64 -64
- package/bmad/core/tasks/review-adversarial-general.xml +41 -41
- package/bmad/core/tasks/shard-doc.xml +108 -108
- package/bmad/core/tasks/validate-workflow.xml +88 -88
- package/bmad/core/tasks/workflow.xml +234 -234
- package/bmad/core/workflows/advanced-elicitation/methods.csv +51 -51
- package/bmad/core/workflows/advanced-elicitation/workflow.xml +116 -116
- package/bmad/core/workflows/brainstorming/brain-methods.csv +61 -61
- package/bmad/core/workflows/brainstorming/steps/step-01-session-setup.md +197 -197
- package/bmad/core/workflows/brainstorming/steps/step-01b-continue.md +122 -122
- package/bmad/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -225
- package/bmad/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -237
- package/bmad/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -209
- package/bmad/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -264
- package/bmad/core/workflows/brainstorming/steps/step-03-technique-execution.md +340 -340
- package/bmad/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -303
- package/bmad/core/workflows/brainstorming/template.md +15 -15
- package/bmad/core/workflows/brainstorming/workflow.md +51 -51
- package/bmad/core/workflows/party-mode/steps/step-01-agent-loading.md +139 -139
- package/bmad/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +204 -204
- package/bmad/core/workflows/party-mode/steps/step-03-graceful-exit.md +159 -159
- package/bmad/core/workflows/party-mode/workflow.md +206 -206
- package/claude/hooks/file-restriction-hook.py +51 -51
- package/claude/hooks/track-agent.py +67 -67
- package/claude/settings.local.json +76 -76
- package/gemini/commands/BMad/agents/analyst.toml +6 -0
- package/gemini/commands/BMad/agents/architect.toml +6 -0
- package/gemini/commands/BMad/agents/bmad-master.toml +6 -0
- package/gemini/commands/BMad/agents/bmad-orchestrator.toml +6 -0
- package/gemini/commands/BMad/agents/dev.toml +6 -0
- package/gemini/commands/BMad/agents/pm.toml +6 -0
- package/gemini/commands/BMad/agents/po.toml +6 -0
- package/gemini/commands/BMad/agents/qa.toml +6 -0
- package/gemini/commands/BMad/agents/sm.toml +6 -0
- package/gemini/commands/BMad/agents/ux-expert.toml +6 -0
- package/gemini/commands/BMad/tasks/advanced-elicitation.toml +6 -0
- package/gemini/commands/BMad/tasks/apply-qa-fixes.toml +6 -0
- package/gemini/commands/BMad/tasks/brownfield-create-epic.toml +6 -0
- package/gemini/commands/BMad/tasks/brownfield-create-story.toml +6 -0
- package/gemini/commands/BMad/tasks/correct-course.toml +6 -0
- package/gemini/commands/BMad/tasks/create-brownfield-story.toml +6 -0
- package/gemini/commands/BMad/tasks/create-deep-research-prompt.toml +6 -0
- package/gemini/commands/BMad/tasks/create-doc.toml +6 -0
- package/gemini/commands/BMad/tasks/create-next-story.toml +6 -0
- package/gemini/commands/BMad/tasks/document-project.toml +6 -0
- package/gemini/commands/BMad/tasks/execute-checklist.toml +6 -0
- package/gemini/commands/BMad/tasks/facilitate-brainstorming-session.toml +6 -0
- package/gemini/commands/BMad/tasks/generate-ai-frontend-prompt.toml +6 -0
- package/gemini/commands/BMad/tasks/index-docs.toml +6 -0
- package/gemini/commands/BMad/tasks/kb-mode-interaction.toml +6 -0
- package/gemini/commands/BMad/tasks/nfr-assess.toml +6 -0
- package/gemini/commands/BMad/tasks/qa-gate.toml +6 -0
- package/gemini/commands/BMad/tasks/review-story.toml +6 -0
- package/gemini/commands/BMad/tasks/risk-profile.toml +6 -0
- package/gemini/commands/BMad/tasks/shard-doc.toml +6 -0
- package/gemini/commands/BMad/tasks/test-design.toml +6 -0
- package/gemini/commands/BMad/tasks/trace-requirements.toml +6 -0
- package/gemini/commands/BMad/tasks/validate-next-story.toml +6 -0
- package/github/workflows/publish.yml +150 -150
- package/index.js +9 -9
- package/mcp.json +14 -14
- package/package.json +41 -40
- package/resources/images/Siesa_Logosimbolo_Azul.svg +24 -24
- package/resources/images/Siesa_Logosimbolo_Blanco.svg +24 -24
- package/resources/images/Siesa_Simbolo_Azul.svg +14 -14
- package/resources/images/Siesa_Simbolo_Blanco.svg +14 -14
- package/vscode/mcp.json +15 -15
- package/vscode/settings.json +12 -12
|
@@ -1,675 +1,675 @@
|
|
|
1
|
-
# CI Pipeline and Burn-In Strategy
|
|
2
|
-
|
|
3
|
-
## Principle
|
|
4
|
-
|
|
5
|
-
CI pipelines must execute tests reliably, quickly, and provide clear feedback. Burn-in testing (running changed tests multiple times) flushes out flakiness before merge. Stage jobs strategically: install/cache once, run changed specs first for fast feedback, then shard full suites with fail-fast disabled to preserve evidence.
|
|
6
|
-
|
|
7
|
-
## Rationale
|
|
8
|
-
|
|
9
|
-
CI is the quality gate for production. A poorly configured pipeline either wastes developer time (slow feedback, false positives) or ships broken code (false negatives, insufficient coverage). Burn-in testing ensures reliability by stress-testing changed code, while parallel execution and intelligent test selection optimize speed without sacrificing thoroughness.
|
|
10
|
-
|
|
11
|
-
## Pattern Examples
|
|
12
|
-
|
|
13
|
-
### Example 1: GitHub Actions Workflow with Parallel Execution
|
|
14
|
-
|
|
15
|
-
**Context**: Production-ready CI/CD pipeline for E2E tests with caching, parallelization, and burn-in testing.
|
|
16
|
-
|
|
17
|
-
**Implementation**:
|
|
18
|
-
|
|
19
|
-
```yaml
|
|
20
|
-
# .github/workflows/e2e-tests.yml
|
|
21
|
-
name: E2E Tests
|
|
22
|
-
on:
|
|
23
|
-
pull_request:
|
|
24
|
-
push:
|
|
25
|
-
branches: [main, develop]
|
|
26
|
-
|
|
27
|
-
env:
|
|
28
|
-
NODE_VERSION_FILE: '.nvmrc'
|
|
29
|
-
CACHE_KEY: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
30
|
-
|
|
31
|
-
jobs:
|
|
32
|
-
install-dependencies:
|
|
33
|
-
name: Install & Cache Dependencies
|
|
34
|
-
runs-on: ubuntu-latest
|
|
35
|
-
timeout-minutes: 10
|
|
36
|
-
steps:
|
|
37
|
-
- name: Checkout code
|
|
38
|
-
uses: actions/checkout@v4
|
|
39
|
-
|
|
40
|
-
- name: Setup Node.js
|
|
41
|
-
uses: actions/setup-node@v4
|
|
42
|
-
with:
|
|
43
|
-
node-version-file: ${{ env.NODE_VERSION_FILE }}
|
|
44
|
-
cache: 'npm'
|
|
45
|
-
|
|
46
|
-
- name: Cache node modules
|
|
47
|
-
uses: actions/cache@v4
|
|
48
|
-
id: npm-cache
|
|
49
|
-
with:
|
|
50
|
-
path: |
|
|
51
|
-
~/.npm
|
|
52
|
-
node_modules
|
|
53
|
-
~/.cache/Cypress
|
|
54
|
-
~/.cache/ms-playwright
|
|
55
|
-
key: ${{ env.CACHE_KEY }}
|
|
56
|
-
restore-keys: |
|
|
57
|
-
${{ runner.os }}-node-
|
|
58
|
-
|
|
59
|
-
- name: Install dependencies
|
|
60
|
-
if: steps.npm-cache.outputs.cache-hit != 'true'
|
|
61
|
-
run: npm ci --prefer-offline --no-audit
|
|
62
|
-
|
|
63
|
-
- name: Install Playwright browsers
|
|
64
|
-
if: steps.npm-cache.outputs.cache-hit != 'true'
|
|
65
|
-
run: npx playwright install --with-deps chromium
|
|
66
|
-
|
|
67
|
-
test-changed-specs:
|
|
68
|
-
name: Test Changed Specs First (Burn-In)
|
|
69
|
-
needs: install-dependencies
|
|
70
|
-
runs-on: ubuntu-latest
|
|
71
|
-
timeout-minutes: 15
|
|
72
|
-
steps:
|
|
73
|
-
- name: Checkout code
|
|
74
|
-
uses: actions/checkout@v4
|
|
75
|
-
with:
|
|
76
|
-
fetch-depth: 0 # Full history for accurate diff
|
|
77
|
-
|
|
78
|
-
- name: Setup Node.js
|
|
79
|
-
uses: actions/setup-node@v4
|
|
80
|
-
with:
|
|
81
|
-
node-version-file: ${{ env.NODE_VERSION_FILE }}
|
|
82
|
-
cache: 'npm'
|
|
83
|
-
|
|
84
|
-
- name: Restore dependencies
|
|
85
|
-
uses: actions/cache@v4
|
|
86
|
-
with:
|
|
87
|
-
path: |
|
|
88
|
-
~/.npm
|
|
89
|
-
node_modules
|
|
90
|
-
~/.cache/ms-playwright
|
|
91
|
-
key: ${{ env.CACHE_KEY }}
|
|
92
|
-
|
|
93
|
-
- name: Detect changed test files
|
|
94
|
-
id: changed-tests
|
|
95
|
-
run: |
|
|
96
|
-
CHANGED_SPECS=$(git diff --name-only origin/main...HEAD | grep -E '\.(spec|test)\.(ts|js|tsx|jsx)$' || echo "")
|
|
97
|
-
echo "changed_specs=${CHANGED_SPECS}" >> $GITHUB_OUTPUT
|
|
98
|
-
echo "Changed specs: ${CHANGED_SPECS}"
|
|
99
|
-
|
|
100
|
-
- name: Run burn-in on changed specs (10 iterations)
|
|
101
|
-
if: steps.changed-tests.outputs.changed_specs != ''
|
|
102
|
-
run: |
|
|
103
|
-
SPECS="${{ steps.changed-tests.outputs.changed_specs }}"
|
|
104
|
-
echo "Running burn-in: 10 iterations on changed specs"
|
|
105
|
-
for i in {1..10}; do
|
|
106
|
-
echo "Burn-in iteration $i/10"
|
|
107
|
-
npm run test -- $SPECS || {
|
|
108
|
-
echo "❌ Burn-in failed on iteration $i"
|
|
109
|
-
exit 1
|
|
110
|
-
}
|
|
111
|
-
done
|
|
112
|
-
echo "✅ Burn-in passed - 10/10 successful runs"
|
|
113
|
-
|
|
114
|
-
- name: Upload artifacts on failure
|
|
115
|
-
if: failure()
|
|
116
|
-
uses: actions/upload-artifact@v4
|
|
117
|
-
with:
|
|
118
|
-
name: burn-in-failure-artifacts
|
|
119
|
-
path: |
|
|
120
|
-
test-results/
|
|
121
|
-
playwright-report/
|
|
122
|
-
screenshots/
|
|
123
|
-
retention-days: 7
|
|
124
|
-
|
|
125
|
-
test-e2e-sharded:
|
|
126
|
-
name: E2E Tests (Shard ${{ matrix.shard }}/${{ strategy.job-total }})
|
|
127
|
-
needs: [install-dependencies, test-changed-specs]
|
|
128
|
-
runs-on: ubuntu-latest
|
|
129
|
-
timeout-minutes: 30
|
|
130
|
-
strategy:
|
|
131
|
-
fail-fast: false # Run all shards even if one fails
|
|
132
|
-
matrix:
|
|
133
|
-
shard: [1, 2, 3, 4]
|
|
134
|
-
steps:
|
|
135
|
-
- name: Checkout code
|
|
136
|
-
uses: actions/checkout@v4
|
|
137
|
-
|
|
138
|
-
- name: Setup Node.js
|
|
139
|
-
uses: actions/setup-node@v4
|
|
140
|
-
with:
|
|
141
|
-
node-version-file: ${{ env.NODE_VERSION_FILE }}
|
|
142
|
-
cache: 'npm'
|
|
143
|
-
|
|
144
|
-
- name: Restore dependencies
|
|
145
|
-
uses: actions/cache@v4
|
|
146
|
-
with:
|
|
147
|
-
path: |
|
|
148
|
-
~/.npm
|
|
149
|
-
node_modules
|
|
150
|
-
~/.cache/ms-playwright
|
|
151
|
-
key: ${{ env.CACHE_KEY }}
|
|
152
|
-
|
|
153
|
-
- name: Run E2E tests (shard ${{ matrix.shard }})
|
|
154
|
-
run: npm run test:e2e -- --shard=${{ matrix.shard }}/4
|
|
155
|
-
env:
|
|
156
|
-
TEST_ENV: staging
|
|
157
|
-
CI: true
|
|
158
|
-
|
|
159
|
-
- name: Upload test results
|
|
160
|
-
if: always()
|
|
161
|
-
uses: actions/upload-artifact@v4
|
|
162
|
-
with:
|
|
163
|
-
name: test-results-shard-${{ matrix.shard }}
|
|
164
|
-
path: |
|
|
165
|
-
test-results/
|
|
166
|
-
playwright-report/
|
|
167
|
-
retention-days: 30
|
|
168
|
-
|
|
169
|
-
- name: Upload JUnit report
|
|
170
|
-
if: always()
|
|
171
|
-
uses: actions/upload-artifact@v4
|
|
172
|
-
with:
|
|
173
|
-
name: junit-results-shard-${{ matrix.shard }}
|
|
174
|
-
path: test-results/junit.xml
|
|
175
|
-
retention-days: 30
|
|
176
|
-
|
|
177
|
-
merge-test-results:
|
|
178
|
-
name: Merge Test Results & Generate Report
|
|
179
|
-
needs: test-e2e-sharded
|
|
180
|
-
runs-on: ubuntu-latest
|
|
181
|
-
if: always()
|
|
182
|
-
steps:
|
|
183
|
-
- name: Download all shard results
|
|
184
|
-
uses: actions/download-artifact@v4
|
|
185
|
-
with:
|
|
186
|
-
pattern: test-results-shard-*
|
|
187
|
-
path: all-results/
|
|
188
|
-
|
|
189
|
-
- name: Merge HTML reports
|
|
190
|
-
run: |
|
|
191
|
-
npx playwright merge-reports --reporter=html all-results/
|
|
192
|
-
echo "Merged report available in playwright-report/"
|
|
193
|
-
|
|
194
|
-
- name: Upload merged report
|
|
195
|
-
uses: actions/upload-artifact@v4
|
|
196
|
-
with:
|
|
197
|
-
name: merged-playwright-report
|
|
198
|
-
path: playwright-report/
|
|
199
|
-
retention-days: 30
|
|
200
|
-
|
|
201
|
-
- name: Comment PR with results
|
|
202
|
-
if: github.event_name == 'pull_request'
|
|
203
|
-
uses: daun/playwright-report-comment@v3
|
|
204
|
-
with:
|
|
205
|
-
report-path: playwright-report/
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
**Key Points**:
|
|
209
|
-
|
|
210
|
-
- **Install once, reuse everywhere**: Dependencies cached across all jobs
|
|
211
|
-
- **Burn-in first**: Changed specs run 10x before full suite
|
|
212
|
-
- **Fail-fast disabled**: All shards run to completion for full evidence
|
|
213
|
-
- **Parallel execution**: 4 shards cut execution time by ~75%
|
|
214
|
-
- **Artifact retention**: 30 days for reports, 7 days for failure debugging
|
|
215
|
-
|
|
216
|
-
---
|
|
217
|
-
|
|
218
|
-
### Example 2: Burn-In Loop Pattern (Standalone Script)
|
|
219
|
-
|
|
220
|
-
**Context**: Reusable bash script for burn-in testing changed specs locally or in CI.
|
|
221
|
-
|
|
222
|
-
**Implementation**:
|
|
223
|
-
|
|
224
|
-
```bash
|
|
225
|
-
#!/bin/bash
|
|
226
|
-
# scripts/burn-in-changed.sh
|
|
227
|
-
# Usage: ./scripts/burn-in-changed.sh [iterations] [base-branch]
|
|
228
|
-
|
|
229
|
-
set -e # Exit on error
|
|
230
|
-
|
|
231
|
-
# Configuration
|
|
232
|
-
ITERATIONS=${1:-10}
|
|
233
|
-
BASE_BRANCH=${2:-main}
|
|
234
|
-
SPEC_PATTERN='\.(spec|test)\.(ts|js|tsx|jsx)$'
|
|
235
|
-
|
|
236
|
-
echo "🔥 Burn-In Test Runner"
|
|
237
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
238
|
-
echo "Iterations: $ITERATIONS"
|
|
239
|
-
echo "Base branch: $BASE_BRANCH"
|
|
240
|
-
echo ""
|
|
241
|
-
|
|
242
|
-
# Detect changed test files
|
|
243
|
-
echo "📋 Detecting changed test files..."
|
|
244
|
-
CHANGED_SPECS=$(git diff --name-only $BASE_BRANCH...HEAD | grep -E "$SPEC_PATTERN" || echo "")
|
|
245
|
-
|
|
246
|
-
if [ -z "$CHANGED_SPECS" ]; then
|
|
247
|
-
echo "✅ No test files changed. Skipping burn-in."
|
|
248
|
-
exit 0
|
|
249
|
-
fi
|
|
250
|
-
|
|
251
|
-
echo "Changed test files:"
|
|
252
|
-
echo "$CHANGED_SPECS" | sed 's/^/ - /'
|
|
253
|
-
echo ""
|
|
254
|
-
|
|
255
|
-
# Count specs
|
|
256
|
-
SPEC_COUNT=$(echo "$CHANGED_SPECS" | wc -l | xargs)
|
|
257
|
-
echo "Running burn-in on $SPEC_COUNT test file(s)..."
|
|
258
|
-
echo ""
|
|
259
|
-
|
|
260
|
-
# Burn-in loop
|
|
261
|
-
FAILURES=()
|
|
262
|
-
for i in $(seq 1 $ITERATIONS); do
|
|
263
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
264
|
-
echo "🔄 Iteration $i/$ITERATIONS"
|
|
265
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
266
|
-
|
|
267
|
-
# Run tests with explicit file list
|
|
268
|
-
if npm run test -- $CHANGED_SPECS 2>&1 | tee "burn-in-log-$i.txt"; then
|
|
269
|
-
echo "✅ Iteration $i passed"
|
|
270
|
-
else
|
|
271
|
-
echo "❌ Iteration $i failed"
|
|
272
|
-
FAILURES+=($i)
|
|
273
|
-
|
|
274
|
-
# Save failure artifacts
|
|
275
|
-
mkdir -p burn-in-failures/iteration-$i
|
|
276
|
-
cp -r test-results/ burn-in-failures/iteration-$i/ 2>/dev/null || true
|
|
277
|
-
cp -r screenshots/ burn-in-failures/iteration-$i/ 2>/dev/null || true
|
|
278
|
-
|
|
279
|
-
echo ""
|
|
280
|
-
echo "🛑 BURN-IN FAILED on iteration $i"
|
|
281
|
-
echo "Failure artifacts saved to: burn-in-failures/iteration-$i/"
|
|
282
|
-
echo "Logs saved to: burn-in-log-$i.txt"
|
|
283
|
-
echo ""
|
|
284
|
-
exit 1
|
|
285
|
-
fi
|
|
286
|
-
|
|
287
|
-
echo ""
|
|
288
|
-
done
|
|
289
|
-
|
|
290
|
-
# Success summary
|
|
291
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
292
|
-
echo "🎉 BURN-IN PASSED"
|
|
293
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
294
|
-
echo "All $ITERATIONS iterations passed for $SPEC_COUNT test file(s)"
|
|
295
|
-
echo "Changed specs are stable and ready to merge."
|
|
296
|
-
echo ""
|
|
297
|
-
|
|
298
|
-
# Cleanup logs
|
|
299
|
-
rm -f burn-in-log-*.txt
|
|
300
|
-
|
|
301
|
-
exit 0
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
**Usage**:
|
|
305
|
-
|
|
306
|
-
```bash
|
|
307
|
-
# Run locally with default settings (10 iterations, compare to main)
|
|
308
|
-
./scripts/burn-in-changed.sh
|
|
309
|
-
|
|
310
|
-
# Custom iterations and base branch
|
|
311
|
-
./scripts/burn-in-changed.sh 20 develop
|
|
312
|
-
|
|
313
|
-
# Add to package.json
|
|
314
|
-
{
|
|
315
|
-
"scripts": {
|
|
316
|
-
"test:burn-in": "bash scripts/burn-in-changed.sh",
|
|
317
|
-
"test:burn-in:strict": "bash scripts/burn-in-changed.sh 20"
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
**Key Points**:
|
|
323
|
-
|
|
324
|
-
- **Exit on first failure**: Flaky tests caught immediately
|
|
325
|
-
- **Failure artifacts**: Saved per-iteration for debugging
|
|
326
|
-
- **Flexible configuration**: Iterations and base branch customizable
|
|
327
|
-
- **CI/local parity**: Same script runs in both environments
|
|
328
|
-
- **Clear output**: Visual feedback on progress and results
|
|
329
|
-
|
|
330
|
-
---
|
|
331
|
-
|
|
332
|
-
### Example 3: Shard Orchestration with Result Aggregation
|
|
333
|
-
|
|
334
|
-
**Context**: Advanced sharding strategy for large test suites with intelligent result merging.
|
|
335
|
-
|
|
336
|
-
**Implementation**:
|
|
337
|
-
|
|
338
|
-
```javascript
|
|
339
|
-
// scripts/run-sharded-tests.js
|
|
340
|
-
const { spawn } = require('child_process');
|
|
341
|
-
const fs = require('fs');
|
|
342
|
-
const path = require('path');
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Run tests across multiple shards and aggregate results
|
|
346
|
-
* Usage: node scripts/run-sharded-tests.js --shards=4 --env=staging
|
|
347
|
-
*/
|
|
348
|
-
|
|
349
|
-
const SHARD_COUNT = parseInt(process.env.SHARD_COUNT || '4');
|
|
350
|
-
const TEST_ENV = process.env.TEST_ENV || 'local';
|
|
351
|
-
const RESULTS_DIR = path.join(__dirname, '../test-results');
|
|
352
|
-
|
|
353
|
-
console.log(`🚀 Running tests across ${SHARD_COUNT} shards`);
|
|
354
|
-
console.log(`Environment: ${TEST_ENV}`);
|
|
355
|
-
console.log('━'.repeat(50));
|
|
356
|
-
|
|
357
|
-
// Ensure results directory exists
|
|
358
|
-
if (!fs.existsSync(RESULTS_DIR)) {
|
|
359
|
-
fs.mkdirSync(RESULTS_DIR, { recursive: true });
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* Run a single shard
|
|
364
|
-
*/
|
|
365
|
-
function runShard(shardIndex) {
|
|
366
|
-
return new Promise((resolve, reject) => {
|
|
367
|
-
const shardId = `${shardIndex}/${SHARD_COUNT}`;
|
|
368
|
-
console.log(`\n📦 Starting shard ${shardId}...`);
|
|
369
|
-
|
|
370
|
-
const child = spawn('npx', ['playwright', 'test', `--shard=${shardId}`, '--reporter=json'], {
|
|
371
|
-
env: { ...process.env, TEST_ENV, SHARD_INDEX: shardIndex },
|
|
372
|
-
stdio: 'pipe',
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
let stdout = '';
|
|
376
|
-
let stderr = '';
|
|
377
|
-
|
|
378
|
-
child.stdout.on('data', (data) => {
|
|
379
|
-
stdout += data.toString();
|
|
380
|
-
process.stdout.write(data);
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
child.stderr.on('data', (data) => {
|
|
384
|
-
stderr += data.toString();
|
|
385
|
-
process.stderr.write(data);
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
child.on('close', (code) => {
|
|
389
|
-
// Save shard results
|
|
390
|
-
const resultFile = path.join(RESULTS_DIR, `shard-${shardIndex}.json`);
|
|
391
|
-
try {
|
|
392
|
-
const result = JSON.parse(stdout);
|
|
393
|
-
fs.writeFileSync(resultFile, JSON.stringify(result, null, 2));
|
|
394
|
-
console.log(`✅ Shard ${shardId} completed (exit code: ${code})`);
|
|
395
|
-
resolve({ shardIndex, code, result });
|
|
396
|
-
} catch (error) {
|
|
397
|
-
console.error(`❌ Shard ${shardId} failed to parse results:`, error.message);
|
|
398
|
-
reject({ shardIndex, code, error });
|
|
399
|
-
}
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
child.on('error', (error) => {
|
|
403
|
-
console.error(`❌ Shard ${shardId} process error:`, error.message);
|
|
404
|
-
reject({ shardIndex, error });
|
|
405
|
-
});
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* Aggregate results from all shards
|
|
411
|
-
*/
|
|
412
|
-
function aggregateResults() {
|
|
413
|
-
console.log('\n📊 Aggregating results from all shards...');
|
|
414
|
-
|
|
415
|
-
const shardResults = [];
|
|
416
|
-
let totalTests = 0;
|
|
417
|
-
let totalPassed = 0;
|
|
418
|
-
let totalFailed = 0;
|
|
419
|
-
let totalSkipped = 0;
|
|
420
|
-
let totalFlaky = 0;
|
|
421
|
-
|
|
422
|
-
for (let i = 1; i <= SHARD_COUNT; i++) {
|
|
423
|
-
const resultFile = path.join(RESULTS_DIR, `shard-${i}.json`);
|
|
424
|
-
if (fs.existsSync(resultFile)) {
|
|
425
|
-
const result = JSON.parse(fs.readFileSync(resultFile, 'utf8'));
|
|
426
|
-
shardResults.push(result);
|
|
427
|
-
|
|
428
|
-
// Aggregate stats
|
|
429
|
-
totalTests += result.stats?.expected || 0;
|
|
430
|
-
totalPassed += result.stats?.expected || 0;
|
|
431
|
-
totalFailed += result.stats?.unexpected || 0;
|
|
432
|
-
totalSkipped += result.stats?.skipped || 0;
|
|
433
|
-
totalFlaky += result.stats?.flaky || 0;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
const summary = {
|
|
438
|
-
totalShards: SHARD_COUNT,
|
|
439
|
-
environment: TEST_ENV,
|
|
440
|
-
totalTests,
|
|
441
|
-
passed: totalPassed,
|
|
442
|
-
failed: totalFailed,
|
|
443
|
-
skipped: totalSkipped,
|
|
444
|
-
flaky: totalFlaky,
|
|
445
|
-
duration: shardResults.reduce((acc, r) => acc + (r.duration || 0), 0),
|
|
446
|
-
timestamp: new Date().toISOString(),
|
|
447
|
-
};
|
|
448
|
-
|
|
449
|
-
// Save aggregated summary
|
|
450
|
-
fs.writeFileSync(path.join(RESULTS_DIR, 'summary.json'), JSON.stringify(summary, null, 2));
|
|
451
|
-
|
|
452
|
-
console.log('\n━'.repeat(50));
|
|
453
|
-
console.log('📈 Test Results Summary');
|
|
454
|
-
console.log('━'.repeat(50));
|
|
455
|
-
console.log(`Total tests: ${totalTests}`);
|
|
456
|
-
console.log(`✅ Passed: ${totalPassed}`);
|
|
457
|
-
console.log(`❌ Failed: ${totalFailed}`);
|
|
458
|
-
console.log(`⏭️ Skipped: ${totalSkipped}`);
|
|
459
|
-
console.log(`⚠️ Flaky: ${totalFlaky}`);
|
|
460
|
-
console.log(`⏱️ Duration: ${(summary.duration / 1000).toFixed(2)}s`);
|
|
461
|
-
console.log('━'.repeat(50));
|
|
462
|
-
|
|
463
|
-
return summary;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* Main execution
|
|
468
|
-
*/
|
|
469
|
-
async function main() {
|
|
470
|
-
const startTime = Date.now();
|
|
471
|
-
const shardPromises = [];
|
|
472
|
-
|
|
473
|
-
// Run all shards in parallel
|
|
474
|
-
for (let i = 1; i <= SHARD_COUNT; i++) {
|
|
475
|
-
shardPromises.push(runShard(i));
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
try {
|
|
479
|
-
await Promise.allSettled(shardPromises);
|
|
480
|
-
} catch (error) {
|
|
481
|
-
console.error('❌ One or more shards failed:', error);
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// Aggregate results
|
|
485
|
-
const summary = aggregateResults();
|
|
486
|
-
|
|
487
|
-
const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
488
|
-
console.log(`\n⏱️ Total execution time: ${totalTime}s`);
|
|
489
|
-
|
|
490
|
-
// Exit with failure if any tests failed
|
|
491
|
-
if (summary.failed > 0) {
|
|
492
|
-
console.error('\n❌ Test suite failed');
|
|
493
|
-
process.exit(1);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
console.log('\n✅ All tests passed');
|
|
497
|
-
process.exit(0);
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
main().catch((error) => {
|
|
501
|
-
console.error('Fatal error:', error);
|
|
502
|
-
process.exit(1);
|
|
503
|
-
});
|
|
504
|
-
```
|
|
505
|
-
|
|
506
|
-
**package.json integration**:
|
|
507
|
-
|
|
508
|
-
```json
|
|
509
|
-
{
|
|
510
|
-
"scripts": {
|
|
511
|
-
"test:sharded": "node scripts/run-sharded-tests.js",
|
|
512
|
-
"test:sharded:ci": "SHARD_COUNT=8 TEST_ENV=staging node scripts/run-sharded-tests.js"
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
```
|
|
516
|
-
|
|
517
|
-
**Key Points**:
|
|
518
|
-
|
|
519
|
-
- **Parallel shard execution**: All shards run simultaneously
|
|
520
|
-
- **Result aggregation**: Unified summary across shards
|
|
521
|
-
- **Failure detection**: Exit code reflects overall test status
|
|
522
|
-
- **Artifact preservation**: Individual shard results saved for debugging
|
|
523
|
-
- **CI/local compatibility**: Same script works in both environments
|
|
524
|
-
|
|
525
|
-
---
|
|
526
|
-
|
|
527
|
-
### Example 4: Selective Test Execution (Changed Files + Tags)
|
|
528
|
-
|
|
529
|
-
**Context**: Optimize CI by running only relevant tests based on file changes and tags.
|
|
530
|
-
|
|
531
|
-
**Implementation**:
|
|
532
|
-
|
|
533
|
-
```bash
|
|
534
|
-
#!/bin/bash
|
|
535
|
-
# scripts/selective-test-runner.sh
|
|
536
|
-
# Intelligent test selection based on changed files and test tags
|
|
537
|
-
|
|
538
|
-
set -e
|
|
539
|
-
|
|
540
|
-
BASE_BRANCH=${BASE_BRANCH:-main}
|
|
541
|
-
TEST_ENV=${TEST_ENV:-local}
|
|
542
|
-
|
|
543
|
-
echo "🎯 Selective Test Runner"
|
|
544
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
545
|
-
echo "Base branch: $BASE_BRANCH"
|
|
546
|
-
echo "Environment: $TEST_ENV"
|
|
547
|
-
echo ""
|
|
548
|
-
|
|
549
|
-
# Detect changed files (all types, not just tests)
|
|
550
|
-
CHANGED_FILES=$(git diff --name-only $BASE_BRANCH...HEAD)
|
|
551
|
-
|
|
552
|
-
if [ -z "$CHANGED_FILES" ]; then
|
|
553
|
-
echo "✅ No files changed. Skipping tests."
|
|
554
|
-
exit 0
|
|
555
|
-
fi
|
|
556
|
-
|
|
557
|
-
echo "Changed files:"
|
|
558
|
-
echo "$CHANGED_FILES" | sed 's/^/ - /'
|
|
559
|
-
echo ""
|
|
560
|
-
|
|
561
|
-
# Determine test strategy based on changes
|
|
562
|
-
run_smoke_only=false
|
|
563
|
-
run_all_tests=false
|
|
564
|
-
affected_specs=""
|
|
565
|
-
|
|
566
|
-
# Critical files = run all tests
|
|
567
|
-
if echo "$CHANGED_FILES" | grep -qE '(package\.json|package-lock\.json|playwright\.config|cypress\.config|\.github/workflows)'; then
|
|
568
|
-
echo "⚠️ Critical configuration files changed. Running ALL tests."
|
|
569
|
-
run_all_tests=true
|
|
570
|
-
|
|
571
|
-
# Auth/security changes = run all auth + smoke tests
|
|
572
|
-
elif echo "$CHANGED_FILES" | grep -qE '(auth|login|signup|security)'; then
|
|
573
|
-
echo "🔒 Auth/security files changed. Running auth + smoke tests."
|
|
574
|
-
npm run test -- --grep "@auth|@smoke"
|
|
575
|
-
exit $?
|
|
576
|
-
|
|
577
|
-
# API changes = run integration + smoke tests
|
|
578
|
-
elif echo "$CHANGED_FILES" | grep -qE '(api|service|controller)'; then
|
|
579
|
-
echo "🔌 API files changed. Running integration + smoke tests."
|
|
580
|
-
npm run test -- --grep "@integration|@smoke"
|
|
581
|
-
exit $?
|
|
582
|
-
|
|
583
|
-
# UI component changes = run related component tests
|
|
584
|
-
elif echo "$CHANGED_FILES" | grep -qE '\.(tsx|jsx|vue)$'; then
|
|
585
|
-
echo "🎨 UI components changed. Running component + smoke tests."
|
|
586
|
-
|
|
587
|
-
# Extract component names and find related tests
|
|
588
|
-
components=$(echo "$CHANGED_FILES" | grep -E '\.(tsx|jsx|vue)$' | xargs -I {} basename {} | sed 's/\.[^.]*$//')
|
|
589
|
-
for component in $components; do
|
|
590
|
-
# Find tests matching component name
|
|
591
|
-
affected_specs+=$(find tests -name "*${component}*" -type f) || true
|
|
592
|
-
done
|
|
593
|
-
|
|
594
|
-
if [ -n "$affected_specs" ]; then
|
|
595
|
-
echo "Running tests for: $affected_specs"
|
|
596
|
-
npm run test -- $affected_specs --grep "@smoke"
|
|
597
|
-
else
|
|
598
|
-
echo "No specific tests found. Running smoke tests only."
|
|
599
|
-
npm run test -- --grep "@smoke"
|
|
600
|
-
fi
|
|
601
|
-
exit $?
|
|
602
|
-
|
|
603
|
-
# Documentation/config only = run smoke tests
|
|
604
|
-
elif echo "$CHANGED_FILES" | grep -qE '\.(md|txt|json|yml|yaml)$'; then
|
|
605
|
-
echo "📝 Documentation/config files changed. Running smoke tests only."
|
|
606
|
-
run_smoke_only=true
|
|
607
|
-
else
|
|
608
|
-
echo "⚙️ Other files changed. Running smoke tests."
|
|
609
|
-
run_smoke_only=true
|
|
610
|
-
fi
|
|
611
|
-
|
|
612
|
-
# Execute selected strategy
|
|
613
|
-
if [ "$run_all_tests" = true ]; then
|
|
614
|
-
echo ""
|
|
615
|
-
echo "Running full test suite..."
|
|
616
|
-
npm run test
|
|
617
|
-
elif [ "$run_smoke_only" = true ]; then
|
|
618
|
-
echo ""
|
|
619
|
-
echo "Running smoke tests..."
|
|
620
|
-
npm run test -- --grep "@smoke"
|
|
621
|
-
fi
|
|
622
|
-
```
|
|
623
|
-
|
|
624
|
-
**Usage in GitHub Actions**:
|
|
625
|
-
|
|
626
|
-
```yaml
|
|
627
|
-
# .github/workflows/selective-tests.yml
|
|
628
|
-
name: Selective Tests
|
|
629
|
-
on: pull_request
|
|
630
|
-
|
|
631
|
-
jobs:
|
|
632
|
-
selective-tests:
|
|
633
|
-
runs-on: ubuntu-latest
|
|
634
|
-
steps:
|
|
635
|
-
- uses: actions/checkout@v4
|
|
636
|
-
with:
|
|
637
|
-
fetch-depth: 0
|
|
638
|
-
|
|
639
|
-
- name: Run selective tests
|
|
640
|
-
run: bash scripts/selective-test-runner.sh
|
|
641
|
-
env:
|
|
642
|
-
BASE_BRANCH: ${{ github.base_ref }}
|
|
643
|
-
TEST_ENV: staging
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
**Key Points**:
|
|
647
|
-
|
|
648
|
-
- **Intelligent routing**: Tests selected based on changed file types
|
|
649
|
-
- **Tag-based filtering**: Use @smoke, @auth, @integration tags
|
|
650
|
-
- **Fast feedback**: Only relevant tests run on most PRs
|
|
651
|
-
- **Safety net**: Critical changes trigger full suite
|
|
652
|
-
- **Component mapping**: UI changes run related component tests
|
|
653
|
-
|
|
654
|
-
---
|
|
655
|
-
|
|
656
|
-
## CI Configuration Checklist
|
|
657
|
-
|
|
658
|
-
Before deploying your CI pipeline, verify:
|
|
659
|
-
|
|
660
|
-
- [ ] **Caching strategy**: node_modules, npm cache, browser binaries cached
|
|
661
|
-
- [ ] **Timeout budgets**: Each job has reasonable timeout (10-30 min)
|
|
662
|
-
- [ ] **Artifact retention**: 30 days for reports, 7 days for failure artifacts
|
|
663
|
-
- [ ] **Parallelization**: Matrix strategy uses fail-fast: false
|
|
664
|
-
- [ ] **Burn-in enabled**: Changed specs run 5-10x before merge
|
|
665
|
-
- [ ] **wait-on app startup**: CI waits for app (wait-on: '<http://localhost:3000>')
|
|
666
|
-
- [ ] **Secrets documented**: README lists required secrets (API keys, tokens)
|
|
667
|
-
- [ ] **Local parity**: CI scripts runnable locally (npm run test:ci)
|
|
668
|
-
|
|
669
|
-
## Integration Points
|
|
670
|
-
|
|
671
|
-
- Used in workflows: `*ci` (CI/CD pipeline setup)
|
|
672
|
-
- Related fragments: `selective-testing.md`, `playwright-config.md`, `test-quality.md`
|
|
673
|
-
- CI tools: GitHub Actions, GitLab CI, CircleCI, Jenkins
|
|
674
|
-
|
|
675
|
-
_Source: Murat CI/CD strategy blog, Playwright/Cypress workflow examples, SEON production pipelines_
|
|
1
|
+
# CI Pipeline and Burn-In Strategy
|
|
2
|
+
|
|
3
|
+
## Principle
|
|
4
|
+
|
|
5
|
+
CI pipelines must execute tests reliably, quickly, and provide clear feedback. Burn-in testing (running changed tests multiple times) flushes out flakiness before merge. Stage jobs strategically: install/cache once, run changed specs first for fast feedback, then shard full suites with fail-fast disabled to preserve evidence.
|
|
6
|
+
|
|
7
|
+
## Rationale
|
|
8
|
+
|
|
9
|
+
CI is the quality gate for production. A poorly configured pipeline either wastes developer time (slow feedback, false positives) or ships broken code (false negatives, insufficient coverage). Burn-in testing ensures reliability by stress-testing changed code, while parallel execution and intelligent test selection optimize speed without sacrificing thoroughness.
|
|
10
|
+
|
|
11
|
+
## Pattern Examples
|
|
12
|
+
|
|
13
|
+
### Example 1: GitHub Actions Workflow with Parallel Execution
|
|
14
|
+
|
|
15
|
+
**Context**: Production-ready CI/CD pipeline for E2E tests with caching, parallelization, and burn-in testing.
|
|
16
|
+
|
|
17
|
+
**Implementation**:
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
# .github/workflows/e2e-tests.yml
|
|
21
|
+
name: E2E Tests
|
|
22
|
+
on:
|
|
23
|
+
pull_request:
|
|
24
|
+
push:
|
|
25
|
+
branches: [main, develop]
|
|
26
|
+
|
|
27
|
+
env:
|
|
28
|
+
NODE_VERSION_FILE: '.nvmrc'
|
|
29
|
+
CACHE_KEY: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
30
|
+
|
|
31
|
+
jobs:
|
|
32
|
+
install-dependencies:
|
|
33
|
+
name: Install & Cache Dependencies
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
timeout-minutes: 10
|
|
36
|
+
steps:
|
|
37
|
+
- name: Checkout code
|
|
38
|
+
uses: actions/checkout@v4
|
|
39
|
+
|
|
40
|
+
- name: Setup Node.js
|
|
41
|
+
uses: actions/setup-node@v4
|
|
42
|
+
with:
|
|
43
|
+
node-version-file: ${{ env.NODE_VERSION_FILE }}
|
|
44
|
+
cache: 'npm'
|
|
45
|
+
|
|
46
|
+
- name: Cache node modules
|
|
47
|
+
uses: actions/cache@v4
|
|
48
|
+
id: npm-cache
|
|
49
|
+
with:
|
|
50
|
+
path: |
|
|
51
|
+
~/.npm
|
|
52
|
+
node_modules
|
|
53
|
+
~/.cache/Cypress
|
|
54
|
+
~/.cache/ms-playwright
|
|
55
|
+
key: ${{ env.CACHE_KEY }}
|
|
56
|
+
restore-keys: |
|
|
57
|
+
${{ runner.os }}-node-
|
|
58
|
+
|
|
59
|
+
- name: Install dependencies
|
|
60
|
+
if: steps.npm-cache.outputs.cache-hit != 'true'
|
|
61
|
+
run: npm ci --prefer-offline --no-audit
|
|
62
|
+
|
|
63
|
+
- name: Install Playwright browsers
|
|
64
|
+
if: steps.npm-cache.outputs.cache-hit != 'true'
|
|
65
|
+
run: npx playwright install --with-deps chromium
|
|
66
|
+
|
|
67
|
+
test-changed-specs:
|
|
68
|
+
name: Test Changed Specs First (Burn-In)
|
|
69
|
+
needs: install-dependencies
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
timeout-minutes: 15
|
|
72
|
+
steps:
|
|
73
|
+
- name: Checkout code
|
|
74
|
+
uses: actions/checkout@v4
|
|
75
|
+
with:
|
|
76
|
+
fetch-depth: 0 # Full history for accurate diff
|
|
77
|
+
|
|
78
|
+
- name: Setup Node.js
|
|
79
|
+
uses: actions/setup-node@v4
|
|
80
|
+
with:
|
|
81
|
+
node-version-file: ${{ env.NODE_VERSION_FILE }}
|
|
82
|
+
cache: 'npm'
|
|
83
|
+
|
|
84
|
+
- name: Restore dependencies
|
|
85
|
+
uses: actions/cache@v4
|
|
86
|
+
with:
|
|
87
|
+
path: |
|
|
88
|
+
~/.npm
|
|
89
|
+
node_modules
|
|
90
|
+
~/.cache/ms-playwright
|
|
91
|
+
key: ${{ env.CACHE_KEY }}
|
|
92
|
+
|
|
93
|
+
- name: Detect changed test files
|
|
94
|
+
id: changed-tests
|
|
95
|
+
run: |
|
|
96
|
+
CHANGED_SPECS=$(git diff --name-only origin/main...HEAD | grep -E '\.(spec|test)\.(ts|js|tsx|jsx)$' || echo "")
|
|
97
|
+
echo "changed_specs=${CHANGED_SPECS}" >> $GITHUB_OUTPUT
|
|
98
|
+
echo "Changed specs: ${CHANGED_SPECS}"
|
|
99
|
+
|
|
100
|
+
- name: Run burn-in on changed specs (10 iterations)
|
|
101
|
+
if: steps.changed-tests.outputs.changed_specs != ''
|
|
102
|
+
run: |
|
|
103
|
+
SPECS="${{ steps.changed-tests.outputs.changed_specs }}"
|
|
104
|
+
echo "Running burn-in: 10 iterations on changed specs"
|
|
105
|
+
for i in {1..10}; do
|
|
106
|
+
echo "Burn-in iteration $i/10"
|
|
107
|
+
npm run test -- $SPECS || {
|
|
108
|
+
echo "❌ Burn-in failed on iteration $i"
|
|
109
|
+
exit 1
|
|
110
|
+
}
|
|
111
|
+
done
|
|
112
|
+
echo "✅ Burn-in passed - 10/10 successful runs"
|
|
113
|
+
|
|
114
|
+
- name: Upload artifacts on failure
|
|
115
|
+
if: failure()
|
|
116
|
+
uses: actions/upload-artifact@v4
|
|
117
|
+
with:
|
|
118
|
+
name: burn-in-failure-artifacts
|
|
119
|
+
path: |
|
|
120
|
+
test-results/
|
|
121
|
+
playwright-report/
|
|
122
|
+
screenshots/
|
|
123
|
+
retention-days: 7
|
|
124
|
+
|
|
125
|
+
test-e2e-sharded:
|
|
126
|
+
name: E2E Tests (Shard ${{ matrix.shard }}/${{ strategy.job-total }})
|
|
127
|
+
needs: [install-dependencies, test-changed-specs]
|
|
128
|
+
runs-on: ubuntu-latest
|
|
129
|
+
timeout-minutes: 30
|
|
130
|
+
strategy:
|
|
131
|
+
fail-fast: false # Run all shards even if one fails
|
|
132
|
+
matrix:
|
|
133
|
+
shard: [1, 2, 3, 4]
|
|
134
|
+
steps:
|
|
135
|
+
- name: Checkout code
|
|
136
|
+
uses: actions/checkout@v4
|
|
137
|
+
|
|
138
|
+
- name: Setup Node.js
|
|
139
|
+
uses: actions/setup-node@v4
|
|
140
|
+
with:
|
|
141
|
+
node-version-file: ${{ env.NODE_VERSION_FILE }}
|
|
142
|
+
cache: 'npm'
|
|
143
|
+
|
|
144
|
+
- name: Restore dependencies
|
|
145
|
+
uses: actions/cache@v4
|
|
146
|
+
with:
|
|
147
|
+
path: |
|
|
148
|
+
~/.npm
|
|
149
|
+
node_modules
|
|
150
|
+
~/.cache/ms-playwright
|
|
151
|
+
key: ${{ env.CACHE_KEY }}
|
|
152
|
+
|
|
153
|
+
- name: Run E2E tests (shard ${{ matrix.shard }})
|
|
154
|
+
run: npm run test:e2e -- --shard=${{ matrix.shard }}/4
|
|
155
|
+
env:
|
|
156
|
+
TEST_ENV: staging
|
|
157
|
+
CI: true
|
|
158
|
+
|
|
159
|
+
- name: Upload test results
|
|
160
|
+
if: always()
|
|
161
|
+
uses: actions/upload-artifact@v4
|
|
162
|
+
with:
|
|
163
|
+
name: test-results-shard-${{ matrix.shard }}
|
|
164
|
+
path: |
|
|
165
|
+
test-results/
|
|
166
|
+
playwright-report/
|
|
167
|
+
retention-days: 30
|
|
168
|
+
|
|
169
|
+
- name: Upload JUnit report
|
|
170
|
+
if: always()
|
|
171
|
+
uses: actions/upload-artifact@v4
|
|
172
|
+
with:
|
|
173
|
+
name: junit-results-shard-${{ matrix.shard }}
|
|
174
|
+
path: test-results/junit.xml
|
|
175
|
+
retention-days: 30
|
|
176
|
+
|
|
177
|
+
merge-test-results:
|
|
178
|
+
name: Merge Test Results & Generate Report
|
|
179
|
+
needs: test-e2e-sharded
|
|
180
|
+
runs-on: ubuntu-latest
|
|
181
|
+
if: always()
|
|
182
|
+
steps:
|
|
183
|
+
- name: Download all shard results
|
|
184
|
+
uses: actions/download-artifact@v4
|
|
185
|
+
with:
|
|
186
|
+
pattern: test-results-shard-*
|
|
187
|
+
path: all-results/
|
|
188
|
+
|
|
189
|
+
- name: Merge HTML reports
|
|
190
|
+
run: |
|
|
191
|
+
npx playwright merge-reports --reporter=html all-results/
|
|
192
|
+
echo "Merged report available in playwright-report/"
|
|
193
|
+
|
|
194
|
+
- name: Upload merged report
|
|
195
|
+
uses: actions/upload-artifact@v4
|
|
196
|
+
with:
|
|
197
|
+
name: merged-playwright-report
|
|
198
|
+
path: playwright-report/
|
|
199
|
+
retention-days: 30
|
|
200
|
+
|
|
201
|
+
- name: Comment PR with results
|
|
202
|
+
if: github.event_name == 'pull_request'
|
|
203
|
+
uses: daun/playwright-report-comment@v3
|
|
204
|
+
with:
|
|
205
|
+
report-path: playwright-report/
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Key Points**:
|
|
209
|
+
|
|
210
|
+
- **Install once, reuse everywhere**: Dependencies cached across all jobs
|
|
211
|
+
- **Burn-in first**: Changed specs run 10x before full suite
|
|
212
|
+
- **Fail-fast disabled**: All shards run to completion for full evidence
|
|
213
|
+
- **Parallel execution**: 4 shards cut execution time by ~75%
|
|
214
|
+
- **Artifact retention**: 30 days for reports, 7 days for failure debugging
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
### Example 2: Burn-In Loop Pattern (Standalone Script)
|
|
219
|
+
|
|
220
|
+
**Context**: Reusable bash script for burn-in testing changed specs locally or in CI.
|
|
221
|
+
|
|
222
|
+
**Implementation**:
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
#!/bin/bash
|
|
226
|
+
# scripts/burn-in-changed.sh
|
|
227
|
+
# Usage: ./scripts/burn-in-changed.sh [iterations] [base-branch]
|
|
228
|
+
|
|
229
|
+
set -e # Exit on error
|
|
230
|
+
|
|
231
|
+
# Configuration
|
|
232
|
+
ITERATIONS=${1:-10}
|
|
233
|
+
BASE_BRANCH=${2:-main}
|
|
234
|
+
SPEC_PATTERN='\.(spec|test)\.(ts|js|tsx|jsx)$'
|
|
235
|
+
|
|
236
|
+
echo "🔥 Burn-In Test Runner"
|
|
237
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
238
|
+
echo "Iterations: $ITERATIONS"
|
|
239
|
+
echo "Base branch: $BASE_BRANCH"
|
|
240
|
+
echo ""
|
|
241
|
+
|
|
242
|
+
# Detect changed test files
|
|
243
|
+
echo "📋 Detecting changed test files..."
|
|
244
|
+
CHANGED_SPECS=$(git diff --name-only $BASE_BRANCH...HEAD | grep -E "$SPEC_PATTERN" || echo "")
|
|
245
|
+
|
|
246
|
+
if [ -z "$CHANGED_SPECS" ]; then
|
|
247
|
+
echo "✅ No test files changed. Skipping burn-in."
|
|
248
|
+
exit 0
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
echo "Changed test files:"
|
|
252
|
+
echo "$CHANGED_SPECS" | sed 's/^/ - /'
|
|
253
|
+
echo ""
|
|
254
|
+
|
|
255
|
+
# Count specs
|
|
256
|
+
SPEC_COUNT=$(echo "$CHANGED_SPECS" | wc -l | xargs)
|
|
257
|
+
echo "Running burn-in on $SPEC_COUNT test file(s)..."
|
|
258
|
+
echo ""
|
|
259
|
+
|
|
260
|
+
# Burn-in loop
|
|
261
|
+
FAILURES=()
|
|
262
|
+
for i in $(seq 1 $ITERATIONS); do
|
|
263
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
264
|
+
echo "🔄 Iteration $i/$ITERATIONS"
|
|
265
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
266
|
+
|
|
267
|
+
# Run tests with explicit file list
|
|
268
|
+
if npm run test -- $CHANGED_SPECS 2>&1 | tee "burn-in-log-$i.txt"; then
|
|
269
|
+
echo "✅ Iteration $i passed"
|
|
270
|
+
else
|
|
271
|
+
echo "❌ Iteration $i failed"
|
|
272
|
+
FAILURES+=($i)
|
|
273
|
+
|
|
274
|
+
# Save failure artifacts
|
|
275
|
+
mkdir -p burn-in-failures/iteration-$i
|
|
276
|
+
cp -r test-results/ burn-in-failures/iteration-$i/ 2>/dev/null || true
|
|
277
|
+
cp -r screenshots/ burn-in-failures/iteration-$i/ 2>/dev/null || true
|
|
278
|
+
|
|
279
|
+
echo ""
|
|
280
|
+
echo "🛑 BURN-IN FAILED on iteration $i"
|
|
281
|
+
echo "Failure artifacts saved to: burn-in-failures/iteration-$i/"
|
|
282
|
+
echo "Logs saved to: burn-in-log-$i.txt"
|
|
283
|
+
echo ""
|
|
284
|
+
exit 1
|
|
285
|
+
fi
|
|
286
|
+
|
|
287
|
+
echo ""
|
|
288
|
+
done
|
|
289
|
+
|
|
290
|
+
# Success summary
|
|
291
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
292
|
+
echo "🎉 BURN-IN PASSED"
|
|
293
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
294
|
+
echo "All $ITERATIONS iterations passed for $SPEC_COUNT test file(s)"
|
|
295
|
+
echo "Changed specs are stable and ready to merge."
|
|
296
|
+
echo ""
|
|
297
|
+
|
|
298
|
+
# Cleanup logs
|
|
299
|
+
rm -f burn-in-log-*.txt
|
|
300
|
+
|
|
301
|
+
exit 0
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Usage**:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
# Run locally with default settings (10 iterations, compare to main)
|
|
308
|
+
./scripts/burn-in-changed.sh
|
|
309
|
+
|
|
310
|
+
# Custom iterations and base branch
|
|
311
|
+
./scripts/burn-in-changed.sh 20 develop
|
|
312
|
+
|
|
313
|
+
# Add to package.json
|
|
314
|
+
{
|
|
315
|
+
"scripts": {
|
|
316
|
+
"test:burn-in": "bash scripts/burn-in-changed.sh",
|
|
317
|
+
"test:burn-in:strict": "bash scripts/burn-in-changed.sh 20"
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**Key Points**:
|
|
323
|
+
|
|
324
|
+
- **Exit on first failure**: Flaky tests caught immediately
|
|
325
|
+
- **Failure artifacts**: Saved per-iteration for debugging
|
|
326
|
+
- **Flexible configuration**: Iterations and base branch customizable
|
|
327
|
+
- **CI/local parity**: Same script runs in both environments
|
|
328
|
+
- **Clear output**: Visual feedback on progress and results
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
### Example 3: Shard Orchestration with Result Aggregation
|
|
333
|
+
|
|
334
|
+
**Context**: Advanced sharding strategy for large test suites with intelligent result merging.
|
|
335
|
+
|
|
336
|
+
**Implementation**:
|
|
337
|
+
|
|
338
|
+
```javascript
|
|
339
|
+
// scripts/run-sharded-tests.js
|
|
340
|
+
const { spawn } = require('child_process');
|
|
341
|
+
const fs = require('fs');
|
|
342
|
+
const path = require('path');
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Run tests across multiple shards and aggregate results
|
|
346
|
+
* Usage: node scripts/run-sharded-tests.js --shards=4 --env=staging
|
|
347
|
+
*/
|
|
348
|
+
|
|
349
|
+
const SHARD_COUNT = parseInt(process.env.SHARD_COUNT || '4');
|
|
350
|
+
const TEST_ENV = process.env.TEST_ENV || 'local';
|
|
351
|
+
const RESULTS_DIR = path.join(__dirname, '../test-results');
|
|
352
|
+
|
|
353
|
+
console.log(`🚀 Running tests across ${SHARD_COUNT} shards`);
|
|
354
|
+
console.log(`Environment: ${TEST_ENV}`);
|
|
355
|
+
console.log('━'.repeat(50));
|
|
356
|
+
|
|
357
|
+
// Ensure results directory exists
|
|
358
|
+
if (!fs.existsSync(RESULTS_DIR)) {
|
|
359
|
+
fs.mkdirSync(RESULTS_DIR, { recursive: true });
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Run a single shard
|
|
364
|
+
*/
|
|
365
|
+
function runShard(shardIndex) {
|
|
366
|
+
return new Promise((resolve, reject) => {
|
|
367
|
+
const shardId = `${shardIndex}/${SHARD_COUNT}`;
|
|
368
|
+
console.log(`\n📦 Starting shard ${shardId}...`);
|
|
369
|
+
|
|
370
|
+
const child = spawn('npx', ['playwright', 'test', `--shard=${shardId}`, '--reporter=json'], {
|
|
371
|
+
env: { ...process.env, TEST_ENV, SHARD_INDEX: shardIndex },
|
|
372
|
+
stdio: 'pipe',
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
let stdout = '';
|
|
376
|
+
let stderr = '';
|
|
377
|
+
|
|
378
|
+
child.stdout.on('data', (data) => {
|
|
379
|
+
stdout += data.toString();
|
|
380
|
+
process.stdout.write(data);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
child.stderr.on('data', (data) => {
|
|
384
|
+
stderr += data.toString();
|
|
385
|
+
process.stderr.write(data);
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
child.on('close', (code) => {
|
|
389
|
+
// Save shard results
|
|
390
|
+
const resultFile = path.join(RESULTS_DIR, `shard-${shardIndex}.json`);
|
|
391
|
+
try {
|
|
392
|
+
const result = JSON.parse(stdout);
|
|
393
|
+
fs.writeFileSync(resultFile, JSON.stringify(result, null, 2));
|
|
394
|
+
console.log(`✅ Shard ${shardId} completed (exit code: ${code})`);
|
|
395
|
+
resolve({ shardIndex, code, result });
|
|
396
|
+
} catch (error) {
|
|
397
|
+
console.error(`❌ Shard ${shardId} failed to parse results:`, error.message);
|
|
398
|
+
reject({ shardIndex, code, error });
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
child.on('error', (error) => {
|
|
403
|
+
console.error(`❌ Shard ${shardId} process error:`, error.message);
|
|
404
|
+
reject({ shardIndex, error });
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Aggregate results from all shards
|
|
411
|
+
*/
|
|
412
|
+
function aggregateResults() {
|
|
413
|
+
console.log('\n📊 Aggregating results from all shards...');
|
|
414
|
+
|
|
415
|
+
const shardResults = [];
|
|
416
|
+
let totalTests = 0;
|
|
417
|
+
let totalPassed = 0;
|
|
418
|
+
let totalFailed = 0;
|
|
419
|
+
let totalSkipped = 0;
|
|
420
|
+
let totalFlaky = 0;
|
|
421
|
+
|
|
422
|
+
for (let i = 1; i <= SHARD_COUNT; i++) {
|
|
423
|
+
const resultFile = path.join(RESULTS_DIR, `shard-${i}.json`);
|
|
424
|
+
if (fs.existsSync(resultFile)) {
|
|
425
|
+
const result = JSON.parse(fs.readFileSync(resultFile, 'utf8'));
|
|
426
|
+
shardResults.push(result);
|
|
427
|
+
|
|
428
|
+
// Aggregate stats
|
|
429
|
+
totalTests += result.stats?.expected || 0;
|
|
430
|
+
totalPassed += result.stats?.expected || 0;
|
|
431
|
+
totalFailed += result.stats?.unexpected || 0;
|
|
432
|
+
totalSkipped += result.stats?.skipped || 0;
|
|
433
|
+
totalFlaky += result.stats?.flaky || 0;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const summary = {
|
|
438
|
+
totalShards: SHARD_COUNT,
|
|
439
|
+
environment: TEST_ENV,
|
|
440
|
+
totalTests,
|
|
441
|
+
passed: totalPassed,
|
|
442
|
+
failed: totalFailed,
|
|
443
|
+
skipped: totalSkipped,
|
|
444
|
+
flaky: totalFlaky,
|
|
445
|
+
duration: shardResults.reduce((acc, r) => acc + (r.duration || 0), 0),
|
|
446
|
+
timestamp: new Date().toISOString(),
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
// Save aggregated summary
|
|
450
|
+
fs.writeFileSync(path.join(RESULTS_DIR, 'summary.json'), JSON.stringify(summary, null, 2));
|
|
451
|
+
|
|
452
|
+
console.log('\n━'.repeat(50));
|
|
453
|
+
console.log('📈 Test Results Summary');
|
|
454
|
+
console.log('━'.repeat(50));
|
|
455
|
+
console.log(`Total tests: ${totalTests}`);
|
|
456
|
+
console.log(`✅ Passed: ${totalPassed}`);
|
|
457
|
+
console.log(`❌ Failed: ${totalFailed}`);
|
|
458
|
+
console.log(`⏭️ Skipped: ${totalSkipped}`);
|
|
459
|
+
console.log(`⚠️ Flaky: ${totalFlaky}`);
|
|
460
|
+
console.log(`⏱️ Duration: ${(summary.duration / 1000).toFixed(2)}s`);
|
|
461
|
+
console.log('━'.repeat(50));
|
|
462
|
+
|
|
463
|
+
return summary;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Main execution
|
|
468
|
+
*/
|
|
469
|
+
async function main() {
|
|
470
|
+
const startTime = Date.now();
|
|
471
|
+
const shardPromises = [];
|
|
472
|
+
|
|
473
|
+
// Run all shards in parallel
|
|
474
|
+
for (let i = 1; i <= SHARD_COUNT; i++) {
|
|
475
|
+
shardPromises.push(runShard(i));
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
try {
|
|
479
|
+
await Promise.allSettled(shardPromises);
|
|
480
|
+
} catch (error) {
|
|
481
|
+
console.error('❌ One or more shards failed:', error);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// Aggregate results
|
|
485
|
+
const summary = aggregateResults();
|
|
486
|
+
|
|
487
|
+
const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
488
|
+
console.log(`\n⏱️ Total execution time: ${totalTime}s`);
|
|
489
|
+
|
|
490
|
+
// Exit with failure if any tests failed
|
|
491
|
+
if (summary.failed > 0) {
|
|
492
|
+
console.error('\n❌ Test suite failed');
|
|
493
|
+
process.exit(1);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
console.log('\n✅ All tests passed');
|
|
497
|
+
process.exit(0);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
main().catch((error) => {
|
|
501
|
+
console.error('Fatal error:', error);
|
|
502
|
+
process.exit(1);
|
|
503
|
+
});
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
**package.json integration**:
|
|
507
|
+
|
|
508
|
+
```json
|
|
509
|
+
{
|
|
510
|
+
"scripts": {
|
|
511
|
+
"test:sharded": "node scripts/run-sharded-tests.js",
|
|
512
|
+
"test:sharded:ci": "SHARD_COUNT=8 TEST_ENV=staging node scripts/run-sharded-tests.js"
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
**Key Points**:
|
|
518
|
+
|
|
519
|
+
- **Parallel shard execution**: All shards run simultaneously
|
|
520
|
+
- **Result aggregation**: Unified summary across shards
|
|
521
|
+
- **Failure detection**: Exit code reflects overall test status
|
|
522
|
+
- **Artifact preservation**: Individual shard results saved for debugging
|
|
523
|
+
- **CI/local compatibility**: Same script works in both environments
|
|
524
|
+
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
### Example 4: Selective Test Execution (Changed Files + Tags)
|
|
528
|
+
|
|
529
|
+
**Context**: Optimize CI by running only relevant tests based on file changes and tags.
|
|
530
|
+
|
|
531
|
+
**Implementation**:
|
|
532
|
+
|
|
533
|
+
```bash
|
|
534
|
+
#!/bin/bash
|
|
535
|
+
# scripts/selective-test-runner.sh
|
|
536
|
+
# Intelligent test selection based on changed files and test tags
|
|
537
|
+
|
|
538
|
+
set -e
|
|
539
|
+
|
|
540
|
+
BASE_BRANCH=${BASE_BRANCH:-main}
|
|
541
|
+
TEST_ENV=${TEST_ENV:-local}
|
|
542
|
+
|
|
543
|
+
echo "🎯 Selective Test Runner"
|
|
544
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
545
|
+
echo "Base branch: $BASE_BRANCH"
|
|
546
|
+
echo "Environment: $TEST_ENV"
|
|
547
|
+
echo ""
|
|
548
|
+
|
|
549
|
+
# Detect changed files (all types, not just tests)
|
|
550
|
+
CHANGED_FILES=$(git diff --name-only $BASE_BRANCH...HEAD)
|
|
551
|
+
|
|
552
|
+
if [ -z "$CHANGED_FILES" ]; then
|
|
553
|
+
echo "✅ No files changed. Skipping tests."
|
|
554
|
+
exit 0
|
|
555
|
+
fi
|
|
556
|
+
|
|
557
|
+
echo "Changed files:"
|
|
558
|
+
echo "$CHANGED_FILES" | sed 's/^/ - /'
|
|
559
|
+
echo ""
|
|
560
|
+
|
|
561
|
+
# Determine test strategy based on changes
|
|
562
|
+
run_smoke_only=false
|
|
563
|
+
run_all_tests=false
|
|
564
|
+
affected_specs=""
|
|
565
|
+
|
|
566
|
+
# Critical files = run all tests
|
|
567
|
+
if echo "$CHANGED_FILES" | grep -qE '(package\.json|package-lock\.json|playwright\.config|cypress\.config|\.github/workflows)'; then
|
|
568
|
+
echo "⚠️ Critical configuration files changed. Running ALL tests."
|
|
569
|
+
run_all_tests=true
|
|
570
|
+
|
|
571
|
+
# Auth/security changes = run all auth + smoke tests
|
|
572
|
+
elif echo "$CHANGED_FILES" | grep -qE '(auth|login|signup|security)'; then
|
|
573
|
+
echo "🔒 Auth/security files changed. Running auth + smoke tests."
|
|
574
|
+
npm run test -- --grep "@auth|@smoke"
|
|
575
|
+
exit $?
|
|
576
|
+
|
|
577
|
+
# API changes = run integration + smoke tests
|
|
578
|
+
elif echo "$CHANGED_FILES" | grep -qE '(api|service|controller)'; then
|
|
579
|
+
echo "🔌 API files changed. Running integration + smoke tests."
|
|
580
|
+
npm run test -- --grep "@integration|@smoke"
|
|
581
|
+
exit $?
|
|
582
|
+
|
|
583
|
+
# UI component changes = run related component tests
|
|
584
|
+
elif echo "$CHANGED_FILES" | grep -qE '\.(tsx|jsx|vue)$'; then
|
|
585
|
+
echo "🎨 UI components changed. Running component + smoke tests."
|
|
586
|
+
|
|
587
|
+
# Extract component names and find related tests
|
|
588
|
+
components=$(echo "$CHANGED_FILES" | grep -E '\.(tsx|jsx|vue)$' | xargs -I {} basename {} | sed 's/\.[^.]*$//')
|
|
589
|
+
for component in $components; do
|
|
590
|
+
# Find tests matching component name
|
|
591
|
+
affected_specs+=$(find tests -name "*${component}*" -type f) || true
|
|
592
|
+
done
|
|
593
|
+
|
|
594
|
+
if [ -n "$affected_specs" ]; then
|
|
595
|
+
echo "Running tests for: $affected_specs"
|
|
596
|
+
npm run test -- $affected_specs --grep "@smoke"
|
|
597
|
+
else
|
|
598
|
+
echo "No specific tests found. Running smoke tests only."
|
|
599
|
+
npm run test -- --grep "@smoke"
|
|
600
|
+
fi
|
|
601
|
+
exit $?
|
|
602
|
+
|
|
603
|
+
# Documentation/config only = run smoke tests
|
|
604
|
+
elif echo "$CHANGED_FILES" | grep -qE '\.(md|txt|json|yml|yaml)$'; then
|
|
605
|
+
echo "📝 Documentation/config files changed. Running smoke tests only."
|
|
606
|
+
run_smoke_only=true
|
|
607
|
+
else
|
|
608
|
+
echo "⚙️ Other files changed. Running smoke tests."
|
|
609
|
+
run_smoke_only=true
|
|
610
|
+
fi
|
|
611
|
+
|
|
612
|
+
# Execute selected strategy
|
|
613
|
+
if [ "$run_all_tests" = true ]; then
|
|
614
|
+
echo ""
|
|
615
|
+
echo "Running full test suite..."
|
|
616
|
+
npm run test
|
|
617
|
+
elif [ "$run_smoke_only" = true ]; then
|
|
618
|
+
echo ""
|
|
619
|
+
echo "Running smoke tests..."
|
|
620
|
+
npm run test -- --grep "@smoke"
|
|
621
|
+
fi
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
**Usage in GitHub Actions**:
|
|
625
|
+
|
|
626
|
+
```yaml
|
|
627
|
+
# .github/workflows/selective-tests.yml
|
|
628
|
+
name: Selective Tests
|
|
629
|
+
on: pull_request
|
|
630
|
+
|
|
631
|
+
jobs:
|
|
632
|
+
selective-tests:
|
|
633
|
+
runs-on: ubuntu-latest
|
|
634
|
+
steps:
|
|
635
|
+
- uses: actions/checkout@v4
|
|
636
|
+
with:
|
|
637
|
+
fetch-depth: 0
|
|
638
|
+
|
|
639
|
+
- name: Run selective tests
|
|
640
|
+
run: bash scripts/selective-test-runner.sh
|
|
641
|
+
env:
|
|
642
|
+
BASE_BRANCH: ${{ github.base_ref }}
|
|
643
|
+
TEST_ENV: staging
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
**Key Points**:
|
|
647
|
+
|
|
648
|
+
- **Intelligent routing**: Tests selected based on changed file types
|
|
649
|
+
- **Tag-based filtering**: Use @smoke, @auth, @integration tags
|
|
650
|
+
- **Fast feedback**: Only relevant tests run on most PRs
|
|
651
|
+
- **Safety net**: Critical changes trigger full suite
|
|
652
|
+
- **Component mapping**: UI changes run related component tests
|
|
653
|
+
|
|
654
|
+
---
|
|
655
|
+
|
|
656
|
+
## CI Configuration Checklist
|
|
657
|
+
|
|
658
|
+
Before deploying your CI pipeline, verify:
|
|
659
|
+
|
|
660
|
+
- [ ] **Caching strategy**: node_modules, npm cache, browser binaries cached
|
|
661
|
+
- [ ] **Timeout budgets**: Each job has reasonable timeout (10-30 min)
|
|
662
|
+
- [ ] **Artifact retention**: 30 days for reports, 7 days for failure artifacts
|
|
663
|
+
- [ ] **Parallelization**: Matrix strategy uses fail-fast: false
|
|
664
|
+
- [ ] **Burn-in enabled**: Changed specs run 5-10x before merge
|
|
665
|
+
- [ ] **wait-on app startup**: CI waits for app (wait-on: '<http://localhost:3000>')
|
|
666
|
+
- [ ] **Secrets documented**: README lists required secrets (API keys, tokens)
|
|
667
|
+
- [ ] **Local parity**: CI scripts runnable locally (npm run test:ci)
|
|
668
|
+
|
|
669
|
+
## Integration Points
|
|
670
|
+
|
|
671
|
+
- Used in workflows: `*ci` (CI/CD pipeline setup)
|
|
672
|
+
- Related fragments: `selective-testing.md`, `playwright-config.md`, `test-quality.md`
|
|
673
|
+
- CI tools: GitHub Actions, GitLab CI, CircleCI, Jenkins
|
|
674
|
+
|
|
675
|
+
_Source: Murat CI/CD strategy blog, Playwright/Cypress workflow examples, SEON production pipelines_
|