End-to-end testing for a Next.js app, the way Next.js teams actually do it
Three public Next.js products with real Playwright suites solved the same four problems in nearly the same way: log in over the API, seed users through the ORM, write the session to a file once, and test the preview deployment rather than a local guess. This page is that pattern, with the counts and the vendor documentation behind it.
Suite counts are ours, taken from public default branches on 3 September 2026 by sparse-cloning the test directories read-only and counting with grep. Platform behavior is quoted from Next.js, Playwright and Vercel documentation, read the same day and cited at the bottom. QA Reef is not affiliated with Vercel, Next.js, or the Playwright project.
The framework's own recommendation
Next.js says it plainly in its testing guide: "Since async Server Components are new to the React ecosystem, some tools do not fully support them. In the meantime, we recommend using End-to-End Testing over Unit Testing for async components."
That is a load-bearing sentence for a modern App Router codebase. A large share of a Next.js app is data fetching that resolves on the server, and the cheapest test that proves it works is a browser opening the real route on a real deployment. Which makes the end-to-end suite the load-bearing suite, and makes its flakiness a product problem rather than a testing detail.
Four things the Next.js suites we read all do
1 · Log in over the API
Post the CSRF token and credentials to the auth callback route from the browser context, then carry on. Three separate products wrote the same roughly twenty-line helper against NextAuth-shaped and Better Auth-shaped backends. One marks its UI login helper deprecated in favor of the API one.
2 · Seed with the ORM
Test users, teams and records are created directly through Prisma in a fixture, never by driving the signup screen. Across the wider sample, one suite makes 387 direct API calls from its specs purely to set up data.
3 · Write the session once
The other half of the sample uses a setup project that authenticates and saves storageState to a per-role file, then makes every other project depend on it. Across 15 Playwright suites, 14 use one of these two approaches. One fills the login form in the UI.
4 · Test the deployment
Run the suite against the preview URL that the pull request produced, with the protection bypass secret, so what you tested is what you promote.
Testing a protected preview deployment
Deployment Protection is on by default for a lot of teams, and a suite pointed at a protected preview does not fail loudly; it happily asserts against an authentication page. Vercel's answer is Protection Bypass for Automation: a per-project secret sent as the x-vercel-protection-bypass header or query parameter, exposed to deployments as the VERCEL_AUTOMATION_BYPASS_SECRET environment variable. For in-browser testing, Vercel's documentation adds a second header, x-vercel-set-bypass-cookie, which sets the bypass as a cookie so follow-up requests carry it, and notes the value samesitenone for iframe cases.
Vercel publishes the Playwright config for it. The shape is:
use: {
extraHTTPHeaders: {
'x-vercel-protection-bypass': process.env.VERCEL_AUTOMATION_BYPASS_SECRET,
'x-vercel-set-bypass-cookie': 'true',
},
}
Two operational notes from the same page, worth knowing before you debug for an hour: the bypass does not override active DDoS mitigations or attack-time rate limits, and regenerating or deleting the secret invalidates previous deployments, so you have to redeploy after rotating it.
QA Reef treats a protected preview the same way, and refuses to guess. Give the project's bypass secret to the check, scoped to that deployment's origin. Without it, a protected preview is a critical finding, not a quiet pass. That rule comes from the same discipline as the rest of the product: a page we could not read is UNMEASURED, never a green tick.
What makes Next.js suites slow and flaky
- Waiting for the network to go quiet. Playwright's API reference marks the
networkidleload state DISCOURAGED: "Don't use this method for testing, rely on web assertions to assess readiness instead." An app that streams and revalidates in the background may never give you a quiet network. In our 15-suite sample, one suite carried 194 of these waits. What the disciplined suites use instead shows up in the counts: about 12,200toBeVisibleassertions and roughly 470waitForURLcalls. - Hard sleeps after navigation. 482
waitForTimeoutcalls across roughly 15,800 tests, clustering at 500 and 1000 ms. The worst instance in the sample was not in a spec at all: one project's login fixture ends with a half-second sleep, so every test in that suite inherits it. Check your fixtures before you blame your specs.
More on where flakiness actually comes from: why end-to-end tests break.
On top of a normal Playwright suite
A blocking check on every deployment
Every deployment gets crawled, up to 50 same-origin pages: broken links, 4xx and 5xx pages, console errors, failed requests, missing title or h1, mixed content, load timing, and full-page screenshots diffed against the previous deployment. A critical finding fails the check and blocks the promote, linked to the evidence. Recorded flows replay against the same URL.
Specs you own
Record a flow in a hosted browser and deterministic codegen writes a plain Playwright spec under your own playwright.config. The generator prefers a data-testid when your app has the convention, then role and accessible name, then label or placeholder, then scoped text. It does not emit XPath, and it never emits a sleep.
Cost, since preview testing is a per-pull-request habit: QA Reef meters browser-minutes and nothing else. The free tier is 500 browser-minutes a month plus $20 in signup credit; Solo is $20/mo with 1,333 minutes; Team $99/mo with 10,000; Scale $499/mo with 60,000; overage is $0.015 per browser-minute on every plan. A four-minute suite across 30 preview deployments in a month is 120 browser-minutes. AI usage is never metered. Full detail on the pricing page.
Questions about testing Next.js apps
Should I unit test async Server Components?
Next.js recommends against it for now: "some tools do not fully support them. In the meantime, we recommend using End-to-End Testing over Unit Testing for async components." Read from its testing guide, documentation version 16.3.4, on 3 September 2026.
How should tests log in?
Over the API. In the Next.js suites we read, each posts the CSRF token and credentials to its auth callback route from the browser context, and creates the user itself with the ORM first. Across the wider sample of 15 Playwright suites, 14 use API login or a saved storageState, and exactly one drives the login form.
How do I test a protected preview deployment?
Send the project's Protection Bypass for Automation secret as the x-vercel-protection-bypass header, plus x-vercel-set-bypass-cookie: true for browser testing. Vercel exposes the secret as VERCEL_AUTOMATION_BYPASS_SECRET and publishes the Playwright config snippet. Rotating the secret invalidates old deployments, so redeploy after you rotate.
Playwright or Cypress for a Next.js app?
Next.js documents setup guides for both. On what public suites actually run, we counted the difference: Playwright vs Cypress, counted in public repos.
Do I have to use QA Reef's runner?
No. The output is an ordinary Playwright spec in your repository. Run it in your own CI, on your own machines, or on ours. If you stop using QA Reef the tests keep running, which is deliberate.
Sources
All read 3 September 2026. Suite counts are our own, from public default branches, with the method stated at the top of the page.
- nextjs.org/docs/app/guides/testing, documentation version 16.3.4, last updated 3 February 2026, for the async Server Components recommendation
- Vercel: Protection Bypass for Automation, last updated 11 August 2026, for the bypass headers, the environment variable, the Playwright example and the limits
- playwright.dev/docs/api/class-page, for the discouraged
networkidleload state
Sitewide caveats, on every page: QA Reef is pre-launch. No customers, no case studies, no SOC 2 report. Hosted billing has not opened yet. The Vercel integration is built and tested but not yet listed on the Vercel Marketplace. Mobile native app testing is not supported.
Point it at one preview URL.
Bring a Next.js project and a bypass secret. We will crawl a deployment and show you the findings with the evidence attached.
Talk to the team