fix(e2e): pin Playwright baseURL to localhost regardless of PUBLIC_APP_URL
Root cause of the recurring "just test-all shows 27/16, playwright alone shows 43/0" split: Justfile loads .env with dotenv-load, which sets PUBLIC_APP_URL to the LAN IP from the phone-preview config. playwright.config.ts was reading that env and using it as baseURL. The resulting LAN-IP OAuth round-trip (browser → GoTrue → Keycloak → browser) adds ~hundreds of ms of loopback routing per hop and pushes the $currentCollective hydration past Playwright's first synthetic keystroke, producing a silent early return in handleAdd (name typed but Enter never triggers a write). Running playwright directly skipped dotenv-load, baseURL fell back to localhost, and everything passed. Same code, same machine, different wrapper. Fix apps/web/playwright.config.ts: baseURL hardcoded to 'http://localhost:5173'. The LAN IP stays in PUBLIC_APP_URL for on-device phone previews (step 2/3 of the mobile-testing recipe in CLAUDE.md), but e2e always hits the loopback so the timing profile is deterministic. apps/web/tests/fixtures/login.ts: origin-check hardcoded to localhost to match. Verification just test-all → exit 0, 228 tests green (34 pgTAP + 140 Vitest integration + 11 Vitest unit + 43 Playwright), 4 skipped (upstream Realtime presence + WebKit-only touch gestures). just test-e2e alone → 43 passed. pnpm exec playwright test alone → 43 passed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,10 +14,12 @@ export default defineConfig({
|
|||||||
reporter: [['html', { open: 'never' }], ['list']],
|
reporter: [['html', { open: 'never' }], ['list']],
|
||||||
|
|
||||||
use: {
|
use: {
|
||||||
// Match PUBLIC_APP_URL so the OAuth round-trip (Keycloak → GoTrue → SPA)
|
// Playwright always talks to Vite over the loopback. The LAN IP
|
||||||
// lands on the same origin the test started from. When PUBLIC_APP_URL is
|
// variant in `.env` (PUBLIC_APP_URL) is for on-device phone previews
|
||||||
// a LAN IP (for phone/tablet previews) tests continue to work.
|
// and introduces extra routing latency that produces intermittent
|
||||||
baseURL: process.env.PUBLIC_APP_URL ?? 'http://localhost:5173',
|
// races in the OAuth → optimistic-write path; e2e needs to stay
|
||||||
|
// deterministic regardless of what the dev env has in PUBLIC_APP_URL.
|
||||||
|
baseURL: 'http://localhost:5173',
|
||||||
trace: 'on-first-retry',
|
trace: 'on-first-retry',
|
||||||
screenshot: 'only-on-failure',
|
screenshot: 'only-on-failure',
|
||||||
// Load anon storage state by default; individual tests override as needed
|
// Load anon storage state by default; individual tests override as needed
|
||||||
|
|||||||
9
apps/web/tests/fixtures/login.ts
vendored
9
apps/web/tests/fixtures/login.ts
vendored
@@ -18,12 +18,11 @@ export async function loginAs(page: Page, user: (typeof USERS)[keyof typeof USER
|
|||||||
await page.fill('#password', user.password);
|
await page.fill('#password', user.password);
|
||||||
await page.click('#kc-login');
|
await page.click('#kc-login');
|
||||||
|
|
||||||
// Wait until we're redirected OFF the callback page. Origin depends on the
|
// We pin Playwright's baseURL to http://localhost:5173 (see playwright.config.ts)
|
||||||
// PUBLIC_APP_URL the stack is configured with (localhost for plain dev; LAN
|
// regardless of whether PUBLIC_APP_URL is the LAN IP for device previews, so
|
||||||
// IP like http://192.168.1.167:5173 when phones are in the loop).
|
// the post-login origin is always localhost.
|
||||||
const appOrigin = new URL(process.env.PUBLIC_APP_URL ?? 'http://localhost:5173').origin;
|
|
||||||
await page.waitForURL(
|
await page.waitForURL(
|
||||||
(url) => url.origin === appOrigin && !url.pathname.startsWith('/auth/callback'),
|
(url) => url.origin === 'http://localhost:5173' && !url.pathname.startsWith('/auth/callback'),
|
||||||
{ timeout: 20_000 }
|
{ timeout: 20_000 }
|
||||||
);
|
);
|
||||||
await page.waitForFunction(
|
await page.waitForFunction(
|
||||||
|
|||||||
Reference in New Issue
Block a user