リクエストのインターセプトと改変 ― Playwright ネットワーク操作&モック

1. 基本思想

Playwright では page.route()browserContext.route() を使って
任意の URL パターンに合致するネットワークリクエストを “低レベルで横取り” できます。
ハンドラ内では route オブジェクトを通じて

  • そのまま通す route.continue()

  • ブロックする route.abort()

  • モック応答を返す route.fulfill()

  • 一度実リクエストを取りに行ってから書き換える route.fetch() → route.fulfill()

――の 4 通りで制御しますplaywright.dev
page.route() はページ限定、browserContext.route() はコンテキスト全体(新規タブ・ポップアップ含む)に作用します。


2. ルーティング対象の指定

パターン記法 特徴
Glob (**/*.js, **/*.{png,jpg} など) シンプル・高速。Playwright 独自の * / ** ルールを持つ。
RegExp (/\\.jpeg$/) 複雑な条件に最適。
v1.52 以降は ?[] を含む旧 Glob が非推奨になり、複雑なマッチは正規表現推奨playwright.dev

3. リクエスト改変:route.continue([options])

ts
await page.route('**/*', async route => { const headers = { ...route.request().headers(), 'x-test': 'intercept' }; await route.continue({ method: 'POST', // メソッドの書き換え headers, // ヘッダー追加・削除 postData: '{"patched": true}', // ボディ改変 url: route.request().url().replace('v1', 'v2') // リダイレクト }); });

ポイント

  • Cookie ヘッダーは v1.52 以降書き換え不可。クッキーを操作したい場合は browserContext.addCookies() を使いますplaywright.dev

  • 同一 URL に複数ルートが重なる場合、最初に登録したハンドラが優先されます。テストごとに route.unroute() で解除しておくと安全です。


4. レスポンス改変:route.fulfill()route.fetch()

ts
await page.route('**/title.html', async route => { const original = await route.fetch(); // 元レスポンス取得 let body = await original.text(); body = body.replace('<title>', '<title>Test:'); await route.fulfill({ response: original, // 既存ヘッダー・ステータスを継承 body, // ボディだけ差し替え headers: { ...original.headers(), 'x-mock': 'yes' } }); });
  • route.fetch()透過的プロキシとしてオリジナルにアクセスし、
    必要箇所だけ書き換えて返すハイブリッド手法が可能ですplaywright.dev

  • JSON を返す場合は content-type: application/json を忘れずに。


5. 典型ユースケース

目的 実装例
外部 API を完全にスタブ route.fulfill({ status: 200, body: JSON.stringify(fake) })
画像・CSS の読み込み高速化 route.abort() で不要リソースをブロック
認証トークンのヘッダー差し込み route.continue({ headers: { ...h, Authorization: 'Bearer …' } })
E2E テストで A/B テストバナーを強制非表示 レスポンス HTML を置換して要素ごと削除

6. ベストプラクティス & 落とし穴

  1. パターンは絞る
    **/* へのフックは便利ですがコスト大。ドメイン・パス単位で限定しましょう。

  2. Service Worker 競合
    Service Worker がネットワークを奪うとルートが効かなくなります。設定で serviceWorkers: 'block' を指定すると解決できますplaywright.dev

  3. 並列テストとの相性
    Playwright Test のワーカー並列実行では 各テスト内で newContextroute 登録 が鉄則。グローバルに route を張らない。

  4. 後片付け
    page.unroute() / browserContext.unroute() でインターセプトを解除しておくと、次のテストに影響が残りません。

  5. HAR ベースの再生
    実運用 API を一度キャプチャし、browserContext.routeFromHAR() でリプレイすれば、外部依存ゼロで統合テストが行えます。


7. まとめ

Playwright のルーティング API は

  • 観測page.on('request')/('response')

  • 改変route.continue/fulfill/abort

  • ハイブリッドroute.fetch()

を網羅的に提供するため、「本物のブラウザ+柔軟なネットワークスタブ」 を一つのフレームワーク内で完結できます。
上記の注意点を押さえておくことで、E2E テストを 高速・安定・再現性高く 実行できるようになります。

ChatGPT4o 生成日:2025/06/22