1
0
Fork 0
polaris-task-force/tests/e2e/banner_check.spec.mjs
Z8MB1E d16e721ccc test(e2e): seed e2e user, serialize workers, and deflake specs
The suite could not pass on the test database: global setup now seeds the shared dev/Test123 login with a superuser Roles doc and the dashboard rank, and points its own Payload connection at the test database. Playwright runs one worker with generous test and expect timeouts because first navigation to a route triggers a cold webpack compile, and gains E2E_BROWSER_PATH to swap the browser binary when the installed Vivaldi crashes under automation. The landing page gains the missing h1 the guest specs assert, login flows wait for the redirect to land, strict-mode locator collisions get exact or level-scoped matches, the session banner test re-signs the login claims with a short expiry using the runtime secret, and the reservation dialog click forces the dispatch and verifies the dialog opened (the trigger goes aria-hidden behind the modal mid-click, which stranded the retry loop).
2026-09-30 18:43:29 -04:00

58 lines
2.1 KiB
JavaScript

import { test, expect } from "@playwright/test";
test("banner shows countdown + extend button", async ({ page, context }) => {
// Craft near-expiry token and set it as cookie
const { SignJWT } = await import("jose");
// IMPORTANT: this must be the RUNTIME payload secret, not .env's
// PAYLOAD_SECRET. A previous session confirmed the Payload AI plugin
// rewrites the secret at runtime; the value below is stable for this repo
// (verified empirically by signing a login token and verifying it).
const SECRET = "f80003be79c28ca283c2cbfde2984356";
const key = new TextEncoder().encode(SECRET);
// Login to get a real session, then re-sign the EXACT same claims with a
// short exp (echoing all claims keeps Payload's token verification happy).
const loginRes = await fetch("http://localhost:3000/api/users/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username: "dev", password: "Test123" }),
});
const data = await loginRes.json();
const claims = JSON.parse(Buffer.from(data.token.split(".")[1], "base64url").toString());
const now = Math.floor(Date.now() / 1000);
const near = await new SignJWT({ ...claims, iat: now, exp: now + 600 })
.setProtectedHeader({ alg: "HS256", typ: "JWT" })
.setIssuedAt(now)
.setExpirationTime(now + 600)
.sign(key);
// Set cookie
await context.addCookies([
{
name: "payload-token",
value: near,
domain: "localhost",
path: "/",
expires: now + 600,
},
]);
// Navigate to home
await page.goto("http://localhost:3000/");
await page.waitForSelector("role=status", { timeout: 10000 });
// Check banner is visible
const banner = page.locator("role=status").first();
await expect(banner).toBeVisible();
// Check countdown
const countdown = banner.locator(".font-mono.tabular-nums").first();
await expect(countdown).toHaveText(/0\d:\d{2}/); // should show ~10:00
// Check extend button
const extendBtn = banner.locator("button:has-text('Extend')");
await expect(extendBtn).toBeVisible();
console.log("Banner check PASSED");
});