Playwrightの waitUntil: networkidle と domcontentloaded の違い
Playwright Testing E2E Frontend
結論
networkidle は非推奨です。domcontentloaded + expect(locator).toBeVisible() を使います。
// Playwright公式推奨:Flaky を防ぐ堅牢なページ遷移コード
import { test, expect } from '@playwright/test';
test('ユーザーダッシュボード表示テスト', async ({ page }) => {
// 1. waitUntil には domcontentloaded を指定して即座に完了させる
await page.goto('/dashboard', { waitUntil: 'domcontentloaded' });
// 2. 目的の要素が可視化されるのを Locator 経由で自動待機(Actionability Check)
const heading = page.getByRole('heading', { name: 'ダッシュボード' });
await expect(heading).toBeVisible();
});
Playwright公式仕様:waitUntil オプションの評価比較
Playwright公式ドキュメント(playwright.dev/docs/api/class-page)において、page.goto() の waitUntil パラメータは以下のように定義されています。
| オプション名 | 公式評価 | 完了の判定タイミング | 特徴と注意点 |
|---|---|---|---|
'domcontentloaded' | 推奨 | DOMContentLoaded イベント発火時 | HTMLのパース完了時点で終了。高速でテストが最も安定 |
'load' | 標準 (デフォルト) | load イベント発火時 | 画像やスタイルシートを含む全アセットの読み込み完了 |
'networkidle' | ⚠️ 非推奨 (DISCOURAGED) | 少なくとも 500ms 間ネットワーク通信がゼロになった時 | バックグラウンド通信やアナリティクスでタイムアウト頻発 |
なぜ networkidle は非推奨で Flaky テストの主因になるのか?
Playwright開発チームが networkidle の使用を「DISCOURAGED(非推奨)」と警告している最大の理由は、現代のWebアプリケーションの通信構造にあります。
SPAや現代のWebサイトでは、以下のようなバックグラウンド通信が継続的に発生します:
- SWR や React Query による裏でのデータ再取得
- Google Analytics や Sentry へのメトリクス送信
- 画像やアドバナーの遅延読み込み(Lazy Loading)
networkidle を指定すると、これらの通信によって「500ms 間ネットワークリクエスト数が0件」という条件が満たされず、TimeoutError: page.goto: Timeout 30000ms exceeded が多発してテストが落ちる事故が発生します。
正しいテスト待機手順
page.goto(url, { waitUntil: 'domcontentloaded' })でHTMLロード完了直後にテスト制御を戻す- 通信完了を直接待つのではなく、表示したいコンポーネントの Locator を定義する
await expect(page.getByTestId('user-profile')).toBeVisible()でアサーションを行う(Playwrightの自動リトライ機能が働く)