From a session to a regression
Capture real traffic once. Replay it anywhere. Turn the responses into assertions that ship with the request.
Same recording format every protocol Bowire knows produces. Same replay engine the mock server and the security scanner use. bowire scan with a recording = vulnerability template; bowire mock with a recording = live fixture; bowire test in CI = regression test.
Capture — one click, every protocol
Click Record, run the sequence, click Stop. Every request, response, status, header, and inter-call timing ends up in one JSON file — gRPC streams next to SignalR hub invocations next to MQTT publishes next to REST hits.
The recording format (.bwr) is plain JSON. Version it in Git, review it in a PR, diff it across releases. Bowire writes one file per session by default; the Replay button, bowire test <recording> in CI, and bowire mock all read the same shape.
Cross-protocol on purpose: one capture against a service that uses gRPC for internal calls + SignalR for live updates + REST for client APIs ends up as one timeline you can replay end-to-end, not three separate test fixtures glued together by a script.
Recording feature reference →Replay — spot drift across environments
Switch the environment dropdown, hit Replay, get a side-by-side diff against the original capture. Same calls, different host, same expectations.
Variables in the recording substitute against whatever environment you replay against ({{env.baseUrl}}, {{env.token}}, …). The diff highlights status changes, response-shape drift, missing fields, latency spikes — you see immediately whether Staging still behaves like Prod or where the rollout broke something.
For long-running comparisons (week-over-week regression suites): drop the recording in CI behind bowire test, point at --env staging, fail the build on any diff that crosses a configured threshold with --fail-on.
flowchart LR
subgraph cap["1 · Capture"]
direction TB
Live(["Live session"])
BWR[("session.bwr")]
Live --> BWR
end
subgraph rep["2 · Replay"]
direction TB
Dev(["Dev"])
Stag(["Staging"])
Prod(["Prod"])
end
subgraph ass["3 · Assert"]
direction TB
Ops(["eq · gt · contains · matches"])
end
BWR --> Dev
BWR --> Stag
BWR --> Prod
Dev --> Ops
Stag --> Ops
Prod --> Ops
Ops -->|"all match"| Pass(["pass"])
Ops -->|"any miss"| Fail(["fail CI"])
.bwr file drives three replays across environments; the same Newman-style assertion set runs against each. bowire test wires the same loop into CI — non-zero exit code on any miss, with --report / --junit / --sarif artifacts.Assert — next to the request, not in a separate file
Eleven Newman-style operators (eq, ne, gt, contains, matches, type, …) target any value via response.path.to.value JSONPath. Stored per method, replay with every invocation, green/red badge inline.
Streaming responses get assertions on the accumulated frames — “expect at least 3 frames of type TICK within 2 s” is one rule. No plugins, no pipeline, just a test that lives next to the request and ships in the same recording file.
Export the recording (including its assertions) into your repo, run bowire test in CI, fail the build when an assertion flips. The same file drives the interactive workbench replay and the headless CI run — no second test fixture to maintain.
Beyond replay — the v2.2 Test pillar
Record → replay → assert is the floor. The Test pillar adds consumer-driven contracts, snapshots, and data-driven runs so one recording covers a whole class of inputs, not a single captured path.
Pact-style contracts — bowire contract publish | verify
Turn a recording into a consumer-driven contract: the consumer side runs bowire contract publish, the provider side runs bowire contract verify against its live endpoint and fails when it no longer satisfies the agreed shape. A broker stays opt-in — point at one with --broker-url to share contracts across teams, or keep them as files in the repo when you don't want the infrastructure.
Snapshot testing — exact or structural
Lock a response the first time you see it: Bowire writes it to __snapshots__/ next to the recording and diffs every later run against it. Choose exact (byte-for-byte) or structural (shape and types, ignoring volatile values like ids and timestamps). When a change is intentional, re-baseline with --update-snapshots — the diff shows up in the PR just like source.
Data-driven steps — one recording, many rows
Parameterise a step and feed it a table: inline rows, a CSV file, or a generator. Each row substitutes into the request via {{...}} variables and runs the assertions independently, so “this endpoint holds for 200 fixtures” is one recording, not 200 copies.
Regression coverage chips summarise the run at a glance — how many steps asserted, how many snapshots matched, how many contract obligations held — both inline in the workbench and in the bowire test --report HTML.
Try the regression flow
The shortest end-to-end story: capture a session against staging, replay it against prod, lock the responses with assertions, drop the file in your CI.
A different lane fits better? All solution lanes →