Stage 5 upload: Playwright-driven adds and version updates

Queue from to_add/to_update minus upload_log.csv (append-per-attempt,
so runs resume); per-game failure isolation with 2-4s pacing;
--dry-run/--verify/--retry-failed/--limit; stub-fixture marker blocks
real runs, dry-run warns. Headed browser by default: live recon showed
Cloudflare Turnstile hard-blocks headless, and BGG never reaches
networkidle. Login selectors verified anonymously; version-picker
pagination and the collection-row update flow remain unverified until
real data exists. Client collection fetches gain a refresh passthrough
so --verify sees the live collection, not cache.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-01 19:03:25 -04:00
parent 196862e243
commit 3ca7e7f650
8 changed files with 968 additions and 19 deletions
+22
View File
@@ -78,3 +78,25 @@ runs): pagination controls in the version sub-view, exact post-save behavior
(toast? dialog close? redirect?), and how the dialog differs when the game is
ALREADY in the collection (second-copy flow must create a new entry, not edit
the existing one).
## Login page (recon 2026-08-01, anonymous probe via Playwright)
- **Cloudflare Turnstile blocks headless browsers outright**: the headless
shell never gets past "Just a moment..." (`cf-turnstile-response` hidden
input, no form). A normal **headed** Chromium passed the check without
interaction. Hence `bggpipe upload` runs headed by default; `--headless`
exists but expect login to fail there. A first login in headed mode may
still need one human click on the challenge widget; the session then
persists via `storage_state.json` (gitignored).
- **BGG pages never reach Playwright's `networkidle`** — ad/analytics
requests poll forever. Navigate with `wait_until="domcontentloaded"` and
rely on element-level auto-waiting.
- Verified form selectors at `/login`: `#inputUsername` (name=`username`,
formcontrolname=`username`), `#inputPassword`, and a button with
accessible name **"Sign In"** (`type="button"` — Angular handles submit,
so click the button rather than pressing Enter and hoping for a form
submit). Labels "Username"/"Password" point at those ids. Cookie-consent
checkboxes (Essential, Performance Analytics, ...) render on the same
page but did not overlay the form in the probe.
- Logged-in detection heuristic (unverified): the header shows a "Sign In"
link only when logged out.