bmad-fh 6.0.0-alpha.052779ef
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/.coderabbit.yaml +40 -0
- package/.githooks/post-checkout +129 -0
- package/.githooks/pre-commit +63 -0
- package/.githooks/pre-push +135 -0
- package/.github/CODE_OF_CONDUCT.md +128 -0
- package/.github/FUNDING.yaml +15 -0
- package/.github/ISSUE_TEMPLATE/config.yaml +8 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
- package/.github/ISSUE_TEMPLATE/issue.md +32 -0
- package/.github/scripts/discord-helpers.sh +34 -0
- package/.github/workflows/bundle-latest.yaml +330 -0
- package/.github/workflows/discord.yaml +90 -0
- package/.github/workflows/docs.yaml +63 -0
- package/.github/workflows/manual-release.yaml +190 -0
- package/.github/workflows/publish-multi-artifact.yaml +54 -0
- package/.github/workflows/quality.yaml +115 -0
- package/.husky/pre-commit +20 -0
- package/.markdownlint-cli2.yaml +41 -0
- package/.nvmrc +1 -0
- package/.prettierignore +9 -0
- package/.vscode/settings.json +97 -0
- package/CHANGELOG.md +1394 -0
- package/CNAME +1 -0
- package/CONTRIBUTING.md +306 -0
- package/CONTRIBUTORS.md +32 -0
- package/LICENSE +30 -0
- package/README.md +126 -0
- package/SECURITY.md +85 -0
- package/TRADEMARK.md +55 -0
- package/Wordmark.png +0 -0
- package/banner-bmad-method.png +0 -0
- package/docs/404.md +9 -0
- package/docs/_README_WORKFLOW_DIAGRAMS.md +40 -0
- package/docs/_STYLE_GUIDE.md +367 -0
- package/docs/_archive/customize-workflows.md +30 -0
- package/docs/_archive/getting-started-bmadv4.md +247 -0
- package/docs/_archive/vendor-workflows.md +52 -0
- package/docs/downloads.md +72 -0
- package/docs/explanation/agents/barry-quick-flow.md +328 -0
- package/docs/explanation/agents/index.md +19 -0
- package/docs/explanation/architecture/four-phases.md +107 -0
- package/docs/explanation/architecture/preventing-agent-conflicts.md +111 -0
- package/docs/explanation/architecture/why-solutioning-matters.md +75 -0
- package/docs/explanation/bmm/index.md +131 -0
- package/docs/explanation/core/index.md +18 -0
- package/docs/explanation/core-concepts/agent-roles.md +179 -0
- package/docs/explanation/core-concepts/index.md +35 -0
- package/docs/explanation/core-concepts/what-are-agents.md +97 -0
- package/docs/explanation/core-concepts/what-are-modules.md +85 -0
- package/docs/explanation/core-concepts/what-are-workflows.md +204 -0
- package/docs/explanation/faq/brownfield-faq.md +73 -0
- package/docs/explanation/faq/getting-started-faq.md +67 -0
- package/docs/explanation/faq/implementation-faq.md +52 -0
- package/docs/explanation/faq/index.md +16 -0
- package/docs/explanation/faq/levels-and-tracks-faq.md +52 -0
- package/docs/explanation/faq/planning-faq.md +41 -0
- package/docs/explanation/faq/tools-faq.md +277 -0
- package/docs/explanation/faq/workflows-faq.md +61 -0
- package/docs/explanation/features/advanced-elicitation.md +95 -0
- package/docs/explanation/features/brainstorming-techniques.md +92 -0
- package/docs/explanation/features/party-mode.md +95 -0
- package/docs/explanation/features/quick-flow.md +149 -0
- package/docs/explanation/features/tea-overview.md +410 -0
- package/docs/explanation/features/web-bundles.md +34 -0
- package/docs/explanation/philosophy/facilitation-over-generation.md +333 -0
- package/docs/explanation/philosophy/testing-as-engineering.md +112 -0
- package/docs/explanation/tea/engagement-models.md +710 -0
- package/docs/explanation/tea/fixture-architecture.md +457 -0
- package/docs/explanation/tea/knowledge-base-system.md +554 -0
- package/docs/explanation/tea/network-first-patterns.md +853 -0
- package/docs/explanation/tea/risk-based-testing.md +586 -0
- package/docs/explanation/tea/test-quality-standards.md +907 -0
- package/docs/how-to/brownfield/add-feature-to-existing.md +74 -0
- package/docs/how-to/brownfield/document-existing-project.md +66 -0
- package/docs/how-to/brownfield/index.md +84 -0
- package/docs/how-to/brownfield/quick-fix-in-brownfield.md +77 -0
- package/docs/how-to/brownfield/use-tea-for-enterprise.md +526 -0
- package/docs/how-to/brownfield/use-tea-with-existing-tests.md +577 -0
- package/docs/how-to/customization/customize-agents.md +212 -0
- package/docs/how-to/customization/enable-tea-mcp-enhancements.md +424 -0
- package/docs/how-to/customization/index.md +23 -0
- package/docs/how-to/customization/integrate-playwright-utils.md +813 -0
- package/docs/how-to/customization/shard-large-documents.md +101 -0
- package/docs/how-to/get-answers-about-bmad.md +102 -0
- package/docs/how-to/installation/index.md +12 -0
- package/docs/how-to/installation/install-bmad.md +111 -0
- package/docs/how-to/installation/install-custom-modules.md +118 -0
- package/docs/how-to/installation/upgrade-to-v6.md +131 -0
- package/docs/how-to/workflows/bmgd-quick-flow.md +156 -0
- package/docs/how-to/workflows/conduct-research.md +97 -0
- package/docs/how-to/workflows/create-architecture.md +119 -0
- package/docs/how-to/workflows/create-epics-and-stories.md +109 -0
- package/docs/how-to/workflows/create-prd.md +91 -0
- package/docs/how-to/workflows/create-product-brief.md +94 -0
- package/docs/how-to/workflows/create-story.md +102 -0
- package/docs/how-to/workflows/create-ux-design.md +100 -0
- package/docs/how-to/workflows/implement-story.md +97 -0
- package/docs/how-to/workflows/quick-spec.md +122 -0
- package/docs/how-to/workflows/run-atdd.md +436 -0
- package/docs/how-to/workflows/run-automate.md +653 -0
- package/docs/how-to/workflows/run-brainstorming-session.md +73 -0
- package/docs/how-to/workflows/run-code-review.md +89 -0
- package/docs/how-to/workflows/run-implementation-readiness.md +125 -0
- package/docs/how-to/workflows/run-nfr-assess.md +679 -0
- package/docs/how-to/workflows/run-sprint-planning.md +94 -0
- package/docs/how-to/workflows/run-test-design.md +98 -0
- package/docs/how-to/workflows/run-test-review.md +605 -0
- package/docs/how-to/workflows/run-trace.md +883 -0
- package/docs/how-to/workflows/setup-ci.md +712 -0
- package/docs/how-to/workflows/setup-party-mode.md +89 -0
- package/docs/how-to/workflows/setup-test-framework.md +98 -0
- package/docs/index.md +63 -0
- package/docs/migration-guide.md +365 -0
- package/docs/multi-scope-guide.md +379 -0
- package/docs/plans/multi-scope-parallel-artifacts-plan.md +695 -0
- package/docs/reference/agents/index.md +109 -0
- package/docs/reference/configuration/core-tasks.md +67 -0
- package/docs/reference/configuration/global-config.md +28 -0
- package/docs/reference/glossary/index.md +159 -0
- package/docs/reference/tea/commands.md +254 -0
- package/docs/reference/tea/configuration.md +678 -0
- package/docs/reference/tea/knowledge-base.md +340 -0
- package/docs/reference/workflows/core-workflows.md +32 -0
- package/docs/reference/workflows/document-project.md +73 -0
- package/docs/reference/workflows/index.md +12 -0
- package/docs/tutorials/getting-started/getting-started-bmadv6.md +246 -0
- package/docs/tutorials/getting-started/images/workflow-method-greenfield.excalidraw +5034 -0
- package/docs/tutorials/getting-started/images/workflow-method-greenfield.svg +4 -0
- package/docs/tutorials/getting-started/images/workflow-overview.jpg +0 -0
- package/docs/tutorials/getting-started/tea-lite-quickstart.md +444 -0
- package/docs/tutorials/getting-started/workflow-overview.jpg +0 -0
- package/eslint.config.mjs +152 -0
- package/package.json +117 -0
- package/prettier.config.mjs +32 -0
- package/src/bmm/_module-installer/installer.js +48 -0
- package/src/bmm/_module-installer/platform-specifics/claude-code.js +35 -0
- package/src/bmm/_module-installer/platform-specifics/windsurf.js +32 -0
- package/src/bmm/agents/analyst.agent.yaml +41 -0
- package/src/bmm/agents/architect.agent.yaml +33 -0
- package/src/bmm/agents/dev.agent.yaml +38 -0
- package/src/bmm/agents/pm.agent.yaml +51 -0
- package/src/bmm/agents/quick-flow-solo-dev.agent.yaml +32 -0
- package/src/bmm/agents/sm.agent.yaml +47 -0
- package/src/bmm/agents/tea.agent.yaml +68 -0
- package/src/bmm/agents/tech-writer/tech-writer-sidecar/documentation-standards.md +224 -0
- package/src/bmm/agents/tech-writer/tech-writer.agent.yaml +49 -0
- package/src/bmm/agents/ux-designer.agent.yaml +30 -0
- package/src/bmm/data/README.md +29 -0
- package/src/bmm/data/project-context-template.md +40 -0
- package/src/bmm/module.yaml +64 -0
- package/src/bmm/sub-modules/claude-code/config.yaml +4 -0
- package/src/bmm/sub-modules/claude-code/injections.yaml +242 -0
- package/src/bmm/sub-modules/claude-code/readme.md +87 -0
- package/src/bmm/teams/default-party.csv +21 -0
- package/src/bmm/teams/team-fullstack.yaml +12 -0
- package/src/bmm/testarch/knowledge/api-request.md +442 -0
- package/src/bmm/testarch/knowledge/api-testing-patterns.md +843 -0
- package/src/bmm/testarch/knowledge/auth-session.md +552 -0
- package/src/bmm/testarch/knowledge/burn-in.md +273 -0
- package/src/bmm/testarch/knowledge/ci-burn-in.md +675 -0
- package/src/bmm/testarch/knowledge/component-tdd.md +486 -0
- package/src/bmm/testarch/knowledge/contract-testing.md +957 -0
- package/src/bmm/testarch/knowledge/data-factories.md +500 -0
- package/src/bmm/testarch/knowledge/email-auth.md +721 -0
- package/src/bmm/testarch/knowledge/error-handling.md +725 -0
- package/src/bmm/testarch/knowledge/feature-flags.md +750 -0
- package/src/bmm/testarch/knowledge/file-utils.md +463 -0
- package/src/bmm/testarch/knowledge/fixture-architecture.md +401 -0
- package/src/bmm/testarch/knowledge/fixtures-composition.md +382 -0
- package/src/bmm/testarch/knowledge/intercept-network-call.md +430 -0
- package/src/bmm/testarch/knowledge/log.md +429 -0
- package/src/bmm/testarch/knowledge/network-error-monitor.md +405 -0
- package/src/bmm/testarch/knowledge/network-first.md +486 -0
- package/src/bmm/testarch/knowledge/network-recorder.md +527 -0
- package/src/bmm/testarch/knowledge/nfr-criteria.md +670 -0
- package/src/bmm/testarch/knowledge/overview.md +286 -0
- package/src/bmm/testarch/knowledge/playwright-config.md +730 -0
- package/src/bmm/testarch/knowledge/probability-impact.md +601 -0
- package/src/bmm/testarch/knowledge/recurse.md +421 -0
- package/src/bmm/testarch/knowledge/risk-governance.md +615 -0
- package/src/bmm/testarch/knowledge/selective-testing.md +732 -0
- package/src/bmm/testarch/knowledge/selector-resilience.md +527 -0
- package/src/bmm/testarch/knowledge/test-healing-patterns.md +644 -0
- package/src/bmm/testarch/knowledge/test-levels-framework.md +473 -0
- package/src/bmm/testarch/knowledge/test-priorities-matrix.md +373 -0
- package/src/bmm/testarch/knowledge/test-quality.md +664 -0
- package/src/bmm/testarch/knowledge/timing-debugging.md +372 -0
- package/src/bmm/testarch/knowledge/visual-debugging.md +524 -0
- package/src/bmm/testarch/tea-index.csv +34 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +177 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +161 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +199 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +202 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +205 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +219 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +194 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/workflow.md +58 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +443 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +200 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +475 -0
- package/src/bmm/workflows/1-analysis/research/research.template.md +29 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +239 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +486 -0
- package/src/bmm/workflows/1-analysis/research/workflow.md +173 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +248 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +228 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +43 -0
- package/src/bmm/workflows/2-plan-workflows/prd/data/domain-complexity.csv +13 -0
- package/src/bmm/workflows/2-plan-workflows/prd/data/prd-purpose.md +197 -0
- package/src/bmm/workflows/2-plan-workflows/prd/data/project-types.csv +11 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-01-init.md +191 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-01b-continue.md +153 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-02-discovery.md +224 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-03-success.md +226 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-04-journeys.md +213 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-05-domain.md +207 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-06-innovation.md +226 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-07-project-type.md +237 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-08-scoping.md +228 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-09-functional.md +231 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-10-nonfunctional.md +242 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-11-polish.md +217 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-12-complete.md +180 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-01-discovery.md +247 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-01b-legacy-conversion.md +208 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-02-review.md +249 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-03-edit.md +253 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-04-complete.md +168 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-01-discovery.md +218 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-02-format-detection.md +191 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-02b-parity-check.md +209 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-03-density-validation.md +174 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-04-brief-coverage-validation.md +214 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-05-measurability-validation.md +228 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-06-traceability-validation.md +217 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-08-domain-compliance-validation.md +243 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-09-project-type-validation.md +263 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-10-smart-validation.md +209 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-11-holistic-quality-validation.md +264 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-12-completeness-validation.md +242 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-13-report-complete.md +232 -0
- package/src/bmm/workflows/2-plan-workflows/prd/templates/prd-template.md +10 -0
- package/src/bmm/workflows/2-plan-workflows/prd/validation-report-prd-workflow.md +433 -0
- package/src/bmm/workflows/2-plan-workflows/prd/workflow.md +150 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +190 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +178 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +179 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +139 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +252 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +133 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +55 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +11 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +7 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +153 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +164 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +331 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +318 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +359 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +359 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +352 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/workflow.md +50 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +145 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +59 -0
- package/src/bmm/workflows/4-implementation/code-review/checklist.md +23 -0
- package/src/bmm/workflows/4-implementation/code-review/instructions.xml +227 -0
- package/src/bmm/workflows/4-implementation/code-review/workflow.yaml +51 -0
- package/src/bmm/workflows/4-implementation/correct-course/checklist.md +288 -0
- package/src/bmm/workflows/4-implementation/correct-course/instructions.md +206 -0
- package/src/bmm/workflows/4-implementation/correct-course/workflow.yaml +60 -0
- package/src/bmm/workflows/4-implementation/create-story/checklist.md +358 -0
- package/src/bmm/workflows/4-implementation/create-story/instructions.xml +345 -0
- package/src/bmm/workflows/4-implementation/create-story/template.md +49 -0
- package/src/bmm/workflows/4-implementation/create-story/workflow.yaml +61 -0
- package/src/bmm/workflows/4-implementation/dev-story/checklist.md +80 -0
- package/src/bmm/workflows/4-implementation/dev-story/instructions.xml +410 -0
- package/src/bmm/workflows/4-implementation/dev-story/workflow.yaml +27 -0
- package/src/bmm/workflows/4-implementation/retrospective/instructions.md +1443 -0
- package/src/bmm/workflows/4-implementation/retrospective/workflow.yaml +58 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/instructions.md +225 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +54 -0
- package/src/bmm/workflows/4-implementation/sprint-status/instructions.md +229 -0
- package/src/bmm/workflows/4-implementation/sprint-status/workflow.yaml +36 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +156 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +120 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +113 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +113 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +106 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +140 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +52 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-01-understand.md +189 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +144 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +128 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +191 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/tech-spec-template.md +74 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +79 -0
- package/src/bmm/workflows/document-project/checklist.md +245 -0
- package/src/bmm/workflows/document-project/documentation-requirements.csv +12 -0
- package/src/bmm/workflows/document-project/instructions.md +221 -0
- package/src/bmm/workflows/document-project/templates/deep-dive-template.md +345 -0
- package/src/bmm/workflows/document-project/templates/index-template.md +169 -0
- package/src/bmm/workflows/document-project/templates/project-overview-template.md +103 -0
- package/src/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -0
- package/src/bmm/workflows/document-project/templates/source-tree-template.md +135 -0
- package/src/bmm/workflows/document-project/workflow.yaml +30 -0
- package/src/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -0
- package/src/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -0
- package/src/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -0
- package/src/bmm/workflows/document-project/workflows/full-scan.yaml +31 -0
- package/src/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-library.json +90 -0
- package/src/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-templates.yaml +127 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/checklist.md +39 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/instructions.md +130 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml +27 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-diagram/checklist.md +43 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-diagram/instructions.md +141 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml +27 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/checklist.md +49 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/instructions.md +241 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml +27 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/checklist.md +38 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/instructions.md +133 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml +27 -0
- package/src/bmm/workflows/generate-project-context/project-context-template.md +21 -0
- package/src/bmm/workflows/generate-project-context/steps/step-01-discover.md +184 -0
- package/src/bmm/workflows/generate-project-context/steps/step-02-generate.md +318 -0
- package/src/bmm/workflows/generate-project-context/steps/step-03-complete.md +278 -0
- package/src/bmm/workflows/generate-project-context/workflow.md +49 -0
- package/src/bmm/workflows/testarch/atdd/atdd-checklist-template.md +364 -0
- package/src/bmm/workflows/testarch/atdd/checklist.md +374 -0
- package/src/bmm/workflows/testarch/atdd/instructions.md +806 -0
- package/src/bmm/workflows/testarch/atdd/workflow.yaml +47 -0
- package/src/bmm/workflows/testarch/automate/checklist.md +582 -0
- package/src/bmm/workflows/testarch/automate/instructions.md +1324 -0
- package/src/bmm/workflows/testarch/automate/workflow.yaml +54 -0
- package/src/bmm/workflows/testarch/ci/checklist.md +248 -0
- package/src/bmm/workflows/testarch/ci/github-actions-template.yaml +198 -0
- package/src/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +149 -0
- package/src/bmm/workflows/testarch/ci/instructions.md +536 -0
- package/src/bmm/workflows/testarch/ci/workflow.yaml +47 -0
- package/src/bmm/workflows/testarch/framework/checklist.md +321 -0
- package/src/bmm/workflows/testarch/framework/instructions.md +481 -0
- package/src/bmm/workflows/testarch/framework/workflow.yaml +49 -0
- package/src/bmm/workflows/testarch/nfr-assess/checklist.md +407 -0
- package/src/bmm/workflows/testarch/nfr-assess/instructions.md +722 -0
- package/src/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +445 -0
- package/src/bmm/workflows/testarch/nfr-assess/workflow.yaml +49 -0
- package/src/bmm/workflows/testarch/test-design/checklist.md +235 -0
- package/src/bmm/workflows/testarch/test-design/instructions.md +788 -0
- package/src/bmm/workflows/testarch/test-design/test-design-template.md +294 -0
- package/src/bmm/workflows/testarch/test-design/workflow.yaml +56 -0
- package/src/bmm/workflows/testarch/test-review/checklist.md +472 -0
- package/src/bmm/workflows/testarch/test-review/instructions.md +628 -0
- package/src/bmm/workflows/testarch/test-review/test-review-template.md +390 -0
- package/src/bmm/workflows/testarch/test-review/workflow.yaml +48 -0
- package/src/bmm/workflows/testarch/trace/checklist.md +655 -0
- package/src/bmm/workflows/testarch/trace/instructions.md +1047 -0
- package/src/bmm/workflows/testarch/trace/trace-template.md +675 -0
- package/src/bmm/workflows/testarch/trace/workflow.yaml +57 -0
- package/src/bmm/workflows/workflow-status/init/instructions.md +346 -0
- package/src/bmm/workflows/workflow-status/init/workflow.yaml +30 -0
- package/src/bmm/workflows/workflow-status/instructions.md +397 -0
- package/src/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +103 -0
- package/src/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +100 -0
- package/src/bmm/workflows/workflow-status/paths/method-brownfield.yaml +103 -0
- package/src/bmm/workflows/workflow-status/paths/method-greenfield.yaml +100 -0
- package/src/bmm/workflows/workflow-status/project-levels.yaml +59 -0
- package/src/bmm/workflows/workflow-status/workflow-status-template.yaml +24 -0
- package/src/bmm/workflows/workflow-status/workflow.yaml +32 -0
- package/src/core/_module-installer/installer.js +60 -0
- package/src/core/agents/bmad-master.agent.yaml +30 -0
- package/src/core/lib/scope/artifact-resolver.js +298 -0
- package/src/core/lib/scope/event-logger.js +400 -0
- package/src/core/lib/scope/index.js +30 -0
- package/src/core/lib/scope/scope-context.js +301 -0
- package/src/core/lib/scope/scope-initializer.js +456 -0
- package/src/core/lib/scope/scope-manager.js +512 -0
- package/src/core/lib/scope/scope-migrator.js +434 -0
- package/src/core/lib/scope/scope-sync.js +483 -0
- package/src/core/lib/scope/scope-validator.js +294 -0
- package/src/core/lib/scope/state-lock.js +336 -0
- package/src/core/module.yaml +53 -0
- package/src/core/resources/excalidraw/README.md +160 -0
- package/src/core/resources/excalidraw/excalidraw-helpers.md +127 -0
- package/src/core/resources/excalidraw/library-loader.md +50 -0
- package/src/core/resources/excalidraw/validate-json-instructions.md +79 -0
- package/src/core/tasks/editorial-review-prose.xml +91 -0
- package/src/core/tasks/editorial-review-structure.xml +198 -0
- package/src/core/tasks/index-docs.xml +65 -0
- package/src/core/tasks/review-adversarial-general.xml +46 -0
- package/src/core/tasks/shard-doc.xml +109 -0
- package/src/core/tasks/workflow.xml +277 -0
- package/src/core/workflows/advanced-elicitation/methods.csv +51 -0
- package/src/core/workflows/advanced-elicitation/workflow.xml +117 -0
- package/src/core/workflows/brainstorming/brain-methods.csv +62 -0
- package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +197 -0
- package/src/core/workflows/brainstorming/steps/step-01b-continue.md +122 -0
- package/src/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -0
- package/src/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -0
- package/src/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -0
- package/src/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -0
- package/src/core/workflows/brainstorming/steps/step-03-technique-execution.md +399 -0
- package/src/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -0
- package/src/core/workflows/brainstorming/template.md +15 -0
- package/src/core/workflows/brainstorming/workflow.md +58 -0
- package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +138 -0
- package/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +187 -0
- package/src/core/workflows/party-mode/steps/step-03-graceful-exit.md +157 -0
- package/src/core/workflows/party-mode/workflow.md +194 -0
- package/src/utility/agent-components/activation-rules.txt +6 -0
- package/src/utility/agent-components/activation-steps.txt +28 -0
- package/src/utility/agent-components/agent-command-header.md +1 -0
- package/src/utility/agent-components/agent.customize.template.yaml +41 -0
- package/src/utility/agent-components/handler-action.txt +4 -0
- package/src/utility/agent-components/handler-data.txt +5 -0
- package/src/utility/agent-components/handler-exec.txt +19 -0
- package/src/utility/agent-components/handler-multi.txt +14 -0
- package/src/utility/agent-components/handler-tmpl.txt +5 -0
- package/src/utility/agent-components/handler-validate-workflow.txt +7 -0
- package/src/utility/agent-components/handler-workflow.txt +10 -0
- package/src/utility/agent-components/menu-handlers.txt +6 -0
- package/test/README.md +295 -0
- package/test/fixtures/agent-schema/invalid/critical-actions/actions-as-string.agent.yaml +27 -0
- package/test/fixtures/agent-schema/invalid/critical-actions/empty-string-in-actions.agent.yaml +30 -0
- package/test/fixtures/agent-schema/invalid/menu/empty-menu.agent.yaml +22 -0
- package/test/fixtures/agent-schema/invalid/menu/missing-menu.agent.yaml +20 -0
- package/test/fixtures/agent-schema/invalid/menu-commands/empty-command-target.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-commands/no-command-target.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/camel-case.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/compound-invalid-format.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/compound-mismatched-kebab.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/duplicate-triggers.agent.yaml +31 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/empty-trigger.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/leading-asterisk.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/snake-case.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/trigger-with-spaces.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/metadata/empty-module-string.agent.yaml +26 -0
- package/test/fixtures/agent-schema/invalid/metadata/empty-name.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/metadata/extra-metadata-fields.agent.yaml +27 -0
- package/test/fixtures/agent-schema/invalid/metadata/missing-id.agent.yaml +23 -0
- package/test/fixtures/agent-schema/invalid/persona/empty-principles-array.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/persona/empty-string-in-principles.agent.yaml +27 -0
- package/test/fixtures/agent-schema/invalid/persona/extra-persona-fields.agent.yaml +27 -0
- package/test/fixtures/agent-schema/invalid/persona/missing-role.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/prompts/empty-content.agent.yaml +29 -0
- package/test/fixtures/agent-schema/invalid/prompts/extra-prompt-fields.agent.yaml +31 -0
- package/test/fixtures/agent-schema/invalid/prompts/missing-content.agent.yaml +28 -0
- package/test/fixtures/agent-schema/invalid/prompts/missing-id.agent.yaml +28 -0
- package/test/fixtures/agent-schema/invalid/top-level/empty-file.agent.yaml +5 -0
- package/test/fixtures/agent-schema/invalid/top-level/extra-top-level-keys.agent.yaml +28 -0
- package/test/fixtures/agent-schema/invalid/top-level/missing-agent-key.agent.yaml +11 -0
- package/test/fixtures/agent-schema/invalid/yaml-errors/invalid-indentation.agent.yaml +19 -0
- package/test/fixtures/agent-schema/invalid/yaml-errors/malformed-yaml.agent.yaml +18 -0
- package/test/fixtures/agent-schema/valid/critical-actions/empty-critical-actions.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/critical-actions/no-critical-actions.agent.yaml +22 -0
- package/test/fixtures/agent-schema/valid/critical-actions/valid-critical-actions.agent.yaml +27 -0
- package/test/fixtures/agent-schema/valid/menu/multiple-menu-items.agent.yaml +31 -0
- package/test/fixtures/agent-schema/valid/menu/single-menu-item.agent.yaml +22 -0
- package/test/fixtures/agent-schema/valid/menu-commands/all-command-types.agent.yaml +38 -0
- package/test/fixtures/agent-schema/valid/menu-commands/multiple-commands.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/menu-triggers/compound-triggers.agent.yaml +31 -0
- package/test/fixtures/agent-schema/valid/menu-triggers/kebab-case-triggers.agent.yaml +34 -0
- package/test/fixtures/agent-schema/valid/metadata/core-agent-with-module.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/metadata/empty-module-name-in-path.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/metadata/malformed-path-treated-as-core.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/metadata/module-agent-correct.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/metadata/module-agent-missing-module.agent.yaml +23 -0
- package/test/fixtures/agent-schema/valid/metadata/wrong-module-value.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/persona/complete-persona.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/prompts/empty-prompts.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/prompts/no-prompts.agent.yaml +22 -0
- package/test/fixtures/agent-schema/valid/prompts/valid-prompts-minimal.agent.yaml +28 -0
- package/test/fixtures/agent-schema/valid/prompts/valid-prompts-with-description.agent.yaml +30 -0
- package/test/fixtures/agent-schema/valid/top-level/minimal-core-agent.agent.yaml +24 -0
- package/test/test-agent-schema.js +387 -0
- package/test/test-cli-integration.sh +159 -0
- package/test/test-installation-components.js +214 -0
- package/test/test-scope-e2e.js +439 -0
- package/test/test-scope-system.js +781 -0
- package/test/unit-test-schema.js +133 -0
- package/tools/bmad-npx-wrapper.js +38 -0
- package/tools/build-docs.js +577 -0
- package/tools/cli/README.md +7 -0
- package/tools/cli/bmad-cli.js +58 -0
- package/tools/cli/commands/install.js +87 -0
- package/tools/cli/commands/scope.js +474 -0
- package/tools/cli/external-official-modules.yaml +41 -0
- package/tools/cli/installers/install-messages.yaml +58 -0
- package/tools/cli/installers/lib/core/config-collector.js +1079 -0
- package/tools/cli/installers/lib/core/custom-module-cache.js +259 -0
- package/tools/cli/installers/lib/core/dependency-resolver.js +739 -0
- package/tools/cli/installers/lib/core/detector.js +223 -0
- package/tools/cli/installers/lib/core/ide-config-manager.js +156 -0
- package/tools/cli/installers/lib/core/installer.js +2585 -0
- package/tools/cli/installers/lib/core/manifest-generator.js +963 -0
- package/tools/cli/installers/lib/core/manifest.js +590 -0
- package/tools/cli/installers/lib/custom/handler.js +363 -0
- package/tools/cli/installers/lib/ide/_base-ide.js +654 -0
- package/tools/cli/installers/lib/ide/antigravity.js +486 -0
- package/tools/cli/installers/lib/ide/auggie.js +244 -0
- package/tools/cli/installers/lib/ide/claude-code.js +487 -0
- package/tools/cli/installers/lib/ide/cline.js +269 -0
- package/tools/cli/installers/lib/ide/codex.js +375 -0
- package/tools/cli/installers/lib/ide/crush.js +300 -0
- package/tools/cli/installers/lib/ide/cursor.js +169 -0
- package/tools/cli/installers/lib/ide/gemini.js +301 -0
- package/tools/cli/installers/lib/ide/github-copilot.js +383 -0
- package/tools/cli/installers/lib/ide/iflow.js +191 -0
- package/tools/cli/installers/lib/ide/kilo.js +250 -0
- package/tools/cli/installers/lib/ide/kiro-cli.js +326 -0
- package/tools/cli/installers/lib/ide/manager.js +244 -0
- package/tools/cli/installers/lib/ide/opencode.js +257 -0
- package/tools/cli/installers/lib/ide/qwen.js +372 -0
- package/tools/cli/installers/lib/ide/roo.js +270 -0
- package/tools/cli/installers/lib/ide/rovo-dev.js +290 -0
- package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +96 -0
- package/tools/cli/installers/lib/ide/shared/bmad-artifacts.js +158 -0
- package/tools/cli/installers/lib/ide/shared/module-injections.js +136 -0
- package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +119 -0
- package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +242 -0
- package/tools/cli/installers/lib/ide/templates/agent-command-template.md +29 -0
- package/tools/cli/installers/lib/ide/templates/gemini-agent-command.toml +14 -0
- package/tools/cli/installers/lib/ide/templates/gemini-task-command.toml +12 -0
- package/tools/cli/installers/lib/ide/templates/workflow-command-template.md +30 -0
- package/tools/cli/installers/lib/ide/templates/workflow-commander.md +45 -0
- package/tools/cli/installers/lib/ide/trae.js +313 -0
- package/tools/cli/installers/lib/ide/windsurf.js +258 -0
- package/tools/cli/installers/lib/message-loader.js +85 -0
- package/tools/cli/installers/lib/modules/external-manager.js +133 -0
- package/tools/cli/installers/lib/modules/manager.js +1362 -0
- package/tools/cli/lib/activation-builder.js +163 -0
- package/tools/cli/lib/agent/compiler.js +522 -0
- package/tools/cli/lib/agent/installer.js +716 -0
- package/tools/cli/lib/agent/template-engine.js +152 -0
- package/tools/cli/lib/agent-analyzer.js +109 -0
- package/tools/cli/lib/agent-party-generator.js +194 -0
- package/tools/cli/lib/cli-utils.js +227 -0
- package/tools/cli/lib/config.js +213 -0
- package/tools/cli/lib/file-ops.js +204 -0
- package/tools/cli/lib/platform-codes.js +116 -0
- package/tools/cli/lib/project-root.js +77 -0
- package/tools/cli/lib/prompts.js +433 -0
- package/tools/cli/lib/ui.js +1591 -0
- package/tools/cli/lib/xml-handler.js +177 -0
- package/tools/cli/lib/xml-to-markdown.js +82 -0
- package/tools/cli/lib/yaml-format.js +245 -0
- package/tools/cli/lib/yaml-xml-builder.js +587 -0
- package/tools/cli/scripts/migrate-workflows.js +273 -0
- package/tools/docs/BUNDLE_DISTRIBUTION_SETUP.md +95 -0
- package/tools/docs/index.md +2 -0
- package/tools/fix-doc-links.js +288 -0
- package/tools/flattener/aggregate.js +76 -0
- package/tools/flattener/binary.js +80 -0
- package/tools/flattener/discovery.js +71 -0
- package/tools/flattener/files.js +35 -0
- package/tools/flattener/ignoreRules.js +172 -0
- package/tools/flattener/main.js +483 -0
- package/tools/flattener/projectRoot.js +201 -0
- package/tools/flattener/prompts.js +44 -0
- package/tools/flattener/stats.helpers.js +368 -0
- package/tools/flattener/stats.js +75 -0
- package/tools/flattener/test-matrix.js +409 -0
- package/tools/flattener/xml.js +82 -0
- package/tools/format-workflow-md.js +263 -0
- package/tools/lib/xml-utils.js +13 -0
- package/tools/maintainer/review-pr-README.md +55 -0
- package/tools/maintainer/review-pr.md +242 -0
- package/tools/migrate-custom-module-paths.js +124 -0
- package/tools/platform-codes.yaml +157 -0
- package/tools/schema/agent.js +493 -0
- package/tools/validate-agent-schema.js +110 -0
- package/tools/validate-doc-links.js +363 -0
- package/tools/validate-svg-changes.sh +356 -0
- package/website/README.md +76 -0
- package/website/astro.config.mjs +228 -0
- package/website/public/favicon.ico +0 -0
- package/website/public/img/bmad-dark.png +0 -0
- package/website/public/img/bmad-light.png +0 -0
- package/website/public/img/logo.svg +4 -0
- package/website/public/robots.txt +37 -0
- package/website/src/components/Banner.astro +59 -0
- package/website/src/components/Header.astro +121 -0
- package/website/src/components/MobileMenuFooter.astro +53 -0
- package/website/src/content/config.ts +6 -0
- package/website/src/lib/site-url.js +25 -0
- package/website/src/rehype-markdown-links.js +102 -0
- package/website/src/styles/custom.css +485 -0
|
@@ -0,0 +1,907 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Test Quality Standards Explained"
|
|
3
|
+
description: Understanding TEA's Definition of Done for deterministic, isolated, and maintainable tests
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Test Quality Standards Explained
|
|
7
|
+
|
|
8
|
+
Test quality standards define what makes a test "good" in TEA. These aren't suggestions - they're the Definition of Done that prevents tests from rotting in review.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
**TEA's Quality Principles:**
|
|
13
|
+
- **Deterministic** - Same result every run
|
|
14
|
+
- **Isolated** - No dependencies on other tests
|
|
15
|
+
- **Explicit** - Assertions visible in test body
|
|
16
|
+
- **Focused** - Single responsibility, appropriate size
|
|
17
|
+
- **Fast** - Execute in reasonable time
|
|
18
|
+
|
|
19
|
+
**Why these matter:** Tests that violate these principles create maintenance burden, slow down development, and lose team trust.
|
|
20
|
+
|
|
21
|
+
## The Problem
|
|
22
|
+
|
|
23
|
+
### Tests That Rot in Review
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// ❌ The anti-pattern: This test will rot
|
|
27
|
+
test('user can do stuff', async ({ page }) => {
|
|
28
|
+
await page.goto('/');
|
|
29
|
+
await page.waitForTimeout(5000); // Non-deterministic
|
|
30
|
+
|
|
31
|
+
if (await page.locator('.banner').isVisible()) { // Conditional
|
|
32
|
+
await page.click('.dismiss');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
try { // Try-catch for flow control
|
|
36
|
+
await page.click('#load-more');
|
|
37
|
+
} catch (e) {
|
|
38
|
+
// Silently continue
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ... 300 more lines of test logic
|
|
42
|
+
// ... no clear assertions
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**What's wrong:**
|
|
47
|
+
- **Hard wait** - Flaky, wastes time
|
|
48
|
+
- **Conditional** - Non-deterministic behavior
|
|
49
|
+
- **Try-catch** - Hides failures
|
|
50
|
+
- **Too large** - Hard to maintain
|
|
51
|
+
- **Vague name** - Unclear purpose
|
|
52
|
+
- **No explicit assertions** - What's being tested?
|
|
53
|
+
|
|
54
|
+
**Result:** PR review comments: "This test is flaky, please fix" → never merged → test deleted → coverage lost
|
|
55
|
+
|
|
56
|
+
### AI-Generated Tests Without Standards
|
|
57
|
+
|
|
58
|
+
AI-generated tests without quality guardrails:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// AI generates 50 tests like this:
|
|
62
|
+
test('test1', async ({ page }) => {
|
|
63
|
+
await page.goto('/');
|
|
64
|
+
await page.waitForTimeout(3000);
|
|
65
|
+
// ... flaky, vague, redundant
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('test2', async ({ page }) => {
|
|
69
|
+
await page.goto('/');
|
|
70
|
+
await page.waitForTimeout(3000);
|
|
71
|
+
// ... duplicates test1
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// ... 48 more similar tests
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Result:** 50 tests, 80% redundant, 90% flaky, 0% trusted by team - low-quality outputs that create maintenance burden.
|
|
78
|
+
|
|
79
|
+
## The Solution: TEA's Quality Standards
|
|
80
|
+
|
|
81
|
+
### 1. Determinism (No Flakiness)
|
|
82
|
+
|
|
83
|
+
**Rule:** Test produces same result every run.
|
|
84
|
+
|
|
85
|
+
**Requirements:**
|
|
86
|
+
- ❌ No hard waits (`waitForTimeout`)
|
|
87
|
+
- ❌ No conditionals for flow control (`if/else`)
|
|
88
|
+
- ❌ No try-catch for flow control
|
|
89
|
+
- ✅ Use network-first patterns (wait for responses)
|
|
90
|
+
- ✅ Use explicit waits (waitForSelector, waitForResponse)
|
|
91
|
+
|
|
92
|
+
**Bad Example:**
|
|
93
|
+
```typescript
|
|
94
|
+
test('flaky test', async ({ page }) => {
|
|
95
|
+
await page.click('button');
|
|
96
|
+
await page.waitForTimeout(2000); // ❌ Might be too short
|
|
97
|
+
|
|
98
|
+
if (await page.locator('.modal').isVisible()) { // ❌ Non-deterministic
|
|
99
|
+
await page.click('.dismiss');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try { // ❌ Silently handles errors
|
|
103
|
+
await expect(page.locator('.success')).toBeVisible();
|
|
104
|
+
} catch (e) {
|
|
105
|
+
// Test passes even if assertion fails!
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Good Example (Vanilla Playwright):**
|
|
111
|
+
```typescript
|
|
112
|
+
test('deterministic test', async ({ page }) => {
|
|
113
|
+
const responsePromise = page.waitForResponse(
|
|
114
|
+
resp => resp.url().includes('/api/submit') && resp.ok()
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
await page.click('button');
|
|
118
|
+
await responsePromise; // ✅ Wait for actual response
|
|
119
|
+
|
|
120
|
+
// Modal should ALWAYS show (make it deterministic)
|
|
121
|
+
await expect(page.locator('.modal')).toBeVisible();
|
|
122
|
+
await page.click('.dismiss');
|
|
123
|
+
|
|
124
|
+
// Explicit assertion (fails if not visible)
|
|
125
|
+
await expect(page.locator('.success')).toBeVisible();
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**With Playwright Utils (Even Cleaner):**
|
|
130
|
+
```typescript
|
|
131
|
+
import { test } from '@seontechnologies/playwright-utils/fixtures';
|
|
132
|
+
import { expect } from '@playwright/test';
|
|
133
|
+
|
|
134
|
+
test('deterministic test', async ({ page, interceptNetworkCall }) => {
|
|
135
|
+
const submitCall = interceptNetworkCall({
|
|
136
|
+
method: 'POST',
|
|
137
|
+
url: '**/api/submit'
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
await page.click('button');
|
|
141
|
+
|
|
142
|
+
// Wait for actual response (automatic JSON parsing)
|
|
143
|
+
const { status, responseJson } = await submitCall;
|
|
144
|
+
expect(status).toBe(200);
|
|
145
|
+
|
|
146
|
+
// Modal should ALWAYS show (make it deterministic)
|
|
147
|
+
await expect(page.locator('.modal')).toBeVisible();
|
|
148
|
+
await page.click('.dismiss');
|
|
149
|
+
|
|
150
|
+
// Explicit assertion (fails if not visible)
|
|
151
|
+
await expect(page.locator('.success')).toBeVisible();
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Why both work:**
|
|
156
|
+
- Waits for actual event (network response)
|
|
157
|
+
- No conditionals (behavior is deterministic)
|
|
158
|
+
- Assertions fail loudly (no silent failures)
|
|
159
|
+
- Same result every run (deterministic)
|
|
160
|
+
|
|
161
|
+
**Playwright Utils additional benefits:**
|
|
162
|
+
- Automatic JSON parsing
|
|
163
|
+
- `{ status, responseJson }` structure (can validate response data)
|
|
164
|
+
- No manual `await response.json()`
|
|
165
|
+
|
|
166
|
+
### 2. Isolation (No Dependencies)
|
|
167
|
+
|
|
168
|
+
**Rule:** Test runs independently, no shared state.
|
|
169
|
+
|
|
170
|
+
**Requirements:**
|
|
171
|
+
- ✅ Self-cleaning (cleanup after test)
|
|
172
|
+
- ✅ No global state dependencies
|
|
173
|
+
- ✅ Can run in parallel
|
|
174
|
+
- ✅ Can run in any order
|
|
175
|
+
- ✅ Use unique test data
|
|
176
|
+
|
|
177
|
+
**Bad Example:**
|
|
178
|
+
```typescript
|
|
179
|
+
// ❌ Tests depend on execution order
|
|
180
|
+
let userId: string; // Shared global state
|
|
181
|
+
|
|
182
|
+
test('create user', async ({ apiRequest }) => {
|
|
183
|
+
const { body } = await apiRequest({
|
|
184
|
+
method: 'POST',
|
|
185
|
+
path: '/api/users',
|
|
186
|
+
body: { email: 'test@example.com' } (hard-coded)
|
|
187
|
+
});
|
|
188
|
+
userId = body.id; // Store in global
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
test('update user', async ({ apiRequest }) => {
|
|
192
|
+
// Depends on previous test setting userId
|
|
193
|
+
await apiRequest({
|
|
194
|
+
method: 'PATCH',
|
|
195
|
+
path: `/api/users/${userId}`,
|
|
196
|
+
body: { name: 'Updated' }
|
|
197
|
+
});
|
|
198
|
+
// No cleanup - leaves user in database
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Problems:**
|
|
203
|
+
- Tests must run in order (can't parallelize)
|
|
204
|
+
- Second test fails if first skipped (`.only`)
|
|
205
|
+
- Hard-coded data causes conflicts
|
|
206
|
+
- No cleanup (database fills with test data)
|
|
207
|
+
|
|
208
|
+
**Good Example (Vanilla Playwright):**
|
|
209
|
+
```typescript
|
|
210
|
+
test('should update user profile', async ({ request }) => {
|
|
211
|
+
// Create unique test data
|
|
212
|
+
const testEmail = `test-${Date.now()}@example.com`;
|
|
213
|
+
|
|
214
|
+
// Setup: Create user
|
|
215
|
+
const createResp = await request.post('/api/users', {
|
|
216
|
+
data: { email: testEmail, name: 'Original' }
|
|
217
|
+
});
|
|
218
|
+
const user = await createResp.json();
|
|
219
|
+
|
|
220
|
+
// Test: Update user
|
|
221
|
+
const updateResp = await request.patch(`/api/users/${user.id}`, {
|
|
222
|
+
data: { name: 'Updated' }
|
|
223
|
+
});
|
|
224
|
+
const updated = await updateResp.json();
|
|
225
|
+
|
|
226
|
+
expect(updated.name).toBe('Updated');
|
|
227
|
+
|
|
228
|
+
// Cleanup: Delete user
|
|
229
|
+
await request.delete(`/api/users/${user.id}`);
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Even Better (With Playwright Utils):**
|
|
234
|
+
```typescript
|
|
235
|
+
import { test } from '@seontechnologies/playwright-utils/api-request/fixtures';
|
|
236
|
+
import { expect } from '@playwright/test';
|
|
237
|
+
import { faker } from '@faker-js/faker';
|
|
238
|
+
|
|
239
|
+
test('should update user profile', async ({ apiRequest }) => {
|
|
240
|
+
// Dynamic unique test data
|
|
241
|
+
const testEmail = faker.internet.email();
|
|
242
|
+
|
|
243
|
+
// Setup: Create user
|
|
244
|
+
const { status: createStatus, body: user } = await apiRequest({
|
|
245
|
+
method: 'POST',
|
|
246
|
+
path: '/api/users',
|
|
247
|
+
body: { email: testEmail, name: faker.person.fullName() }
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
expect(createStatus).toBe(201);
|
|
251
|
+
|
|
252
|
+
// Test: Update user
|
|
253
|
+
const { status, body: updated } = await apiRequest({
|
|
254
|
+
method: 'PATCH',
|
|
255
|
+
path: `/api/users/${user.id}`,
|
|
256
|
+
body: { name: 'Updated Name' }
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
expect(status).toBe(200);
|
|
260
|
+
expect(updated.name).toBe('Updated Name');
|
|
261
|
+
|
|
262
|
+
// Cleanup: Delete user
|
|
263
|
+
await apiRequest({
|
|
264
|
+
method: 'DELETE',
|
|
265
|
+
path: `/api/users/${user.id}`
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Playwright Utils Benefits:**
|
|
271
|
+
- `{ status, body }` destructuring (cleaner than `response.status()` + `await response.json()`)
|
|
272
|
+
- No manual `await response.json()`
|
|
273
|
+
- Automatic retry for 5xx errors
|
|
274
|
+
- Optional schema validation with `.validateSchema()`
|
|
275
|
+
|
|
276
|
+
**Why it works:**
|
|
277
|
+
- No global state
|
|
278
|
+
- Unique test data (no conflicts)
|
|
279
|
+
- Self-cleaning (deletes user)
|
|
280
|
+
- Can run in parallel
|
|
281
|
+
- Can run in any order
|
|
282
|
+
|
|
283
|
+
### 3. Explicit Assertions (No Hidden Validation)
|
|
284
|
+
|
|
285
|
+
**Rule:** Assertions visible in test body, not abstracted.
|
|
286
|
+
|
|
287
|
+
**Requirements:**
|
|
288
|
+
- ✅ Assertions in test code (not helper functions)
|
|
289
|
+
- ✅ Specific assertions (not generic `toBeTruthy`)
|
|
290
|
+
- ✅ Meaningful expectations (test actual behavior)
|
|
291
|
+
|
|
292
|
+
**Bad Example:**
|
|
293
|
+
```typescript
|
|
294
|
+
// ❌ Assertions hidden in helper
|
|
295
|
+
async function verifyProfilePage(page: Page) {
|
|
296
|
+
// Assertions buried in helper (not visible in test)
|
|
297
|
+
await expect(page.locator('h1')).toBeVisible();
|
|
298
|
+
await expect(page.locator('.email')).toContainText('@');
|
|
299
|
+
await expect(page.locator('.name')).not.toBeEmpty();
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
test('profile page', async ({ page }) => {
|
|
303
|
+
await page.goto('/profile');
|
|
304
|
+
await verifyProfilePage(page); // What's being verified?
|
|
305
|
+
});
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**Problems:**
|
|
309
|
+
- Can't see what's tested (need to read helper)
|
|
310
|
+
- Hard to debug failures (which assertion failed?)
|
|
311
|
+
- Reduces test readability
|
|
312
|
+
- Hides important validation
|
|
313
|
+
|
|
314
|
+
**Good Example:**
|
|
315
|
+
```typescript
|
|
316
|
+
// ✅ Assertions explicit in test
|
|
317
|
+
test('should display profile with correct data', async ({ page }) => {
|
|
318
|
+
await page.goto('/profile');
|
|
319
|
+
|
|
320
|
+
// Explicit assertions - clear what's tested
|
|
321
|
+
await expect(page.locator('h1')).toContainText('Test User');
|
|
322
|
+
await expect(page.locator('.email')).toContainText('test@example.com');
|
|
323
|
+
await expect(page.locator('.bio')).toContainText('Software Engineer');
|
|
324
|
+
await expect(page.locator('img[alt="Avatar"]')).toBeVisible();
|
|
325
|
+
});
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Why it works:**
|
|
329
|
+
- See what's tested at a glance
|
|
330
|
+
- Debug failures easily (know which assertion failed)
|
|
331
|
+
- Test is self-documenting
|
|
332
|
+
- No hidden behavior
|
|
333
|
+
|
|
334
|
+
**Exception:** Use helper for setup/cleanup, not assertions.
|
|
335
|
+
|
|
336
|
+
### 4. Focused Tests (Appropriate Size)
|
|
337
|
+
|
|
338
|
+
**Rule:** Test has single responsibility, reasonable size.
|
|
339
|
+
|
|
340
|
+
**Requirements:**
|
|
341
|
+
- ✅ Test size < 300 lines
|
|
342
|
+
- ✅ Single responsibility (test one thing well)
|
|
343
|
+
- ✅ Clear describe/test names
|
|
344
|
+
- ✅ Appropriate scope (not too granular, not too broad)
|
|
345
|
+
|
|
346
|
+
**Bad Example:**
|
|
347
|
+
```typescript
|
|
348
|
+
// ❌ 500-line test testing everything
|
|
349
|
+
test('complete user flow', async ({ page }) => {
|
|
350
|
+
// Registration (50 lines)
|
|
351
|
+
await page.goto('/register');
|
|
352
|
+
await page.fill('#email', 'test@example.com');
|
|
353
|
+
// ... 48 more lines
|
|
354
|
+
|
|
355
|
+
// Profile setup (100 lines)
|
|
356
|
+
await page.goto('/profile');
|
|
357
|
+
// ... 98 more lines
|
|
358
|
+
|
|
359
|
+
// Settings configuration (150 lines)
|
|
360
|
+
await page.goto('/settings');
|
|
361
|
+
// ... 148 more lines
|
|
362
|
+
|
|
363
|
+
// Data export (200 lines)
|
|
364
|
+
await page.goto('/export');
|
|
365
|
+
// ... 198 more lines
|
|
366
|
+
|
|
367
|
+
// Total: 500 lines, testing 4 different features
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Problems:**
|
|
372
|
+
- Failure in line 50 prevents testing lines 51-500
|
|
373
|
+
- Hard to understand (what's being tested?)
|
|
374
|
+
- Slow to execute (testing too much)
|
|
375
|
+
- Hard to debug (which feature failed?)
|
|
376
|
+
|
|
377
|
+
**Good Example:**
|
|
378
|
+
```typescript
|
|
379
|
+
// ✅ Focused tests - one responsibility each
|
|
380
|
+
|
|
381
|
+
test('should register new user', async ({ page }) => {
|
|
382
|
+
await page.goto('/register');
|
|
383
|
+
await page.fill('#email', 'test@example.com');
|
|
384
|
+
await page.fill('#password', 'password123');
|
|
385
|
+
await page.click('button[type="submit"]');
|
|
386
|
+
|
|
387
|
+
await expect(page).toHaveURL('/welcome');
|
|
388
|
+
await expect(page.locator('h1')).toContainText('Welcome');
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
test('should configure user profile', async ({ page, authSession }) => {
|
|
392
|
+
await authSession.login({ email: 'test@example.com', password: 'pass' });
|
|
393
|
+
await page.goto('/profile');
|
|
394
|
+
|
|
395
|
+
await page.fill('#name', 'Test User');
|
|
396
|
+
await page.fill('#bio', 'Software Engineer');
|
|
397
|
+
await page.click('button:has-text("Save")');
|
|
398
|
+
|
|
399
|
+
await expect(page.locator('.success')).toBeVisible();
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
// ... separate tests for settings, export (each < 50 lines)
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
**Why it works:**
|
|
406
|
+
- Each test has one responsibility
|
|
407
|
+
- Failure is easy to diagnose
|
|
408
|
+
- Can run tests independently
|
|
409
|
+
- Test names describe exactly what's tested
|
|
410
|
+
|
|
411
|
+
### 5. Fast Execution (Performance Budget)
|
|
412
|
+
|
|
413
|
+
**Rule:** Individual test executes in < 1.5 minutes.
|
|
414
|
+
|
|
415
|
+
**Requirements:**
|
|
416
|
+
- ✅ Test execution < 90 seconds
|
|
417
|
+
- ✅ Efficient selectors (getByRole > XPath)
|
|
418
|
+
- ✅ Minimal redundant actions
|
|
419
|
+
- ✅ Parallel execution enabled
|
|
420
|
+
|
|
421
|
+
**Bad Example:**
|
|
422
|
+
```typescript
|
|
423
|
+
// ❌ Slow test (3+ minutes)
|
|
424
|
+
test('slow test', async ({ page }) => {
|
|
425
|
+
await page.goto('/');
|
|
426
|
+
await page.waitForTimeout(10000); // 10s wasted
|
|
427
|
+
|
|
428
|
+
// Navigate through 10 pages (2 minutes)
|
|
429
|
+
for (let i = 1; i <= 10; i++) {
|
|
430
|
+
await page.click(`a[href="/page-${i}"]`);
|
|
431
|
+
await page.waitForTimeout(5000); // 5s per page = 50s wasted
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Complex XPath selector (slow)
|
|
435
|
+
await page.locator('//div[@class="container"]/section[3]/div[2]/p').click();
|
|
436
|
+
|
|
437
|
+
// More waiting
|
|
438
|
+
await page.waitForTimeout(30000); // 30s wasted
|
|
439
|
+
|
|
440
|
+
await expect(page.locator('.result')).toBeVisible();
|
|
441
|
+
});
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
**Total time:** 3+ minutes (95 seconds wasted on hard waits)
|
|
445
|
+
|
|
446
|
+
**Good Example (Vanilla Playwright):**
|
|
447
|
+
```typescript
|
|
448
|
+
// ✅ Fast test (< 10 seconds)
|
|
449
|
+
test('fast test', async ({ page }) => {
|
|
450
|
+
// Set up response wait
|
|
451
|
+
const apiPromise = page.waitForResponse(
|
|
452
|
+
resp => resp.url().includes('/api/result') && resp.ok()
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
await page.goto('/');
|
|
456
|
+
|
|
457
|
+
// Direct navigation (skip intermediate pages)
|
|
458
|
+
await page.goto('/page-10');
|
|
459
|
+
|
|
460
|
+
// Efficient selector
|
|
461
|
+
await page.getByRole('button', { name: 'Submit' }).click();
|
|
462
|
+
|
|
463
|
+
// Wait for actual response (fast when API is fast)
|
|
464
|
+
await apiPromise;
|
|
465
|
+
|
|
466
|
+
await expect(page.locator('.result')).toBeVisible();
|
|
467
|
+
});
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
**With Playwright Utils:**
|
|
471
|
+
```typescript
|
|
472
|
+
import { test } from '@seontechnologies/playwright-utils/fixtures';
|
|
473
|
+
import { expect } from '@playwright/test';
|
|
474
|
+
|
|
475
|
+
test('fast test', async ({ page, interceptNetworkCall }) => {
|
|
476
|
+
// Set up interception
|
|
477
|
+
const resultCall = interceptNetworkCall({
|
|
478
|
+
method: 'GET',
|
|
479
|
+
url: '**/api/result'
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
await page.goto('/');
|
|
483
|
+
|
|
484
|
+
// Direct navigation (skip intermediate pages)
|
|
485
|
+
await page.goto('/page-10');
|
|
486
|
+
|
|
487
|
+
// Efficient selector
|
|
488
|
+
await page.getByRole('button', { name: 'Submit' }).click();
|
|
489
|
+
|
|
490
|
+
// Wait for actual response (automatic JSON parsing)
|
|
491
|
+
const { status, responseJson } = await resultCall;
|
|
492
|
+
|
|
493
|
+
expect(status).toBe(200);
|
|
494
|
+
await expect(page.locator('.result')).toBeVisible();
|
|
495
|
+
|
|
496
|
+
// Can also validate response data if needed
|
|
497
|
+
// expect(responseJson.data).toBeDefined();
|
|
498
|
+
});
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
**Total time:** < 10 seconds (no wasted waits)
|
|
502
|
+
|
|
503
|
+
**Both examples achieve:**
|
|
504
|
+
- No hard waits (wait for actual events)
|
|
505
|
+
- Direct navigation (skip unnecessary steps)
|
|
506
|
+
- Efficient selectors (getByRole)
|
|
507
|
+
- Fast execution
|
|
508
|
+
|
|
509
|
+
**Playwright Utils bonus:**
|
|
510
|
+
- Can validate API response data easily
|
|
511
|
+
- Automatic JSON parsing
|
|
512
|
+
- Cleaner API
|
|
513
|
+
|
|
514
|
+
## TEA's Quality Scoring
|
|
515
|
+
|
|
516
|
+
TEA reviews tests against these standards in `*test-review`:
|
|
517
|
+
|
|
518
|
+
### Scoring Categories (100 points total)
|
|
519
|
+
|
|
520
|
+
**Determinism (35 points):**
|
|
521
|
+
- No hard waits: 10 points
|
|
522
|
+
- No conditionals: 10 points
|
|
523
|
+
- No try-catch flow: 10 points
|
|
524
|
+
- Network-first patterns: 5 points
|
|
525
|
+
|
|
526
|
+
**Isolation (25 points):**
|
|
527
|
+
- Self-cleaning: 15 points
|
|
528
|
+
- No global state: 5 points
|
|
529
|
+
- Parallel-safe: 5 points
|
|
530
|
+
|
|
531
|
+
**Assertions (20 points):**
|
|
532
|
+
- Explicit in test body: 10 points
|
|
533
|
+
- Specific and meaningful: 10 points
|
|
534
|
+
|
|
535
|
+
**Structure (10 points):**
|
|
536
|
+
- Test size < 300 lines: 5 points
|
|
537
|
+
- Clear naming: 5 points
|
|
538
|
+
|
|
539
|
+
**Performance (10 points):**
|
|
540
|
+
- Execution time < 1.5 min: 10 points
|
|
541
|
+
|
|
542
|
+
#### Quality Scoring Breakdown
|
|
543
|
+
|
|
544
|
+
```mermaid
|
|
545
|
+
%%{init: {'theme':'base', 'themeVariables': { 'fontSize':'14px'}}}%%
|
|
546
|
+
pie title Test Quality Score (100 points)
|
|
547
|
+
"Determinism" : 35
|
|
548
|
+
"Isolation" : 25
|
|
549
|
+
"Assertions" : 20
|
|
550
|
+
"Structure" : 10
|
|
551
|
+
"Performance" : 10
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
```mermaid
|
|
555
|
+
%%{init: {'theme':'base', 'themeVariables': { 'fontSize':'13px'}}}%%
|
|
556
|
+
flowchart LR
|
|
557
|
+
subgraph Det[Determinism - 35 pts]
|
|
558
|
+
D1[No hard waits<br/>10 pts]
|
|
559
|
+
D2[No conditionals<br/>10 pts]
|
|
560
|
+
D3[No try-catch flow<br/>10 pts]
|
|
561
|
+
D4[Network-first<br/>5 pts]
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
subgraph Iso[Isolation - 25 pts]
|
|
565
|
+
I1[Self-cleaning<br/>15 pts]
|
|
566
|
+
I2[No global state<br/>5 pts]
|
|
567
|
+
I3[Parallel-safe<br/>5 pts]
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
subgraph Assrt[Assertions - 20 pts]
|
|
571
|
+
A1[Explicit in body<br/>10 pts]
|
|
572
|
+
A2[Specific/meaningful<br/>10 pts]
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
subgraph Struct[Structure - 10 pts]
|
|
576
|
+
S1[Size < 300 lines<br/>5 pts]
|
|
577
|
+
S2[Clear naming<br/>5 pts]
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
subgraph Perf[Performance - 10 pts]
|
|
581
|
+
P1[Time < 1.5 min<br/>10 pts]
|
|
582
|
+
end
|
|
583
|
+
|
|
584
|
+
Det --> Total([Total: 100 points])
|
|
585
|
+
Iso --> Total
|
|
586
|
+
Assrt --> Total
|
|
587
|
+
Struct --> Total
|
|
588
|
+
Perf --> Total
|
|
589
|
+
|
|
590
|
+
style Det fill:#ffebee,stroke:#c62828,stroke-width:2px
|
|
591
|
+
style Iso fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
|
|
592
|
+
style Assrt fill:#f3e5f5,stroke:#6a1b9a,stroke-width:2px
|
|
593
|
+
style Struct fill:#fff9c4,stroke:#f57f17,stroke-width:2px
|
|
594
|
+
style Perf fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
|
|
595
|
+
style Total fill:#fff,stroke:#000,stroke-width:3px
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
### Score Interpretation
|
|
599
|
+
|
|
600
|
+
| Score | Interpretation | Action |
|
|
601
|
+
| ---------- | -------------- | -------------------------------------- |
|
|
602
|
+
| **90-100** | Excellent | Production-ready, minimal changes |
|
|
603
|
+
| **80-89** | Good | Minor improvements recommended |
|
|
604
|
+
| **70-79** | Acceptable | Address recommendations before release |
|
|
605
|
+
| **60-69** | Needs Work | Fix critical issues |
|
|
606
|
+
| **< 60** | Critical | Significant refactoring needed |
|
|
607
|
+
|
|
608
|
+
## Comparison: Good vs Bad Tests
|
|
609
|
+
|
|
610
|
+
### Example: User Login
|
|
611
|
+
|
|
612
|
+
**Bad Test (Score: 45/100):**
|
|
613
|
+
```typescript
|
|
614
|
+
test('login test', async ({ page }) => { // Vague name
|
|
615
|
+
await page.goto('/login');
|
|
616
|
+
await page.waitForTimeout(3000); // -10 (hard wait)
|
|
617
|
+
|
|
618
|
+
await page.fill('[name="email"]', 'test@example.com');
|
|
619
|
+
await page.fill('[name="password"]', 'password');
|
|
620
|
+
|
|
621
|
+
if (await page.locator('.remember-me').isVisible()) { // -10 (conditional)
|
|
622
|
+
await page.click('.remember-me');
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
await page.click('button');
|
|
626
|
+
|
|
627
|
+
try { // -10 (try-catch flow)
|
|
628
|
+
await page.waitForURL('/dashboard', { timeout: 5000 });
|
|
629
|
+
} catch (e) {
|
|
630
|
+
// Ignore navigation failure
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// No assertions! -10
|
|
634
|
+
// No cleanup! -10
|
|
635
|
+
});
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
**Issues:**
|
|
639
|
+
- Determinism: 5/35 (hard wait, conditional, try-catch)
|
|
640
|
+
- Isolation: 10/25 (no cleanup)
|
|
641
|
+
- Assertions: 0/20 (no assertions!)
|
|
642
|
+
- Structure: 15/10 (okay)
|
|
643
|
+
- Performance: 5/10 (slow)
|
|
644
|
+
- **Total: 45/100**
|
|
645
|
+
|
|
646
|
+
**Good Test (Score: 95/100):**
|
|
647
|
+
```typescript
|
|
648
|
+
test('should login with valid credentials and redirect to dashboard', async ({ page, authSession }) => {
|
|
649
|
+
// Use fixture for deterministic auth
|
|
650
|
+
const loginPromise = page.waitForResponse(
|
|
651
|
+
resp => resp.url().includes('/api/auth/login') && resp.ok()
|
|
652
|
+
);
|
|
653
|
+
|
|
654
|
+
await page.goto('/login');
|
|
655
|
+
await page.getByLabel('Email').fill('test@example.com');
|
|
656
|
+
await page.getByLabel('Password').fill('password123');
|
|
657
|
+
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
658
|
+
|
|
659
|
+
// Wait for actual API response
|
|
660
|
+
const response = await loginPromise;
|
|
661
|
+
const { token } = await response.json();
|
|
662
|
+
|
|
663
|
+
// Explicit assertions
|
|
664
|
+
expect(token).toBeDefined();
|
|
665
|
+
await expect(page).toHaveURL('/dashboard');
|
|
666
|
+
await expect(page.getByText('Welcome back')).toBeVisible();
|
|
667
|
+
|
|
668
|
+
// Cleanup handled by authSession fixture
|
|
669
|
+
});
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
**Quality:**
|
|
673
|
+
- Determinism: 35/35 (network-first, no conditionals)
|
|
674
|
+
- Isolation: 25/25 (fixture handles cleanup)
|
|
675
|
+
- Assertions: 20/20 (explicit and specific)
|
|
676
|
+
- Structure: 10/10 (clear name, focused)
|
|
677
|
+
- Performance: 5/10 (< 1 min)
|
|
678
|
+
- **Total: 95/100**
|
|
679
|
+
|
|
680
|
+
### Example: API Testing
|
|
681
|
+
|
|
682
|
+
**Bad Test (Score: 50/100):**
|
|
683
|
+
```typescript
|
|
684
|
+
test('api test', async ({ request }) => {
|
|
685
|
+
const response = await request.post('/api/users', {
|
|
686
|
+
data: { email: 'test@example.com' } // Hard-coded (conflicts)
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
if (response.ok()) { // Conditional
|
|
690
|
+
const user = await response.json();
|
|
691
|
+
// Weak assertion
|
|
692
|
+
expect(user).toBeTruthy();
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// No cleanup - user left in database
|
|
696
|
+
});
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
**Good Test (Score: 92/100):**
|
|
700
|
+
```typescript
|
|
701
|
+
test('should create user with valid data', async ({ apiRequest }) => {
|
|
702
|
+
// Unique test data
|
|
703
|
+
const testEmail = `test-${Date.now()}@example.com`;
|
|
704
|
+
|
|
705
|
+
// Create user
|
|
706
|
+
const { status, body } = await apiRequest({
|
|
707
|
+
method: 'POST',
|
|
708
|
+
path: '/api/users',
|
|
709
|
+
body: { email: testEmail, name: 'Test User' }
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
// Explicit assertions
|
|
713
|
+
expect(status).toBe(201);
|
|
714
|
+
expect(body.id).toBeDefined();
|
|
715
|
+
expect(body.email).toBe(testEmail);
|
|
716
|
+
expect(body.name).toBe('Test User');
|
|
717
|
+
|
|
718
|
+
// Cleanup
|
|
719
|
+
await apiRequest({
|
|
720
|
+
method: 'DELETE',
|
|
721
|
+
path: `/api/users/${body.id}`
|
|
722
|
+
});
|
|
723
|
+
});
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
## How TEA Enforces Standards
|
|
727
|
+
|
|
728
|
+
### During Test Generation (`*atdd`, `*automate`)
|
|
729
|
+
|
|
730
|
+
TEA generates tests following standards by default:
|
|
731
|
+
|
|
732
|
+
```typescript
|
|
733
|
+
// TEA-generated test (automatically follows standards)
|
|
734
|
+
test('should submit contact form', async ({ page }) => {
|
|
735
|
+
// Network-first pattern (no hard waits)
|
|
736
|
+
const submitPromise = page.waitForResponse(
|
|
737
|
+
resp => resp.url().includes('/api/contact') && resp.ok()
|
|
738
|
+
);
|
|
739
|
+
|
|
740
|
+
// Accessible selectors (resilient)
|
|
741
|
+
await page.getByLabel('Name').fill('Test User');
|
|
742
|
+
await page.getByLabel('Email').fill('test@example.com');
|
|
743
|
+
await page.getByLabel('Message').fill('Test message');
|
|
744
|
+
await page.getByRole('button', { name: 'Send' }).click();
|
|
745
|
+
|
|
746
|
+
const response = await submitPromise;
|
|
747
|
+
const result = await response.json();
|
|
748
|
+
|
|
749
|
+
// Explicit assertions
|
|
750
|
+
expect(result.success).toBe(true);
|
|
751
|
+
await expect(page.getByText('Message sent')).toBeVisible();
|
|
752
|
+
|
|
753
|
+
// Size: 15 lines (< 300 ✓)
|
|
754
|
+
// Execution: ~2 seconds (< 90s ✓)
|
|
755
|
+
});
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
### During Test Review (*test-review)
|
|
759
|
+
|
|
760
|
+
TEA audits tests and flags violations:
|
|
761
|
+
|
|
762
|
+
```markdown
|
|
763
|
+
## Critical Issues
|
|
764
|
+
|
|
765
|
+
### Hard Wait Detected (tests/login.spec.ts:23)
|
|
766
|
+
**Issue:** `await page.waitForTimeout(3000)`
|
|
767
|
+
**Score Impact:** -10 (Determinism)
|
|
768
|
+
**Fix:** Use network-first pattern
|
|
769
|
+
|
|
770
|
+
### Conditional Flow Control (tests/profile.spec.ts:45)
|
|
771
|
+
**Issue:** `if (await page.locator('.banner').isVisible())`
|
|
772
|
+
**Score Impact:** -10 (Determinism)
|
|
773
|
+
**Fix:** Make banner presence deterministic
|
|
774
|
+
|
|
775
|
+
## Recommendations
|
|
776
|
+
|
|
777
|
+
### Extract Fixture (tests/auth.spec.ts)
|
|
778
|
+
**Issue:** Login code repeated 5 times
|
|
779
|
+
**Score Impact:** -3 (Structure)
|
|
780
|
+
**Fix:** Extract to authSession fixture
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
## Definition of Done Checklist
|
|
784
|
+
|
|
785
|
+
When is a test "done"?
|
|
786
|
+
|
|
787
|
+
**Test Quality DoD:**
|
|
788
|
+
- [ ] No hard waits (`waitForTimeout`)
|
|
789
|
+
- [ ] No conditionals for flow control
|
|
790
|
+
- [ ] No try-catch for flow control
|
|
791
|
+
- [ ] Network-first patterns used
|
|
792
|
+
- [ ] Assertions explicit in test body
|
|
793
|
+
- [ ] Test size < 300 lines
|
|
794
|
+
- [ ] Clear, descriptive test name
|
|
795
|
+
- [ ] Self-cleaning (cleanup in afterEach or test)
|
|
796
|
+
- [ ] Unique test data (no hard-coded values)
|
|
797
|
+
- [ ] Execution time < 1.5 minutes
|
|
798
|
+
- [ ] Can run in parallel
|
|
799
|
+
- [ ] Can run in any order
|
|
800
|
+
|
|
801
|
+
**Code Review DoD:**
|
|
802
|
+
- [ ] Test quality score > 80
|
|
803
|
+
- [ ] No critical issues from `*test-review`
|
|
804
|
+
- [ ] Follows project patterns (fixtures, selectors)
|
|
805
|
+
- [ ] Test reviewed by team member
|
|
806
|
+
|
|
807
|
+
## Common Quality Issues
|
|
808
|
+
|
|
809
|
+
### Issue: "My test needs conditionals for optional elements"
|
|
810
|
+
|
|
811
|
+
**Wrong approach:**
|
|
812
|
+
```typescript
|
|
813
|
+
if (await page.locator('.banner').isVisible()) {
|
|
814
|
+
await page.click('.dismiss');
|
|
815
|
+
}
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
**Right approach - Make it deterministic:**
|
|
819
|
+
```typescript
|
|
820
|
+
// Option 1: Always expect banner
|
|
821
|
+
await expect(page.locator('.banner')).toBeVisible();
|
|
822
|
+
await page.click('.dismiss');
|
|
823
|
+
|
|
824
|
+
// Option 2: Test both scenarios separately
|
|
825
|
+
test('should show banner for new users', ...);
|
|
826
|
+
test('should not show banner for returning users', ...);
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
### Issue: "My test needs try-catch for error handling"
|
|
830
|
+
|
|
831
|
+
**Wrong approach:**
|
|
832
|
+
```typescript
|
|
833
|
+
try {
|
|
834
|
+
await page.click('#optional-button');
|
|
835
|
+
} catch (e) {
|
|
836
|
+
// Silently continue
|
|
837
|
+
}
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
**Right approach - Make failures explicit:**
|
|
841
|
+
```typescript
|
|
842
|
+
// Option 1: Button should exist
|
|
843
|
+
await page.click('#optional-button'); // Fails loudly if missing
|
|
844
|
+
|
|
845
|
+
// Option 2: Button might not exist (test both)
|
|
846
|
+
test('should work with optional button', async ({ page }) => {
|
|
847
|
+
const hasButton = await page.locator('#optional-button').count() > 0;
|
|
848
|
+
if (hasButton) {
|
|
849
|
+
await page.click('#optional-button');
|
|
850
|
+
}
|
|
851
|
+
// But now you're testing optional behavior explicitly
|
|
852
|
+
});
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
### Issue: "Hard waits are easier than network patterns"
|
|
856
|
+
|
|
857
|
+
**Short-term:** Hard waits seem simpler
|
|
858
|
+
**Long-term:** Flaky tests waste more time than learning network patterns
|
|
859
|
+
|
|
860
|
+
**Investment:**
|
|
861
|
+
- 30 minutes to learn network-first patterns
|
|
862
|
+
- Prevents hundreds of hours debugging flaky tests
|
|
863
|
+
- Tests run faster (no wasted waits)
|
|
864
|
+
- Team trusts test suite
|
|
865
|
+
|
|
866
|
+
## Technical Implementation
|
|
867
|
+
|
|
868
|
+
For detailed test quality patterns, see:
|
|
869
|
+
- [Test Quality Fragment](/docs/reference/tea/knowledge-base.md#quality-standards)
|
|
870
|
+
- [Test Levels Framework Fragment](/docs/reference/tea/knowledge-base.md#quality-standards)
|
|
871
|
+
- [Complete Knowledge Base Index](/docs/reference/tea/knowledge-base.md)
|
|
872
|
+
|
|
873
|
+
## Related Concepts
|
|
874
|
+
|
|
875
|
+
**Core TEA Concepts:**
|
|
876
|
+
- [Risk-Based Testing](/docs/explanation/tea/risk-based-testing.md) - Quality scales with risk
|
|
877
|
+
- [Knowledge Base System](/docs/explanation/tea/knowledge-base-system.md) - How standards are enforced
|
|
878
|
+
- [Engagement Models](/docs/explanation/tea/engagement-models.md) - Quality in different models
|
|
879
|
+
|
|
880
|
+
**Technical Patterns:**
|
|
881
|
+
- [Network-First Patterns](/docs/explanation/tea/network-first-patterns.md) - Determinism explained
|
|
882
|
+
- [Fixture Architecture](/docs/explanation/tea/fixture-architecture.md) - Isolation through fixtures
|
|
883
|
+
|
|
884
|
+
**Overview:**
|
|
885
|
+
- [TEA Overview](/docs/explanation/features/tea-overview.md) - Quality standards in lifecycle
|
|
886
|
+
- [Testing as Engineering](/docs/explanation/philosophy/testing-as-engineering.md) - Why quality matters
|
|
887
|
+
|
|
888
|
+
## Practical Guides
|
|
889
|
+
|
|
890
|
+
**Workflow Guides:**
|
|
891
|
+
- [How to Run Test Review](/docs/how-to/workflows/run-test-review.md) - Audit against these standards
|
|
892
|
+
- [How to Run ATDD](/docs/how-to/workflows/run-atdd.md) - Generate quality tests
|
|
893
|
+
- [How to Run Automate](/docs/how-to/workflows/run-automate.md) - Expand with quality
|
|
894
|
+
|
|
895
|
+
**Use-Case Guides:**
|
|
896
|
+
- [Using TEA with Existing Tests](/docs/how-to/brownfield/use-tea-with-existing-tests.md) - Improve legacy quality
|
|
897
|
+
- [Running TEA for Enterprise](/docs/how-to/brownfield/use-tea-for-enterprise.md) - Enterprise quality thresholds
|
|
898
|
+
|
|
899
|
+
## Reference
|
|
900
|
+
|
|
901
|
+
- [TEA Command Reference](/docs/reference/tea/commands.md) - *test-review command
|
|
902
|
+
- [Knowledge Base Index](/docs/reference/tea/knowledge-base.md) - Test quality fragment
|
|
903
|
+
- [Glossary](/docs/reference/glossary/index.md#test-architect-tea-concepts) - TEA terminology
|
|
904
|
+
|
|
905
|
+
---
|
|
906
|
+
|
|
907
|
+
Generated with [BMad Method](https://bmad-method.org) - TEA (Test Architect)
|