ci(web-e2e): run against a local API + Neon proxy instead of the deployed API#2541
Conversation
…oyed API Web E2E has been failing on development for days: globalSetup signs in via a cross-origin fetch to the *deployed* API (EXPO_PUBLIC_API_URL), which returns 'Failed to fetch' (status 0) through all 8 retries — the deployed dev API is 5xx-ing / unreachable from CI. The code comment already assumed 'a local wrangler dev worker', but the workflow never stood one up. This wires the workflow to the local stack that already exists for local dev (docker-compose.test.yml + maybeConfigureLocalNeon + .dev.vars.e2e.example): - start Postgres + the Neon HTTP/WS proxy (:4444) via docker-compose.test.yml - migrate + seed the e2e user into the local DB (raw pg on :5433) - boot the API via 'wrangler dev' on :8787 with a generated .dev.vars (real URLs + dummy-but-schema-valid stand-ins for AI/email/storage keys) - build the web app against http://localhost:8787 and serve it on :8081 - point Playwright (API_URL/BASE_URL) at the local stack CORS already allows localhost, so sign-in works against the local worker with no dependency on deployed-API health or cross-origin config. NOTE: first CI iteration — the open question is whether 'wrangler dev' boots cleanly given the container-backed AppContainer Durable Object (image: ./Dockerfile); logs are captured (Dump API log on failure) to debug. May also need E2E_BETTER_AUTH_SECRET / E2E_JWT_SECRET repo secrets (falls back to placeholders).
|
Warning Review limit reached
More reviews will be available in 17 minutes and 46 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Switches the Web E2E workflow from hitting the deployed dev API (which has been failing for days with Failed to fetch) to a fully local stack: a Dockerized Postgres + Neon HTTP/WS proxy, a wrangler dev worker, and the web SPA — all on localhost. This eliminates the cross-origin/deployed‑API dependency that was breaking globalSetup's sign‑in.
Changes:
- Adds
packages/api/**to the workflow's path filters and triggers. - Stands up Postgres + Neon proxy via
docker-compose.test.yml, runs migrate + seed against raw Postgres on:5433, and writes a synthesized.dev.vars(real DB/auth URLs, placeholder values for AI/email/storage keys) so the worker can boot. - Boots
wrangler devon:8787, retargets the Expo build, the served SPA, and Playwright (API_URL/BASE_URL) at localhost; drops theNEON_DEV_DATABASE_URL/EXPO_PUBLIC_API_URLsecret dependency and dumps wrangler logs on failure.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| RESEND_API_KEY=e2e-resend-key | ||
| EMAIL_FROM=no-reply@packrattest.local | ||
| OPENAI_API_KEY=sk-e2e-placeholder | ||
| GOOGLE_GENERATIVE_AI_API_KEY=e2e-google-ai | ||
| PERPLEXITY_API_KEY=pplx-e2e-placeholder | ||
| OPENWEATHER_KEY=e2e-openweather | ||
| WEATHER_API_KEY=e2e-weather |
First CI run got the full stack up (Postgres + Neon proxy + worker env all loaded) but wrangler dev failed: the Workers AI binding runs in 'remote' mode (no local emulator), so wrangler opened a remote-proxy session requiring CF login. Sign-in never uses AI, and env-validation's AI: z.unknown() tolerates it absent, so generate an AI-stripped wrangler.e2e.json for the run → no remote bindings → boots fully local, no CF auth needed. (The container-backed AppContainer DO booted fine — wrangler only lists it, doesn't build at startup.)
Iteration 2 reached the actual sign-in: the local worker booted and responded, but POST /api/auth/sign-in/email 500'd because the per-request getEnv() validation found EMAIL_PROVIDER and AI_PROVIDER missing (required enums). Both are in .dev.vars.e2e.example; they were omitted from the generated vars. Added EMAIL_PROVIDER=resend and AI_PROVIDER=openai.
Iter 3 got past env-validation; sign-in now 403'd with 'Invalid origin: http://localhost:8081'. Elysia CORS allows localhost (OPTIONS 204), but Better Auth has its own trustedOrigins check that only adds 'http://localhost:*' when env.ENVIRONMENT === 'development' (auth/index.ts:207) — and the workflow never set ENVIRONMENT. Add ENVIRONMENT=development to .dev.vars. (The Apple client-secret pkcs8 warning from the dummy key is harmless — web OAuth only.)
…ey fix) The previous workflow pointed playwright at the deployed API ($EXPO_PUBLIC_API_URL) but this branch's e2e changes assume a fully local stack — Docker Postgres + Neon HTTP proxy + wrangler dev — with localhost-trusted origins, ENVIRONMENT=development gating, etc. Adopt the workflow from PR #2541 (fix/web-e2e-local-api), which: - boots a local Neon proxy + Postgres via docker compose - writes a CI-only .dev.vars with valid placeholder schema entries - generates a no-AI-binding wrangler.e2e.json so wrangler dev doesn't need a CF login for the binding - runs wrangler dev locally, serves the exported web SPA on :8081 - drives playwright against that fully-local stack Re-apply the cache-key fix from c760b79 on top: hash workspace package.json files too and drop the wildcard restore-keys so the @babel/helper-compilation-targets nested lru-cache@5 doesn't disappear between bun.lock-equivalent updates. This file overlaps with PR #2541; the divergence is just the cache key hardening. Whichever lands second can keep that delta in a follow-up.
Problem
Web E2E has been failing on
developmentfor days (5+ consecutive runs).globalSetup.tssigns in via a cross-origin browser fetch to the deployed API (EXPO_PUBLIC_API_URL), which returnsFailed to fetch(status0) through all 8 retries — the deployed dev API is 5xx-ing / unreachable from CI. The code comment already assumed "a local wrangler dev worker talking to a raw Postgres," but the workflow never stood one up — it pointed at the deployed API instead.CORS is not the issue (
/^http:\/\/localhost:\d+$/is already in the API's allowlist). And driving the login UI wouldn't help — the app's client resolves to the sameEXPO_PUBLIC_API_URL(getBaseUrl.ts), so it'd make the identical failing request.Fix
Wire the workflow to the local stack that already exists for local dev (
docker-compose.test.yml,maybeConfigureLocalNeoninpackages/api/src/index.ts,.dev.vars.e2e.example) — it was used on developer machines (hit "9/14 passing" per the solution doc) but never in CI::4444) viadocker-compose.test.yml.:5433; the worker usesdb.localtest.me→ proxy:4444).wrangler devon:8787, with a generated.dev.vars(real URLs + dummy-but-schema-valid stand-ins for the ~25 keysenv-validation.tsrequires; sign-in only needs the DB + Better Auth).http://localhost:8787and serve on:8081.API_URL/BASE_URL) at the local stack.Now sign-in runs against a local worker + local DB — no dependency on deployed-API health or cross-origin config, using the same
@neondatabase/serverlessdriver path as production.I can't exercise this locally (Docker + secrets), so it's push-and-watch. Known open questions the first runs will answer:
wrangler devboot cleanly given the container-backedAppContainerDurable Object (image: ./Dockerfile)? If it tries to build that container at boot, the step may need a tweak. Logs are captured (Dump API log on failure).E2E_BETTER_AUTH_SECRET/E2E_JWT_SECRET(falls back to placeholders).db.localtest.meDNS resolution + migrate/seed connectivity in CI.Note
The
checksjob on this PR will show a pre-existing@packrat-ai/nativewinduiversion mismatch ondevelopment(packages/ui^2.0.6vsapps/expo2.0.3-2) — not introduced here; it's resolved by the dependency-policy PR (#2531).