671 文字
3 分

Q. ローカル環境でのE2EテストがReactDevOverlayにより失敗する

状況#

Next.js を利用したサービスで動作確認のために Playwright テストをローカル環境で実行したところ、Hydration Error により ReactDevOverlay が表示され、テストが失敗するという報告があった。

ReactDevOverlay とは#

Next.js アプリをローカルで開発している際に、エラーが発生すると表示されるモーダルは ReactDevOverlay と呼ばれている。

https://www.npmjs.com/package/@next/react-dev-overlay

これの存在意義については、CRA の issue で言及されている。

https://github.com/facebook/create-react-app/issues/6530#issuecomment-662914362

また、ReactDevOverlay を無効にしない理由として上記の issue が Next.js のメンテナに引用されている。

https://github.com/vercel/next.js/discussions/23970#discussioncomment-599510

つまり、Next.js は ReactDevOverlay を無効にする機能を提供していない。

解決案#

次にあげている手法を安直に適用すると、通常の開発時にも影響があるため注意。

ReactDevOverlay を非表示にする#

Next.js で表示される ReactDevOverlay は、nextjs-portal という web component が実体のため、これを非表示にすれば ReactDevOverlay を無効化することが出来る。

nextjs-portal {
display: none;
}

Next.js は、next.config.js などで ReactDevOverlay を無効にする機能を提供していない。

Hydration Error を無効にする#

React では、suppressHydrationWarningを指定することで、その配下で発生する Hydration Error を無効にすることができる。

<div suppressHydrationWarning={true}>
Current Date: {new Date().toLocaleDateString()}
</div>

雑に無効化したいのであれば、suppressHydrationWarningを html 要素や body 要素に指定してしまえばいい。 ただし、本来suppressHydrationWarningは Hydration Error を避けることが困難な状況においてのみ限定的に利用するのが望ましい。

https://ja.react.dev/reference/react-dom/client/hydrateRoot#suppressing-unavoidable-hydration-mismatch-errors

解決案の応用例#

通常の開発時にも ReactDevOverlay が表示されなくなることは好ましくないため、E2E テストの実行時のみ適用されるのが望ましい。

E2E テスト実行時のみ ReactDevOverlay を非表示にする#

Next.js の Page Router であれば_app.js、App Router であればlayout.jsなどで、環境変数を参照して ReactDevOverlay を非表示にする。

{
process.env.E2E ? (
<style>
{`
nextjs-portal {
display: none;
}
`}
</style>
) : null;
}

E2E テスト実行時のみ Hydration Error を無効にする#

環境変数を参照して、suppressHydrationWarningを指定することで Hydration Error を無効にする。

return (
<html lang="ja">
<body suppressHydrationWarning={process.env.E2E ? true : false}>
{children}
</body>
</html>
);

Playwright で ReactDevOverlay を非表示にする#

ページ遷移後に、実行する必要がある点に注意。

await page.goto("http://localhost:3000");
await page.addStyleTag({
content: `
nextjs-portal {
display: none;
}`,
});

Playwright で Hydration Error を無効にする#

ページ遷移後に、実行する必要がある点に注意。

await page.goto("http://localhost:3000");
await page.evaluate(() => {
const body = document.querySelector("body");
body.setAttribute("suppressHydrationWarning", "true");
});
Q. ローカル環境でのE2EテストがReactDevOverlayにより失敗する
https://blog.ohirunewani.com/posts/disablehydrationerrorreactdevovelay/
作者
hrdtbs
公開日
2024-11-15
ライセンス
CC BY-NC-SA 4.0