Expand description
Values a request pulls out of its response and hands to the requests after it.
A request file may carry a capture block: variable names mapped to a
source to read from the response once it arrives. The default source,
and originally the only one, is a JSON path evaluated against the
response body — a bare string still means exactly that, for every file
already written against it. Two more sources are read from a response’s
envelope rather than its body: a named header, and the status code
itself.
name: Log in
method: POST
url: https://api.example.com/login
capture:
auth_token: $.token # JSON path (default, bare string)
user_id: $.user.id
session_id:
header: Set-Cookie # a response header
request_status:
status: true # the numeric status, as a string§Header capture and repeated headers
Header names are matched case-insensitively, the way assertions
matches them. A header that does not repeat captures
its one value. A header that repeats (Set-Cookie is the common case) is
ambiguous rather than resolved by taking the first or the last: this
mirrors the JSON-path rule that a path selecting more than one value is a
failure rather than a silent pick (see CaptureFailure::Ambiguous).
An assertion checking headers: { set-cookie: ... } passes if any
repeated value matches, because it is testing a predicate; a capture
binds a name to one value that later requests will substitute, and
guessing which repeat that should be would make the same file behave
differently depending on header order a server happens to send in. A
file that wants one specific cookie out of several should be more
specific than header: Set-Cookie can be today — see the module-level
non-goal note below.
§Only the final response’s headers
With follow_redirects on, header capture reads the headers of the
response evaluate is called with — the final response in the chain.
Response::redirects records each intermediate hop’s
status and the Location it pointed at, but deliberately does not carry
that hop’s full header set (see the type’s own docs), so there is no
intermediate Set-Cookie or other header for this to reach even if the
schema grew a way to ask for one. Capturing the final hop’s Location
is possible today (a response that redirected already exposes its own
Location if it is itself 3xx and redirects were disabled or exhausted),
but reaching into an earlier hop is out of scope here: it would need
RedirectHop extended to carry headers, which is a bigger, separate
change. Documented as a non-goal rather than a partial hop: key that
could only ever address the one field RedirectHop already has.
Every name captured this way becomes usable as {{auth_token}} in every
request after this one, in file order, through the same substitution pass
an environment file feeds. Nothing is written anywhere: a capture lives for
the rest of one sendra run or sendra test invocation and no longer. A
fresh process starts with nothing captured, which is the same non-goal
environments shipped with.
§A capture is not a check
Captures::evaluate returns a CaptureReport and no Result, exactly
as Assertions::evaluate does, and for the
same reason: the response has already arrived, so there is nothing left to
abort, and the only useful thing to do with a capture that did not work is
to say precisely how it did not work, next to the ones that did.
But it is not an assertion either, and the difference decides how a
front-end counts it. An assertion is an expectation about the response; a
capture is a dependency of the rest of the run. So a capture that succeeds
says nothing about whether the response was correct — a request that
captured a token and asserted nothing was still not checked — while a
capture that fails is a genuine failure, because a value the file promised
to the requests downstream is not there. See CaptureReport::passed and
the Summary type in sendra-cli for where that lands.
§Why the failures are typed rather than [SendraError]s
A [SendraError] means “this request could not be completed”, and every
variant of it is raised on a path where there is no response: a file that
does not parse, a {{var}} with nothing behind it, a refused connection, a
pre_request script that threw. A capture failure is the opposite shape —
the response arrived, was read, and did not contain what the file said it
would — and folding it into that enum would have put it in the one category
it is definitely not in.
Typing it as CaptureFailure instead also keeps the block’s entries
independent: three captures against one response produce three results, the
way three assertions do, rather than the first failure discarding whatever
the other two would have found.
Structs§
- Capture
Report - Every entry of one request’s
captureblock, evaluated against its response, in sorted-name order. - Capture
Result - One entry of a
captureblock, evaluated. - Captures
- The
captureblock of a request, exactly as it appears on disk: variable name toCaptureSource.
Enums§
- Capture
Failure - Why one entry of a
captureblock did not produce a value. - Capture
Source - Where one
captureentry reads its value from.