diff --git a/apps/web/playwright.config.ts b/apps/web/playwright.config.ts index 33372eb..b7a7191 100644 --- a/apps/web/playwright.config.ts +++ b/apps/web/playwright.config.ts @@ -14,10 +14,12 @@ export default defineConfig({ reporter: [['html', { open: 'never' }], ['list']], use: { - // Match PUBLIC_APP_URL so the OAuth round-trip (Keycloak → GoTrue → SPA) - // lands on the same origin the test started from. When PUBLIC_APP_URL is - // a LAN IP (for phone/tablet previews) tests continue to work. - baseURL: process.env.PUBLIC_APP_URL ?? 'http://localhost:5173', + // Playwright always talks to Vite over the loopback. The LAN IP + // variant in `.env` (PUBLIC_APP_URL) is for on-device phone previews + // and introduces extra routing latency that produces intermittent + // 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', screenshot: 'only-on-failure', // Load anon storage state by default; individual tests override as needed diff --git a/apps/web/tests/fixtures/login.ts b/apps/web/tests/fixtures/login.ts index c971185..ecf812d 100644 --- a/apps/web/tests/fixtures/login.ts +++ b/apps/web/tests/fixtures/login.ts @@ -18,12 +18,11 @@ export async function loginAs(page: Page, user: (typeof USERS)[keyof typeof USER await page.fill('#password', user.password); await page.click('#kc-login'); - // Wait until we're redirected OFF the callback page. Origin depends on the - // PUBLIC_APP_URL the stack is configured with (localhost for plain dev; LAN - // IP like http://192.168.1.167:5173 when phones are in the loop). - const appOrigin = new URL(process.env.PUBLIC_APP_URL ?? 'http://localhost:5173').origin; + // We pin Playwright's baseURL to http://localhost:5173 (see playwright.config.ts) + // regardless of whether PUBLIC_APP_URL is the LAN IP for device previews, so + // the post-login origin is always localhost. 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 } ); await page.waitForFunction(