Playwright ネットワーク傍受と Mock

この章では、Playwright を使用してネットワークリクエストを傍受・変更・模擬し、バックエンド API に依存しない独立したテストを実現する方法を紹介します。


ネットワーク傍受とは

ネットワーク傍受により、ブラウザが HTTP リクエストを発行する際に介入できます。

次のことができます:リクエストのブロック、レスポンスの変更、モックデータの返却により、テストを外部 API やネットワーク状態に依存させません。


page.route() によるリクエスト傍受

page.route(url, handler)指定した URL パターンに一致するすべてのネットワークリクエストを傍受するために使用します。

基本の傍受

例

test('すべての画像リクエストを傍受', async ({ page }) => {
  // すべての PNG および JPEG 画像を傍受
  await page.route('**/*.{png,jpg,jpeg}', route => route.abort());

  // ページに移動(画像は読み込まれない)
  await page.goto('https://www.example.com/');
  // 画像をダウンロードしないため、ページの読み込みが速くなる可能性があります
});

URL マッチングパターン次の形式をサポートしています:

パターン例説明
完全な URL'https://api.example.com/users'完全一致
Glob ワイルドカード'**/api/**'**任意のパスに一致
正規表現/\/api\/v\d\/users/柔軟なマッチング
関数url => url.includes('/api/')プログラミングロジックによるマッチング

route.abort() によるリクエストのブロック

例

test('サードパーティ製アナリティクススクリプトをブロック', async ({ page }) => {
  // Google Analytics などの分析スクリプトをブロック
  await page.route('**/*analytics*', route => route.abort());
  // CSS ファイルをブロック
  await page.route('**/*.css', route => route.abort());

  await page.goto('https://www.example.com/');
  // ページはスタイルなしで読み込まれますが、機能テストには影響しません
});

route.fulfill() によるレスポンスの模擬

route.fulfill()は最も強力な Mock メソッドであり、任意のカスタムレスポンスを返すことができます。

JSON データの Mock

例

test('ユーザー一覧 API の Mock', async ({ page }) => {
  // ユーザー一覧 API を傍受し、モックデータを返す
  await page.route('**/api/users', async route => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      json: [
        { id: 1, name: 'サンプル_user', email: '[email protected]' },
        { id: 2, name: 'test_user', email: '[email protected]' },
      ],
    });
  });

  await page.goto('https://www.example.com/users');
  // ページには実際の API データではなく Mock データが表示されます
});

エラーレスポンスの Mock

例

test('API エラーハンドリングのテスト', async ({ page }) => {
  // 500 サーバーエラーを模擬
  await page.route('**/api/data', async route => {
    await route.fulfill({
      status: 500,
      contentType: 'application/json',
      json: { error: 'サーバー内部エラー' },
    });
  });

  await page.goto('https://www.example.com/dashboard');
  // エラーメッセージが正しく表示されるか検証
  await expect(page.getByText('サーバー内部エラー')).toBeVisible();
});

route.continue() で変更後に続行

モックデータを直接返すのではなく、実際のリクエストまたはレスポンスを変更してからサーバーへの送信を続けます。

例

test('リクエストヘッダーの変更', async ({ page }) => {
  await page.route('**/api/**', async (route, request) => {
    // リクエストヘッダーを変更し、カスタムヘッダーを追加
    const headers = {
      ...request.headers(),
      'X-Custom-Header': 'サンプル-TEST',
    };
    await route.continue({ headers });
  });

  await page.goto('https://www.example.com/');
});

test('POST データの変更', async ({ page }) => {
  await page.route('**/api/login', async (route, request) => {
    // POST リクエストの body を上書き
    const postData = JSON.parse(request.postData() || '{}');
    postData.mode = 'test';  // テストマーカーを追加
    await route.continue({
      postData: JSON.stringify(postData),
    });
  });
});

route.fetch() による実際のリクエスト

Mock ハンドラー関数内では、route.fetch()実際にリクエストを送信して実際のレスポンスを取得し、それを変更できます。

例

test('実際のレスポンスの変更', async ({ page }) => {
  await page.route('**/api/products', async route => {
    // まず実際のレスポンスを取得
    const response = await route.fetch();
    const body = await response.json();

    // レスポンスデータを変更
    body.items[0].name = 'サンプル 変更後の商品名';

    // 変更後のデータを返す
    await route.fulfill({
      status: response.status(),
      contentType: 'application/json',
      json: body,
    });
  });
});

Context レベルの傍受 vs Page レベルの傍受

方式適用範囲適用シーン
page.route()現在のページのみ単一ページのネットワーク Mock
context.route()この Context 配下のすべてのページ複数のページで共有される Mock ルール

例

test.beforeEach(async ({ context }) => {
  // Context 全体で傍受し、すべてのページで有効
  await context.route('**/*.css', route => route.abort());
});

test('テスト 1', async ({ page }) => { /* CSS なし */ });
test('テスト 2', async ({ page }) => { /* CSS なし */ });

HAR ファイルの記録と再生

HAR(HTTP Archive)ファイルは、ページのすべてのネットワークリクエストを記録し、それを再生して模擬することができます。

例

test('HAR ファイルを使用した Mock', async ({ page }) => {
  // HAR ファイルからネットワーク記録を読み込んで再生
  await page.routeFromHAR('tests/hars/api-responses.har');

  await page.goto('https://www.example.com/');
  // 一致するすべてのリクエストは HAR ファイルからレスポンスを取得します
});
# 录制 HAR 文件
npx playwright open --save-har=tests/hars/api-responses.har https://www.example.com/

HAR ファイルは、大量または複雑な API レスポンスの Mock に適しています。一度記録しておけば、以降のテストはすべて HAR から再生されるため、実際のサーバーに依存しません。

その他の拡張