this repo has no description
33
fork

Configure Feed

Select the types of activity you want to include in your feed.

TypeScript 92.5%
JavaScript 7.2%
Other 0.2%
49 1 2

Clone this repository

https://tangled.org/alice.mosphere.at/atproto-smoke https://tangled.org/did:plc:by3jhwdqgbtrcc7q4tkkv3cf/atproto-smoke
git@tangled.org:alice.mosphere.at/atproto-smoke git@tangled.org:did:plc:by3jhwdqgbtrcc7q4tkkv3cf/atproto-smoke

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

atproto-smoke#

Browser-driven smoke tests for any AT Protocol PDS. Point it at your server, give it two accounts, and it will log into bsky.app and exercise the real social flows — posting, following, lists, notifications, settings, and more.

It grew out of perlsky but is designed to work with any PDS implementation.

atproto-smoke demo

What it looks like in bsky.app

bsky.app profile during smoke run

Quick start#

bun install
bunx playwright install chromium

# generate a config, fill in your PDS URL and credentials
bunx tsx bin/atproto-smoke.ts write-example --mode dual --output config.json
$EDITOR config.json

# validate and run
bunx tsx bin/atproto-smoke.ts validate --mode dual --config config.json
node dist/bin/atproto-smoke.js run-dual --config config.json

That's it. Provide a pdsUrl and two account credentials, and the suite handles the rest. Run commands print per-step progress to stderr and write a JSON summary to stdout (--json-only for machine-readable output only).

What it covers#

  • Post creation (text and image), like, repost, quote, reply, bookmark, follow/unfollow
  • Cross-PDS reply — set remoteReplyPostUrl to exercise replying to a post on a different server
  • Profile edit and avatar upload
  • Signed-in profile reload with rendered follow/follower count verification
  • List lifecycle (create, edit, add/remove members, delete)
  • Notification checks
  • Settings-depth flows
  • Mute/unmute, block/unblock, report draft

Every run produces screenshots, console output, failed requests, HTTP failures, and recent XRPC traffic as artifacts. Steps have bounded timeouts so a hung browser fails with artifacts instead of hanging forever.

DMs are intentionally deferred — the current suite is focused on stable social, list, and settings interactions first.

Adapters#

The suite ships with built-in adapters for different PDS implementations:

node dist/bin/atproto-smoke.js list-adapters
  • bring-your-own — the default. Works with any PDS that has accounts you can log into.
  • perlsky — thin adapter for perlsky-specific defaults like cleanup prefixes.
  • tranquil-pds — thin adapter for tranquil-pds-specific defaults like cleanup prefixes and hosted-handle examples.

Other PDS projects (rsky, pegasus, etc.) can add their own adapters without changing the core browser flows. The adapter contract is documented in docs/ADAPTERS.md.

Using from perlsky#

If you keep the repos side by side, perlsky finds this checkout automatically:

.../perlsky
.../atproto-smoke

Otherwise set PERLSKY_BROWSER_SUITE_ROOT=/path/to/atproto-smoke.

Config#

The config surface is intentionally small — suite-level settings (pdsUrl, artifactsDir, headless, strictErrors, targetHandle, remoteReplyPostUrl, etc.) and per-account settings (handle, password, optional loginIdentifier, postText, cleanupPostPrefixes, etc.). pdsHost is derived from pdsUrl automatically.

Example configs live in examples/. See docs/SAMPLE_OUTPUT.md for representative CLI output and summary.json shape.

For the local pdslab.net smoke lab, the committed non-secret target inventory lives in src/lab/pdslab-targets.ts. If you also have the local credential ledger in .tmp/smoke-accounts.local.json, you can generate runnable configs into .tmp/generated/pdslab-configs/ with:

bun run write:pdslab-configs

That writes one config per runnable target plus an inventory.json summary, while keeping passwords out of git.

Future direction#

The long-term shape is a test pyramid: direct PDS/AppView contract tests at the bottom, cross-service integration checks in the middle, and a thinner bsky.app browser smoke on top. The browser layer stays because it catches real social-app assumptions that API tests miss.