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"], }, }, ],