diff --git a/surfsense_web/tests/auth.setup.ts b/surfsense_web/tests/auth.setup.ts index a33a81b3c..7c1e37a39 100644 --- a/surfsense_web/tests/auth.setup.ts +++ b/surfsense_web/tests/auth.setup.ts @@ -1,5 +1,6 @@ import path from "node:path"; import { expect, test as setup } from "@playwright/test"; +import { announcements } from "../lib/announcements/announcements-data"; import { acquireTestToken } from "./helpers/api/auth"; /** @@ -7,21 +8,58 @@ import { acquireTestToken } from "./helpers/api/auth"; * e2e user (rate-limit-free /__e2e__/auth/token first, /auth/jwt/login * fallback) and persists it via localStorage so every test in the * chromium project starts already authenticated. + * + * Also pre-seeds the localStorage flags that gate the two new-user UI + * overlays so they never intercept clicks in journeys: + * - `surfsense_announcements_state` — the blocking AnnouncementSpotlight + * dialog (e.g. "Introducing AI Automations") plus its toasts. + * - `surfsense-tour-` — the OnboardingTour spotlight for new users. */ const authFile = path.join(__dirname, "..", "playwright", ".auth", "user.json"); const STORAGE_KEY = "surfsense_bearer_token"; +const ANNOUNCEMENTS_KEY = "surfsense_announcements_state"; + +/** Decode the user id (`sub`) from a JWT without verifying the signature. */ +function decodeUserId(token: string): string | null { + try { + const payload = token.split(".")[1]; + if (!payload) return null; + const json = Buffer.from(payload, "base64").toString("utf8"); + const obj = JSON.parse(json) as { sub?: string }; + return obj.sub ?? null; + } catch { + return null; + } +} setup("authenticate", async ({ page, request }) => { const access_token = await acquireTestToken(request); expect(access_token, "Failed to acquire e2e bearer token").toBeTruthy(); + const userId = decodeUserId(access_token); + // Mark every known announcement read + toasted so spotlight/toast + // announcements never overlay the dashboard during journeys. Sourced + // from the real data file so future announcements are covered too. + const announcementIds = announcements.map((a) => a.id); + const announcementState = { readIds: announcementIds, toastedIds: announcementIds }; + await page.addInitScript( - ({ key, token }) => { + ({ key, token, announcementsKey, state, uid }) => { localStorage.setItem(key, token); + localStorage.setItem(announcementsKey, JSON.stringify(state)); + if (uid) { + localStorage.setItem(`surfsense-tour-${uid}`, "true"); + } }, - { key: STORAGE_KEY, token: access_token } + { + key: STORAGE_KEY, + token: access_token, + announcementsKey: ANNOUNCEMENTS_KEY, + state: announcementState, + uid: userId, + } ); // Use a public page so the init script can write localStorage without