Java中使用远程PlayWright进行网页接口测试(附Docker部署方式)

0. PlayWright简介

PlayWrightSelenium 相比,具有Api更灵活、无需浏览器Driver 的特点,特别是在当下AI盛行的时代,使用PlayWright 进行自动化测试已为WEB研发人员必需了解的技能。

PlayWright由微软发起,其开源地址为:https://github.com/microsoft/playwright

PlayWright 支持 Chromium, Firefox, WebKit on Linux这些主流浏览器,且支持多种语言的API,如:Python.NETJavaNode.js等。

在本文中,将使用PlayWright 配合服务器中的Java程序 ,通过具体示例的方式,完成对PlayWright的熟悉

1. PlayWright简单使用(控制本地浏览器)

以让PlayWright 打开一个URL为例,演示一下它的用法。

假设需要打开的URL为:http://bilibili.com/video/BV1oN7A67EFU,这里使用的编程语言为java。

使用前,先在在pom文件 中引入playwright的依赖:

xml 复制代码
        <dependency>
            <groupId>com.microsoft.playwright</groupId>
            <artifactId>playwright</artifactId>
            <version>1.59.0</version>
        </dependency>

再编写以下代码并运行:

java 复制代码
        try (Playwright playwright = Playwright.create()) {
            // 1. 获取 Chromium 浏览器
            BrowserType chromium = playwright.chromium();
            // 2. 启动浏览器
            // headless(false) 表示显示浏览器窗口,方便你观察
            Browser browser = chromium.launch();
            // 3. 新建页面
            Page page = browser.newPage();
            // 4. 打开页面
            String url = "https://www.bilibili.com/video/BV1oN7A67EFU";
            System.out.println("正在打开页面:" + url);
            page.navigate(url);
            // 5. 等待页面加载
            page.waitForLoadState();
            Thread.sleep(3_000);
            // 6. 输出页面信息
            System.out.println("页面已打开");
            System.out.println("当前 URL:" + page.url());
            System.out.println("页面标题:" + page.title());
            // 7. 关闭浏览器
            browser.close();
            System.out.println("浏览器已关闭");
        }

运行结果为:

从运行结果可以看出,它成功打开了指定的URL,并将标题输出到了控制台中。

在整个运行过程中,它没有打开界面,这是因为默认用的是chromium无头模式 ,如需要查看到界面,可以将headless 设置为false,这样就可以看到具体的界面,以方便观察了。

2. PlayWright简单使用(控制远程浏览器)

有时,我们需要在我们的服务中调用PlayWright ,但服务中是没有部署浏览器的(如linux中以docker方式运行的java程序),这时就需要用到PlayWright 的远程模式。

依旧使用上面的示例功能,这时需要将代码进行改造:

java 复制代码
        try (Playwright playwright = Playwright.create()) {
            // 1. 获取远程 Chromium 浏览器
            // 2. 启动浏览器
            Browser browser = playwright.chromium().connect("ws://192.168.140.110:3000");
            // 3. 新建页面
            Page page = browser.newPage();
            // 4. 打开页面
            String url = "https://www.bilibili.com/video/BV1oN7A67EFU";
            System.out.println("正在打开页面:" + url);
            page.navigate(url);
            // 5. 等待页面加载
            page.waitForLoadState();
            Thread.sleep(3_000);
            // 6. 输出页面信息
            System.out.println("页面已打开");
            System.out.println("当前 URL:" + page.url());
            System.out.println("页面标题:" + page.title());
            // 7. 关闭浏览器
            browser.close();
            System.out.println("浏览器已关闭");
        }

其中connect 中的参数ws://192.168.140.110:3001PlayWright容器的地址,如我这里是以Docker启动的,命令为:

docker run -p 3000:3000 --rm --init -it --workdir /home/pwuser --user pwuser mcr.microsoft.com/playwright:v1.59.0-noble /bin/sh -c "npx -y playwright@1.59.0 run-server --port 3000 --host 0.0.0.0"

在上面这个playwright 的容器中,它内置了一个playwright 运行所需要的默认浏览器。(https://playwright.dev/docs/browsers#install-browsers

上面的java程序运行结果为:

从运行结果看到,它和本地启动的PlayWright没有什么区别。

但需要注意的是,如果使用PlayWright的远程模式 时,需要在JAVA程序的POM中添加以下配置:

复制代码
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <requiresUnpack>
                        <dependency>
                            <groupId>com.microsoft.playwright</groupId>
                            <artifactId>driver-bundle</artifactId>
                        </dependency>
                    </requiresUnpack>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>

并将java容器的docker镜像构建时的form 修改为FROM eclipse-temurin:21-jre-jammy,这样拥有更多的内置包,避免运行时缺少相关依赖。

3. playwright-mcp与chrome-devtools-mcp应用场景

最后,本文中提到了很多PlayWright ,那我们也需要了解一下它和chrome-devtools 的区别和应用场景。

PlayWright 与诸如chrome 这样的浏览器通信时,它也是使用的Chrome DevTools Protocol 通信协议,但PlayWright 的API包装性更好

为便于理解,可用下图展示:

同时,随着AI工具的普及,playwrightchrome 也都有各自对应的mcp ,分别为:playwright-mcpchrome-devtools-mcp,它们都可以添加到相关的AI工具中。使用时,它们的使用区别也主要一个更适合用于测试业务流程 ,另一个适合用于单一事件

这里以这两个MCP的实际使用示例,看一下它们的区别,先确保已经安装了这两个mcp,我这里使用的AI工具是claude code

3.1 playwright-mcp使用示例

现在让playwright-mcpchrome-devtools-mcp都完成同一件事,看一下区别。

任务为:打开https://blog.csdn.net/puhaiyang这个博客地址,并获取出这个博客中最新文章的标题

当使用playwright-mcp时,首次使用这样发送提示词:

复制代码
使用 Playwright MCP 打开 https://blog.csdn.net/puhaiyang,
获取页面中最新一篇文章的标题。
要求:
1. 打开页面;
2. 等待文章列表加载完成;
3. 获取文章列表第一篇文章标题;
4. 输出标题;
5. 如果可以,顺便生成一段 Playwright 脚本。

之后,当有了playwright的脚本之后,后面再去完成这个任务,就可直接让AI完成这个任务了,如:

运行get-csdn-latest-article.js,完成这个任务

其中的get-csdn-latest-article.js中的内容为:

node.js 复制代码
/**
 * 获取 CSDN 博主最新一篇文章标题
 * 使用方式:
 *   1. 安装依赖: npm init -y && npm install playwright
 *   2. 运行脚本: node get-csdn-latest-article.js [博主ID]
 *   示例: node get-csdn-latest-article.js puhaiyang
 */
const { chromium } = require('playwright');

async function getLatestArticleTitle(username = 'puhaiyang') {
  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({
    userAgent:
      'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' +
      'AppleWebKit/537.36 (KHTML, like Gecko) ' +
      'Chrome/120.0.0.0 Safari/537.36',
  });
  const page = await context.newPage();

  const url = `https://blog.csdn.net/${username}`;
  console.log(`正在访问: ${url}`);

  await page.goto(url, { waitUntil: 'domcontentloaded' });

  // 等待文章列表加载完成(CSDN 文章块 class 为 blog-list-box)
  await page.waitForSelector('article.blog-list-box', { timeout: 20000 });

  // 取第一篇文章标题(CSDN 标题在 h4 内)
  let title;
  try {
    title = await page
      .locator('article.blog-list-box')
      .first()
      .locator('h4')
      .first()
      .innerText();
  } catch (e) {
    // 兜底:直接取 article 内文本
    title = await page
      .locator('article.blog-list-box')
      .first()
      .innerText();
  }

  console.log('==================================================');
  console.log(`博主 ${username} 的最新文章标题: ${title.trim()}`);
  console.log('==================================================');

  await browser.close();
  return title.trim();
}

// 从命令行参数读取博主 ID,默认 puhaiyang
const targetUser = process.argv[2] || 'puhaiyang';
getLatestArticleTitle(targetUser).catch((err) => {
  console.error('执行失败:', err);
  process.exit(1);
});

运行结果为:

3.2 chrome-devtools-mcp使用示例

当使用chrome-devtools-mcp时,发送的提示词为:

使用 Chrome DevTools MCP 打开 https://blog.csdn.net/puhaiyang,并获取页面中最新一篇文章的标题

输出结果为:

3.3 playwright-mcp/chrome-devtools-mcp应用场景总结

从上面3.13.2 两个示例可以看到,这两个mcp的输出结果是一致的,但如果有了playwright 的脚本之后再去执行某个任务,与全描述chrome-devtools-mcp的提示词相比,它的执行速度会更快,且消耗最少的token,对于业务功能测试的场景更为合适。

而对于一次性场景和单一功能性能分析的场景,chrome-devtools-mcp就更合适。

相关推荐
farerboy1 小时前
23-Java 构造函数
java·后端
坚持的小马1 小时前
Rocketmq搭建操作步骤
java·rocketmq·java-rocketmq
砚底藏山河2 小时前
多家股票数据接口对比、企业级股票数据API
java·python·金融·maven
VX_bysjlw9852 小时前
基于微信小程序的宠物用品商城系统-后端74346-计算机毕设原创(免费领源码+带部署教程)
java·redis·微信小程序·eclipse·mybatis·idea·微信开发者工具
JAVA面经实录9172 小时前
图解23种设计模式完整知识体系(Java后端面试完整版)
java·架构
会飞的大鱼人3 小时前
一文搞懂 Java HashSet:把它想成游乐园里只允许一次入场的盖章名单
java·开发语言·windows
AI_小站3 小时前
Loop Engineering又是啥?一文讲清企业Agent落地的四层工程进化论
java·人工智能·架构·prompt·大模型开发·智能体·大模型应用
jiay23 小时前
【.net10】顶级程序语句
java·开发语言
2601_953824614 小时前
【计算机毕业设计】基于Spring Boot的画师接稿平台设计与实现
java·spring boot·后端
小宋10214 小时前
不用学算法也能玩转 AI?普通 Java 程序员转 AI 应用开发路线
java·人工智能·重构