fix(e2e): exempt loopback from ambient HTTP proxy so pnpm e2e:web boots locally#116
Conversation
…rver probe When `pnpm e2e:web` runs inside an ambient HTTP-proxy environment (e.g. a network sandbox that injects HTTP_PROXY/http_proxy), Playwright's webServer readiness probe resolves its target through `proxy-from-env`, so the `http://127.0.0.1:4991` probe was routed through the proxy, which answered 405. 405 is >= 400, so the waiter never saw the dev server's real 200 and timed out at 120s — the server itself was healthy the whole time. Fix: exempt loopback (localhost,127.0.0.1,::1) from NO_PROXY before Playwright reads the env, so the probe connects straight to `next`. External hosts (Clerk, corelive.app) stay proxied, so any firewall is still enforced for real outbound traffic. Strict no-op where no proxy is set (e.g. CI) — `getProxyForUrl` already returns "" there regardless. Also pin the probe to the 127.0.0.1 IP literal (unambiguous IPv4, matches the host CI listens on); the NO_PROXY exemption is what actually unblocks it. Verified: `pnpm e2e:web e2e/web/category.spec.ts` -> 21 passed under the sandbox (previously a 120s webServer timeout). Closes #115
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough
ChangesPlaywright loopback proxy exemption and probe URL fix
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #116 +/- ##
=======================================
Coverage 67.18% 67.18%
=======================================
Files 138 138
Lines 4376 4376
Branches 1197 1197
=======================================
Hits 2940 2940
Misses 1218 1218
Partials 218 218 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Summary
pnpm e2e:webcould not boot locally on macOS — Playwright'swebServerreadinessprobe timed out at 120s before
next startwas ever reached, so no web E2E speccould run on this machine. This exempts loopback from any ambient HTTP proxy before
Playwright reads the environment, so the probe connects straight to
next.Closes #115.
Root cause (corrected)
The earlier hypothesis in the issue (IPv4/IPv6 loopback / happy-eyeballs mismatch)
was falsified: pinning the probe to the
127.0.0.1literal still timed out, whilecurl/bare-Node got200on the same URL.The real cause is the Bash-tool network sandbox (Socket Firewall /
sfw): itinjects
HTTP_PROXY/http_proxy=http://127.0.0.1:<dynamic-port>into every childprocess to police outbound traffic. Playwright's webServer waiter resolves its target
through
proxy-from-env(getProxyForUrl), which honors those vars — so thehttp://127.0.0.1:4991probe was routed through the firewall proxy, which answered405 (observed before
nexthad even started — only a proxy can405a portwith no upstream).
405 >= 400, so the waiter never saw the dev server's real200and timed out.
curl/bare-Node bypass the proxy, which is why they returned200andmade the hostname theories look plausible.
Fix
playwright.config.ts, top-level (runs beforedefineConfigreads env):NO_PROXY/no_proxysogetProxyForUrlreturns""for theprobe URL and the waiter connects directly to
next.NO_PROXY(Clerk, corelive.app) — they remainproxied, so the firewall is still enforced for real outbound traffic.
[::1], not bare::1):proxy-from-envmatchesNO_PROXYentries against the URL host verbatim and a URL host keeps its brackets,so a bare
::1entry would never match a[::1]probe.urlstays pinned to the127.0.0.1literal (unambiguous IPv4, matchesthe host CI listens on);
use.baseURLstayslocalhost(drives Chromium; Clerk devkeys are localhost-scoped) — unchanged.
Verification
pnpm e2e:web e2e/web/category.spec.tsunder the live sandbox → 21 passed (3.8m);DEBUG=pw:webservershowsECONNREFUSED → start → HTTP 200 → WebServer available(no 405, no timeout).
mise exec node@24.13.0 -- pnpm test→ 662 passed / 33 skipped, exit 0.getProxyForUrlalready returns""for loopback regardless — the appendedNO_PROXYchanges nothing there.Acceptance criteria (#115)
pnpm e2e:webboots locally on macOS (21-pass proof above)playwright.config.ts)Summary by CodeRabbit