import { test, expect } from "@playwright/test"; import { resetData, generateReport } from "./helpers"; // A TRIPWIRE, not a benchmark. // // These budgets are enormous relative to what the pages cost against the test // corpus (tens of milliseconds) and they run on a shared machine alongside // other work, so they will not catch a 2× slowdown. What they catch is the // specific failure this whole change set was about: a render path quietly // acquiring a full corpus walk again. That turns tens of milliseconds into // seconds, and it is the kind of regression that is invisible in review and // obvious here. // // If one of these fails, the question to ask is "what did this page start // reading?" — not "is the machine busy?". const BUDGET_MS = 3_000; test.describe("perf budget", () => { test.beforeEach(async () => { await resetData("channel-with-counts"); }); test("the dashboard renders within budget", async ({ page }) => { const started = Date.now(); await page.goto("/"); await expect( page.getByRole("heading", { name: "Dashboard", level: 1 }), ).toBeVisible(); const elapsed = Date.now() - started; expect(elapsed, `dashboard took ${elapsed}ms`).toBeLessThan(BUDGET_MS); }); test("the channels page renders within budget", async ({ page }) => { const started = Date.now(); await page.goto("/channels"); await expect( page.getByRole("heading", { name: "Channels", level: 1 }), ).toBeVisible(); const elapsed = Date.now() - started; expect(elapsed, `channels took ${elapsed}ms`).toBeLessThan(BUDGET_MS); }); test("the sidebar's reclaimable-disk badge is not a corpus walk", async ({ page, request, }) => { // This endpoint is the one that used to cost 4.4 s to describe ~98 videos, // on every widget poll. It reads the per-channel snapshots now. await generateReport(page, "counted"); const started = Date.now(); const res = await request.get("/api/widget/cleanable"); const elapsed = Date.now() - started; expect(res.ok()).toBe(true); expect(elapsed, `/api/widget/cleanable took ${elapsed}ms`).toBeLessThan( BUDGET_MS, ); }); });