Next.js & Web
Stand up a fast route-coverage suite in Playwright: assert every public page returns 200, gate the CI on it, and keep it deterministic with real waits.
1 file
Description
Stand up a fast route-coverage suite in Playwright: assert every public page returns 200, gate the CI on it, and keep it deterministic with real waits.
Wiring the first Playwright suite, adding a route-coverage gate to CI, or a deploy that shipped a 500 page a unit test never saw.
Before elaborate flow tests, prove every route returns a real page. One data-driven test catches the class of bug where a new page compiles but throws at request time.
import { test, expect } from "@playwright/test";
const PUBLIC_ROUTES = ["/", "/blog", "/library", "/library/skills", "/tools"];
for (const path of PUBLIC_ROUTES) {
test(\`GET \${path} returns 200\`, async ({ request }) => {
const res = await request.get(path);
expect(res.status(), path).toBe(200);
});
}
Generate the route list from the same source the app uses (the content loaders, the tools array) so a new entry is covered automatically instead of by hand.
Point webServer in playwright.config.ts at the app so the suite boots it:
export default defineConfig({
webServer: { command: "pnpm build && pnpm start", url: "http://localhost:3000", reuseExistingServer: !process.env.CI },
use: { baseURL: "http://localhost:3000" },
});
Test against a production build, not pnpm dev. The dev server hides errors (looser types, on-demand compile) that the built app surfaces.
For pages behind auth, either expect the redirect (assert a 3xx to the sign-in URL) or seed a test session. Do not assert 200 on a protected route without a session; that hides a broken gate.
page.waitForTimeout (a fixed sleep) makes the suite flaky and slow. Wait on waitForLoadState or an element instead.webServer command..next. Serialize them.Added 2026-07-01. Back to the Skill Library.

New tutorials, open-source projects, and deep dives on coding agents - delivered weekly.