You cannot read the inbox in a test, so generate the link with the admin API and visit it. This catches the broken callback route, which is the failure people actually ship. Run it against a preview deployment, not production.
// tests/login.spec.ts import { test, expect } from "@playwright/test"; import { createClient } from "@supabase/supabase-js"; const admin = createClient( process.env.SUPABASE_URL!, process.env.SUPABASE_SERVICE_ROLE_KEY! ); test("magic link signs the user in", async ({ page }) => { const email = `test+${Date.now()}@example.com`; const { data, error } = await admin.auth.admin.generateLink({ type: "magiclink", email, }); expect(error).toBeNull(); await page.goto(data!.properties!.action_link); await expect(page.getByRole("link", { name: "Profile" })).toBeVisible(); });