A deterministic API quality-engineering framework built with Express, Supertest, Jest, Axios, and Pact. Component tests execute the real Express app in-process; transport policy is isolated behind a provider-neutral client; Pact owns consumer compatibility; a loopback listener proves real TCP/serialization behavior; and native Supertest agents/expectations remain available for stateful protocol contracts.
Important
Application behavior, in-process HTTP semantics, outbound transport, contract compatibility, real-listener behavior, packaged runtime, and deployed integration are deliberately separate failure domains.
Start here: capabilities · architecture · quick start · repository map · documentation
| Plane | Purpose | Primary evidence |
|---|---|---|
| Component | Express routing, validation, middleware, stable error envelopes | Jest + coverage |
| Stateful protocol | Cookies, query/body/header composition, redirects, HEAD/OPTIONS | Native Supertest assertions |
| Transport | Target, timeout, correlation, failure normalization | Deterministic Axios-boundary tests |
| Contract | Consumer/provider HTTP expectations | Pact interactions/artifacts |
| Listener | Real Node TCP, middleware, serialization, correlation | Loopback smoke evidence |
| Packaged runtime | Governed container build + test entrypoint | Container execution result |
| Security | SAST, advisories, repository/image risk, dependency-diff risk | CodeQL, npm Audit, Trivy, Dependency Review |
| Documentation | README/workflow/governance consistency | Documentation contract status |
flowchart LR
CHANGE[Repository change] --> TEST[Jest + Supertest]
TEST --> AGENT[Scoped request.agent]
AGENT --> APP[Express application]
APP --> ROUTE[Posts router]
ROUTE --> CLIENT[Injected posts client]
CLIENT --> TRANSPORT[PostsUpstreamClient / Axios]
APP --> ERR[Stable public error middleware]
CHANGE --> PACT[Pact contracts]
CHANGE --> LISTENER[Ephemeral loopback listener]
LISTENER --> APP
CHANGE --> IMAGE[Tracked container boundary]
TEST --> GATES[CI gates]
PACT --> GATES
LISTENER --> GATES
IMAGE --> GATES
GATES --> RESULT[Qualified repository change]
classDef entry fill:#DDF4FF,stroke:#0969DA,color:#24292F,stroke-width:1.5px;
classDef policy fill:#FBEFFF,stroke:#8250DF,color:#24292F,stroke-width:1.5px;
classDef runtime fill:#FFF8C5,stroke:#9A6700,color:#24292F,stroke-width:1.5px;
classDef evidence fill:#DAFBE1,stroke:#1A7F37,color:#24292F,stroke-width:1.5px;
class CHANGE entry;
class AGENT,CLIENT,ERR policy;
class TEST,APP,ROUTE,TRANSPORT,PACT,LISTENER,IMAGE runtime;
class GATES,RESULT evidence;
linkStyle default stroke:#57606A,stroke-width:1.4px;
Tests own application/protocol intent; injected clients own dependency seams; transport code owns Axios policy; Pact owns consumer compatibility; the listener/container lanes own their runtime boundaries. See docs/ARCHITECTURE.md for the full dependency model.
npm ci --ignore-scripts
npm run check
npm run test:coverageExercise the real listener without an external dependency:
npm run test:live-smokeStart the real service only with an explicitly approved upstream:
UPSTREAM_BASE_URL=https://api.test.example.internal npm startFor the complete command reference, runtime variables, native Supertest surface, failure taxonomy, request correlation, evidence, dependency maintenance, and triage, see docs/OPERATIONS.md.
.
├── .github/
├── docs/
├── scripts/
└── src/
- In-process first: ordinary API behavior uses
createApp({ postsClient })+ Supertest; no listener or public dependency is required. - Native state ownership:
request.agent(app)is scoped to the scenario that needs cookies/session continuity rather than shared globally. - Dependency isolation: routes depend on a narrow provider-neutral client, never Axios directly.
- Explicit runtime ownership:
UPSTREAM_BASE_URLis required for real server startup; there is no public fallback. - Stable public errors: transport implementation details normalize into deliberate API error codes/statuses.
- Correlation discipline: run identity and per-request identity remain bounded and distinct.
- Cheapest sufficient boundary: use Supertest, transport tests, Pact, loopback sockets, containers, or deployed integration only when that boundary adds required semantics.
- Semantic evidence: CI validates that tests/interactions/listener work actually executed rather than accepting artifact presence alone.
| Stable status | Responsibility |
|---|---|
ci-gate |
Component/transport/Pact coverage plus packaged-runtime evidence for the primary quality conclusion |
extended-gate |
Real loopback-listener compatibility across the supported Node runtime matrix |
security-gate |
CodeQL, npm Audit, repository/image Trivy, and Dependency Review when available |
Workflow definitions: ci.yml · extended.yml · security.yml · docs.yml.
| Guide | Use it for |
|---|---|
docs/README.md |
Documentation index |
docs/ARCHITECTURE.md |
Composition, configuration, correlation, Supertest state, transport, errors, Pact, listener, container boundaries |
docs/TEST_STRATEGY.md |
Risk-based test-layer selection and exit criteria |
docs/OPERATIONS.md |
Commands, runtime inputs, native protocol contracts, correlation, evidence, dependencies, triage |
docs/DEPENDENCY_BOUNDARIES.md |
Component, transport, contract, listener, and live-integration dependency ownership |
docs/DEPENDENCY_GOVERNANCE.md |
Dependency qualification and control-plane governance |
The deeper protocol, failure-taxonomy, correlation, evidence, and dependency detail lives in /docs; the main README intentionally retains only the architecture overview above.
A strong Supertest framework makes the failed boundary obvious: application behavior, stateful in-process HTTP semantics, input policy, transport normalization, compatibility, listener runtime, packaged runtime, or explicit external dependency.