import assert from "node:assert/strict"; import { chromium } from "playwright-core"; const username = process.env.E2E_USERNAME ?? "regular-user"; const password = process.env.E2E_PASSWORD; assert.ok(password, "E2E_PASSWORD must be set"); const browser = await chromium.launch({ executablePath: process.env.CHROME_BIN ?? "/usr/bin/google-chrome", headless: true, args: ["--no-sandbox"], }); try { const context = await browser.newContext(); const page = await context.newPage(); let authorizationUrl; page.on("request", (request) => { if (request.url().includes("/protocol/openid-connect/auth")) { authorizationUrl = new URL(request.url()); } }); await page.goto("http://localhost:8088"); await page.locator("#login").click(); await page.waitForURL(/localhost:8080/u); await page.locator("#username").fill(username); await page.locator("#password").fill(password); await page.locator("#kc-login").click(); await page.waitForURL("http://localhost:8088/"); await page.locator('[data-authenticated="true"]').waitFor(); assert.equal(authorizationUrl?.searchParams.get("response_type"), "code"); assert.equal(authorizationUrl?.searchParams.get("code_challenge_method"), "S256"); assert.ok(authorizationUrl?.searchParams.get("code_challenge")); const accessToken = await page.evaluate(() => window.__pattern1.getAccessToken()); assert.ok(accessToken, "access token must exist in browser memory"); const storageSnapshot = await page.evaluate(() => ({ localStorage: Object.values(localStorage), sessionStorage: Object.values(sessionStorage), })); assert.equal( JSON.stringify(storageSnapshot).includes(accessToken), false, "access token must not be persisted in Web Storage", ); await page.locator("#call-api").click(); await page.waitForFunction(() => { const text = document.querySelector("#result")?.textContent ?? ""; return text.includes('"httpStatus": 200'); }); await page.reload(); await page.locator('[data-authenticated="false"]').waitFor(); assert.equal( await page.evaluate(() => window.__pattern1.getAccessToken()), null, "reload must clear the memory-only token", ); console.log( "pattern1 browser verified: code+PKCE S256, protected API 200, Web Storage token 0, reload clears token", ); } finally { await browser.close(); }