at-record e2e #
Real end-to-end tests against a fully local, deterministic atproto network (a PDS, jetstream, Constellation, Slingshot, Caddy for TLS on the test handles) — not the public network, so no indexing lag and no dependency on real accounts.
These exist for what the unit tests structurally can't cover: the real
OAuth wire flow (PAR/PKCE/DPoP against a real PDS), and cross-account
behavior that depends on real Constellation indexing (adoption, the
edit-inbox). Business logic itself is already covered fast and in isolation
by server/test/promotion_test.gleam and friends via injected Deps
stubs — don't duplicate that here.
One-time setup #
make e2e-setup # clones jetstream + microcosm-rs at pinned commits, generates devnet secrets
Running #
Three things need to be running:
- The devnet:
make e2e-up(wipes any previous devnet state for a clean slate, boots fresh, waits for the PDS to be healthy, seeds the fixedalice.test/bob.testaccounts). - at-record's own dev server, pointed at the devnet:
SLINGSHOT_URL=http://localhost:6790 CONSTELLATION_URL=http://localhost:6789 ./scripts/dev.sh - The test suite:
make e2e(this also does step 1 for you — running it standalone is only useful if you want to poke at the devnet by hand first).
make e2e-down tears the devnet down and wipes its volumes when you're done.
Why fixed test handles, not generated per run #
Caddy's TLS termination and the PDS's network alias are declared per-handle
in devnet/docker-compose.yml and devnet/Caddyfile (atproto's
bidirectional handle verification needs a real, if locally-CA-signed, TLS
endpoint for each handle — see the devnet's own README for why). Adding a
handle means declaring it in both places, not just calling
create-test-accounts.sh with a new name. make e2e-up wipes and reseeds
the same two accounts fresh each run instead, which is enough isolation for
now — revisit if tests start needing more than two accounts at once.
Pinned dependencies #
devnet/setup.sh clones bluesky-social/jetstream and
microcosm.blue/microcosm-rs at specific commits, not main. Both are
under active, fast-moving development with no published container image
matching their current main — pinning is what keeps this reproducible.
Re-pin deliberately (edit the SHAs in setup.sh, rm -rf the old clones,
re-run make e2e-setup) when there's a reason to, not by accident.