A TypeScript portfolio lab for risk-based API contract testing of a deterministic checkout flow.
Status: Implemented and verified as a local CLI/test project. There is no hosted API or browser demo.
Happy-path API tests can pass while response shapes, error contracts, or critical validation rules regress. This lab demonstrates how a small, deterministic suite can connect an OpenAPI reference, positive and negative scenarios, runtime validation, evidence-rich reporting, and mutation proof.
- OpenAPI 3.1 contract for products, carts, inventory, quotes, and payments.
- Typed in-process checkout API fixture with deterministic IDs, timestamps, stock, and payment behavior.
- Handwritten runtime validators for products, carts, errors, headers, and payment results.
- Eight P0/P1 scenarios covering successful and unsuccessful paths.
- Negative cases for invalid email, out-of-stock inventory, expired cards, and declined cards.
- Mutation adapter that intentionally authorizes an expired card.
- Proof command that confirms scenario
API-007detects the injected regression. - Markdown CLI report containing status, priority, endpoint, result, and failure evidence.
- Vitest coverage, Oxlint, TypeScript checks, build output, QA documentation, and GitHub Actions CI.
- TypeScript 6
- Node.js 22
- Vitest
- TSX
- OpenAPI 3.1
- Oxlint
- GitHub Actions
flowchart LR
S["Risk-based scenario definitions"] --> R["Scenario runner"]
O["OpenAPI 3.1 reference contract"] -. documents expected operations .-> S
F["Deterministic CheckoutApi fixture"] --> R
M["Mutated API adapter"] --> R
R --> V["Handwritten runtime validators"]
V --> C["ContractCheck evidence"]
C --> T["Vitest assertions"]
C --> P["Markdown CLI report"]
The OpenAPI document is the human-readable source contract. The current suite does not generate validators or clients from the YAML; TypeScript validators and scenario expectations are maintained explicitly so their behavior is visible during review.
| ID | Priority | Behavior |
|---|---|---|
| API-001 | P0 | Product list returns the expected array contract |
| API-002 | P1 | Invalid buyer email returns a validation error |
| API-003 | P0 | A valid cart can be created |
| API-004 | P0 | A valid item can be added to a cart |
| API-005 | P1 | Cart quote totals match the contract |
| API-006 | P1 | Excess inventory request returns a conflict |
| API-007 | P0 | Expired cards are rejected before authorization |
| API-008 | P0 | Declined cards return the expected payment response |
Every scenario also checks the response status, body shape, and deterministic x-request-id header.
npm run checkThe complete check runs lint, typecheck, Vitest, the passing report, mutation proof, and the TypeScript build. The mutation command is expected to display one failed P0 contract check and then exit successfully only when the suite detects the injected defect.
Supporting QA artifacts:
Requirements: Node.js 22 and npm.
git clone https://github.com/madara66613/api-contract-testing-lab.git
cd api-contract-testing-lab
npm install
npm run check| Command | Purpose |
|---|---|
npm run lint |
Run Oxlint |
npm run typecheck |
Validate TypeScript without emitting files |
npm run test |
Run the Vitest suite |
npm run report |
Execute the normal contract suite and print Markdown |
npm run mutation:proof |
Inject the expired-card regression and prove detection |
npm run build |
Compile TypeScript |
npm run check |
Run the complete verification chain |
.github/workflows/ci.yml CI verification
docs/
bug-report.md Example defect report
test-plan.md Risk and coverage strategy
openapi/
checkout-api.yaml OpenAPI 3.1 reference contract
src/
fakeApi.ts Deterministic in-process API fixture
contracts.ts Runtime response validators
scenarios.ts P0/P1 executable scenarios
mutations.ts Intentionally broken API adapter
report.ts Markdown report builder
cli.ts Normal report entrypoint
mutationCli.ts Mutation-proof entrypoint
tests/
contracts.test.ts Validator coverage
scenarios.test.ts Scenario and mutation coverage
- Deterministic fixtures: fixed time, counters, data, and request IDs make failures repeatable.
- Evidence instead of snapshots: each check records the expected rule, actual status, and relevant facts.
- Visible negative testing: validation, inventory, and payment failures are first-class scenarios.
- Mutation proof: an intentionally broken adapter shows that the suite can fail for a meaningful reason.
- No external service dependency: reviewers can run the complete project offline after dependency installation.
- The API is an in-process TypeScript fixture, not an HTTP server or deployed service.
- Network behavior, authentication, authorization, rate limiting, retries, latency, and load are not tested.
- OpenAPI conformance is not generated or automatically parsed from the YAML.
- The fixture uses a fixed July 2026 clock and USD checkout data.
- The report is printed to stdout; it is not persisted as a CI artifact.
- Add an HTTP adapter and run the same scenarios against a real local endpoint.
- Validate the OpenAPI file in CI and add generated-schema comparison.
- Publish report output as a GitHub Actions artifact.
- Add authentication, idempotency, retry, and rate-limit scenarios.
- Run
npm run reportand review the eight passing scenarios. - Run
npm run mutation:proof. - Show the failed P0
API-007evidence for the intentionally authorized expired card. - Open
openapi/checkout-api.yaml, then compare it with the explicit validator and scenario code. - Explain which production concerns are deliberately outside this fixture-based scope.
Built a TypeScript API contract-testing lab with an OpenAPI 3.1 reference, deterministic checkout fixtures, handwritten runtime validators, risk-based positive and negative scenarios, mutation proof, Markdown evidence reporting, Vitest coverage, and GitHub Actions CI.