CLAUDE.md@.claude/packages/test-google-login · git:20260912.8721dbb · 2026-09-12 · sha256 0bcb014dad28f555
CLAUDE.md@.claude/packages/test-google-login git:20260912.8721dbbA
Immutable. This exact content is served forever at /api/v1/blob/0bcb014dad28f555.
# CLAUDE.md — `test-google-login` **skill:** [`skills/test-google-login`](../../../skills/test-google-login/SKILL.md) · **runner:** Vitest · **build:** Vite, two entries (`dist/index.js`, `dist/worker.js`) Captures a Google sign-in once as a Playwright `storageState`, then reuses it — in the local suite, in CI, and from a Cloudflare Browser Rendering Durable Object. ## Rules - **The state file is the credential, not the password.** `playwright/.auth/*.json` holds live cookies and tokens. Nothing here may log a value, return one over HTTP, write one world-readable, or commit one. Writes are `0600` and the directory is `0700` — do not relax either to make something convenient. - **There is no route and no function that returns a live state over the wire.** The Worker's `GET /state` returns `redactStorageState()` output on purpose. Adding a "just for debugging" raw route turns this into a credential exfiltration endpoint with a test-shaped name. - **Real Google sign-in stays opt-in and off by default.** Two gates: `TEST_GOOGLE_LOGIN_ALLOW_REAL` plus credentials on the Playwright side, `ALLOW_REAL_GOOGLE_LOGIN === "true"` plus credentials in the Worker. Never default either on, and never add a path around MFA, CAPTCHA or a device check. - **`src/state-core.ts` must not import a Node builtin.** It is the half the Worker bundle pulls in; one `node:fs` there and the deploy fails rather than a test. `storage-state.ts` is the filesystem layer and re-exports it, so Node callers still see one surface. `grep -n "node:" dist/worker.js` must print nothing after a build. - **No runtime dependencies.** Playwright and `@cloudflare/puppeteer` are optional peers; every function takes the `page` / `context` / `request` it needs as an argument. That is also what lets the suite run with no browser — keep it that way rather than importing either at module scope. - **The three format differences between Playwright and CDP are load-bearing** (session-cookie `expires`, `sameSite` casing, `localStorage` needing a document). Each has a test naming the failure it prevents; if you touch `puppeteer-state.ts`, those tests are the specification. - The negative assertions in the suite — "this string does not appear in the output" — are the point of several tests. Do not weaken one to accommodate a new field. ```bash cd packages/test-google-login && bun run test && bun run typecheck && bun run build ```