import type { Browser, Page } from "@playwright/test" /** * Talking to the API directly, for the setup and teardown around a spec. * * The specs run against a development stack, so whatever they create has to go * again — the same bargain the backend suite strikes with its throwaway * database. What a spec leaves behind is in someone's flow list tomorrow. */ import { apiUrl } from "../config.ts" const authFile = "playwright/.auth/user.json" /** Call the API as the logged-in user of *page*. */ export async function api( page: Page, path: string, init: Record = {}, ) { const token = await page.evaluate(() => localStorage.getItem("access_token")) return page.request.fetch(`${apiUrl}/api/v1${path}`, { ...init, headers: { Authorization: `Bearer ${token}` }, }) } /** An authenticated page for a `beforeAll`/`afterAll`, which get no `page`. */ export async function apiPage(browser: Browser) { const page = await browser.newPage({ storageState: authFile }) await page.goto("/") return page } /** Delete the given API paths, whether or not they are still there. */ export async function deleteAll(browser: Browser, paths: string[]) { const page = await apiPage(browser) for (const path of paths) { await api(page, path, { method: "DELETE" }) } await page.close() }