多线程
简介
Playwright Java 不是线程安全的,即其所有方法以及其创建的所有对象(例如 BrowserContext、Browser、Page 等)上的方法都应在创建 Playwright 对象的同一线程上调用,或者应实现适当的同步以确保在任何给定时间只有一个线程调用 Playwright 方法。话虽如此,在每个线程上创建多个 Playwright 实例是可以的。
以下是一个示例,其中在每个线程上创建三个 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.net.cn/");
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 的一个结果是,如果您出于任何原因调用 Thread.sleep()
,则在线程休眠期间不会触发任何事件。如果您希望在程序暂停执行时分发来自浏览器的事件,请使用 Page.waitForTimeout() 或 Frame.waitForTimeout()
执行。
page.onResponse(response -> System.out.println(response.url()));
page.navigate("https://playwright.net.cn");
System.out.println("-- did navigate --");
// Block current thread for 60s and ensure the events are dispatched.
page.waitForTimeout(60_000);