import { request, type APIRequestContext } from '@playwright/test'; import { promises as fs } from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const API_BASE = process.env.E2E_API_BASE ?? 'http://127.0.0.1:18080'; const STATE_PATH = path.join(__dirname, '..', '.auth', 'admin.json'); interface StoredState { origins: Array<{ origin: string; localStorage: Array<{ name: string; value: string }>; }>; } let cachedToken: string | null = null; async function readAdminToken(): Promise { if (cachedToken) return cachedToken; const raw = await fs.readFile(STATE_PATH, 'utf8'); const state = JSON.parse(raw) as StoredState; for (const origin of state.origins) { const entry = origin.localStorage.find((e) => e.name === 'picloud.admin.token'); if (entry) { cachedToken = entry.value; return entry.value; } } throw new Error(`No picloud.admin.token in ${STATE_PATH} — did globalSetup run?`); } // Thin wrapper around Playwright's request context that injects the // admin bearer token from the shared storageState. Use this for // setup/teardown shortcuts when the *test itself* is about something // else (e.g., a script-editor test that just needs an app to exist). export async function adminApi(): Promise { const token = await readAdminToken(); return request.newContext({ baseURL: API_BASE, extraHTTPHeaders: { authorization: `Bearer ${token}`, 'content-type': 'application/json' } }); }