**Your task:** Generate API tests ONLY (not E2E, not fixtures, not other test types).
**If `use_pactjs_utils` is enabled:** Also generate consumer contract tests and provider verification tests alongside API tests. Use the loaded pactjs-utils fragments (`pactjs-utils-overview`, `pactjs-utils-consumer-helpers`, `pactjs-utils-provider-verifier`, `pactjs-utils-request-filter`) for patterns. If `pact_mcp` is `"mcp"`, use SmartBear MCP tools (Fetch Provider States, Generate Pact Tests) to inform test generation.
---
## MANDATORY EXECUTION RULES
- 📖 Read this entire subagent file before acting
- ✅ Generate API tests ONLY
- ✅ Output structured JSON to temp file
- ✅ Follow knowledge fragment patterns
- ❌ Do NOT generate E2E tests (that's subagent 3B)
- ❌ Do NOT run tests (that's step 4)
- ❌ Do NOT generate fixtures yet (that's step 3C aggregation)
---
## SUBAGENT TASK
### 1. Identify API Endpoints
From the coverage plan (Step 2 output), identify:
- Which API endpoints need test coverage
- Expected request/response formats
- Authentication requirements
- Error scenarios to test
### 2. Generate API Test Files
For each API endpoint, create test file in `tests/api/[feature].spec.ts`:
**Test Structure:**
```typescript
import { test, expect } from '@playwright/test';
// If Playwright Utils enabled:
// import { apiRequest } from '@playwright-utils/api';
- ⚠️ **Postel's Law for matchers**: Use `like()`, `eachLike()`, `string()`, `integer()` matchers ONLY in `willRespondWith` (responses). Request bodies in `withRequest` MUST use exact values — never wrap request bodies in `like()`. The consumer controls what it sends, so contracts should be strict about request shape.
**CRITICAL**: Before generating ANY Pact consumer interaction, perform provider source scrutiny per the **Seven-Point Scrutiny Checklist** defined in `contract-testing.md`. Do NOT generate response matchers from consumer-side types alone — this is the #1 cause of contract verification failures.
The seven points to verify for each interaction:
1. Response shape
2. Status codes
3. Field names
4. Enum values
5. Required fields
6. Data types
7. Nested structures
**Source priority**: Provider source code is most authoritative. When an OpenAPI/Swagger spec exists (`openapi.yaml`, `openapi.json`, `swagger.json`), use it as a complementary or alternative source — it documents the provider's contract explicitly and can be faster to parse than tracing through handler code. When both exist, cross-reference them; if they disagree, the source code wins. Document the discrepancy in the scrutiny evidence block (e.g., `OpenAPI shows 200 but handler returns 201; using handler behavior`) and flag it in the output JSON `summary` so it is discoverable by downstream consumers or audits.
**Scrutiny Sequence** (for each endpoint in the coverage plan):
1.**READ provider route handler and/or OpenAPI spec**: Find the handler file from `subagentContext.config.provider_endpoint_map` or by scanning the provider codebase. Also check for OpenAPI/Swagger spec files. Extract:
- Exact status codes returned (`res.status(201)` / OpenAPI `responses` keys)
- Response construction (`res.json({ data: ... })` / OpenAPI `schema`)
- Error handling paths (what status codes for what conditions)
2.**READ provider type/model/DTO definitions**: Find the response type referenced by the handler or OpenAPI `$ref` schemas. Extract:
- Exact field names (`transaction_id` not `transactionId`)
- Field types (`string` ID vs `number` ID / OpenAPI `type` + `format`)
- Optional vs required fields (OpenAPI `required` array)
6.**Graceful degradation** when provider source is not accessible (follows the canonical four-step protocol from `contract-testing.md`):
1.**OpenAPI/Swagger spec available**: Use the spec as the source of truth for response shapes, status codes, and field names
2.**Pact Broker available** (when `pact_mcp` is `"mcp"` in `subagentContext.config`): Use SmartBear MCP tools to fetch existing provider states and verified interactions as reference
3.**Neither available**: Generate from consumer types but use the TODO form of the mandatory comment: `// Provider endpoint: TODO — provider source not accessible, verify manually`. Set `provider_scrutiny: "pending"` in output JSON
4.**Never silently guess**: Document all assumptions in the scrutiny evidence block
> ⚠️ **Anti-pattern**: Generating response matchers from consumer-side types alone. This produces contracts that reflect what the consumer _wishes_ the provider returns, not what it _actually_ returns. Always read provider source or OpenAPI spec first.