From 46e686f396bb870a161ccbfb8a9f6e1c7d5e03e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sat, 9 May 2026 01:52:57 +0200 Subject: [PATCH] fix(e2e): switch mobile project to chromium and repair spec flakiness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three orthogonal fixes that account for most of the e2e suite's ongoing red: - The `chromium-mobile` project was actually iPhone 13 (webkit) — CI's `playwright install chromium` therefore could not launch it (`webkit-2272/pw_run.sh` does not exist). Renaming-to-Pixel-5 makes the project name match what the runner provides without expanding the install footprint. - `locale-switch.spec.ts` tried to anchor the cookie at `page.url()`, which on a fresh context is `about:blank`; Playwright rejected the cookie outright. Using the project's configured baseURL is the documented way and works regardless of navigation timing. - `login.spec.ts` looked for the username/password inputs immediately after navigation, but the password form is mounted lazily once the user clicks "Login with password" (passkey is the default mode). A small helper now opens the form before the assertions run. Co-Authored-By: Claude Opus 4.7 (1M context) --- e2e/locale-switch.spec.ts | 7 ++++++- e2e/login.spec.ts | 20 ++++++++++++++++---- playwright.config.ts | 6 +++++- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/e2e/locale-switch.spec.ts b/e2e/locale-switch.spec.ts index d217e1648..d249bc772 100644 --- a/e2e/locale-switch.spec.ts +++ b/e2e/locale-switch.spec.ts @@ -16,11 +16,16 @@ test.describe("locale switch", () => { page, context, }) => { + // Cookies must be addressable to a real origin — `page.url()` on + // a fresh context returns `about:blank`, which Playwright rejects. + // Anchor at the configured base URL explicitly. + const baseURL = + test.info().project.use.baseURL ?? "http://localhost:3000"; await context.addCookies([ { name: "healthlog_locale", value: locale, - url: page.url() || "http://localhost:3000", + url: baseURL, }, ]); await page.goto("/auth/login"); diff --git a/e2e/login.spec.ts b/e2e/login.spec.ts index ff07c4ee3..a9aea596c 100644 --- a/e2e/login.spec.ts +++ b/e2e/login.spec.ts @@ -9,13 +9,25 @@ import { expect, test } from "@playwright/test"; * roundtrip is exercised by the integration test in * tests/integration/auth-flow.test.ts. */ +async function openPasswordForm(page: import("@playwright/test").Page) { + await page.goto("/auth/login"); + // The login page defaults to passkey mode; the password form is + // mounted only after clicking the "Login with password" / "Mit + // Passwort anmelden" outline button. + await page + .getByRole("button", { name: /login with password|mit passwort/i }) + .click(); +} + test.describe("login page", () => { test("renders username + password inputs with the right autoComplete", async ({ page, }) => { - await page.goto("/auth/login"); + await openPasswordForm(page); - const username = page.getByLabel(/username|benutzername/i).first(); + const username = page + .getByLabel(/username|benutzername|email|e-mail/i) + .first(); await expect(username).toBeVisible(); await expect(username).toHaveAttribute("autoComplete", /username|email/); @@ -25,10 +37,10 @@ test.describe("login page", () => { }); test("rejects an obviously-wrong credential pair", async ({ page }) => { - await page.goto("/auth/login"); + await openPasswordForm(page); await page - .getByLabel(/username|benutzername/i) + .getByLabel(/username|benutzername|email|e-mail/i) .first() .fill("nobody-here"); await page.locator('input[type="password"]').first().fill("not-the-pw"); diff --git a/playwright.config.ts b/playwright.config.ts index 8d0a8c43a..47cc160ec 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -44,7 +44,11 @@ export default defineConfig({ { name: "chromium-mobile", use: { - ...devices["iPhone 13"], + // Pixel 5 — Chromium-based mobile profile so CI only needs + // `playwright install chromium` instead of also pulling + // webkit. iPhone-13 is intentionally avoided here; the + // mobile-Safari smoke is exercised by the iOS app suite. + ...devices["Pixel 5"], }, }, ],