ネットワーク
はじめに
Playwrightは、HTTPとHTTPSの両方で、ブラウザのネットワークトラフィックを監視および変更するためのAPIを提供します。XHRおよびfetchリクエストを含む、ページが行うあらゆるリクエストを追跡、変更、処理できます。
APIのモック
API モックの詳細については、API モックガイドをご覧ください。
- APIリクエストをモックし、APIにヒットしない
- APIリクエストを実行し、レスポンスを変更する
- HARファイルを使用してネットワークリクエストをモックする。
HTTP認証
HTTP認証を実行します。
BrowserContext context = browser.newContext(new Browser.NewContextOptions()
  .setHttpCredentials("bill", "pa55w0rd"));
Page page = context.newPage();
page.navigate("https://example.com");
HTTPプロキシ
ページをHTTP(S)プロキシまたはSOCKSv5経由でロードするように構成できます。プロキシはブラウザ全体にグローバルに設定することも、各ブラウザコンテキストに個別に設定することもできます。
HTTP(S) プロキシのユーザー名とパスワードを任意で指定できます。また、setProxy をバイパスするホストを指定することもできます。
グローバルプロキシの例を次に示します。
Browser browser = chromium.launch(new BrowserType.LaunchOptions()
  .setProxy(new Proxy("http://myproxy.com:3128")
  .setUsername("usr")
  .setPassword("pwd")));
コンテキストごとに指定することも可能です。
Browser browser = chromium.launch();
BrowserContext context = browser.newContext(new Browser.NewContextOptions()
  .setProxy(new Proxy("http://myproxy.com:3128")));
ネットワークイベント
import com.microsoft.playwright.*;
public class Example {
  public static void main(String[] args) {
    try (Playwright playwright = Playwright.create()) {
      BrowserType chromium = playwright.chromium();
      Browser browser = chromium.launch();
      Page page = browser.newPage();
      page.onRequest(request -> System.out.println(">> " + request.method() + " " + request.url()));
      page.onResponse(response -> System.out.println("<<" + response.status() + " " + response.url()));
      page.navigate("https://example.com");
      browser.close();
    }
  }
}
または、Page.waitForResponse() を使用して、ボタンクリック後のネットワーク応答を待機します。
// Use a glob URL pattern
Response response = page.waitForResponse("**/api/fetch_data", () -> {
  page.getByText("Update").click();
});
バリエーション
Page.waitForResponse() を使用してレスポンスを待機します。
// Use a RegExp
Response response = page.waitForResponse(Pattern.compile("\\.jpeg$"), () -> {
  page.getByText("Update").click();
});
// Use a predicate taking a Response object
Response response = page.waitForResponse(r -> r.url().contains(token), () -> {
  page.getByText("Update").click();
});
リクエストの処理
page.route("**/api/fetch_data", route -> route.fulfill(new Route.FulfillOptions()
  .setStatus(200)
  .setBody(testData)));
page.navigate("https://example.com");
Playwrightスクリプトでネットワークリクエストを処理することで、APIエンドポイントをモックできます。
バリエーション
BrowserContext.route() を使用してブラウザコンテキスト全体、またはPage.route() を使用してページにルートを設定します。これはポップアップウィンドウや開かれたリンクに適用されます。
browserContext.route("**/api/login", route -> route.fulfill(new Route.FulfillOptions()
  .setStatus(200)
  .setBody("accept")));
page.navigate("https://example.com");
リクエストの変更
// Delete header
page.route("**/*", route -> {
  Map<String, String> headers = new HashMap<>(route.request().headers());
  headers.remove("X-Secret");
    route.resume(new Route.ResumeOptions().setHeaders(headers));
});
// Continue requests as POST.
page.route("**/*", route -> route.resume(new Route.ResumeOptions().setMethod("POST")));
変更を加えてリクエストを続行できます。上記の例では、送信されるリクエストからHTTPヘッダーを削除しています。
リクエストの破棄
Page.route() および Route.abort() を使用してリクエストを中止できます。
page.route("**/*.{png,jpg,jpeg}", route -> route.abort());
// Abort based on the request type
page.route("**/*", route -> {
  if ("image".equals(route.request().resourceType()))
    route.abort();
  else
    route.resume();
});
レスポンスの変更
レスポンスを変更するには、APIRequestContext を使用して元のレスポンスを取得し、そのレスポンスを Route.fulfill() に渡します。オプションを使用して、レスポンスの個々のフィールドを上書きできます。
page.route("**/title.html", route -> {
  // Fetch original response.
  APIResponse response = route.fetch();
  // Add a prefix to the title.
  String body = response.text();
  body = body.replace("<title>", "<title>My prefix:");
  Map<String, String> headers = response.headers();
  headers.put("content-type", "text/html");
  route.fulfill(new Route.FulfillOptions()
    // Pass all fields from the response.
    .setResponse(response)
    // Override response body.
    .setBody(body)
    // Force content type to be html.
    .setHeaders(headers));
});
Glob URLパターン
Playwright は、Page.route() や Page.waitForResponse() などのネットワークインターセプトメソッドで URL マッチングに簡略化されたグロブパターンを使用します。これらのパターンは基本的なワイルドカードをサポートしています。
- アスタリスク
- 単一の*は/以外の任意の文字に一致します。
- 二重の**は/を含む任意の文字に一致します。
 
- 単一の
- 疑問符?は疑問符?のみに一致します。任意の文字に一致させたい場合は、代わりに*を使用してください。
- 中括弧{}は、コンマ,で区切られたオプションのリストに一致させるために使用できます。
- バックスラッシュ\は、特殊文字をエスケープするために使用できます(バックスラッシュ自体を\\としてエスケープすることに注意してください)。
例
- https://example.com/*.jsは- https://example.com/file.jsに一致しますが、- https://example.com/path/file.jsには一致しません。
- https://example.com/?page=1は- https://example.com/?page=1に一致しますが、- https://example.comには一致しません。
- **/*.jsは- https://example.com/file.jsと- https://example.com/path/file.jsの両方に一致します。
- **/*.{png,jpg,jpeg}はすべての画像リクエストに一致します。
重要な注意点
- globパターンは、URLの一部だけでなく、URL全体に一致する必要があります。
- URLマッチングにglobを使用する場合は、プロトコルやパスセパレータを含む完全なURL構造を考慮してください。
- より複雑なマッチング要件には、グロブパターンではなく [RegExp] を使用することを検討してください。
WebSockets
Playwright は WebSockets の検査、モック、変更をすぐにサポートしています。WebSockets をモックする方法については、API モックガイドを参照してください。
WebSocket が作成されるたびに、Page.onWebSocket(handler) イベントが発行されます。このイベントには、さらなる Web ソケットフレーム検査のためのWebSocket インスタンスが含まれています。
page.onWebSocket(ws -> {
  log("WebSocket opened: " + ws.url());
  ws.onFrameSent(frameData -> log(frameData.text()));
  ws.onFrameReceived(frameData -> log(frameData.text()));
  ws.onClose(ws1 -> log("WebSocket closed"));
});
不足しているネットワークイベントとサービスワーカー
Playwright の組み込みの BrowserContext.route() と Page.route() を使用すると、テストでネイティブにリクエストをルーティングし、モックとインターセプトを実行できます。
- Playwright のネイティブな BrowserContext.route() と Page.route() を使用していて、ネットワークイベントが不足しているように見える場合は、setServiceWorkers を 'block'に設定して Service Workers を無効にしてください。
- Mock Service Worker (MSW) などのモックツールを使用している可能性があります。このツールはレスポンスのモックにはすぐに使用できますが、独自の Service Worker を追加し、それがネットワークリクエストを引き継ぐため、BrowserContext.route() および Page.route() からはそれらのリクエストが見えなくなります。ネットワークテストとモックの両方に興味がある場合は、レスポンスモックのために組み込みの BrowserContext.route() および Page.route() を使用することを検討してください。
- テストやネットワークモックにサービスワーカーのみを使用するのではなく、サービスワーカー自体が行ったリクエストのルーティングとリッスンに興味がある場合は、この実験的な機能を参照してください。