/* eslint-env jest */ import { FileRef, nextTestSetup } from 'e2e-utils' import path from 'path' import { outdent } from 'outdent' import { waitForNoRedbox, getRedboxErrorLink, getToastErrorCount, retry, } from 'next-test-utils' describe('Error overlay for hydration errors in App router', () => { const { next, isTurbopack } = nextTestSetup({ files: new FileRef(path.join(__dirname, 'fixtures', 'hydration-errors')), }) it('includes a React docs link when hydration error does occur', async () => { const browser = await next.browser('/text-mismatch', { pushErrorAsConsoleLog: true, }) const logs = await browser.log() expect(logs).toEqual( expect.arrayContaining([ { // TODO: Should probably link to https://nextjs.org/docs/messages/react-hydration-error instead. message: expect.stringContaining( 'https://react.dev/link/hydration-mismatch' ), source: 'error', }, ]) ) }) it('should show correct hydration error when client and server render different text', async () => { const browser = await next.browser('/text-mismatch') await expect(browser).toDisplayCollapsedRedbox(` { "componentStack": "...
+ client - server ... ... ...", "description": "Hydration failed because the server rendered text didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:", "environmentLabel": null, "label": "Recoverable Error", "source": "app/(default)/text-mismatch/page.tsx (8:7) @ Mismatch > 8 |
{isClient ? 'client' : 'server'}
| ^", "stack": [ "main ", "Mismatch app/(default)/text-mismatch/page.tsx (8:7)", ], } `) expect(await getRedboxErrorLink(browser)).toMatchInlineSnapshot( `"See more info here: https://nextjs.org/docs/messages/react-hydration-error"` ) await next.patchFile( 'app/(default)/text-mismatch/page.tsx', outdent` 'use client' export default function Mismatch() { return (
Value
); } `, async () => { await waitForNoRedbox(browser) expect(await browser.elementByCss('.child').text()).toBe('Value') } ) }) it('should show correct hydration error when client renders an extra element', async () => { const browser = await next.browser('/extra-element-client') await expect(browser).toDisplayCollapsedRedbox(` { "componentStack": "...
+
... ... ...", "description": "Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:", "environmentLabel": null, "label": "Recoverable Error", "source": "app/(default)/extra-element-client/page.tsx (6:47) @ Mismatch > 6 | return
{isClient &&
}
| ^", "stack": [ "main ", "Mismatch app/(default)/extra-element-client/page.tsx (6:47)", ], } `) }) it('should show correct hydration error when extra attributes set on server', async () => { const browser = await next.browser('/extra-attributes') if (isTurbopack) { await expect(browser).toDisplayCollapsedRedbox(` { "componentStack": "...