docs: add design spec for Reddit post Playwright sidecar

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Doar Mihai
2026-07-18 18:00:20 +03:00
co-authored by Claude Sonnet 5
parent e0b8f2f924
commit 44040e7c1e
@@ -0,0 +1,81 @@
# Reddit Post Sidecar — Design
## Purpose
A standalone Playwright acceptance test, living under `sidecars/`, that logs into Reddit with supplied credentials and creates a text post in a given subreddit. It is invoked as a CLI tool (not an HTTP service) so an external caller — most likely the AI agent that also manages this project's Sites/Social Accounts/Posts data — can shell out to it, passing credentials and post content as arguments, and get back a structured success/failure result it can act on (e.g. to `PATCH` the Laravel Posts API's `status` field to `published` or `failed`).
This is a sidecar: independent of the Laravel app's PHP/Composer/npm toolchain, with its own `package.json` and dependencies, callable standalone.
## Scope
- One Playwright Test (`@playwright/test`) that:
1. Logs into Reddit with a given username/password
2. Navigates to a given subreddit's submit page
3. Creates a text post with a given title and body
4. Verifies the post was created and captures its URL
- A thin CLI wrapper script that accepts friendly `--flag` arguments and translates them into the environment variables the Playwright test reads, then invokes `npx playwright test`
- Structured JSON output (success or failure) printed to stdout, with a matching process exit code, so any caller can parse the result reliably
Out of scope:
- Link posts (URL posts) — text posts only
- Interactive CAPTCHA/2FA solving — if login doesn't complete cleanly, the test fails with a descriptive error rather than waiting for a human
- Any wiring back into the Laravel app's Posts API — this sidecar only performs the Reddit action and reports the result; calling it and acting on the result is the caller's (the AI's) responsibility
- Any other social network — this is Reddit-only for now; the same pattern could be repeated per-network later, but that's not part of this spec
## Arguments
Via the wrapper script (`run.sh`):
| Flag | Required | Description |
|---|---|---|
| `--username` | yes | Reddit username or email to log in with |
| `--password` | yes | Reddit account password |
| `--subreddit` | yes | Subreddit to post to (without the `r/` prefix) |
| `--title` | yes | Post title |
| `--body` | yes | Post body text |
| `--headed` | no | If passed, runs with a visible browser window instead of headless (for debugging) |
The wrapper translates these into environment variables (`REDDIT_USERNAME`, `REDDIT_PASSWORD`, `SUBREDDIT`, `POST_TITLE`, `POST_BODY`, `HEADLESS`) that the Playwright config and test read, since Playwright Test reserves its own CLI argument syntax and custom flags cannot be passed through directly to `npx playwright test`.
## Behavior
**Login:**
- Navigate to Reddit's login page
- Fill username and password fields, submit
- Wait for a reliable "logged in" signal (e.g. presence of the user menu/avatar) within a bounded timeout
- If the logged-in state isn't reached in time — whether due to a CAPTCHA, 2FA/"verify it's you" prompt, or wrong credentials — fail immediately with a descriptive error. No interactive fallback.
**Posting:**
- Navigate to `https://www.reddit.com/r/{subreddit}/submit`
- Select the text-post type (as opposed to link/image/poll)
- Fill in the title and body fields
- Submit the post
- Wait for navigation to the new post's permalink (or another reliable success signal) within a bounded timeout
- If the post doesn't appear to succeed within the timeout, fail with a descriptive error (e.g. "post submission did not complete" or a captured error banner's text if Reddit shows one)
**Assertions:** Playwright's `expect()` is used at each key step (login success, submit page loaded, post created) so this genuinely functions as an acceptance test, not just an unassertive script — a failed assertion is what produces the failure exit path.
## Output Contract
Regardless of how it's invoked, the wrapper script always prints exactly one JSON object to stdout as its last line, and exits with a matching code:
- **Success:** exit code `0`, stdout ends with `{"success": true, "url": "<permalink of the new post>"}`
- **Failure:** exit code `1`, stdout ends with `{"success": false, "error": "<human-readable description of what went wrong>"}`
The Playwright test itself writes this result to a fixed JSON file (e.g. `test-results/result.json`) during its run (in a step that always executes, success or failure, so the file exists either way); the wrapper reads that file after the `playwright test` process exits and echoes its contents to stdout as the final line, then exits with the same code Playwright produced.
## Technical Setup
- New directory: `sidecars/reddit-post/`
- Own `package.json` with `@playwright/test` as the sole dependency
- `playwright.config.js`: headless by default (`HEADLESS` env var can override to `false`), single browser project (Chromium is sufficient — no cross-browser requirement for this internal tool), no automatic retries (a retry would mask a flaky login/post flow rather than surface it), screenshot-on-failure enabled for debugging
- Setup note (in this sidecar's own short README) that `npx playwright install chromium` must be run once after `npm install`, since Playwright needs its browser binaries downloaded separately
## Testing / Verification
Since this automates a real third-party site (Reddit) with real credentials, there is no "test the test" step in the traditional sense — verification means actually running the wrapper against a real (test) Reddit account and confirming:
- A successful run produces a real post visible on Reddit, and the JSON result's `url` resolves to it
- A run with wrong credentials fails cleanly with a descriptive error and exit code 1
- A run with an invalid/nonexistent subreddit fails cleanly with a descriptive error and exit code 1
These are manual verification steps to run once the implementation is complete, not automated CI tests (there's no sandboxed "fake Reddit" to test against, and using real Reddit in automated CI is undesirable — rate limits, ToS, account flagging risk).