bmad-method-test-architecture-enterprise 1.22.3-next.0 → 1.22.3
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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +50 -0
- package/README.md +3 -3
- package/cli/lib/build-prompt.js +15 -0
- package/cli/lib/convention-baseline.js +23 -6
- package/cli/lib/resolve-tea-config.js +62 -4
- package/cli/test-review.js +6 -1
- package/docs/explanation/knowledge-base-system.md +2 -2
- package/docs/explanation/network-first-patterns.md +3 -1
- package/docs/explanation/tea-overview.md +11 -7
- package/docs/explanation/verification-architecture.md +1 -1
- package/docs/glossary/index.md +1 -1
- package/docs/how-to/customization/integrate-pactjs-utils.md +184 -0
- package/docs/how-to/customization/integrate-playwright-utils.md +28 -0
- package/docs/how-to/workflows/setup-test-framework.md +14 -3
- package/docs/how-to/workflows/teach-me-testing.md +5 -5
- package/docs/reference/commands.md +1 -1
- package/docs/reference/configuration.md +41 -22
- package/docs/reference/execution-targets.md +2 -2
- package/docs/reference/knowledge-base.md +28 -23
- package/docs/reference/troubleshooting.md +50 -4
- package/docs/tutorials/learn-testing-tea-academy.md +2 -2
- package/package.json +1 -1
- package/src/agents/bmad-tea/SKILL.md +6 -0
- package/src/agents/bmad-tea/customize.toml +1 -0
- package/src/agents/bmad-tea/resources/knowledge/library-integration-mandate.md +93 -0
- package/src/agents/bmad-tea/resources/knowledge/pact-consumer-di.md +1 -1
- package/src/agents/bmad-tea/resources/knowledge/pact-mcp.md +37 -0
- package/src/agents/bmad-tea/resources/knowledge/pactjs-utils-mandate.md +204 -0
- package/src/agents/bmad-tea/resources/knowledge/playwright-utils-mandate.md +183 -0
- package/src/agents/bmad-tea/resources/tea-index.csv +3 -0
- package/src/module.yaml +24 -7
- package/src/workflows/testarch/bmad-teach-me-testing/data/session-content-map.yaml +3 -0
- package/src/workflows/testarch/bmad-teach-me-testing/data/tea-resources-index.yaml +22 -3
- package/src/workflows/testarch/bmad-testarch-atdd/checklist.md +35 -2
- package/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/confidence-gate.md +73 -0
- package/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/contract-testing.md +2 -3
- package/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/library-integration-mandate.md +93 -0
- package/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pact-consumer-di.md +1 -1
- package/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pact-consumer-framework-setup.md +42 -95
- package/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pact-mcp.md +37 -0
- package/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pactjs-utils-consumer-helpers.md +5 -6
- package/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pactjs-utils-mandate.md +204 -0
- package/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/pactjs-utils-provider-verifier.md +1 -1
- package/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/playwright-utils-mandate.md +183 -0
- package/src/workflows/testarch/bmad-testarch-atdd/resources/knowledge/test-quality.md +1 -0
- package/src/workflows/testarch/bmad-testarch-atdd/resources/tea-index.csv +4 -0
- package/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-01-preflight-and-context.md +15 -6
- package/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04-generate-tests.md +27 -0
- package/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04a-subagent-api-failing.md +55 -26
- package/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04b-subagent-e2e-failing.md +80 -19
- package/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04c-aggregate.md +37 -1
- package/src/workflows/testarch/bmad-testarch-automate/checklist.md +40 -6
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/confidence-gate.md +73 -0
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/contract-testing.md +16 -16
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/library-integration-mandate.md +93 -0
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pact-consumer-di.md +1 -1
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pact-consumer-framework-setup.md +42 -95
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pact-mcp.md +37 -0
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pactjs-utils-consumer-helpers.md +5 -6
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pactjs-utils-mandate.md +204 -0
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pactjs-utils-overview.md +15 -12
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pactjs-utils-provider-verifier.md +1 -1
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/pactjs-utils-zod-to-pact.md +262 -0
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/playwright-utils-mandate.md +183 -0
- package/src/workflows/testarch/bmad-testarch-automate/resources/knowledge/test-quality.md +1 -0
- package/src/workflows/testarch/bmad-testarch-automate/resources/tea-index.csv +5 -0
- package/src/workflows/testarch/bmad-testarch-automate/steps-c/step-01-preflight-and-context.md +17 -7
- package/src/workflows/testarch/bmad-testarch-automate/steps-c/step-03-generate-tests.md +25 -0
- package/src/workflows/testarch/bmad-testarch-automate/steps-c/step-03a-subagent-api.md +78 -16
- package/src/workflows/testarch/bmad-testarch-automate/steps-c/step-03b-subagent-backend.md +2 -0
- package/src/workflows/testarch/bmad-testarch-automate/steps-c/step-03b-subagent-e2e.md +84 -15
- package/src/workflows/testarch/bmad-testarch-automate/steps-c/step-03c-aggregate.md +101 -18
- package/src/workflows/testarch/bmad-testarch-automate/steps-c/step-04-validate-and-summarize.md +6 -0
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/confidence-gate.md +73 -0
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/contract-testing.md +16 -16
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/library-integration-mandate.md +93 -0
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pact-consumer-di.md +1 -1
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pact-consumer-framework-setup.md +42 -95
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pact-mcp.md +37 -0
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pactjs-utils-consumer-helpers.md +5 -6
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pactjs-utils-mandate.md +204 -0
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pactjs-utils-overview.md +15 -12
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pactjs-utils-provider-verifier.md +1 -1
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/pactjs-utils-zod-to-pact.md +262 -0
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/playwright-utils-mandate.md +183 -0
- package/src/workflows/testarch/bmad-testarch-ci/resources/knowledge/test-quality.md +1 -0
- package/src/workflows/testarch/bmad-testarch-ci/resources/tea-index.csv +5 -0
- package/src/workflows/testarch/bmad-testarch-ci/steps-c/step-01-preflight.md +12 -0
- package/src/workflows/testarch/bmad-testarch-ci/steps-c/step-02-generate-pipeline.md +2 -0
- package/src/workflows/testarch/bmad-testarch-ci/steps-c/step-03-configure-quality-gates.md +16 -0
- package/src/workflows/testarch/bmad-testarch-framework/checklist.md +15 -0
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/confidence-gate.md +73 -0
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/contract-testing.md +16 -16
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/library-integration-mandate.md +93 -0
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pact-consumer-di.md +1 -1
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pact-consumer-framework-setup.md +42 -95
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pact-mcp.md +37 -0
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pactjs-utils-consumer-helpers.md +5 -6
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pactjs-utils-mandate.md +204 -0
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pactjs-utils-overview.md +15 -12
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pactjs-utils-provider-verifier.md +1 -1
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/pactjs-utils-zod-to-pact.md +262 -0
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/playwright-utils-mandate.md +183 -0
- package/src/workflows/testarch/bmad-testarch-framework/resources/knowledge/test-quality.md +1 -0
- package/src/workflows/testarch/bmad-testarch-framework/resources/tea-index.csv +5 -0
- package/src/workflows/testarch/bmad-testarch-framework/steps-c/step-03-scaffold-framework.md +73 -7
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/confidence-gate.md +73 -0
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/contract-testing.md +16 -16
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/library-integration-mandate.md +93 -0
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pact-consumer-di.md +1 -1
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pact-consumer-framework-setup.md +42 -95
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pact-mcp.md +37 -0
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pactjs-utils-consumer-helpers.md +5 -6
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pactjs-utils-mandate.md +204 -0
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pactjs-utils-overview.md +15 -12
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pactjs-utils-provider-verifier.md +1 -1
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/pactjs-utils-zod-to-pact.md +262 -0
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/playwright-utils-mandate.md +183 -0
- package/src/workflows/testarch/bmad-testarch-nfr/resources/knowledge/test-quality.md +1 -0
- package/src/workflows/testarch/bmad-testarch-nfr/resources/tea-index.csv +5 -0
- package/src/workflows/testarch/bmad-testarch-test-design/checklist.md +2 -1
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/confidence-gate.md +73 -0
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/contract-testing.md +16 -16
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/library-integration-mandate.md +93 -0
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pact-consumer-di.md +1 -1
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pact-consumer-framework-setup.md +42 -95
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pact-mcp.md +37 -0
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pactjs-utils-consumer-helpers.md +5 -6
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pactjs-utils-mandate.md +204 -0
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pactjs-utils-overview.md +15 -12
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pactjs-utils-provider-verifier.md +1 -1
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/pactjs-utils-zod-to-pact.md +262 -0
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/playwright-utils-mandate.md +183 -0
- package/src/workflows/testarch/bmad-testarch-test-design/resources/knowledge/test-quality.md +1 -0
- package/src/workflows/testarch/bmad-testarch-test-design/resources/tea-index.csv +5 -0
- package/src/workflows/testarch/bmad-testarch-test-design/steps-c/step-02-load-context.md +11 -5
- package/src/workflows/testarch/bmad-testarch-test-review/checklist.md +29 -3
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/confidence-gate.md +73 -0
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/contract-testing.md +16 -16
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/library-integration-mandate.md +93 -0
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pact-consumer-di.md +1 -1
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pact-consumer-framework-setup.md +42 -95
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pact-mcp.md +37 -0
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pactjs-utils-consumer-helpers.md +5 -6
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pactjs-utils-mandate.md +204 -0
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pactjs-utils-overview.md +15 -12
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pactjs-utils-provider-verifier.md +1 -1
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/pactjs-utils-zod-to-pact.md +262 -0
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/playwright-utils-mandate.md +183 -0
- package/src/workflows/testarch/bmad-testarch-test-review/resources/knowledge/test-quality.md +1 -0
- package/src/workflows/testarch/bmad-testarch-test-review/resources/tea-index.csv +5 -0
- package/src/workflows/testarch/bmad-testarch-test-review/steps-c/criteria-registry.md +79 -20
- package/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-01-load-context.md +17 -4
- package/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-02-discover-tests.md +36 -10
- package/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-03-quality-evaluation.md +7 -0
- package/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-03c-subagent-maintainability.md +61 -13
- package/src/workflows/testarch/bmad-testarch-test-review/test-review-template.md +2 -0
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/confidence-gate.md +73 -0
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/contract-testing.md +16 -16
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/library-integration-mandate.md +93 -0
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pact-consumer-di.md +1 -1
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pact-consumer-framework-setup.md +42 -95
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pact-mcp.md +37 -0
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pactjs-utils-consumer-helpers.md +5 -6
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pactjs-utils-mandate.md +204 -0
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pactjs-utils-overview.md +15 -12
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pactjs-utils-provider-verifier.md +1 -1
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/pactjs-utils-zod-to-pact.md +262 -0
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/playwright-utils-mandate.md +183 -0
- package/src/workflows/testarch/bmad-testarch-trace/resources/knowledge/test-quality.md +1 -0
- package/src/workflows/testarch/bmad-testarch-trace/resources/tea-index.csv +5 -0
- package/test/test-installation-components.js +5 -4
- package/test/test-knowledge-base.js +150 -0
- package/test/test-test-review-cli.js +49 -14
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"name": "bmad-method-test-architecture-enterprise",
|
|
32
32
|
"source": "./",
|
|
33
33
|
"description": "Master Test Architect module for quality strategy, test automation, CI/CD quality gates, and structured testing education. Part of the BMad Method ecosystem.",
|
|
34
|
-
"version": "1.22.3
|
|
34
|
+
"version": "1.22.3",
|
|
35
35
|
"author": {
|
|
36
36
|
"name": "Murat K Ozcan (TEA Creator) & Brian (BMad) Madison"
|
|
37
37
|
},
|
package/CHANGELOG.md
CHANGED
|
@@ -7,8 +7,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.22.3] - 2026-08-14
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `playwright-utils-mandate.md` knowledge fragment (core tier). Makes `tea_use_playwright_utils: true` binding rather than advisory: when the flag is on, `@seontechnologies/playwright-utils` is the default implementation for every capability it covers. Carries the substitution table (`page.route`/`page.waitForResponse` to `interceptNetworkCall`, raw `request.<method>` to `apiRequest`, `page.waitForTimeout` and hand-written polls to `recurse`, `console.log` to `log`, per-spec `base.extend` to `mergeTests`), a REQUIRED versus RECOMMENDED split so utilities needing project wiring are proposed rather than silently skipped, the legitimate exceptions (`page.route` on analytics, fonts, and third-party scripts), a pre-emit self-check, and a deviation protocol that puts a stated reason on any surviving vanilla call. Scoped to JS/TS suites on the Playwright runner; Cypress, Maestro, Pact/Vitest, and non-Playwright backend suites are explicitly out of scope.
|
|
15
|
+
- Criteria registry rows `M9` (MEDIUM) and `L9` (LOW). `M9` fires when a file hand-rolls a capability the installed playwright-utils already provides with no stated deviation; its gate needs both `tea_use_playwright_utils: true` and the package present in `package.json`, so a flag with no install never produces per-file deductions. `L9` fires when a spec imports `test` from `@playwright/test` against a merged-fixtures convention. Both surface in the report as a new `Playwright Utils Adoption` criterion.
|
|
16
|
+
- `playwrightUtils` convention key in the `test-review` baseline, mechanically detected in `cli/lib/convention-baseline.js`. Partial migration now reads as an adoption ratio instead of collapsing to a single pass or fail.
|
|
17
|
+
- `library-integration-mandate.md` knowledge fragment (core tier). The general contract every per-library mandate instantiates, so the pattern generalizes past the two libraries that exist today: the two gates (the flag is `true` AND the package is installed), the REQUIRED versus RECOMMENDED levels, the deviation protocol, scope decided by the runner a file executes under rather than the language of the code under test, the flag-to-mandate registry, and a ten-point checklist for wiring a new library through config, CLI defaults, fragments, loading, generation, aggregation, review, docs, and changelog. A library wired into fewer than all ten produces the decorative-flag failure the mandates exist to prevent.
|
|
18
|
+
- `pactjs-utils-mandate.md` knowledge fragment (core tier). Makes `tea_use_pactjs_utils: true` binding the same way the Playwright mandate does: `createProviderState` instead of a hand-cast `.given('name', obj as JsonMap)`, `buildVerifierOptions` and `buildMessageVerifierOptions` instead of literal `VerifierOptions` objects, `createRequestFilter` / `noOpRequestFilter` instead of bespoke auth middleware, `setJsonContent` / `setJsonBody` instead of repeated PactV4 builder lambdas, `handlePactBrokerUrlAndSelectors` and `getProviderVersionTags` instead of hand-written env and CI branching. `zodToPactMatchers` and the `pact-consumer-di` injection sit at RECOMMENDED because one needs a Zod schema and the other a two-line production change. Carries a relevance gate so a default-on flag never turns into unwanted scaffolding, and restates the determinism rules the mandate does not relax (one `addInteraction()` per `it()`, the Vitest pool settings, provider scrutiny before matchers).
|
|
19
|
+
- Criteria registry row `M10` (MEDIUM): a file hand-rolls a capability the installed `@seontechnologies/pactjs-utils` already provides, with no stated deviation. Gated on the flag plus the package being a project dependency, so a flag with no install never produces per-file deductions. `MatchersV3` used directly does not fire it. Surfaces as a new `Pact.js Utils Adoption` criterion, bringing the registry to 35 rows.
|
|
20
|
+
- `docs/how-to/customization/integrate-pactjs-utils.md`, covering what the flag changes, the substitution table, the relevance gate, the determinism rules that never relax, and how to turn it off.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **`tea_use_pactjs_utils` now defaults to `true`** (was `false`). It decides _how_ Pact suites are written, not _whether_ a project gets one: the mandate's relevance gate still requires a real consumer-provider boundary: an outbound call to a service the repo does not deploy with, an existing `pact/` directory or `@pact-foundation/pact` dependency, `PACT_BROKER_*` in the environment, a microservices layout, or the user asking. `framework` now checks that gate before creating any Pact directory, script, or CI workflow, and states in the summary when it skipped.
|
|
25
|
+
- **`tea_pact_mcp` now defaults to `"mcp"`** (was `"none"`). Unlike the two library flags this one gates a runtime capability rather than a dependency, so its second gate is whether the SmartBear MCP tools are reachable in the session. All six broker-dependent steps now carry an explicit degradation path: probe once, fall back to provider source or an OpenAPI spec, report that the broker was unreachable, and continue. No workflow blocks on it, nothing retries in a loop, and inferred provider states are never presented as broker data.
|
|
26
|
+
- `framework` installs `@seontechnologies/pactjs-utils` and `@pact-foundation/pact` and scaffolds samples in the mandated style, where it previously only recommended the packages. Declining the install falls the whole contract scaffold through to the raw-Pact branch rather than leaving imports against a package the project lacks.
|
|
27
|
+
- `automate` and `atdd` API workers generate contract artifacts under the mandate and report `pactjs_utils_deviations`; `test-design` loads it so Pact examples in design documents match what `automate` generates.
|
|
28
|
+
- The `bmad-tea` agent's critical action and persona principle are now library-agnostic: they read the integration flags, load `library-integration-mandate.md` plus whichever per-library mandate applies, and carry the same rule into ordinary conversation. Asking Murat for a Pact test no longer requires naming `createProviderState` to get it.
|
|
29
|
+
- `playwright-utils-mandate.md` now states the package-installed gate explicitly and defers the shared contract to `library-integration-mandate.md`.
|
|
30
|
+
- `pact-mcp.md` gains a `When the Tools Are Not Reachable` section, which the six broker-dependent steps now point at instead of each restating it. The probe is defined as a tool-list check and never a broker call, its result is recorded once per run as `pact_mcp_reachable`, and the fallback order is provider source, then an OpenAPI spec, then `confidence-gate.md`.
|
|
31
|
+
- `cli/lib/resolve-tea-config.js` resolves `playwright_utils_installed` and `pactjs_utils_installed` from the project manifest and states them in the headless prompt. Both halves of each mandate gate are now resolved in code; the agent is no longer asked to read `package.json` to decide half of it.
|
|
32
|
+
- Registry rows `M9` and `L9` report an unspread convention rather than staying silent. When the flag is on and the package is installed but the sampled corpus shows `absent` or `unknown` adoption, the score is unchanged and one run-level line says so. That is the freshly scaffolded case: `framework` writes a few sample specs, `automate` writes twenty, and a review of the twenty measures a corpus too small to score while being entirely clean.
|
|
33
|
+
- The `playwrightUtils` convention definition in `step-02-discover-tests.md` now matches the detector regex it is paired with. The table cell still described the two-alternative form after the regex dropped the `merged-fixtures` alternative, so a headless run and an interactive run would have counted different corpora. `L9`'s criterion text moved from "a merged-fixtures convention" to "playwright-utils adoption" for the same reason.
|
|
34
|
+
- Registry rows `M9` and `L9` are Convention rows scored against the `playwrightUtils` baseline rather than Applicability rows, so a brownfield repo mid-migration steps down to LOW and a repo at zero adoption deducts nothing. The flag-plus-install half moved out of the Gate column into a new `RUN-LEVEL PRECONDITIONS` section: when a precondition is false those rows do not exist for the run, reported once instead of as a per-file `PASS (n/a)`.
|
|
35
|
+
- The `playwrightUtils` convention detector no longer matches a bare `merged-fixtures` import. That is the `fixtures` key's signal, and matching it let a repo with no playwright-utils anywhere register adoption.
|
|
36
|
+
- `framework` asks before writing `@seontechnologies/*` packages into `package.json`, naming the packages and their peers. It is the only step that writes outside the test directory.
|
|
37
|
+
- The pactjs relevance gate lives in one place. `framework` defers to `pactjs-utils-mandate.md` rather than carrying a looser copy, and the gate now separates signals that settle the question alone from weak ones (an outbound HTTP call, a generated client, a service URL) that need the called service to have no source in this repo plus a second signal.
|
|
38
|
+
- The Pact canonical shape in `pactjs-utils-mandate.md` is PactV4 `addInteraction()` with `setJsonContent` and `setJsonBody`, demonstrating four REQUIRED substitutions rather than one. A worker copies the canonical shape, so a PactV3 example that skipped its own rules taught the wrong pattern.
|
|
39
|
+
- The Pact.js Utils mandate no longer bans importing `@pact-foundation/pact`. The banned-pattern line read "importing from a package name other than `@seontechnologies/pactjs-utils`", which forbade `PactV3`, `MatchersV3`, and `Verifier` — the Pact API every example in the same fragment imports. Only the helper layer is mandated; the two packages are used side by side.
|
|
40
|
+
- `pactjs-utils-zod-to-pact.md` and `confidence-gate.md` ship to every workflow. Five step files loaded the first and nine loaded the second while neither existed outside the agent directory, so each load silently found nothing. `confidence-gate.md` is the terminal branch of the Pact MCP fallback chain and the stop-and-ask rule six fragments cite, so a workflow that could not open it had no floor under either. The parity test's agent-only allowlist is gone rather than emptied: it was the one line asserting intent instead of measuring, and both of its entries were wrong.
|
|
41
|
+
- `pact-consumer-di.md` cited `api-testing-foundations.md`, a fragment that has never existed. The reference is `api-testing-patterns.md`.
|
|
42
|
+
- The auth fixture scaffold implements the real `AuthProvider` contract. It showed an invented `getToken({ identifier })` method; the interface is `getEnvironment`, `getUserIdentifier`, `extractToken`, `extractCookies`, `isTokenExpired`, and `manageAuthToken`, and a fixture built on the invented shape returns no token.
|
|
43
|
+
- Contract scaffolding is gated on relevance, on the package being installed, and on artifacts existing, not on the flag alone. `atdd` requires all three before generating Pact tests, and `ci` skips contract jobs when the repo has no contract tests to run rather than wiring a job that fails every build on a missing script.
|
|
44
|
+
- Workers receive `pact_mcp_reachable` and the selected fallback source, so a subagent can tell a reachable broker session from an unavailable one. They previously saw only the mode, which says what the user allows rather than what answered.
|
|
45
|
+
- Pact deviations reach the final summary. Only the Playwright roll-up was carried into Step 6, so a stated raw-Pact deviation was recorded by a worker and then dropped.
|
|
46
|
+
- The `playwrightUtils` detector matches import syntax rather than the bare package literal, so a prose mention in a comment no longer registers as adoption.
|
|
47
|
+
- Browser fixtures are merged conditionally, and the ATDD error-path scaffold carries `skipNetworkMonitoring`. A scaffold that stubs a 409 on purpose would otherwise fail on the backend error it was asserting.
|
|
48
|
+
- `merged-fixtures.ts` resolves under `{test_dir}` in every workflow. Three different hardcoded paths across the aggregates, checklists, and fragments could have produced a second entry point in a project whose tests do not live in `tests/`.
|
|
49
|
+
- `tea_use_playwright_utils: true` now changes what gets generated, not only which knowledge fragments load. Previously the flag selected a fragment profile while the code templates the generation workers copied from stayed vanilla, so the agent produced `page.route` and raw `request.post` unless the user asked for a utility by name. The API and E2E workers in `*automate` and `*atdd` now carry the playwright-utils template as the primary shape with the vanilla template kept for the flag-off branch, and both list the mandate's substitutions in their success and failure metrics.
|
|
50
|
+
- `*automate` aggregation generates `tests/support/merged-fixtures.ts` and an `auth-session`-based auth fixture instead of a form-driven login fixture and a `page.route` mock module. Network stubs move into the tests that need them as `interceptNetworkCall({ url, fulfillResponse })`, so the stub and the assertion stay together.
|
|
51
|
+
- `*atdd` aggregation creates the merged-fixtures file the red-phase scaffolds import. A scaffold is the file the developer un-skips and keeps, so it is generated in the mandated style rather than as vanilla code to be rewritten later.
|
|
52
|
+
- `*framework` installs `@seontechnologies/playwright-utils` and scaffolds `merged-fixtures.ts`, the auth fixture, and `global-setup.ts` wiring, where it previously only recommended the package. Sample tests are generated in the mandated style, since every later workflow reads them as the reference.
|
|
53
|
+
- `*ci` reads `tea_use_playwright_utils` and drives burn-in selection through `runBurnIn` instead of `--only-changed` on Playwright stacks. The workflow previously had no playwright-utils reference at all, despite `module.yaml` listing it as a consumer.
|
|
54
|
+
- The `bmad-tea` agent applies the mandate in ordinary conversation, not only inside workflows, via a critical action and a persona principle. Asking Murat to write a Playwright test no longer requires naming `interceptNetworkCall` or `apiRequest` to get them.
|
|
55
|
+
- Corrected the package path in the `*automate` and `*atdd` API worker templates: they showed `@playwright-utils/api`, which is not the published package. It is `@seontechnologies/playwright-utils/api-request`.
|
|
56
|
+
- The `*atdd` E2E scaffold template used CSS attribute and `:has-text()` selectors while the same file's requirements and failure metrics called those brittle. Template and rules now agree on `getByLabel` and `getByRole`.
|
|
57
|
+
- `docs/reference/configuration.md` states what `tea_use_playwright_utils: true` actually means, and corrects the claim that `ci` does not read the key.
|
|
58
|
+
|
|
10
59
|
### Fixed
|
|
11
60
|
|
|
61
|
+
- **All eight workflows had been loading stale knowledge.** Six fragments were out of date in every workflow's `resources/knowledge/` directory, having missed agent-level edits that landed after the original copy-in: `contract-testing.md`, `pact-consumer-framework-setup.md` (174 lines of difference), `pactjs-utils-consumer-helpers.md`, `pactjs-utils-overview.md`, `pactjs-utils-provider-verifier.md`, and `test-quality.md`. Workflows read their own copy, never the agent's, so contract-testing and test-quality guidance differed between what the agent recommended and what a workflow generated or reviewed against. Every copy is re-synced from the agent version, which changes the guidance loaded by `framework`, `atdd`, `automate`, `test-design`, `test-review`, `ci`, `nfr`, and `trace`. Expect contract-testing output in particular to change. `test/test-knowledge-base.js` now asserts, per workflow, that the fragment set matches the agent's, that every shared file is byte-identical, and that the workflow's own `tea-index.csv` lists exactly the fragments on disk. That last check had been running against a single workflow before returning early, leaving seven indexes unvalidated: a fragment present on disk but absent from the index is never selected, which looks identical to a fragment that shipped.
|
|
12
62
|
- `test-design` progress checkpoints now carry run identity, so a run for one epic no longer clobbers an interrupted run for another ([#128](https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise/issues/128)). Every create-mode step wrote to a single fixed `{test_artifacts}/test-design-progress.md`, and each step's save appended to whatever was already there, so a second epic's run merged its content and its `stepsCompleted` into the first epic's checkpoint; resuming the first epic afterwards read the second epic's state. `step-01-detect-mode.md` now resolves `run_scope` and `run_key` (`system`, or `epic-{epic_num}`) before the first save, checkpoints are written to `{test_artifacts}/test-design-progress-{run_key}.md`, and the frontmatter carries `runScope` and `runKey`. Resolving `epic_num` in step 1 also removes the late "if `epic_num` is unclear, ask the user" prompt in `step-05-generate-output.md`, so a plan and its checkpoint always name the same run.
|
|
13
63
|
- `test-design` create mode no longer merges two runs into one checkpoint. When a checkpoint already exists for the same scope, step 1 reports its `lastStep` and `lastSaved` and asks whether to resume or start over, and starting over replaces the file instead of appending to it.
|
|
14
64
|
- `test-design` resume mode selects the checkpoint belonging to the run being resumed, asks which run to continue when several checkpoints exist and no scope was named, and refuses a checkpoint whose `runKey` does not match. Checkpoints written under the old fixed name are detected, confirmed with the user, and migrated.
|
package/README.md
CHANGED
|
@@ -129,9 +129,9 @@ npx bmad-method install
|
|
|
129
129
|
TEA variables are defined in `src/module.yaml` and prompted during install:
|
|
130
130
|
|
|
131
131
|
- `test_artifacts` — base output folder for test artifacts
|
|
132
|
-
- `tea_use_playwright_utils` — enable Playwright Utils integration (boolean)
|
|
133
|
-
- `tea_use_pactjs_utils` — enable Pact.js Utils integration for contract testing
|
|
134
|
-
- `tea_pact_mcp` — SmartBear MCP for PactFlow/Broker interaction
|
|
132
|
+
- `tea_use_playwright_utils` — enable Playwright Utils integration (boolean, default true). When true **and the package is installed**, `@seontechnologies/playwright-utils` becomes the default implementation for everything it covers: generated Playwright tests use `interceptNetworkCall`, `apiRequest`, `recurse`, and `log` without being asked, and `test-review` flags a vanilla equivalent that carries no stated reason. See [Integrate Playwright Utils](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/customization/integrate-playwright-utils/)
|
|
133
|
+
- `tea_use_pactjs_utils` — enable Pact.js Utils integration for contract testing (boolean, default true). It decides how Pact suites are written, not whether a project gets one: TEA still requires a real consumer-provider boundary before scaffolding a contract test. When on **and the package is installed**, generated Pact code uses `createProviderState`, `buildVerifierOptions`, and `createRequestFilter` rather than raw Pact boilerplate. A flag with no install generates the raw path and reports one recommendation rather than flagging every file
|
|
134
|
+
- `tea_pact_mcp` — SmartBear MCP for PactFlow/Broker interaction: mcp, none (string, default mcp). Safe without a broker: every broker-dependent step degrades to provider source or an OpenAPI spec and reports that the broker was unreachable
|
|
135
135
|
- `tea_browser_automation` — browser automation mode: auto, cli, mcp, none (string)
|
|
136
136
|
- `test_framework` — detected or configured test framework (Playwright, Cypress, Jest, Vitest, pytest, JUnit, Go test, dotnet test, RSpec, Maestro)
|
|
137
137
|
- `test_stack_type` — detected or configured stack type (frontend, backend, fullstack, mobile)
|
package/cli/lib/build-prompt.js
CHANGED
|
@@ -103,6 +103,10 @@ function conventionBaselinePromptLines(conventionBaseline) {
|
|
|
103
103
|
* @param {string} [options.scope] - review_scope override (single|directory|suite).
|
|
104
104
|
* Default derives from the review set: single for one file, directory otherwise.
|
|
105
105
|
* @param {string} [options.testDir] - test_dir hint for the workflow.
|
|
106
|
+
* @param {object} [options.installedPackages] - Resolved library-install booleans
|
|
107
|
+
* from resolve-tea-config (`playwright_utils_installed`, `pactjs_utils_installed`).
|
|
108
|
+
* The second half of each mandate gate, read from the project manifest so a
|
|
109
|
+
* headless run never leaves it to the agent.
|
|
106
110
|
* @param {object} [options.teaConfig] - Resolved TEA config keys from
|
|
107
111
|
* resolve-tea-config. Defaults to the module defaults so the prompt always
|
|
108
112
|
* states them and the agent never has to infer them.
|
|
@@ -138,6 +142,7 @@ function buildPrompt({
|
|
|
138
142
|
scope,
|
|
139
143
|
testDir = 'tests',
|
|
140
144
|
teaConfig = MODULE_DEFAULTS,
|
|
145
|
+
installedPackages = { playwright_utils_installed: false, pactjs_utils_installed: false },
|
|
141
146
|
contextFiles = [],
|
|
142
147
|
contextBasis = 'none',
|
|
143
148
|
focus = '',
|
|
@@ -185,9 +190,19 @@ function buildPrompt({
|
|
|
185
190
|
`tea_use_playwright_utils=${teaConfig.tea_use_playwright_utils}`,
|
|
186
191
|
`tea_use_pactjs_utils=${teaConfig.tea_use_pactjs_utils}`,
|
|
187
192
|
`tea_pact_mcp=${teaConfig.tea_pact_mcp}`,
|
|
193
|
+
`playwright_utils_installed=${installedPackages.playwright_utils_installed}`,
|
|
194
|
+
`pactjs_utils_installed=${installedPackages.pactjs_utils_installed}`,
|
|
188
195
|
'The values above are the resolved configuration for this run and take precedence over anything read from',
|
|
189
196
|
'config.yaml. Use them for the step-01 fragment selection (Playwright Utils loading profile, pactjs-utils',
|
|
190
197
|
'fragment set, Pact MCP) instead of inferring the flags.',
|
|
198
|
+
'The two *_installed values above were read from the project manifest by the CLI. Do not re-derive them, and do',
|
|
199
|
+
'not open package.json: they are the second half of each mandate gate, stated here for the same reason the flags are.',
|
|
200
|
+
'playwrightUtilsActive = tea_use_playwright_utils AND playwright_utils_installed; when true, load',
|
|
201
|
+
'playwright-utils-mandate.md and score registry rows M9 and L9. pactjsUtilsActive = tea_use_pactjs_utils AND',
|
|
202
|
+
'pactjs_utils_installed; when true, load pactjs-utils-mandate.md and score registry row M10.',
|
|
203
|
+
'A false precondition means those rows DO NOT EXIST for this run (criteria-registry.md § RUN-LEVEL PRECONDITIONS):',
|
|
204
|
+
'emit no violations and no per-file PASS (n/a) for them, and state the reason once, naming which half was missing.',
|
|
205
|
+
'library-integration-mandate.md carries the general contract behind both rows.',
|
|
191
206
|
'',
|
|
192
207
|
'The file list below IS the complete and authoritative review set: skip the discovery glob in',
|
|
193
208
|
"step-02-discover-tests regardless of review_scope. This overrides step-02's glob for this run only.",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
* sampling rules, just executed by code instead of described in prose. A report
|
|
24
24
|
* that cites a different sampled count, or a different corpus, is provably wrong
|
|
25
25
|
* and rejected outright.
|
|
26
|
-
* - adopted counts for the
|
|
27
|
-
* (priorityMarkers, testIds, networkFirst, dataFactories, fixtures): a generous,
|
|
26
|
+
* - adopted counts for the six keys with a concrete, literal recognized form
|
|
27
|
+
* (priorityMarkers, testIds, networkFirst, dataFactories, fixtures, playwrightUtils): a generous,
|
|
28
28
|
* high-recall regex scan over the real sampled files' real content. This is not
|
|
29
29
|
* claimed to be a precise semantic judgment — a regex cannot know intent — but it
|
|
30
30
|
* gives a safe one-directional floor: when the scan finds ZERO occurrences of any
|
|
@@ -47,8 +47,17 @@ const { isTestFile } = require('./changed-tests');
|
|
|
47
47
|
|
|
48
48
|
// Same order as step-02-discover-tests.md §2b's "Conventions to measure" table and
|
|
49
49
|
// criteria-registry.md's mapping table. Every consumer of this list (build-prompt,
|
|
50
|
-
// parse-report, the tests) shares this one array so the
|
|
51
|
-
const CONVENTION_KEYS = [
|
|
50
|
+
// parse-report, the tests) shares this one array so the eight keys cannot drift.
|
|
51
|
+
const CONVENTION_KEYS = [
|
|
52
|
+
'priorityMarkers',
|
|
53
|
+
'testIds',
|
|
54
|
+
'bddNaming',
|
|
55
|
+
'networkFirst',
|
|
56
|
+
'dataFactories',
|
|
57
|
+
'fixtures',
|
|
58
|
+
'assertionStyle',
|
|
59
|
+
'playwrightUtils',
|
|
60
|
+
];
|
|
52
61
|
|
|
53
62
|
const MAX_SAMPLED_FILES = 40;
|
|
54
63
|
const MIN_CORPUS_TO_ATTEMPT = 1; // 0 eligible files outside the review set: nothing to sample at all.
|
|
@@ -57,8 +66,9 @@ const MIN_CORPUS_TO_ATTEMPT = 1; // 0 eligible files outside the review set: not
|
|
|
57
66
|
// content (case-insensitive, no /g flag so repeated .test() calls carry no state).
|
|
58
67
|
// Deliberately high-recall: a false positive here only ever makes the zero-signal
|
|
59
68
|
// floor check more permissive (it stops treating a convention as unattested), never
|
|
60
|
-
// less — see the module doc comment.
|
|
61
|
-
//
|
|
69
|
+
// less — see the module doc comment. Each detector must match what the "Adopted when
|
|
70
|
+
// a sampled file..." column in step-02-discover-tests.md's table says, so a headless
|
|
71
|
+
// run and an interactive run count the same corpus. Changing one means changing both.
|
|
62
72
|
const MECHANICAL_DETECTORS = {
|
|
63
73
|
priorityMarkers: /(\[P[0-3]\]|@P[0-3]\b|['"`]@?P[0-3]['"`]|\bpriority\s*:\s*['"`]?P[0-3]\b)/i,
|
|
64
74
|
testIds: /(data-testid|data-test-id|getByTestId|test-id\s*=|testid\s*=)/i,
|
|
@@ -66,6 +76,13 @@ const MECHANICAL_DETECTORS = {
|
|
|
66
76
|
/(interceptNetworkCall\s*\(|page\.route\s*\(|cy\.intercept\s*\(|waitForResponse\s*\(|waitForRequest\s*\(|route\.fulfill\s*\()/i,
|
|
67
77
|
dataFactories: /(\bbuild[A-Z]\w*\s*\(|\bFactory\s*\(|from\s+['"][^'"]*factories|\bfactories\/)/i,
|
|
68
78
|
fixtures: /(mergeTests\s*\(|test\.extend\s*\(|from\s+['"][^'"]*fixtures|merged-fixtures)/i,
|
|
79
|
+
// Only the package literal. `merged-fixtures` is already the `fixtures` key's
|
|
80
|
+
// signal, and a hand-rolled merged-fixtures.ts with no playwright-utils anywhere
|
|
81
|
+
// would otherwise register adoption for a package the repo never installed.
|
|
82
|
+
// Import-shaped only. The bare package literal also matches a prose mention in a
|
|
83
|
+
// comment ("// TODO: migrate to @seontechnologies/playwright-utils"), which would
|
|
84
|
+
// register adoption for a file that uses none of it.
|
|
85
|
+
playwrightUtils: /(?:from|require\s*\(|import\s*\()\s*['"`]@seontechnologies\/playwright-utils/i,
|
|
69
86
|
};
|
|
70
87
|
|
|
71
88
|
const MECHANICAL_CONVENTION_KEYS = Object.keys(MECHANICAL_DETECTORS);
|
|
@@ -24,8 +24,8 @@ const CONFIG_RELATIVE_PATH = path.join('_bmad', 'tea', 'config.yaml');
|
|
|
24
24
|
|
|
25
25
|
const MODULE_DEFAULTS = {
|
|
26
26
|
tea_use_playwright_utils: true,
|
|
27
|
-
tea_use_pactjs_utils:
|
|
28
|
-
tea_pact_mcp: '
|
|
27
|
+
tea_use_pactjs_utils: true,
|
|
28
|
+
tea_pact_mcp: 'mcp',
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
const PACT_MCP_VALUES = ['mcp', 'none'];
|
|
@@ -126,6 +126,54 @@ function readTeaConfigFile(projectRoot) {
|
|
|
126
126
|
return { present: true, path: configPath, values };
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Whether a package appears in the consuming project's dependency manifest.
|
|
131
|
+
*
|
|
132
|
+
* Half of a library mandate's gate is the flag, resolved above. The other half is
|
|
133
|
+
* whether the package is actually installed, and leaving that to the agent means a
|
|
134
|
+
* headless run decides it by reading package.json — an unlisted extra read the
|
|
135
|
+
* prompt otherwise discourages, and a judgment call where a lookup will do. Both
|
|
136
|
+
* halves resolve here so the gate closes the same way on every run.
|
|
137
|
+
*
|
|
138
|
+
* Absent, unreadable, or unparseable manifest reads as "not installed": the
|
|
139
|
+
* conservative answer, since the consequence is that a mandate row does not fire.
|
|
140
|
+
*
|
|
141
|
+
* @param {string} projectRoot
|
|
142
|
+
* @param {string} packageName
|
|
143
|
+
* @returns {boolean}
|
|
144
|
+
*/
|
|
145
|
+
function isPackageInstalled(projectRoot, packageName) {
|
|
146
|
+
const manifestPath = path.join(projectRoot, 'package.json');
|
|
147
|
+
if (!fs.existsSync(manifestPath)) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
let manifest;
|
|
151
|
+
try {
|
|
152
|
+
manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
153
|
+
} catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
if (manifest === null || typeof manifest !== 'object' || Array.isArray(manifest)) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
return ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'].some((section) => {
|
|
160
|
+
const deps = manifest[section];
|
|
161
|
+
return Boolean(deps) && typeof deps === 'object' && !Array.isArray(deps) && packageName in deps;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Config key to the npm package whose presence completes its gate. */
|
|
166
|
+
const KEY_TO_PACKAGE = {
|
|
167
|
+
tea_use_playwright_utils: '@seontechnologies/playwright-utils',
|
|
168
|
+
tea_use_pactjs_utils: '@seontechnologies/pactjs-utils',
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/** The `installed` field each gate reports under. */
|
|
172
|
+
const KEY_TO_INSTALLED_FIELD = {
|
|
173
|
+
tea_use_playwright_utils: 'playwright_utils_installed',
|
|
174
|
+
tea_use_pactjs_utils: 'pactjs_utils_installed',
|
|
175
|
+
};
|
|
176
|
+
|
|
129
177
|
/**
|
|
130
178
|
* Resolve every key through the precedence chain.
|
|
131
179
|
*
|
|
@@ -133,7 +181,9 @@ function readTeaConfigFile(projectRoot) {
|
|
|
133
181
|
* @param {string} options.projectRoot - Consuming project root.
|
|
134
182
|
* @param {object} [options.flags] - Parsed CLI options; only the keys in
|
|
135
183
|
* FLAG_TO_KEY are read, and only when not undefined.
|
|
136
|
-
* @returns {{values: object, sources: object, configPath: string, configPresent: boolean}}
|
|
184
|
+
* @returns {{values: object, sources: object, installed: object, configPath: string, configPresent: boolean}}
|
|
185
|
+
* `installed` carries one boolean per library gate, read from the project
|
|
186
|
+
* manifest rather than left to the agent.
|
|
137
187
|
* @throws {Error} With code TEA_CONFIG_INVALID on unusable config content.
|
|
138
188
|
*/
|
|
139
189
|
function resolveTeaConfig({ projectRoot, flags = {} }) {
|
|
@@ -158,12 +208,20 @@ function resolveTeaConfig({ projectRoot, flags = {} }) {
|
|
|
158
208
|
sources[key] = 'default';
|
|
159
209
|
}
|
|
160
210
|
|
|
161
|
-
|
|
211
|
+
const installed = {};
|
|
212
|
+
for (const [key, packageName] of Object.entries(KEY_TO_PACKAGE)) {
|
|
213
|
+
installed[KEY_TO_INSTALLED_FIELD[key]] = isPackageInstalled(projectRoot, packageName);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return { values, sources, installed, configPath: file.path, configPresent: file.present };
|
|
162
217
|
}
|
|
163
218
|
|
|
164
219
|
module.exports = {
|
|
165
220
|
resolveTeaConfig,
|
|
166
221
|
readTeaConfigFile,
|
|
222
|
+
isPackageInstalled,
|
|
223
|
+
KEY_TO_PACKAGE,
|
|
224
|
+
KEY_TO_INSTALLED_FIELD,
|
|
167
225
|
MODULE_DEFAULTS,
|
|
168
226
|
PACT_MCP_VALUES,
|
|
169
227
|
CONFIG_RELATIVE_PATH,
|
package/cli/test-review.js
CHANGED
|
@@ -412,8 +412,11 @@ function main() {
|
|
|
412
412
|
// project's config.yaml, then the module default) and stated in the prompt.
|
|
413
413
|
// An unstated key is one the agent decides per run.
|
|
414
414
|
let teaConfig;
|
|
415
|
+
let installedPackages;
|
|
415
416
|
try {
|
|
416
|
-
|
|
417
|
+
const resolvedTeaConfig = resolveTeaConfig({ projectRoot, flags: options });
|
|
418
|
+
teaConfig = resolvedTeaConfig.values;
|
|
419
|
+
installedPackages = resolvedTeaConfig.installed;
|
|
417
420
|
} catch (error) {
|
|
418
421
|
if (error.code === 'TEA_CONFIG_INVALID') {
|
|
419
422
|
fail(EXIT.ENV_ERROR, error.message);
|
|
@@ -576,6 +579,7 @@ function main() {
|
|
|
576
579
|
scope: options.scope,
|
|
577
580
|
testDir: options.testDir,
|
|
578
581
|
teaConfig,
|
|
582
|
+
installedPackages,
|
|
579
583
|
contextFiles,
|
|
580
584
|
contextBasis,
|
|
581
585
|
focus: options.focus,
|
|
@@ -684,6 +688,7 @@ function main() {
|
|
|
684
688
|
scope: options.scope,
|
|
685
689
|
testDir: options.testDir,
|
|
686
690
|
teaConfig,
|
|
691
|
+
installedPackages,
|
|
687
692
|
contextFiles,
|
|
688
693
|
contextBasis,
|
|
689
694
|
focus: options.focus,
|
|
@@ -20,7 +20,7 @@ network-first,Network-First Safeguards,"Intercept-before-navigate workflow, HAR
|
|
|
20
20
|
test-quality,Test Quality Definition of Done,"Execution limits, isolation rules, green criteria","quality,definition-of-done,tests",core,knowledge/test-quality.md
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
`tier` is one of `core`, `extended`, or `specialized`. The
|
|
23
|
+
`tier` is one of `core`, `extended`, or `specialized`. The 59 fragments split 24 / 19 / 16 across those tiers.
|
|
24
24
|
|
|
25
25
|
The agent-level `resources/` directory is the reference catalog. Workflow skills also carry their own `resources/tea-index.csv` and `resources/knowledge/` directories. That duplication is intentional: workflow step frontmatter resolves `knowledgeIndex: './resources/tea-index.csv'` from `{skill-root}`, which keeps each workflow skill modular and self-contained.
|
|
26
26
|
|
|
@@ -150,7 +150,7 @@ test('job completion', async ({ apiRequest, recurse }) => {
|
|
|
150
150
|
|
|
151
151
|
## Related
|
|
152
152
|
|
|
153
|
-
- [Knowledge Base Index](/docs/reference/knowledge-base.md) - all
|
|
153
|
+
- [Knowledge Base Index](/docs/reference/knowledge-base.md) - all 59 fragments, categorized
|
|
154
154
|
- [Testing as Engineering](/docs/explanation/testing-as-engineering.md) - the context engineering argument
|
|
155
155
|
- [Test Quality Standards](/docs/explanation/test-quality-standards.md) - what `test-quality.md` encodes
|
|
156
156
|
- [Network-First Patterns](/docs/explanation/network-first-patterns.md) - what `network-first.md` encodes
|
|
@@ -135,7 +135,9 @@ Both forms wait exactly as long as needed, whether that is 100 ms or 5 seconds,
|
|
|
135
135
|
|
|
136
136
|
## What Playwright Utils Adds
|
|
137
137
|
|
|
138
|
-
`@seontechnologies/playwright-utils` is optional.
|
|
138
|
+
`@seontechnologies/playwright-utils` is optional as a choice, and binding once chosen. `tea_use_playwright_utils` defaults to `true`, and while it is `true` **and the package is installed** the second form above is what TEA generates and what `test-review` expects. Both halves are required: a flag with no install generates the vanilla form and produces one setup recommendation rather than findings. `page.route` on an application endpoint becomes a finding unless the code says why. It stays correct for what it is genuinely for: blocking analytics, fonts, and third-party scripts, and that needs no justification. Where the utility genuinely does not cover a case, the vanilla call ships with a `// playwright-utils deviation: <reason>` comment on the line and an entry in the workflow's summary, which is what separates a decision from an oversight. The full rule is the `playwright-utils-mandate` knowledge fragment.
|
|
139
|
+
|
|
140
|
+
Seven things the utility changes:
|
|
139
141
|
|
|
140
142
|
1. **Automatic JSON parsing.** No `await response.json()` anywhere.
|
|
141
143
|
2. **Different result shapes for different utilities**, and the distinction matters. `interceptNetworkCall` resolves to `{ status, responseJson, requestJson }` because it observes a browser round trip and can see both directions. `apiRequest` resolves to `{ status, body }` because it issues the request itself.
|
|
@@ -159,7 +159,11 @@ Codex users run `$bmad-testarch-test-design` with the same scope-setting prompt.
|
|
|
159
159
|
|
|
160
160
|
TEA spans Phase 3, Phase 4, and the release gate, where most BMM agents operate in a single phase. That multi-phase role is paired with a dedicated testing knowledge base so standards stay consistent across projects: extensive domain knowledge (test patterns, CI/CD, fixtures, quality practices), cross-cutting standards that apply to every BMad project rather than to one document type, and optional integrations for Playwright Utils, the Playwright CLI, and MCP servers. See [Knowledge Base System](/docs/explanation/knowledge-base-system.md).
|
|
161
161
|
|
|
162
|
-
##
|
|
162
|
+
## Library Integrations
|
|
163
|
+
|
|
164
|
+
"Optional" describes the choice, not the effect. Each library has a config flag, and while a flag is `true` and its package is installed, that library is the implementation TEA reaches for on everything it covers — you never name a utility in a prompt to get it. The contract behind that is the `library-integration-mandate` knowledge fragment, and each library has its own mandate carrying the substitutions. Turning a flag off is what makes TEA hand-roll the equivalent instead.
|
|
165
|
+
|
|
166
|
+
The same fragment holds the checklist for adding the next library, so a new integration lands in generation, aggregation, review, and docs rather than only in a fragment nobody applies.
|
|
163
167
|
|
|
164
168
|
### Playwright Utils (`@seontechnologies/playwright-utils`)
|
|
165
169
|
|
|
@@ -175,7 +179,7 @@ Production-ready fixtures and utilities that enhance TEA workflows.
|
|
|
175
179
|
Contract testing utilities that reduce raw Pact.js boilerplate and standardize provider verification.
|
|
176
180
|
|
|
177
181
|
- Install: `npm install -D @seontechnologies/pactjs-utils @pact-foundation/pact`
|
|
178
|
-
- Config: `tea_use_pactjs_utils: true` (default `false
|
|
182
|
+
- Config: `tea_use_pactjs_utils: true` (the default). It decides _how_ Pact suites are written, never _whether_ a project gets one: TEA still requires a real consumer-provider boundary before scaffolding any contract test. Set `false` to have TEA write raw `@pact-foundation/pact`.
|
|
179
183
|
- Impacts: `framework`, `atdd`, `automate`, `test-design`, `test-review`, `ci`
|
|
180
184
|
- Utilities: createProviderState, toJsonMap, setJsonBody, setJsonContent, buildVerifierOptions, buildMessageVerifierOptions, createRequestFilter, noOpRequestFilter, handlePactBrokerUrlAndSelectors, getProviderVersionTags
|
|
181
185
|
- Supports the local monorepo flow (`pactUrls`) and the remote broker flow (`PACT_BROKER_BASE_URL`, `PACT_BROKER_TOKEN`)
|
|
@@ -213,12 +217,12 @@ Optional design-time broker interaction for contract testing workflows.
|
|
|
213
217
|
|
|
214
218
|
**Configuration** (`_bmad/tea/config.yaml`):
|
|
215
219
|
|
|
216
|
-
tea_pact_mcp: "
|
|
220
|
+
tea_pact_mcp: "mcp" # none | mcp (default "mcp")
|
|
217
221
|
|
|
218
|
-
| Mode | What happens
|
|
219
|
-
| ------ |
|
|
220
|
-
| `mcp` | TEA
|
|
221
|
-
| `none` |
|
|
222
|
+
| Mode | What happens |
|
|
223
|
+
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
224
|
+
| `mcp` | Default. TEA uses SmartBear MCP tools for provider-state discovery, test review support, can-i-deploy, and matrix checks when they are reachable, and degrades to provider source or an OpenAPI spec when they are not. |
|
|
225
|
+
| `none` | TEA never attempts a broker call, and skips the reachability probe entirely. |
|
|
222
226
|
|
|
223
227
|
**Setup:**
|
|
224
228
|
|
|
@@ -87,7 +87,7 @@ TEA's execution coverage is uneven, and the uneven part is deliberate to state r
|
|
|
87
87
|
|
|
88
88
|
### The self-audit
|
|
89
89
|
|
|
90
|
-
Of TEA's
|
|
90
|
+
Of TEA's 59 knowledge fragments, 40 name Playwright or Cypress. Three cover mobile. None covers a backend test framework, and the knowledge index has no row tagged for pytest, JUnit, Go test, xUnit, or RSpec.
|
|
91
91
|
|
|
92
92
|
That is the real shape of the gap, and it is uneven in a specific way. Web and mobile are knowledge-backed: TEA carries curated patterns for both, so what it generates follows a pattern library rather than the model's improvisation. Backend languages are not. TEA can decide to scaffold pytest, and does, but it works from the conventions named inline in the workflow step and from the project it can see. The reasoning that selects pytest is as rigorous for a Python service as for a React Native app. The execution guidance behind it is not yet equivalent.
|
|
93
93
|
|
package/docs/glossary/index.md
CHANGED
|
@@ -135,7 +135,7 @@ Terminology reference for Test Architect (TEA).
|
|
|
135
135
|
| **Epic-Level Test Design** | Test planning per epic (Phase 4) focusing on risk assessment, priorities, and coverage strategy for that specific epic. |
|
|
136
136
|
| **Fixture Architecture** | Pattern of building pure functions first, then wrapping in framework-specific fixtures for testability, reusability, and composition. |
|
|
137
137
|
| **Gate Decision** | Go/no-go decision for release with four outcomes: PASS ✅ (ready), CONCERNS ⚠️ (proceed with mitigation), FAIL ❌ (blocked), WAIVED ⏭️ (approved despite issues). |
|
|
138
|
-
| **Knowledge Fragment** | Individual markdown file in TEA's knowledge base covering a specific testing pattern or practice (
|
|
138
|
+
| **Knowledge Fragment** | Individual markdown file in TEA's knowledge base covering a specific testing pattern or practice (59 fragments total). |
|
|
139
139
|
| **Network-First Pattern** | Testing pattern that waits for actual network responses instead of fixed timeouts to avoid race conditions and flakiness. |
|
|
140
140
|
| **NFR Evidence Audit** | Validation of non-functional requirement evidence (security, performance, reliability, maintainability) against defined thresholds. |
|
|
141
141
|
| **No TEA** | Engagement model 1. Skip all TEA workflows and keep the team's existing testing approach. A valid choice when that approach already works. |
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Integrate Pact.js Utils with TEA'
|
|
3
|
+
description: What TEA generates for consumer-driven contract testing when tea_use_pactjs_utils is on, and how to turn it off
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Integrate Pact.js Utils with TEA
|
|
7
|
+
|
|
8
|
+
`@seontechnologies/pactjs-utils` wraps `@pact-foundation/pact` with type-safe helpers for provider states, PactV4 builders, verifier configuration, and request filters. TEA integrates with it through the `tea_use_pactjs_utils` config flag, which is **on by default**.
|
|
9
|
+
|
|
10
|
+
## What the Flag Actually Does
|
|
11
|
+
|
|
12
|
+
`tea_use_pactjs_utils: true` does not mean "the library is available if you ask for it", and it does not mean "add contract tests to this project". It means: **whenever TEA writes a Pact artifact, it writes it with these utilities.**
|
|
13
|
+
|
|
14
|
+
The rule lives in the `pactjs-utils-mandate` knowledge fragment, which every generating and reviewing workflow loads first. It instantiates the same general contract as the Playwright Utils mandate, documented in `library-integration-mandate`.
|
|
15
|
+
|
|
16
|
+
### Two gates
|
|
17
|
+
|
|
18
|
+
The mandate binds only when both hold:
|
|
19
|
+
|
|
20
|
+
1. `tea_use_pactjs_utils` is `true`.
|
|
21
|
+
2. `@seontechnologies/pactjs-utils` is a dependency in your `package.json`.
|
|
22
|
+
|
|
23
|
+
A flag with no install is an intention, not a capability. TEA will not scaffold imports against a package you do not have, and `test-review` will not deduct for not using one.
|
|
24
|
+
|
|
25
|
+
### The relevance gate
|
|
26
|
+
|
|
27
|
+
Separately from the two gates above, TEA decides whether a Pact suite belongs in your project at all. It scaffolds one only with evidence of a real consumer-provider boundary:
|
|
28
|
+
|
|
29
|
+
**Any one of these settles it:**
|
|
30
|
+
|
|
31
|
+
- An existing `pact/` or `tests/contract/` directory
|
|
32
|
+
- `@pact-foundation/pact` already in `package.json`
|
|
33
|
+
- `PACT_BROKER_*` in the environment or `.env.example`
|
|
34
|
+
- A microservices layout: two or more independently deployable services in the repo that call each other
|
|
35
|
+
- You asked for contract testing
|
|
36
|
+
|
|
37
|
+
**These are weak on their own** and need corroboration: an outbound HTTP call, a generated API client, a service URL in `.env.example`. Most frontends have all three and call a backend that ships in the same deploy. They count only when the called service has no source in this repo and is not started by this repo's compose file, dev script, or CI — **and** a second signal is present.
|
|
38
|
+
|
|
39
|
+
With none of that, TEA creates no Pact artifacts and says why in the summary. A dead contract suite that fails CI for a boundary the project does not have is worse than no suite, so the default-on flag never turns into unwanted scaffolding.
|
|
40
|
+
|
|
41
|
+
## Substitutions
|
|
42
|
+
|
|
43
|
+
**REQUIRED** — drop-in. Generating the raw-Pact equivalent instead is a defect:
|
|
44
|
+
|
|
45
|
+
| You need | TEA emits | Not |
|
|
46
|
+
| ------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------------------- |
|
|
47
|
+
| A provider state on an interaction | `.given(...createProviderState({ name, params }))` | `.given('name', obj as JsonMap)` |
|
|
48
|
+
| Params coerced to Pact's `JsonMap` | `toJsonMap(value)` | Manual casts, per-call-site `null` and `Date` handling |
|
|
49
|
+
| PactV4 request/response builder callbacks | `setJsonContent({ query?, headers?, body? })`, `setJsonBody` | Repeated inline `(b) => { b.query(...); ... }` lambdas |
|
|
50
|
+
| HTTP provider verification options | `buildVerifierOptions({ provider, port, ... })` | A hand-assembled 30-line `VerifierOptions` object |
|
|
51
|
+
| Message/Kafka provider verification | `buildMessageVerifierOptions({ ... })` | A second hand-assembled options object |
|
|
52
|
+
| Broker URL and consumer version selectors | `handlePactBrokerUrlAndSelectors(...)` | Hand-written env-var branching per flow |
|
|
53
|
+
| Provider version tags in CI | `getProviderVersionTags()` | Hand-written branch/tag extraction per CI platform |
|
|
54
|
+
| Auth injection during provider verification | `createRequestFilter({ tokenGenerator })` | Bespoke Express middleware, with its `Bearer Bearer` bug |
|
|
55
|
+
| A provider that needs no auth | `noOpRequestFilter` | An empty inline function |
|
|
56
|
+
|
|
57
|
+
**RECOMMENDED** — needs something the project may not have, so TEA proposes it and names what is missing rather than silently hand-rolling the alternative:
|
|
58
|
+
|
|
59
|
+
- `zodToPactMatchers(schema)` where a Zod schema already exists, instead of a parallel hand-written matcher tree
|
|
60
|
+
- The `pact-consumer-di` injection, so `executeTest` calls your real client with `mockServer.url` instead of raw `fetch`. It needs an optional `baseUrl` on your API context type: two lines of production code
|
|
61
|
+
|
|
62
|
+
**Real exceptions still ship.** `MatchersV3` used directly for something `zodToPactMatchers` cannot express is correct and is not a deviation. Where a genuine gap exists, generated code carries `// pactjs-utils deviation: <reason>` and the workflow summary lists it.
|
|
63
|
+
|
|
64
|
+
## What Never Relaxes
|
|
65
|
+
|
|
66
|
+
The mandate does not soften the correctness rules from the per-utility fragments. They apply with or without the utilities:
|
|
67
|
+
|
|
68
|
+
- **One `pact.addInteraction()` per `it()` block.** PactV4's Rust FFI drops interactions non-deterministically otherwise. Use `it.each` for parameterized cases.
|
|
69
|
+
- **Consumer Vitest config** carries `fileParallelism: false` AND `pool: 'forks'` AND `poolOptions.forks.singleFork: true`.
|
|
70
|
+
- **Provider Vitest config** carries the `pool: 'forks'` + `singleFork` pair.
|
|
71
|
+
- **Provider scrutiny before matchers.** Response matchers come from provider source, an OpenAPI spec, or broker data, never from consumer-side types alone.
|
|
72
|
+
- **Postel's Law.** Matchers in `willRespondWith` only; request bodies in `withRequest` use exact values.
|
|
73
|
+
- **A `// Provider endpoint:` comment** on every interaction.
|
|
74
|
+
|
|
75
|
+
## Canonical Shapes
|
|
76
|
+
|
|
77
|
+
### Consumer test
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { PactV4, MatchersV3 } from '@pact-foundation/pact';
|
|
81
|
+
import { createProviderState, setJsonBody, setJsonContent } from '@seontechnologies/pactjs-utils';
|
|
82
|
+
import { getMovieById } from '../../src/api/movies-client';
|
|
83
|
+
|
|
84
|
+
const { integer, string } = MatchersV3;
|
|
85
|
+
|
|
86
|
+
const pact = new PactV4({ consumer: 'movie-web', provider: 'SampleMoviesAPI', dir: './pacts' });
|
|
87
|
+
|
|
88
|
+
describe('Movie API Contract', () => {
|
|
89
|
+
it('returns a movie by id', async () => {
|
|
90
|
+
// Provider endpoint: server/src/routes/movies.ts -> GET /movies/:id
|
|
91
|
+
await pact
|
|
92
|
+
.addInteraction()
|
|
93
|
+
.given(...createProviderState({ name: 'movie with id 1 exists', params: { id: 1 } }))
|
|
94
|
+
.uponReceiving('a request for movie 1')
|
|
95
|
+
.withRequest('GET', '/movies/1', setJsonContent({ headers: { Accept: 'application/json' } }))
|
|
96
|
+
.willRespondWith(200, setJsonBody({ id: integer(1), name: string('Inception') }))
|
|
97
|
+
.executeTest(async (mockServer) => {
|
|
98
|
+
// The real client, pointed at the mock server
|
|
99
|
+
const movie = await getMovieById(1, { baseUrl: mockServer.url });
|
|
100
|
+
expect(movie.name).toBe('Inception');
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
One `addInteraction()` per `it()`. A second scenario is a second `it()`, or `it.each` — never a second chain in the same block.
|
|
107
|
+
|
|
108
|
+
Where a Zod schema for the response already exists, `zodToPactMatchers(MovieSchema)` replaces the inline `MatchersV3` tree so the schema stays the single source of the shape.
|
|
109
|
+
|
|
110
|
+
### Provider verification
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { Verifier } from '@pact-foundation/pact';
|
|
114
|
+
import { buildVerifierOptions, createRequestFilter } from '@seontechnologies/pactjs-utils';
|
|
115
|
+
import type { StateHandlers } from '@seontechnologies/pactjs-utils';
|
|
116
|
+
|
|
117
|
+
const stateHandlers: StateHandlers = {
|
|
118
|
+
'movie with id 1 exists': {
|
|
119
|
+
setup: async (params) => db.seed({ movies: [{ id: params?.id ?? 1 }] }),
|
|
120
|
+
teardown: async () => db.clean('movies'),
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
await new Verifier(
|
|
125
|
+
buildVerifierOptions({
|
|
126
|
+
provider: 'SampleMoviesAPI',
|
|
127
|
+
port: '3001',
|
|
128
|
+
includeMainAndDeployed: process.env.PACT_BREAKING_CHANGE !== 'true',
|
|
129
|
+
stateHandlers,
|
|
130
|
+
requestFilter: createRequestFilter({ tokenGenerator: () => process.env.TEST_AUTH_TOKEN ?? 'test-token' }),
|
|
131
|
+
}),
|
|
132
|
+
).verifyProvider();
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
State handler names and their `params` must match the consumer's `createProviderState` exactly. That pairing is the contract's own contract.
|
|
136
|
+
|
|
137
|
+
## Which Workflows Change
|
|
138
|
+
|
|
139
|
+
| Workflow | What the flag changes |
|
|
140
|
+
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
141
|
+
| `framework` | Installs `@seontechnologies/pactjs-utils` and `@pact-foundation/pact`, then scaffolds directories, Vitest configs, scripts, CI workflow, and mandated samples — only when the relevance gate opens |
|
|
142
|
+
| `atdd` | Red-phase contract scaffolds generated in the mandated style. A scaffold is the file the developer un-skips and keeps |
|
|
143
|
+
| `automate` | The API worker emits contract artifacts in the mandated style and reports deviations |
|
|
144
|
+
| `test-design` | Pact code examples in design documents match what `automate` will generate |
|
|
145
|
+
| `test-review` | Scores registry row `M10` (a configured contract utility bypassed with no stated deviation, MEDIUM), gated on flag plus install |
|
|
146
|
+
| `ci` | Adds the contract-test stage and quality gates |
|
|
147
|
+
|
|
148
|
+
## Pact MCP (`tea_pact_mcp`)
|
|
149
|
+
|
|
150
|
+
Also on by default, and safe without a broker. It gates a runtime capability rather than a dependency, so its second gate is "are the SmartBear MCP tools reachable in this session".
|
|
151
|
+
|
|
152
|
+
When they are, TEA prefers real broker data for provider states, the verification matrix, and `can-i-deploy`. When they are not, it degrades: falls back to provider source or an OpenAPI spec, states in the output that the broker was unreachable, and continues. No workflow blocks on it, nothing retries in a loop, and inferred provider states are never presented as broker data.
|
|
153
|
+
|
|
154
|
+
Set `tea_pact_mcp: 'none'` to stop TEA attempting a broker call at all.
|
|
155
|
+
|
|
156
|
+
## Turning It Off
|
|
157
|
+
|
|
158
|
+
```yaml
|
|
159
|
+
# _bmad/tea/config.yaml
|
|
160
|
+
tea_use_pactjs_utils: false # TEA writes raw @pact-foundation/pact instead
|
|
161
|
+
tea_pact_mcp: 'none' # TEA never attempts a broker call
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Turning `tea_use_pactjs_utils` off does not disable contract testing. It changes which API the generated tests are written against; the determinism rules and provider scrutiny still apply.
|
|
165
|
+
|
|
166
|
+
## Installation
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
npm install -D @seontechnologies/pactjs-utils @pact-foundation/pact
|
|
170
|
+
# peer dependency: @pact-foundation/pact >= 16.2.0, Node.js >= 18
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
For the remote broker flow, set `PACT_BROKER_BASE_URL` and `PACT_BROKER_TOKEN`, plus `GITHUB_SHA` (GitHub Actions sets this) and `GITHUB_BRANCH` (set it explicitly: `${{ github.head_ref || github.ref_name }}`). The local monorepo flow needs no broker.
|
|
174
|
+
|
|
175
|
+
## Related Guides
|
|
176
|
+
|
|
177
|
+
- [Integrate Playwright Utils](/docs/how-to/customization/integrate-playwright-utils.md) — the same mandate shape for browser and API suites
|
|
178
|
+
- [TEA Configuration Reference](/docs/reference/configuration.md) — every key and its default
|
|
179
|
+
- [Knowledge Base Index](/docs/reference/knowledge-base.md) — the contract-testing fragments
|
|
180
|
+
|
|
181
|
+
## Reference
|
|
182
|
+
|
|
183
|
+
- [Pact.js Utils docs](https://seontechnologies.github.io/pactjs-utils/)
|
|
184
|
+
- [Pact.js Utils on npm](https://www.npmjs.com/package/@seontechnologies/pactjs-utils)
|