Skip to content

An API's manual shows each step's request as a curl command - #86

Open
ptescher wants to merge 1 commit into
mainfrom
http-evidence
Open

ptescher wants to merge 1 commit into
mainfrom
http-evidence

Conversation

@ptescher

Copy link
Copy Markdown
Owner

Expectation could already drive an API, but its manual had nothing to show for a step except a missing screenshot. Now a driver can hand over the HTTP requests it made, and the manual shows each step's request as a curl command with the response it got, where a screenshot would be.

  • Driver::take_exchanges / Bindings::on_exchanges hand over Exchanges (request and response). The runner asks after arranging the start, after each action and after each step's checks, and marks each one setup, action or check. Requests from looking at where the last test ended (A test starts where the last one ended when its Givens hold there #85) are dropped unless the test continues from there.
  • RunOptions::redaction decides what is kept, before anything is saved: a short list of headers; API keys as $API_KEY or a name per key ($MEMBER_API_KEY); secret-looking query, form and JSON fields, and any listed in fields, read REDACTED; a loopback origin becomes $BASE_URL (or base_url). JSON bodies are pretty-printed with numbers as written; one that doesn't parse isn't shown. Bodies are capped at 16 KiB.
  • Exchanges are saved in the results file as new line types that older readers skip, so a manual can be rebuilt from saved results, including when screenshots are behind a URL.
  • Tutorials and feature pages show the action requests (HTML and Markdown). The test page shows them too, with the setup and check requests folded away. A step with requests and no screenshot gets no "No screenshot" placeholder. The same request repeated in a row is shown once, with a count.
  • New example, crates/harness/examples/invoices: a suite run against a std-only stand-in invoices API over HTTP, with admin and member keys and an exception only a member meets (403 Forbidden). --bug lets members void, to show a failure. The site build publishes its manual.
  • New guide page, book/src/api.md, plus updates to the driver docs, README and llms.txt.

Tests: crates/story/src/exchange.rs covers redaction, curl and JSON; there's a results round trip; and crates/harness/tests/exchanges.rs runs the example end to end. It checks the roles, that no key, email, loopback address or dropped header appears anywhere in the published docs or results, the pages, a rebuild from saved results, and a failing run.

Not in this PR:

  • The Swift, JavaScript and embedded Rust drivers don't send exchanges yet.
  • When a scenario's Given overrides a Background state, "Before you begin" lists both. This already happens in the existing docs code; the example sidesteps it with a setup phrase.

The example's features and stories are marked Approval: proposed.

🤖 Generated with Claude Code

A driver can hand over the HTTP requests it made, with their responses
(Driver::take_exchanges, Bindings::on_exchanges). The runner marks each
with what it was for (setting up, the action, or a check), redacts it
and keeps it in the results. The manual shows a step's action request
as a curl command with the response it got, where a screenshot would
be; the test page also has the requests that set up and checked it.

Redaction keeps a short list of headers, turns API keys into $API_KEY
(or a name per key), replaces secret-looking query, form and JSON
fields, and swaps a loopback origin for $BASE_URL. A JSON body that
doesn't parse isn't shown.

The invoices example runs a suite against a stand-in API over HTTP,
with admin and member keys and an exception only a member meets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant