commit a15453b865e64093008ebdf5eff774268c3a758d
parent 314b4ed2b5a260c58bd884a37b36467f8dffecf8
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Mon, 28 Sep 2026 03:40:33 -0400
homepage(e2e): the no-data / and /stats/ are specced again — one serial spec moves the synthetic summary aside and restores it
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Diffstat:
1 file changed, 43 insertions(+), 0 deletions(-)
diff --git a/homepage/e2e/no-data.spec.ts b/homepage/e2e/no-data.spec.ts
@@ -0,0 +1,43 @@
+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 }) => {
+ 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();
+});