import { execFile as execFileCallback, spawn } from "node:child_process"; import { readFileSync } from "node:fs"; import { promisify } from "node:util"; import { expect, test } from "@playwright/test"; import { E2E_CONTEXT_PATH_ENV, type PersistedE2eContext } from "../global-setup"; import { getFreePort, seedInvite, stopDevServer } from "../harness"; const execFile = promisify(execFileCallback); test("runs the OIDC and browser consent simulators against isolated local D1", async ({ page }) => { const contextPath = process.env[E2E_CONTEXT_PATH_ENV]; if (!contextPath) throw new Error("Missing isolated e2e context"); const context = JSON.parse(readFileSync(contextPath, "utf8")) as PersistedE2eContext; const invite = await seedInvite(context.tempDir, "oidc-e2e@example.com"); const accepted = await page.request.post(`${context.baseUrl}/api/invite/${invite.token}`, { headers: { origin: context.baseUrl }, data: { name: "OIDC E2E", password: invite.password, turnstileToken: "loopback" }, }); expect(accepted.ok()).toBe(true); // Promote only this fixture in the test runner's temporary local database. await execFile("npx", [ "--no-install", "wrangler", "d1", "execute", "tessera-prod", "--local", "--persist-to", context.tempDir, "--command", "UPDATE users SET role = 'admin' WHERE email = 'oidc-e2e@example.com'", ]); const clientRun = await execFile("npm", ["run", "test:client"], { env: { ...process.env, ISSUER: context.baseUrl, TEST_EMAIL: invite.email, TEST_PASSWORD: invite.password }, }); expect(clientRun.stdout).toContain("OIDC roundtrip succeeded"); const port = await getFreePort(); const harnessUrl = `http://127.0.0.1:${port}`; const created = await page.request.post(`${context.baseUrl}/api/admin/clients`, { headers: { origin: context.baseUrl }, data: { name: "consent e2e", redirectUris: [`${harnessUrl}/cb`] }, }); expect(created.status()).toBe(201); const client = (await created.json()) as { client_id: string; client_secret: string }; const server = spawn("npm", ["run", "test:consent"], { env: { ...process.env, ISSUER: context.baseUrl, PORT: String(port), CLIENT_ID: client.client_id, CLIENT_SECRET: client.client_secret, }, stdio: "ignore", detached: process.platform !== "win32", }); try { await expect .poll( async () => { try { return (await fetch(harnessUrl)).status; } catch { return 0; } }, { timeout: 15_000 }, ) .toBe(200); await page.goto(harnessUrl); await page.getByRole("link", { name: "Start /authorize →" }).click(); await expect(page.getByRole("heading", { name: "Authorize access" })).toBeVisible(); await page.getByRole("button", { name: "Authorize", exact: true }).click(); await expect(page.getByRole("heading", { name: "Last result ✓ ok" })).toBeVisible(); } finally { await stopDevServer(server); } });