import fs from "node:fs"; import path from "node:path"; import { test, expect } from "@playwright/test"; import { FIXTURE_SUMMARY_NAME } from "./fixture-summary"; // A source-only build has no summary, and both pages must say so rather than // draw zeroes. The e2e server always has the synthetic summary // (fixture-summary.ts), so this file moves it aside, reads `/` and `/stats/`, // and puts it back — `next dev` reads the file on every request (app/lib/ // summary.ts), and the suite runs one test at a time (`workers: 1`). The copy // goes to a gitignored name beside it (`.e2e-summary.json*`), and it is // restored however the test ends; playwright.config.ts also rewrites the file // whenever a worker starts. test.describe.configure({ mode: "serial" }); test("with no summary, / and /stats/ render no numbers and say why", async ({ page }) => { // `mode: "serial"` orders this file's tests, not the files: under // `--workers=N` (N > 1) the other specs run beside this one and read the // same summary file while it is moved aside, so they would draw the empty // state and fail. Only a one-worker run (the config's own) can check it. const workers = test.info().config.workers; test.skip( workers > 1, `no-data moves the shared e2e summary aside, which races the other specs when workers > 1 (this run: ${workers})`, ); const file = path.resolve(test.info().project.testDir, FIXTURE_SUMMARY_NAME); const aside = `${file}.aside`; fs.renameSync(file, aside); try { await page.goto("/"); // The claim without a count, the ways in, and none of the numbers. await expect(page.getByRole("heading", { level: 1 })).toHaveText( "Every word a channel said, searchable to the second.", ); await expect(page.getByRole("link", { name: /download the source/i })).toBeVisible(); await expect(page.getByRole("img", { name: /transcripts by the month/i })).toHaveCount(0); await expect( page.getByRole("heading", { level: 2, name: "Official Instances", exact: true }), ).toHaveCount(0); await expect(page.locator("time[datetime]")).toHaveCount(0); await page.goto("/stats/"); await expect(page.getByText("This build shipped without dashboard data")).toBeVisible(); await expect(page.locator(".recharts-surface")).toHaveCount(0); } finally { fs.renameSync(aside, file); } // Back: the next request draws the fixture's numbers again. await page.goto("/stats/"); await expect(page.locator(".recharts-surface").first()).toBeVisible(); });