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

マルチスレッド

はじめに

Playwright Java はスレッドセーフではありません。つまり、そのすべてのメソッドと、それによって作成されたすべてのオブジェクト(BrowserContextBrowserPageなど)のメソッドは、Playwright オブジェクトが作成されたのと同じスレッドで呼び出されるか、常に1つのスレッドのみが Playwright メソッドを呼び出すことを保証するために適切な同期を実装する必要があります。とは言え、複数の Playwright インスタンスをそれぞれ独自ののスレッドで作成することは問題ありません。

以下は、3つの Playwright インスタンスをそれぞれ独自ののスレッドで作成する例です。各インスタンスは独自のブラウザプロセスを起動し、それに対してテストを実行します。

package org.example;

import com.microsoft.playwright.*;

import java.nio.file.Paths;

import static java.util.Arrays.asList;

public class PlaywrightThread extends Thread {
private final String browserName;

private PlaywrightThread(String browserName) {
this.browserName = browserName;
}

public static void main(String[] args) throws InterruptedException {
// Create separate playwright thread for each browser.
for (String browserName: asList("chromium", "webkit", "firefox")) {
Thread thread = new PlaywrightThread(browserName);
thread.start();
}
}

@Override
public void run() {
try (Playwright playwright = Playwright.create()) {
BrowserType browserType = getBrowserType(playwright, browserName);
Browser browser = browserType.launch();
Page page = browser.newPage();
page.navigate("https://playwright.dokyumento.jp/");
page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get("user-agent-" + browserName + ".png")));
}
}

private static BrowserType getBrowserType(Playwright playwright, String browserName) {
switch (browserName) {
case "chromium":
return playwright.chromium();
case "webkit":
return playwright.webkit();
case "firefox":
return playwright.firefox();
default:
throw new IllegalArgumentException();
}
}
}

同期APIとイベントディスパッチ

同期 Playwright API では、すべてのイベントは Playwright がメッセージループを実行しているときにのみディスパッチされます。これは、API メソッドのいずれかを呼び出すと自動的に行われ、スタックにアクティブな Playwright 呼び出しがない場合は発生しません。イベントを待機する必要がある場合は、waitFor* メソッドのいずれかを使用するのが最善の方法です。

Page.waitForTimeout() と Thread.sleep()

同期 API の結果の1つは、何らかの理由で Thread.sleep() を呼び出すと、スレッドがスリープしている間はイベントが発生しないことです。プログラムの

実行が一時停止されている間にブラウザからのイベントをディスパッチしたい場合は、Page.waitForTimeout() または Frame.waitForTimeout() を使用してください。

page.onResponse(response -> System.out.println(response.url()));
page.navigate("https://playwright.dokyumento.jp");
System.out.println("-- did navigate --");
// Block current thread for 60s and ensure the events are dispatched.
page.waitForTimeout(60_000);