Playwright CLI + Skills:编程 Agent 的浏览器工具调用与执行架构

0 阅读16分钟

Claude Code、Codex 已经能够读取项目代码、执行命令,为什么还需要专门安装 Playwright CLI + Skills?微软推出的这套浏览器自动化工具链,将页面访问、元素定位、交互执行和测试代码生成整合进编程 Agent 的工作流程。本文结合官方实现和 TodoMVC 测试案例,拆解 Skill 加载、CLI 命令执行、浏览器会话管理与 Playwright Test 的协作机制,并讨论它在真实测试开发项目中的使用方式。

一、让 AI 操作浏览器不难,难的是把操作变成测试代码

假设你正在维护一个 Web 自动化测试项目。

产品经理提了一个需求:用户在后台新增一条记录,保存后必须能在列表中查询到,并且状态显示正确。

以前的做法比较熟悉。

打开页面,按 F12 检查元素,编写 Playwright 脚本,补充断言,再运行测试。

现在可以把任务交给 Claude Code:

打开测试页面,找到新增入口,填写表单并提交。验证列表中出现新增记录,然后生成对应的 Playwright TypeScript 测试代码。

问题来了。

Claude Code 虽然会写代码,但它怎么知道当前页面有哪些按钮?怎么找到输入框?执行点击后,怎么确认页面已经发生变化?

更进一步,浏览器里操作成功了,如何把这些操作转成能够在 CI 流水线中反复执行的测试用例?

Playwright MCP 可以解决浏览器交互问题。不过,对于经常需要同时读取代码、修改脚本、运行终端命令的编程 Agent,微软还提供了另一套工具:Playwright CLI + Skills。

Playwright 官方将其定位为面向 Coding Agent 的浏览器自动化接口,支持 Claude Code、GitHub Copilot 等编程工具通过命令行控制浏览器,并利用 Skills 获取操作规范。

这一篇我们先研究它的工作原理,弄清以下几个技术问题:

  • Agent 如何通过 Skill 发现浏览器工具?
  • 每条 CLI 命令背后,浏览器是怎么执行操作的?
  • CLI 命令结束后,为什么浏览器状态没有丢失?
  • Agent 如何将浏览器操作转换成正式的 Playwright 测试代码?

二、先看架构:Skill、CLI、Playwright 各负责什么?

Playwright CLI + Skills 涉及几个组件,但它们的职责并不相同。

组件主要职责
Coding Agent理解测试需求、规划操作、读写项目代码
Agent Skill提供命令说明、操作约束及测试工作流程
Playwright CLI接收命令,调用浏览器自动化能力
浏览器会话保留页面、Cookie、交互状态等运行上下文
Playwright Test执行生成的测试代码,完成断言及回归

其中有个容易误解的地方。

Skill 不会自己打开浏览器,也不是另一个大模型。

它是一套可以被 Agent 读取的技能说明。Agent 根据说明选择 CLI 命令,再通过终端执行浏览器操作。

1. 整体技术架构

图 1:Playwright CLI + Skills 浏览器自动化执行架构

从这张图可以看到,浏览器操作会形成一个反馈循环。

Agent 先决定执行什么命令,CLI 把操作交给浏览器,浏览器返回当前页面信息。

Agent 根据返回结果继续操作,直到完成测试任务。

整个过程中,Skills 主要负责告诉 Agent 怎么合理使用这些命令,以及面对不同任务时应当遵循什么流程。

2. 为什么已经能调用 Shell,还需要 Skills?

其实不安装 Skills,Agent 也能使用 Playwright CLI。

官方就提供了这种用法:让 Agent 读取 playwright-cli --help,自行了解可用命令。

但在稍微复杂一点的任务中,知道有哪些命令远远不够。

例如,用户要求:

“根据登录页面生成三条自动化测试用例。”

Agent 需要先考虑测试环境、是否复用登录状态、怎样识别元素、需要覆盖哪些异常场景,以及生成代码后如何验证。

这些步骤如果全部依赖 Agent 临时规划,每次执行都可能有所不同。

Playwright 官方 Skill 把一些常用流程整理成了可以复用的操作说明,例如:

  • 浏览器交互与页面检查;
  • 测试规划、生成与修复(Plan → Generate → Heal);
  • 浏览器会话管理与登录态保存;
  • 网络 Mock、Trace 和测试调试。

这些能力可以在官方 Playwright CLI Skill 文件 中找到。

这里要注意,Skill 能帮助 Agent 采用更一致的操作流程,但不保证它每次都能正确执行。最终仍要靠测试断言和执行结果来验证。

三、快速上手:在 Claude Code 中安装 Playwright CLI + Skills

先把环境搭起来。

按照 Playwright 官方入门文档,建议准备 Node.js 20 或更新版本,以及一个支持终端命令执行的编程 Agent。

1. 安装 Playwright CLI

在终端执行:

npm install -g @playwright/cli@latest

安装完成后检查:

playwright-cli --version
playwright-cli --help

如果不希望全局安装,也可以在项目中添加开发依赖:

npm install -D @playwright/cli@latest

npx playwright cli --help

本文后面使用全局安装的 playwright-cli 命令。

2. 安装 Playwright Skills

进入测试项目根目录:

playwright-cli install --skills

以 Claude Code 为例,安装后的项目目录可以理解为:

web-testing/
├── .claude/
│   └── skills/
│       └── playwright-cli/
│           ├── SKILL.md
│           └── references/
├── tests/
│   └── todo.spec.ts
├── playwright.config.ts
└── package.json

SKILL.md 是 Agent 使用这套工具的入口说明,references 目录保存更具体的任务指南。

如果希望在多个项目中复用 Skills,还可以使用全局安装:

playwright-cli install --skills -g

使用 Codex 等采用 .agents/skills 布局的工具时,可根据客户端支持情况选择:

playwright-cli install --skills=agents

安装完成后,便可以在 Claude Code 中输入自然语言测试任务,由 Agent 根据已加载的 Skill 使用 CLI。

3. Skill 如何影响工具调用?

不妨看一个实际任务。

用户要求 Agent 测试登录功能。

没有明确工作流程时,Agent 可能直接生成一份测试代码,然后运行。若定位器是根据经验猜出来的,就容易出现元素找不到的问题。

使用 Playwright Skills 后,Agent 可以按照对应指南,先进入浏览器查看页面,再执行操作并利用实际输出生成测试代码。

图 2:Agent 读取 Skill 并完成浏览器测试图

这张图反映的是典型的执行过程,并不意味着所有 Agent 客户端都会严格按照相同顺序调用工具。

工程上需要注意两点。

首先,Skill 可以提供规范,但是否采用该流程仍取决于 Agent 的工具选择和任务执行。

其次,CLI 的操作成功只证明相应的浏览器交互完成了。测试是否通过,还需要检查业务结果。

这两个环节要区分清楚。

四、深入执行原理:CLI 每调用一次,都会重新启动浏览器吗?

这是 Playwright CLI 架构里值得重点研究的部分。

看下面这段命令:

playwright-cli open https://demo.playwright.dev/todomvc/

playwright-cli snapshot

playwright-cli type "学习 Playwright"

playwright-cli press Enter

每一条都是单独的终端命令。

按照一般 CLI 工具的使用习惯,命令运行结束,进程就退出了。

那为什么第二条命令还能访问第一条命令打开的页面?第三条命令又为什么能继续操作同一个浏览器?

答案在于 Playwright CLI 的持久化浏览器进程和会话管理机制。

官方文档将它称为 Daemon Architecture。CLI 将命令执行与持续存在的浏览器会话分离,避免每条命令都重新启动浏览器。

图 3:Playwright CLI 持久化浏览器会话机制

这种架构有两个实际好处。

第一个是减少浏览器初始化成本。

打开页面、填写表单、点击保存等操作可以在同一会话中完成,不用每条命令都重新创建浏览器。

第二个是保留交互上下文。

例如登录后台后,再执行列表查询、打开详情、修改记录等操作,仍然可以在原有会话中继续进行。

不过,默认保存在会话中的浏览器状态并不等于永久持久化。浏览器关闭后,内存中的状态可能丢失。如果需要保存 Cookie 和 Storage State,可以使用 state-save、state-load,或根据场景配置持久化 Profile。

多个测试任务会不会互相干扰?

Playwright CLI 支持命名会话。

# 打开第一个测试会话
playwright-cli -s=admin open https://example.com/

# 打开第二个测试会话
playwright-cli -s=user open https://example.com/

# 查看会话
playwright-cli list

# 关闭指定会话
playwright-cli -s=admin close

这样可以让不同任务在各自的浏览器会话里运行。

对于测试开发团队,多会话能力很实用。例如同时验证管理员和普通用户的权限,避免两个测试任务复用同一个浏览器上下文。

但会话隔离不代表后端数据也隔离。两个会话如果操作同一条业务记录,仍然可能发生测试数据冲突。

五、实战案例:从浏览器交互生成 Playwright 测试代码

下面使用 Playwright 官方 TodoMVC 示例:

demo.playwright.dev/todomvc/

任务很简单:新增待办事项,再将它标记为完成。

这次我们关心的不只是页面操作,还要观察 CLI 如何为 Agent 提供可复用的测试代码。

1. 打开页面并获取快照

执行:

playwright-cli -s=todo-demo open \
  https://demo.playwright.dev/todomvc/ --headed

--headed 表示使用有界面模式,方便观察浏览器行为。不指定时,CLI 默认以无头模式运行。

随后获取快照:

playwright-cli -s=todo-demo snapshot

CLI 会返回类似下面的信息:

### Page
- Page URL: https://demo.playwright.dev/todomvc/#/
- Page Title: React • TodoMVC

### Snapshot
[Snapshot](.playwright-cli/page-xxxx.yml)

这是根据官方文档整理的输出格式示例,实际快照文件名由执行时间等因素决定。

快照文件保存了页面可访问性结构以及元素引用。

与每次直接输出完整页面 DOM 相比,这种文件化的方式允许 Agent 根据任务需要读取信息。

2. 找到输入框并新增事项

可以先使用 find 搜索:

playwright-cli -s=todo-demo \
  find "What needs to be done?"

定位目标后填写内容:

playwright-cli -s=todo-demo \
  fill "getByPlaceholder('What needs to be done?')" \
  "学习 Playwright CLI" --submit

--submit 会在填写后提交输入,相当于在这个场景中按下回车。

随后执行:

playwright-cli -s=todo-demo snapshot

确认新增事项出现在页面中。

再勾选对应复选框:

playwright-cli -s=todo-demo \
  check ".todo-list li .toggle"

最后重新获取页面快照,确认事项状态。

这里使用 CSS 定位器只是为了让命令示例方便复现。实际由 Agent 执行时,可以根据页面语义快照生成更合适的定位器。

3. CLI 如何生成 TypeScript 代码?

这是它在测试开发场景下比较有价值的功能。

Playwright CLI 的交互命令可以输出对应的 Playwright TypeScript 代码。

例如执行表单填写后,CLI 的操作结果中会包含类似:

await page.getByPlaceholder(
  'What needs to be done?'
).fill('学习 Playwright CLI');

Agent 可以将这些操作记录整理为 .spec.ts 文件。

不过,生成操作代码不等于自动生成了正确的业务断言。

完整的测试还需要根据业务需求补充验证条件。官方测试生成 Skill 也明确区分了操作代码与断言生成两个步骤。

4. 将浏览器操作整理成自动化测试

以下是一份可作为工程示例的测试代码:

// tests/todo.spec.ts

import { test, expect } from '@playwright/test';

test('新增并完成待办事项', async ({ page }) => {
  await page.goto(
    'https://demo.playwright.dev/todomvc/'
  );

  const title = '学习 Playwright CLI';

  // 新增事项
  const input = page.getByPlaceholder(
    'What needs to be done?'
  );

  await input.fill(title);
  await input.press('Enter');

  // 验证新增结果
  const todo = page.locator('.todo-list li')
    .filter({ hasText: title });

  await expect(todo).toHaveCount(1);

  // 标记事项为已完成
  await todo.locator('input.toggle').check();

  // 验证完成状态
  await expect(todo).toHaveClass(/completed/);
});

将文件保存到 Playwright 项目后运行:

npx playwright test tests/todo.spec.ts

如果断言通过,就说明这条测试满足了我们定义的新增与完成场景。

此处代码是按照官方示例页面编写的可复现案例,本文没有对它进行本地实测,因此不提供虚构的测试通过日志。

一个关键细节:CLI 快照中的 e12、e21 等引用只适用于当前浏览器交互上下文。正式测试代码应使用稳定的 Locator,而不能依赖这些临时引用。

六、从一次浏览器操作到一条可维护的测试用例,中间还差什么?

很多 AI 浏览器自动化演示,到页面点击成功就结束了。

对于测试开发项目,这个结果还不够。

比如 Agent 在浏览器里成功点击了“保存”,但没有验证新增数据是否出现在列表,也没有验证状态是否正确。

这段操作即使生成了 Playwright 代码,也只能算一段自动化交互脚本。

进入正式测试项目,还需要补充业务断言、处理初始数据和测试环境,并保证能够重复执行。

官方 Playwright CLI Skills 提供的 Plan → Generate → Heal 流程,正是围绕这类测试工程任务组织的。

图 4:Playwright CLI 从测试需求到可回归测试的工作流

这套流程比较适合放进现有的测试开发项目。

例如,Agent 先根据需求建立测试计划,再探索页面生成测试代码,最后使用 Playwright Test 运行并验证。

对于已经存在的 Playwright 测试项目,官方还支持使用 --debug=cli 启动调试会话,再通过 playwright-cli attach 附着到该会话。

这样 Agent 能够在项目原本的 Fixture、登录态和测试环境下进行调试,不需要重新构造一套完全独立的浏览器环境。

至于 Agent 如何接管执行中的测试、检查失败节点和修改定位器,我们会在后续的调试专题中详细展开。

七、为什么 CLI + Skills 适合编程 Agent?

理解了执行流程之后,再看它与 MCP 的主要区别就容易多了。

Playwright MCP 通过结构化工具协议对外提供浏览器能力。

CLI + Skills 则使用 Agent 已经具备的 Shell 执行能力,调用命令行工具,并根据需要读取页面信息。

对于经常同时处理项目代码、日志、测试报告的 Agent,这种方式可以减少额外的工具集成工作。

另一个优势是上下文管理。

CLI 通常将页面快照保存为文件,Agent 可以在需要时读取相关信息。对于大型业务页面,如果不必每一步都读取完整语义树,就有机会降低上下文占用。

不过,CLI 并不天然保证更少 Token 或更高任务成功率。

模型是否反复读取页面、Skill 是否被正确使用、页面结构是否复杂,都会影响最终执行成本。新版 MCP 也具备快照文件化等优化能力,因此具体性能差异需要受控实验来确认。

工程选型时,可以把两套方案理解为不同的工具接口。

工程问题CLI + Skills 的处理方式
Agent 如何发现工具?读取 Skill 与 CLI 帮助信息
如何操作浏览器?执行 CLI 命令
如何保持页面状态?浏览器会话管理
如何获取页面结构?语义快照与元素查询
如何生成测试代码?汇总操作生成的 TypeScript
如何接入现有测试项目?Playwright Test 与代码仓库
如何确认测试成功?明确断言与回归结果

如果团队本身已经使用 Claude Code、Codex 进行测试代码维护,CLI + Skills 可以作为一条相对自然的浏览器交互路径。

而对于专门建设的浏览器 Agent 平台,MCP 的结构化工具调用方式仍然值得考虑。

八、真实项目落地,还需要解决三个问题

第一个是会话和测试数据隔离。

多个 Agent 同时执行时,应该使用独立会话,尽量避免共享同一份可变测试数据。对于登录态文件、Cookie 和页面截图,还需要做好权限控制,防止敏感信息进入不该出现的日志和代码仓库。

第二个是操作记录与业务断言的区别。

CLI 可以帮助生成浏览器操作代码,但业务预期必须来自需求、测试计划或明确的验收标准。不能仅根据页面当前显示的内容,反过来决定测试应该断言什么。

第三个是将生成结果纳入代码审核。

Agent 生成的测试代码需要检查 Locator 的稳定性、等待策略、测试数据清理和断言完整性。涉及权限、支付、订单等关键业务时,尤其不能让 Agent 为了通过测试而擅自删除断言或修改预期结果。

这些问题处理好,CLI + Skills 才适合进入持续使用的自动化测试流程。

九、写在最后

Playwright CLI + Skills 给编程 Agent 提供了一套比较完整的浏览器工具链。

Skill 让 Agent 知道有哪些操作能力、应该按什么流程执行;CLI 负责调用浏览器;持久化会话保留页面状态;交互产生的代码可以进一步整理成 Playwright Test 用例。

对于测试开发工程师,这套方案最方便的地方,是可以直接在已有代码仓库中完成页面探索、脚本生成、调试和回归。

但实际项目里,仍然建议把 Agent 的浏览器探索工作与正式测试执行分开。

新功能出现时,让 Agent 帮忙生成测试代码;页面发生变化时,让 Agent 辅助排查;日常几百条自动化用例的稳定回归,继续交给 Playwright Test 和 CI。

这样既能利用 AI Agent 处理需要分析和判断的工作,也能保留传统自动化测试在可重复执行方面的优势。

本文部分内容参考了霍格沃兹测试开发学社整理的相关技术资料,主要涉及软件测试、自动化测试、测试开发及 AI 测试等内容,侧重测试实践、工具应用与工程经验整理。