···5353- Use `script/perlsky-browser-smoke bootstrap-pair` once to mint and save a dedicated smoke pair, then rerun `script/perlsky-browser-smoke run-dual` as often as you want against those same accounts.
5454- Use `script/perlsky-browser-smoke show-pair` to inspect the saved pair metadata and `script/perlsky-browser-smoke clear-pair` to forget it locally.
5555- Fresh-account creation is still available through the explicit `bootstrap-*` commands, but it is no longer the normal path for repeated browser smoke runs.
5656+- Detailed browser-smoke workflow, current interaction coverage, and the env-gated `prove` wrapper live in `docs/BROWSER_SMOKE.md`.
56575758Moderation and labels:
5859
+79
docs/BROWSER_SMOKE.md
···11+# Browser Smoke
22+33+`perlsky` ships two browser-driven `bsky.app` smoke runners:
44+55+- `script/perlsky-browser-smoke run`
66+ Best for a single-account sanity pass plus direct interactions with `--target-handle`.
77+- `script/perlsky-browser-smoke run-dual`
88+ Best for the broader reusable two-account end-to-end flow.
99+1010+The preferred path is the reusable dual-account smoke because it avoids minting a new actor pair on every run.
1111+1212+## Reusable Pair
1313+1414+Bootstrap a dedicated smoke pair once:
1515+1616+```sh
1717+PERL5LIB=local/lib/perl5 perl script/perlsky-browser-smoke bootstrap-pair
1818+```
1919+2020+That saves the pair locally in `.cache/browser-smoke/reusable-pair.json`.
2121+2222+Useful maintenance commands:
2323+2424+```sh
2525+PERL5LIB=local/lib/perl5 perl script/perlsky-browser-smoke show-pair
2626+PERL5LIB=local/lib/perl5 perl script/perlsky-browser-smoke clear-pair
2727+```
2828+2929+Run the broad strict smoke against the saved pair:
3030+3131+```sh
3232+PERL5LIB=local/lib/perl5 perl script/perlsky-browser-smoke run-dual \
3333+ --artifacts-dir data/browser-smoke/latest-dual \
3434+ --strict-errors
3535+```
3636+3737+## Coverage
3838+3939+The current reusable dual-account smoke exercises these `bsky.app` flows:
4040+4141+- login and age-gate completion
4242+- root post creation
4343+- image-post creation and record verification
4444+- profile edit plus avatar upload
4545+- local and public profile verification after edit
4646+- follow and unfollow between the two smoke accounts
4747+- like, bookmark, repost, quote, and reply
4848+- saved-posts page verification
4949+- notification API verification for like/repost/quote/reply
5050+- notifications-page load checks
5151+- mute and unmute
5252+- block and unblock
5353+- report-post draft flow without submitting the external report
5454+- cleanup of created posts plus undo of follow/like/bookmark/repost state
5555+5656+Artifacts include screenshots plus `summary.json`, which captures:
5757+5858+- step-by-step status
5959+- browser console entries
6060+- page errors
6161+- request failures
6262+- HTTP failures
6363+- recent XRPC traffic
6464+6565+## Test Suite Wrapper
6666+6767+The browser smoke is available from `prove`, but it is intentionally opt-in:
6868+6969+```sh
7070+PERLSKY_RUN_BROWSER_SMOKE=1 prove -lv t/browser-smoke.t
7171+```
7272+7373+That wrapper still uses `script/perlsky-browser-smoke`, so the script remains the canonical entrypoint.
7474+7575+## Notes
7676+7777+- The reusable dual-account path is intentionally conservative about account creation. Fresh actors are only created through explicit `bootstrap-*` commands.
7878+- The report flow stops at the draft/submit screen on purpose so smoke runs do not send moderation reports to external services.
7979+- The current broad smoke automates only dedicated smoke accounts. It does not log into `@alice.mosphere.at`.