Playwright for Java 自动化测试:从核心概念到实战应用
1. 项目概述:为什么是 Playwright for Java?
如果你是一名 Java 后端开发,或者正在从 Selenium 转向更现代的自动化测试方案,那么 Playwright 这个名字你肯定不陌生。但很多人第一反应是:这不是 Node.js 那边的工具吗?没错,Playwright 最初确实是为 Node.js 生态量身打造的,但微软团队很快意识到,要让这个强大的工具真正普及,必须拥抱企业级开发中最主流的语言之一——Java。于是,Playwright for Java 应运而生,它不是一个简单的语言绑定,而是一个深度集成、充分利用 Java 并发特性和强类型优势的 SDK。
我最初接触 Playwright 也是因为一个老项目的自动化测试重构。当时团队还在用 Selenium WebDriver 配合 TestNG,一套用例跑下来动辄半小时,浏览器兼容性问题和脆弱的元素定位让人头疼不已。直到尝试了 Playwright,我才发现自动化测试可以如此“清爽”:无需手动管理各种浏览器驱动,内置的自动等待机制大幅减少了 Flaky Tests(不稳定的测试),对现代单页应用(SPA)的支持近乎完美。更重要的是,它的 Java API 设计得非常“Java”,让你感觉就像在使用一个原生的 Java 库,而不是一个外来移植品。这篇文章,我就带你从零开始,拆解 Playwright for Java 的核心概念,并通过实际案例,让你能快速上手,应用到你的项目中,无论是做 UI 自动化测试、爬虫,还是日常的重复性网页操作。
2. 核心概念与架构解析
2.1 Playwright 的“三位一体”模型
理解 Playwright,首先要抛开 Selenium 那种“一个驱动对应一个浏览器”的线性思维。Playwright 采用了一个更清晰的三层架构: Playwright -> Browser -> Context -> Page 。这听起来有点抽象,我用一个公司的组织架构来类比:
- Playwright 对象 :就像公司的“创始人”或“工厂”。你的所有自动化旅程都从这里开始。它的主要职责是启动和管理不同类型的浏览器“实例”(BrowserType)。在 Java 中,你通过
Playwright.create()来创建这个入口点。 - Browser 对象 :可以理解为一家“分公司”或一条“生产线”。它代表一个实际的浏览器进程,比如一个 Chrome 或 Firefox 的实例。你可以创建多个独立的 Browser 对象,它们彼此隔离。通过
playwright.chromium().launch()这样的方式来启动。 - BrowserContext 对象 :这是 Playwright 最精妙的设计之一,相当于分公司里的一个“独立项目组”。每个 Context 拥有独立的会话(Session)、Cookie、本地存储和缓存,但共享同一个浏览器进程的资源。这让你能轻松模拟多个用户同时登录、进行并行测试,而无需启动多个沉重的浏览器进程,资源消耗大大降低。
- Page 对象 :这是最终与网页交互的“一线员工”。一个 Context 下可以创建多个 Page(即多个标签页)。你的绝大部分操作,如跳转网址、点击按钮、输入文本,都在 Page 对象上完成。
为什么要这么设计?核心优势在于 隔离性与效率的平衡 。在 Selenium 中,如果你想隔离两个测试场景,通常需要启动两个浏览器,开销巨大。而在 Playwright 中,你只需在一个浏览器进程下创建两个 Context,就能实现完美的隔离,速度更快,资源占用更少。
2.2 Java API 的设计哲学:同步与异步
Playwright 原生是异步的(基于 Node.js 的 Promise),但它的 Java API 提供了两种风格: 同步 API 和 异步 API 。对于大多数从 Selenium 转过来或有传统 Java 背景的开发者,同步 API 更易上手,代码写起来是顺序执行的,更符合直觉。
// 同步 API 示例(最常用)
try (Playwright playwright = Playwright.create()) {
Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
BrowserContext context = browser.newContext();
Page page = context.newPage();
page.navigate("https://example.com");
System.out.println(page.title()); // 同步等待并获取标题
}
而异步 API(基于 CompletableFuture )则提供了更高的灵活性,适合在复杂的并发场景下榨干性能。不过,对于入门和 90% 的用例,同步 API 完全够用且更不易出错。Playwright 的同步 API 底层其实封装了异步操作,并帮你处理好了等待,这也是它比 Selenium 更稳定的原因之一——它内置了智能等待,而不是简单粗暴的 Thread.sleep 。
2.3 与 Selenium 的关键差异点
很多人在选择时会纠结。这里我列几个最关键的差异,帮你决策:
| 特性维度 | Playwright (Java) | Selenium WebDriver |
|---|---|---|
| 架构 | 通过 DevTools Protocol 等现代化协议直接与浏览器通信 | 通过标准化的 W3C WebDriver 协议通信 |
| 启动速度 | 快。浏览器和驱动由 Playwright 统一管理,自动下载。 | 较慢。需要手动匹配和下载浏览器驱动。 |
| 自动等待 | 内置且强大 。几乎所有操作(如 click , fill )都自动等待元素可操作。 |
需要手动设置隐式/显式等待,否则极易因元素未加载而失败。 |
| 浏览器支持 | 统一支持 Chromium, Firefox, WebKit。API 一致,无需为不同浏览器写适配代码。 | 支持更广泛的浏览器,但不同浏览器可能需要特定配置,行为偶有差异。 |
| 网络拦截与 Mock | 原生支持,非常方便。可以轻松拦截修改请求、模拟 API 响应。 | 需要借助其他库(如 BrowserMob Proxy),配置复杂。 |
| 移动端模拟 | 通过设备描述符精准模拟手机视口、User-Agent 等,体验真实。 | 支持,但配置相对基础。 |
| 录制工具 | 内置 playwright codegen ,可生成 Java 代码,是学习利器。 |
有 Selenium IDE,但功能相对简单。 |
| 社区与生态 | 增长迅速,由微软维护,但 Java 生态的第三方库(如报告工具集成)目前略少于 Selenium。 | 极其成熟,有海量的社区解决方案、集成和文档。 |
我的选择建议 :如果你的项目是全新的,或者正被 Selenium 的稳定性问题困扰,强烈建议尝试 Playwright。它的“开箱即用”体验和稳定性提升是立竿见影的。如果项目严重依赖 Selenium 的庞大生态(如某些特定的云测试平台插件),或者需要支持 IE 等老旧浏览器,那么 Selenium 仍是唯一选择。
3. 环境搭建与项目初始化
3.1 依赖管理与构建工具配置
Playwright for Java 主要通过 Maven 或 Gradle 进行依赖管理。这里以最常用的 Maven 为例。
首先,在你的 pom.xml 中添加 Playwright 依赖。 强烈建议使用最新稳定版本 ,你可以去 Maven Central 查看。
<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId>
<version>1.44.0</version> <!-- 请替换为最新版本 -->
</dependency>
添加依赖后,当你第一次运行任何使用 Playwright 的代码时,它会自动下载所需的浏览器二进制文件(Chromium, Firefox, WebKit)到本地缓存中。这个过程是自动的,但有时可能因为网络问题失败。
3.2 解决首次运行的“浏览器下载”问题
自动下载虽然方便,但在公司内网或网络不稳定环境下可能出问题。这时,你可以选择手动安装。
方法一:使用 Maven Goal(推荐) Playwright 提供了一个 Maven 插件,可以显式执行浏览器安装。
mvn exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="install"
或者,如果你已经写了一个简单的测试类,直接运行它也会触发下载。
方法二:使用 Playwright CLI 如果你全局安装了 Playwright CLI,也可以直接使用。但 Java 版更推荐用 Maven Goal。
方法三:完全离线部署 在能联网的机器上,先让 Playwright 完成下载。浏览器通常存放在 ~/.cache/ms-playwright (Linux/Mac)或 %USERPROFILE%\AppData\Local\ms-playwright (Windows)目录下。你可以将这个目录打包,复制到目标机器对应的位置。然后,在启动代码中指定浏览器可执行文件路径:
BrowserType.LaunchOptions options = new BrowserType.LaunchOptions()
.setExecutablePath(Paths.get("/your/offline/path/chrome-win/chrome.exe")); // 指定路径
Browser browser = playwright.chromium().launch(options);
3.3 编写你的第一个脚本:验证环境
创建一个简单的 Java 类来验证一切是否就绪。
import com.microsoft.playwright.*;
public class FirstScript {
public static void main(String[] args) {
// 1. 创建 Playwright 实例。try-with-resources 确保最后关闭。
try (Playwright playwright = Playwright.create()) {
// 2. 启动 Chromium 浏览器。setHeadless(false) 表示显示浏览器界面,方便调试。
Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
// 3. 创建一个新的浏览器上下文(Context)
BrowserContext context = browser.newContext();
// 4. 在上下文中打开一个新页面(Page)
Page page = context.newPage();
// 5. 导航到目标网址
page.navigate("https://playwright.dev/java/");
// 6. 获取页面标题并打印
System.out.println("页面标题: " + page.title());
// 7. 为了看清效果,等待几秒(实际脚本中应使用 Playwright 的等待机制,而非 sleep)
page.waitForTimeout(3000);
} catch (Exception e) {
e.printStackTrace();
}
// try-with-resources 会自动调用 playwright.close(),关闭所有浏览器。
}
}
运行这个程序,你应该能看到一个浏览器窗口打开,访问 Playwright 官网,然后在控制台打印出标题,最后浏览器自动关闭。恭喜,你的 Playwright Java 环境已经成功搭建!
实操心得 :在开发调试阶段,建议将
setHeadless(false)设为false,这样你能直观地看到浏览器的操作过程,便于定位问题。在 CI/CD 流水线或生产环境运行时,再改为true(无头模式),这样不需要图形界面,运行更高效。
4. 核心 API 与元素交互实战
4.1 元素定位器(Locators):稳定定位的基石
元素定位是自动化脚本的“地基”。Playwright 的定位器 API 设计得非常强大和灵活。核心方法是 page.locator(selector) 。
常用定位策略:
- CSS 选择器 :最通用、最推荐的方式。
page.locator("button.submit")。 - 文本定位 :通过元素文本内容定位,对动态变化的 CSS 类不敏感。
page.locator("text=登录")。 - XPath :功能强大但可能较慢且脆弱,慎用。
page.locator("//button[@id='submit']")。 - React/Vue 组件定位 :Playwright 独家支持,如果你测试的是基于这些框架的应用,定位会非常精准。
page.locator("_react=SubmitButton[enabled=true]")。
组合定位与过滤: Playwright 定位器支持链式调用,非常符合 Java 流的操作风格。
// 找到第一个 div 下的所有 li,然后过滤出包含“项目”文本的第二个
Locator item = page.locator("div.list-container > li")
.filter(new Locator.FilterOptions().setHasText("项目"))
.nth(1); // 索引从0开始
// 通过另一个元素来定位(比如在某个特定的表单里找输入框)
Locator form = page.locator("form#login-form");
Locator usernameInput = form.locator("input[name='username']");
避坑指南 :尽量避免使用基于索引的定位(如
:nth-child(3)),因为页面结构一变就失效。优先使用具有唯一性的 ID、属性,或者结合文本内容定位。Playwright 的text=定位器非常智能,它会进行子字符串匹配,且对空格换行不敏感,比 Selenium 的By.linkText好用得多。
4.2 基本交互操作:点击、输入与等待
定位到元素后,就可以进行交互了。Playwright 的所有交互操作都 内置了自动等待 。
// 点击操作
page.locator("button#submit").click(); // 等待按钮可点击后再点击
// 输入文本
page.locator("input#username").fill("myUsername"); // fill() 会先清空再输入
page.locator("input#username").type("myUsername"); // type() 是模拟键盘逐个输入
// 对于富文本编辑器等特殊场景,可能需要先点击再输入
page.locator("div[contenteditable=true]").click();
page.keyboard().type("Hello World");
// 处理下拉框(Select)
Locator countrySelect = page.locator("select#country");
countrySelect.selectOption("china"); // 通过 value 或 label 选择
countrySelect.selectOption(new SelectOption().setLabel("中国")); // 通过标签选择
// 上传文件(极其简单!)
page.locator("input[type='file']").setInputFiles(Paths.get("/path/to/file.pdf"));
// 上传多个文件
page.locator("input[type='file']").setInputFiles(new Path[] {Paths.get("file1.pdf"), Paths.get("file2.pdf")});
等待策略: 除了操作自带的等待,你还可以显式等待。
page.waitForSelector(“selector”): 等待某个元素出现在 DOM 中。page.waitForURL(“**url”): 等待导航到特定 URL。locator.waitFor(): 等待该定位器对应的元素满足某种状态(如可见、隐藏)。
// 等待加载动画消失
page.locator("div.loading-spinner").waitFor(new Locator.WaitForOptions().setState(WaitForSelectorState.HIDDEN));
// 等待某个元素出现并包含特定文本
page.locator("h1.success").waitFor(new Locator.WaitForOptions().setHasText(“操作成功”));
4.3 处理弹窗、框架与多标签页
对话框(Alert, Confirm, Prompt): Playwright 通过监听事件来处理对话框,无需像 Selenium 那样先切换再操作。
// 监听对话框事件,并在触发时接受(相当于点击“确定”)
page.onDialog(dialog -> {
System.out.println("对话框信息: " + dialog.message());
dialog.accept(); // 接受。dialog.dismiss() 是取消。
});
// 然后执行会触发对话框的操作,例如点击删除按钮
page.locator("button.delete").click();
Frame 和 iframe: 处理 iframe 的关键是先获取到 Frame 对象。
// 通过名称或 URL 定位 Frame
Frame frame = page.frame(“frame-name”);
// 或者通过选择器定位 iframe 元素,再获取其 contentFrame
Frame frame = page.locator(“iframe#myIframe”).contentFrame();
// 然后在 Frame 对象上进行操作,就像操作 Page 一样
frame.locator(“button.inside-frame”).click();
多标签页(Tabs):
// 点击一个会打开新标签页的链接(监听 popup 事件)
Page newPage = page.waitForPopup(() -> { // waitForPopup 返回新页面的 Page 对象
page.locator(“a[target=’_blank’]”).click();
});
// 现在可以操作新页面了
newPage.bringToFront(); // 切换到该标签页
System.out.println(newPage.title());
5. 高级特性与实战技巧
5.1 网络拦截与 Mock:提升测试稳定性与速度
这是 Playwright 的王牌功能之一。你可以拦截和修改任何网络请求,这对于测试以下场景至关重要:
- 屏蔽第三方资源 (如广告、分析脚本),加速测试。
- Mock API 响应 ,在后台服务不可用或未完成时,前端功能依然可测。
- 验证请求是否按预期发送 。
// 监听所有请求和响应
page.onRequest(request -> System.out.println(“>> “ + request.method() + “ “ + request.url()));
page.onResponse(response -> System.out.println(“<< “ + response.status() + “ “ + response.url()));
// 拦截并修改请求(例如,在所有请求头中添加一个令牌)
page.route(“**/*”, route -> {
Map<String, String> headers = new HashMap<>(route.request().headers());
headers.put(“X-Custom-Token”, “my-secret-token”);
route.resume(new Route.ResumeOptions().setHeaders(headers));
});
// 拦截特定请求并返回 Mock 数据(关键!)
page.route(“**/api/user/profile”, route -> {
// 构造一个模拟的 JSON 响应
Map<String, Object> mockData = Map.of(
“username”, “mockUser”,
“email”, “mock@example.com”
);
route.fulfill(new Route.FulfillOptions()
.setStatus(200)
.setContentType(“application/json”)
.setBody(playwright.gson().toJson(mockData))); // 使用 Playwright 内置的 Gson
});
// 中止对某些资源的请求(如图片、样式表),加快速度
page.route(“**/*.{png,jpg,jpeg,svg,css}”, route -> route.abort());
5.2 设备模拟与移动端测试
Playwright 内置了众多主流移动设备(如 iPhone, Pixel, Galaxy)的描述符,可以一键模拟。
// 使用预定义的设备描述符
BrowserContext iphoneContext = browser.newContext(playwright.devices().get(“iPhone 13 Pro”));
Page mobilePage = iphoneContext.newPage();
mobilePage.navigate(“https://m.example.com”);
// 此时 mobilePage 的视口、User-Agent、触摸事件等都模拟了 iPhone 13 Pro
// 自定义设备参数
BrowserContext customContext = browser.newContext(new Browser.NewContextOptions()
.setViewportSize(375, 812) // 视口大小
.setDeviceScaleFactor(3) // 设备像素比
.setIsMobile(true)
.setHasTouch(true)
.setUserAgent(“Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) …”));
5.3 录制与代码生成:快速创建脚本骨架
对于初学者或快速探索新页面, playwright codegen 是神器。虽然它是一个命令行工具,但生成的是 Java 代码。
- 打开终端,运行:
mvn exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args=“codegen https://example.com” - 会自动打开两个窗口:一个浏览器,一个代码生成器。
- 在浏览器中操作,右侧的代码生成器会实时生成对应的 Java 代码。
- 操作完成后,你可以将生成的代码复制到你的 IDE 中,作为脚本的起点。
注意事项 :生成的代码通常比较“直白”,可能包含大量基于索引的定位。你需要手动优化这些定位器,使其更具可读性和鲁棒性(例如,将
locator(‘:nth-child(3)’)改为更具语义的定位)。
5.4 集成测试框架与生成报告
单纯的脚本还不够,我们需要将其集成到测试框架中,并生成漂亮的报告。这里以 JUnit 5 和 Allure 为例。
1. 集成 JUnit 5: 添加 JUnit 依赖,并利用 @BeforeEach , @AfterEach 管理 Playwright 生命周期。
import com.microsoft.playwright.*;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
public class LoginTest {
// 共享的静态变量
static Playwright playwright;
static Browser browser;
// 每个测试独立的变量
BrowserContext context;
Page page;
@BeforeAll
static void launchBrowser() {
playwright = Playwright.create();
browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(true)); // CI 环境用无头
}
@AfterAll
static void closeBrowser() {
browser.close();
playwright.close();
}
@BeforeEach
void createContextAndPage() {
context = browser.newContext();
// 可以在这里设置全局的 Viewport、User-Agent 等
page = context.newPage();
}
@AfterEach
void closeContext() {
context.close();
}
@Test
void shouldLoginSuccessfully() {
page.navigate(“https://your-app.com/login”);
page.locator(“input#username”).fill(“testuser”);
page.locator(“input#password”).fill(“password123”);
page.locator(“button[type=’submit’]”).click();
// 使用 Playwright 的断言,它自带等待
assertTrue(page.locator(“text=欢迎回来,testuser”).isVisible());
}
}
2. 生成 Allure 报告并附加失败截图/视频: Playwright 支持在测试失败时自动截图和录制视频,这结合 Allure 非常强大。
首先,在创建 BrowserContext 时配置录像选项:
@BeforeEach
void createContextAndPage() {
// 为每个测试 Context 设置录像,保存到 videos 目录
context = browser.newContext(new Browser.NewContextOptions()
.setRecordVideoDir(Paths.get(“target/videos/”))); // Maven 项目通常输出到 target
page = context.newPage();
}
@AfterEach
void closeContext(TestInfo testInfo) {
// 测试结束后,保存视频并附加到 Allure 报告
if (context != null) {
// 获取该 Context 录制的视频路径
Path videoPath = context.video().path();
context.close();
// 仅当测试失败且视频文件存在时,附加到报告
if (testInfo.getStatus() == TestStatus.FAILED && videoPath.toFile().exists()) {
Allure.addAttachment(“测试执行视频”, “video/webm”, Files.newInputStream(videoPath), “.webm”);
}
}
}
同时,在 @AfterEach 中也可以添加失败截图:
if (testInfo.getStatus() == TestStatus.FAILED) {
// 截图并附加到 Allure
byte[] screenshot = page.screenshot(new Page.ScreenshotOptions().setFullPage(true));
Allure.addAttachment(“失败截图”, “image/png”, new ByteArrayInputStream(screenshot), “.png”);
}
最后,配置你的 Maven pom.xml 或 Gradle 以使用 Allure 插件运行测试并生成报告。
6. 常见问题排查与性能优化
6.1 典型错误与解决方案速查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
TimeoutError: Timeout 30000ms exceeded. |
1. 元素定位器找不到或永远不满足可见/可点击状态。 2. 页面加载太慢或网络请求阻塞。 |
1. 检查定位器是否正确,使用 page.pause() 或浏览器开发者工具复核。 2. 增加超时时间: locator.click(new Locator.ClickOptions().setTimeout(60000)) 。 3. 检查是否有未处理的模态框遮挡。 |
Error: Target closed |
页面或浏览器在你尝试操作时已被关闭。 | 检查代码逻辑,确保在操作 Page 对象时,其所属的 Context 和 Browser 未被提前关闭。常见于异步操作未正确同步。 |
Element is not attached to the DOM |
你定位到的元素在操作前已被从页面移除(动态 DOM)。 | 1. 使用更稳定的定位器,避免定位到动态生成的容器内部元素。 2. 使用 locator.waitFor() 确保元素稳定存在再操作。 3. 考虑使用 page.waitForFunction() 等待某个 JavaScript 条件成立。 |
| 脚本在 CI 服务器上失败,本地却成功 | 1. CI 环境是无头模式,可能与有头模式行为有细微差异。 2. CI 环境资源(CPU/内存)不足。 3. 网络或代理设置不同。 |
1. 本地也使用 setHeadless(true) 运行测试,复现问题。 2. 为 Browser 启动增加参数: .setArgs(Arrays.asList(“--disable-dev-shm-usage”, “--no-sandbox”)) 解决 Docker 中常见问题。 3. 在 CI 脚本中明确设置 HTTP 代理或无代理。 |
| 文件上传不工作 | 文件选择输入框可能是动态生成或隐藏在复杂组件中。 | 1. 确保 setInputFiles 调用在输入框可见可交互之后。 2. 对于隐藏的输入框,可能需要先用 JavaScript 使其可见: page.evalOnSelector(“input[type=’file’]”, “el => el.style.display = ‘block’”) 。 3. 考虑使用 Page.setInputFiles 方法。 |
| 页面卡在加载状态 | 页面有未完成的 long-polling 请求或 WebSocket 连接。 | 使用 page.waitForLoadState(LoadState.NETWORKIDLE) 等待网络空闲,或使用 page.waitForTimeout() 作为最后手段,但尽量避免。 |
6.2 性能优化与最佳实践
- 复用 Browser 和 Context :创建 Browser 实例开销最大。在测试套件级别(
@BeforeAll)创建并共享一个 Browser 实例,在每个测试用例(@BeforeEach)中创建独立的 Context。这是平衡隔离性和性能的最佳实践。 - 善用无头模式 :在 CI/CD 环境中务必使用
setHeadless(true)。如果需要调试,可以通过环境变量控制,或者使用setHeadless(false).setSlowMo(500)(slowMo可以减慢操作速度,方便观察)。 - 拦截不必要的资源 :使用
page.route拦截并中止对图片、字体、样式表等静态资源的请求,可以显著提升测试执行速度。 - 并行执行 :Playwright 天生支持并行。在 JUnit 中,可以通过
@Execution(ExecutionMode.CONCURRENT)注解(需配合junit-platform.properties配置)实现测试类或方法级别的并行。确保每个测试线程使用自己独立的 Context。 - 选择正确的等待 :优先使用 Playwright 内置的自动等待和
locator.waitFor(),避免硬编码Thread.sleep。对于复杂的自定义等待条件,使用page.waitForFunction()。 - 定期清理 :确保在
@AfterEach和@AfterAll中正确关闭 Context 和 Browser,防止资源泄漏导致内存不足。
6.3 调试技巧
-
page.pause():在代码中插入这行,运行时会自动打开 Playwright Inspector,你可以单步执行、查看当前 DOM 快照、实时生成定位器,是最强的调试工具。 - 录制追踪(Tracing) :在测试开始时启动追踪,结束时停止并保存。它记录了测试期间的所有操作、网络请求、控制台日志,生成一个可视化的 ZIP 文件,可以用浏览器打开复盘。
@BeforeEach void startTracing() { context.tracing().start(new Tracing.StartOptions().setScreenshots(true).setSnapshots(true)); } @AfterEach void stopTracing(TestInfo testInfo) { context.tracing().stop(new Tracing.StopOptions() .setPath(Paths.get(“target/traces/” + testInfo.getDisplayName() + “.zip”))); } - 查看控制台日志 :
page.onConsoleMessage(msg -> System.out.println(“CONSOLE: “ + msg.text()));
从概念理解到环境搭建,从基础操作到高级应用,再到集成调试,Playwright for Java 提供了一套完整、现代且高效的浏览器自动化解决方案。它降低了过去在 Selenium 中常见的配置和维护成本,将开发者的精力更多地聚焦在测试逻辑和业务验证本身。开始尝试将它引入你的下一个项目吧,你会发现编写和维护自动化脚本,不再是一件令人望而生畏的苦差事。
更多推荐

所有评论(0)