Next.js & Web
Use when adding end-to-end coverage to a Next.js app with Playwright, especially a route smoke suite proving every public page renders. Covers config, a data-driven route check, auth-gated routes, and keeping the suite deterministic with real waits instead of sleeps. Also use when a suite is flaky, or a page 500s in production that no test covered. If a route can break without a test noticing, use this skill.
1 file
Description
Use when adding end-to-end coverage to a Next.js app with Playwright, especially a route smoke suite proving every public page renders. Covers config, a data-driven route check, auth-gated routes, and keeping the suite deterministic with real waits instead of sleeps. Also use when a suite is flaky, or a page 500s in production that no test covered. If a route can break without a test noticing, use this skill.
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.