メインコンテンツにスキップ

Mock API

はじめに

Web API は通常、HTTP エンドポイントとして実装されます。Playwright は、HTTP と HTTPS の両方のネットワークトラフィックをモックおよび変更するための API を提供します。ページが行うすべてのリクエスト(XHRfetch リクエストを含む)は、追跡、変更、およびモックできます。Playwright を使用すると、ページによって行われた複数のネットワークリクエストを含む HAR ファイルを使用してモックすることもできます。

Mock API リクエスト

次のコードは、*/**/api/v1/fruits へのすべての呼び出しをインターセプトし、代わりにカスタムレスポンスを返します。API へのリクエストは行われません。テストは、モックされたルートを使用する URL に移動し、モックデータがページに存在することを確認します。

// Intercept the route to the fruit API
await page.RouteAsync("*/**/api/v1/fruits", async route => {
var json = new[] { new { name = "Strawberry", id = 21 } };
// fulfill the route with the mock data
await route.FulfillAsync(new()
{
Json = json
});
});

// Go to the page
await page.GotoAsync("https://demo.playwright.dev/api-mocking");

// Assert that the Strawberry fruit is visible
await Expect(page.GetByTextAsync("Strawberry")).ToBeVisibleAsync();

例のテストのトレースから、API が一度も呼び出されず、モックデータで fulfilled されたことがわかります。api mocking trace

高度なネットワークについては、こちらをご覧ください。

API レスポンスの変更

再現性のあるテストを可能にするために、API リクエストを行う必要があり、レスポンスを修正する必要がある場合があります。その場合、リクエストをモックする代わりに、リクエストを実行し、変更されたレスポンスで fulfilled することができます。

以下の例では、fruit API への呼び出しをインターセプトし、「Loquat」という新しいフルーツをデータに追加します。次に、URL に移動し、このデータが存在することを確認します

await page.RouteAsync("*/**/api/v1/fruits", async (route) => {
var response = await route.FetchAsync();
var fruits = await response.JsonAsync<Fruit[]>();
fruits.Add(new Fruit() { Name = "Loquat", Id = 100 });
// Fulfill using the original response, while patching the response body
// with the given JSON object.
await route.FulfillAsync(new ()
{
Response = response,
Json = fruits
});
}
);
// Go to the page
await page.GotoAsync("https://demo.playwright.dev/api-mocking");

// Assert that the Loquat fruit is visible
await Expect(page.GetByTextAsync("Loquat", new () { Exact = true })).ToBeVisibleAsync();

テストのトレースでは、API が呼び出され、レスポンスが変更されたことがわかります。trace of test showing api being called and fulfilled

レスポンスを調べると、新しいフルーツがリストに追加されたことがわかります。trace of test showing the mock response

高度なネットワークについては、こちらをご覧ください。

HAR ファイルを使用したモック

HAR ファイルは、ページがロードされたときに行われるすべてのネットワークリクエストの記録を含む HTTP Archive ファイルです。リクエストとレスポンスのヘッダー、Cookie、コンテンツ、タイミングなどの情報が含まれています。HAR ファイルを使用して、テストでネットワークリクエストをモックできます。必要な手順は次のとおりです。

  1. HAR ファイルを記録します。
  2. HAR ファイルをテストと一緒にコミットします。
  3. テストで保存された HAR ファイルを使用してリクエストをルーティングします。

HAR ファイルの記録

HAR ファイルを記録するには、Page.RouteFromHARAsync() または BrowserContext.RouteFromHARAsync() メソッドを使用します。このメソッドは、HAR ファイルへのパスとオプションのオプションオブジェクトを受け取ります。オプションオブジェクトには URL を含めることができ、指定された glob パターンに一致する URL を持つリクエストのみが HAR ファイルから提供されます。指定しない場合、すべてのリクエストは HAR ファイルから提供されます。

update オプションを true に設定すると、HAR ファイルからリクエストを提供する代わりに、実際のネットワーク情報で HAR ファイルを作成または更新します。テストを作成して HAR に実際のデータを設定する場合に使用します。

// Get the response from the HAR file
await page.RouteFromHARAsync("./hars/fruit.har", new () {
Url = "*/**/api/v1/fruits",
Update = true,
});

// Go to the page
await page.GotoAsync("https://demo.playwright.dev/api-mocking");

// Assert that the fruit is visible
await Expect(page.GetByText("Strawberry")).ToBeVisibleAsync();

HAR ファイルの変更

HAR ファイルを記録したら、「hars」フォルダー内のハッシュ化された .txt ファイルを開き、JSON を編集することで変更できます。このファイルはソース管理にコミットする必要があります。update: true でこのテストを実行するたびに、API からのリクエストで HAR ファイルが更新されます。

[
{
"name": "Playwright",
"id": 100
},
// ... other fruits
]

HAR からの再生

HAR ファイルを記録し、モックデータを変更したので、テストで一致するレスポンスを提供するために使用できます。これを行うには、update オプションをオフにするか、単純に削除します。これにより、API にアクセスする代わりに、HAR ファイルに対してテストが実行されます。

// Replay API requests from HAR.
// Either use a matching response from the HAR,
// or abort the request if nothing matches.
await page.RouteFromHARAsync("./hars/fruit.har", new ()
{
Url = "*/**/api/v1/fruits",
Update = false,
}
);

// Go to the page
await page.GotoAsync("https://demo.playwright.dev/api-mocking");

// Assert that the Playwright fruit is visible
await page.ExpectByTextAsync("Playwright", new() { Exact = true }).ToBeVisibleAsync();

テストのトレースでは、ルートが HAR ファイルから fulfilled され、API が呼び出されなかったことがわかります。trace showing the HAR file being used

レスポンスを調べると、hars フォルダー内のハッシュ化された `.txt` ファイルを手動で更新することによって、新しいフルーツが JSON に追加されたことがわかります。trace showing response from HAR file

HAR の再生は、URL と HTTP メソッドに厳密に一致します。POST リクエストの場合、POST ペイロードにも厳密に一致します。複数の記録がリクエストに一致する場合、最も一致するヘッダーを持つものが選択されます。リダイレクトが発生するエントリは自動的に追跡されます。

記録時と同様に、指定された HAR ファイル名が `.zip` で終わる場合、HAR ファイルと、個別のエントリとして保存されたネットワークペイロードを含むアーカイブと見なされます。このアーカイブを解凍し、ペイロードまたは HAR ログを手動で編集して、解凍された har ファイルをポイントすることもできます。すべてのペイロードは、ファイルシステム上の解凍された har ファイルを基準に解決されます。

CLI を使用した HAR の記録

テスト用の HAR ファイルを記録するには、update オプションを使用することをお勧めします。ただし、Playwright CLI を使用して HAR を記録することもできます。

Playwright CLI でブラウザを開き、--save-har オプションを渡して HAR ファイルを生成します。オプションで、--save-har-glob を使用して、目的のリクエスト(たとえば API エンドポイント)のみを保存します。har ファイル名が `.zip` で終わる場合、アーティファクトは個別のファイルとして書き込まれ、すべて単一の `zip` に圧縮されます。

# Save API requests from example.com as "example.har" archive.
pwsh bin/Debug/netX/playwright.ps1 open --save-har=example.har --save-har-glob="**/api/**" https://example.com

高度なネットワークについては、こちらをご覧ください。

Mock WebSocket

次のコードは、WebSocket 接続をインターセプトし、サーバーに接続する代わりに、WebSocket を介した通信全体をモックします。この例では、"request""response" で応答します。

await page.RouteWebSocketAsync("wss://example.com/ws", ws => {
ws.OnMessage(frame => {
if (frame.Text == "request")
ws.Send("response");
});
});

または、実際のサーバーに接続し、その間のメッセージをインターセプトして変更またはブロックすることもできます。これは、ページからサーバーに送信されたメッセージの一部を変更し、残りを変更しない例です。

await page.RouteWebSocketAsync("wss://example.com/ws", ws => {
var server = ws.ConnectToServer();
ws.OnMessage(frame => {
if (frame.Text == "request")
server.Send("request2");
else
server.Send(frame.Text);
});
});

詳細については、WebSocketRoute を参照してください。