Next.js App Router Changed How Your App Renders. Did Your Tests Notice?
The test still passes. The alert never renders.
Your team migrated a patient medication dashboard to Next.js App Router. You refactored MedicationList as a Server Component to cut Time to First Byte. You wrapped DrugInteractionAlert in a <Suspense> boundary so the medication list appears immediately while the interaction check runs in parallel. Perceived performance improved.
CI stayed green. Your Playwright suite passed every run.
Two weeks later, a nurse filed a bug report: the drug interaction banner wasn't showing on slow hospital wifi connections. It would flash briefly and disappear, or sometimes never appear at all. The medications rendered. The alert — the one that warns about a contraindicated combination — didn't.
The test wasn't catching it because the test was using waitForLoadState('networkidle'). By the time Playwright declared the page idle, the medication list had streamed in and the interaction check was still in-flight. The test asserted the page, saw no alert, logged a pass.
This is not a hypothetical failure mode. It is a specific class of bug introduced by migrating to App Router without updating your test assumptions — and it is consequential in proportion to how much your UI surfaces clinically relevant information.
This post covers what App Router actually changed in the rendering model, why it breaks existing test suites in ways that are especially dangerous for health-adjacent applications, and how O2 — DevAssure's PR-native testing agent — handles these rendering patterns natively without requiring you to write or maintain a single test script.
