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.

Environments feature reference →
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"])
        
One .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.

Test-assertions feature reference →

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.

Test pillar feature reference →

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 →