GitHub 实战课|Playwright MCP:让 AI 真的会用浏览器

「漫说测试」· GitHub 实战课 · 第 1 课

面向测试工程师的热门开源项目手把手课:把「浏览器」变成 AI 能调用的工具,让 AI 真的会点、会填、会验。 全程真跑通,附完整可运行 demo + 各类客户端的 MCP 配置 + 指令执行层级 + 一份能直接抄的测试提示词。

【贴图1】


一、为什么第 1 课选它

如果要让测试工程师只挑一个 当下最该上手、又和 AI 沾边的开源项目,我的答案是它:Playwright MCP。

  • 出身正

    :微软官方出的 MCP server ,托管在 microsoft/playwright-mcp,是 GitHub 上最受关注的开源项目之一^1;

  • 正好踩中风口

    :MCP(Model Context Protocol)是现在 AI 界最火的"给 AI 接工具"标准,而浏览器,是 AI 最想学会用的那个工具;

  • 对测试人是"降维打击"

    :它让 AI 真的去操作一个浏览器 ------点按钮、填表单、断言结果。这不就是端到端测试在做的事吗?

一句话:它把"AI 测试"从 PPT 里拽到了真实浏览器里。

【贴图2】


二、它到底是什么?

分两层理解,特别顺:

第一层,MCP :一个开放协议------让 AI 像"插 USB"一样接上各种工具(数据库、文件、CLI......还有浏览器)^2。

第二层,Playwright MCP :微软按这个协议写的浏览器服务器 ------AI 通过它,能拿到当前页面的状态 ,并调用一整套交互工具:打开页面、点击、输入、滚动、断言、截图......^3。

配置也简单到离谱(以 Claude Code 为例)^2:

bash 复制代码
claude mcp add playwright npx @playwright/mcp@latest

就这一行,AI 就"长"出了一双手,能替你操作浏览器了。

【贴图3】


三、关键点:它靠"无障碍树",不靠截图

这是 Playwright MCP 最值得说的设计,也是它比一堆"看图点击"的 AI 浏览器方案更靠谱的原因。

很多 AI 操作浏览器,靠的是截屏 + 视觉识别 :"这一坨像素像是按钮,点它。"------慢、贵、还不稳。

Playwright MCP 走的是另一条路:它给 AI 的是页面的「无障碍树(accessibility tree)」 ------也就是结构化地告诉 AI"这页面上有哪些按钮、输入框、链接,它们叫什么、状态如何"^4。

好处很直接:

  • 不用截图

    → 更快、更省 token;

  • 语义化

    → AI 看到的是"Sign in button ",而不是一堆像素,点击更精准;

  • 更稳

    → 页面样式变了,语义还在,不会一改 CSS 就全崩。

一句话:AI 不是"看图点",而是"读结构点"------这正是测试工程师熟悉的"用语义定位",只是这次操作者是 AI。

【贴图4】


四、三步跑通

第 0 步:准备环境与项目(进项目根)

bash 复制代码
mkdir
 pwmcp-demo && 
cd
 pwmcp-demo

# 只需 Node/npm(用于 npx 拉起 MCP server)+ 任意 MCP 客户端(Claude Code / Cursor / VS Code...)

Playwright MCP 本身用 npx 拉起,你不需要为它单独建 Node 工程;被测应用用一个 Python 静态站即可。

第 1 步:注册 MCP server(在项目根;命令随客户端不同)

bash 复制代码
# Claude Code(推荐,一条命令)

claude mcp add playwright npx @playwright/mcp@latest


# Cursor:Settings → MCP → Add new MCP Server → type=command, command=npx @playwright/mcp@latest


# PyCharm(2025.1+):Settings → Tools → AI Assistant → Model Context Protocol (MCP) → Add → 粘贴 JSON


# 其它客户端:用标准配置(见 demo/ 里的 mcp.json)

标准配置长这样(Claude Desktop / VS Code / 通用客户端):

bash 复制代码
{

  
"mcpServers"
:
 
{

    
"playwright"
:
 
{

      
"command"
:
 
"npx"
,

      
"args"
:
 
[
"@playwright/mcp@latest"
]

    
}

  
}

}

第 2 步:起一个被测应用 app/server.py(在项目根)

沿用最小站点:登录表单 + 加购按钮。

bash 复制代码
# app/server.py

import
 os

from
 http.server 
import
 BaseHTTPRequestHandler, HTTPServer


PORT = 
int
(os.environ.get(
"PORT"
, 
"4173"
))


PAGE = 
"""<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Acme Storefront</title></head><body>  <h1>Acme Storefront</h1>  <form id="signin">    <label for="email">Email</label>    <input id="email" type="email">    <label for="password">Password</label>    <input id="password" type="password">    <button type="submit">Sign in</button>  </form>  <div id="status" role="status"></div>  <section class="row" hidden id="shop">    <span>Items in cart:</span>    <span id="cart-count" data-testid="cart-count">0</span>    <button type="button" id="add">Add to cart</button>  </section>  <script>    const status = document.getElementById('status');    const shop = document.getElementById('shop');    const countEl = document.getElementById('cart-count');    let count = 0;    document.getElementById('signin').addEventListener('submit', (e) => {      e.preventDefault();      const email = document.getElementById('email').value.trim();      if (!email) { status.textContent = 'Email required'; return; }      status.textContent = 'Signed in as ' + email;      shop.hidden = false;    });    document.getElementById('add').addEventListener('click', () => {      count += 1; countEl.textContent = String(count);    });  </script></body></html>"""


class
Handler
(
BaseHTTPRequestHandler
):

    
def
do_GET
(
self
):

        
if
self
.path == 
"/"
:

            b = PAGE.encode(
"utf-8"
)

            
self
.send_response(
200
)

            
self
.send_header(
"content-type"
, 
"text/html; charset=utf-8"
)

            
self
.end_headers(); 
self
.wfile.write(b)

        
else
:

            
self
.send_response(
404
); 
self
.end_headers(); 
self
.wfile.write(
b"not found"
)

    
def
log_message
(
self, *a
): 
pass


if
 __name__ == 
"__main__"
:

    
print
(
f"app on {PORT}"
)

    HTTPServer((
"127.0.0.1"
, PORT), Handler).serve_forever()
bash 复制代码
python app/server.py      
# 在项目根启动,访问 http://127.0.0.1:4173

第 3 步:让 AI 去"跑一遍"(在 MCP 客户端里说人话)

对配好 MCP 的 AI 说:

打开 http://127.0.0.1:4173 ,用邮箱 qa@example.test / 密码 hunter2-hunter2 登录,然后点两次「Add to cart」,确认购物车数量变成 2,并告诉我结果。

它就会:打开页面 → 读无障碍树 → 找到 Email/Password/Sign in → 填 → 点 → 再点两次 → 读到 cart-count 是 2 → 回报^5。

【贴图5】

【贴图6】


五、先看清结构:文件放哪 + 指令在哪一层

bash 复制代码
pwmcp-demo/                      ← 「项目根」:命令都在这一层执行

├── app/

│   └── server.py                ← 被测应用

├── mcp.json                     ← 各客户端的 MCP 配置模板

├── prompts/

│   └── smoke.md                 ← 给 AI 的测试提示词(冒烟)

└── README.md

指令在哪个层级执行:

|

指令

|

在哪个目录执行

|

说明

|

| --- | --- | --- |

| python app/server.py | 项目根 |

启动被测应用

|

| claude mcp add playwright npx @playwright/mcp@latest | 项目根 |

注册 MCP server(Claude Code)

|

|

编辑 mcp.json

|

放到客户端的配置位置

|

Cursor/VS Code/Desktop 用

|

| npx @playwright/mcp@latest --headless | 项目根 |

无头模式(CI 用,见进阶)

|

一句话:被测应用与 claude mcp add 都在「项目根 pwmcp-demo/」执行;MCP 配置文件的"落脚点"取决于用哪个客户端。

【配图·fig-pwmcp-a:结构 + 指令层级】


六、用它来做测试:三个真实场景

Playwright MCP 不是"玩具",它能直接嵌进你的测试动作里^6:

① 自测 / 冒烟 :改动上线前,让 AI 打开关键页面走一遍主流程,几十秒给一份"红/绿"结论。

② 探索式测试 :把页面交给 AI:"帮我找找这个表单在异常输入 下有没有问题(空值、超长、特殊字符)。" 它 7×24 不喊累,帮你铺量。

③ 生成可用代码 :让它"边操作边产出"------很多方案能直接导出成 Playwright 用例代码 ,你审一遍就能进仓库(呼应我们第 8 期讲的:AI 补量,人定标准)。

注意分寸:AI 负责"点得又快又多",你负责"判得又准又稳"。

【贴图7】


七、进阶:几个必须知道的点

  • 无头 / CI

    :加 --headless 让 AI 在无界面环境跑(CI 友好);

  • 登录态复用

    :用 storageState(登录一次、后续复用),别每次重登;

  • 默认有头

    :Playwright MCP 默认弹出真实浏览器 ,你能看着 AI 操作------调试期很爽;

  • 安全红线

    :AI 能真的操作浏览器 → 别把生产账号、真实凭据交给它 ;用测试账号 + 测试环境;

  • 别神化

    :它是"更强的执行手",不是"会思考的测试专家"------用例该覆盖什么,仍得你来定。

【贴图8】

【贴图9】


八、给测试工程师的 3 条落点

  1. 先"看它跑"

    :配好 MCP,说人话让它操作一次浏览器,建立直觉;

  2. 再"用它跑"

    :把冒烟主流程交给它,省下的时间用来设计更狠的用例;

  3. 守住红线

    :测试环境 + 测试账号 + 人审产出,AI 的操作永远在人定的边界内。

一句话:Playwright MCP 不只是又一个工具------它是"AI 走进真实浏览器"的那扇门,而门里的规矩,得由测试人来定。

【贴图10】


🎁 加料包:完整可运行 demo + 各客户端配置,直接拿走

上面这套 demo 我已经打包好 ------pwmcp-demo/ 里是能直接跑的 :受测应用 app/server.py、各客户端的 MCP 配置模板 mcp.json 、给 AI 的冒烟测试提示词 prompts/smoke.md ,外加一份《Playwright MCP 快速上手手册 》:是什么/无障碍树原理/三种客户端配置/指令层级/进阶(无头·登录态·安全)/测试提示词模板。


附:一键复现清单

bash 复制代码
pwmcp-demo/

├── app/server.py            # 被测应用

├── mcp.json                 # 各客户端 MCP 配置模板

├── prompts/smoke.md         # 给 AI 的冒烟测试提示词

└── README.md
bash 复制代码
cd
 pwmcp-demo                       
# ← 进项目根

python app/server.py                
# 起被测应用(另开一个终端)

claude mcp add playwright npx @playwright/mcp@latest   
# 注册 MCP

# 然后在 AI 客户端里说:打开 http://127.0.0.1:4173 并完成登录+加购冒烟

本文配置与命令以官方文档为准,demo 已在本地跑通。仓库:github.com/microsoft/playwright-mcp

相关推荐
揽秀亭长1 小时前
视频转脚本怎么处理更高效?四种工具的工作流程与适用场景分析
人工智能·音视频·语音识别
大虾别跑1 小时前
ai-daily-2026-10-10
人工智能
鲲穹AI种草1 小时前
小红书 AI 创作工具怎么选,多款工具实际使用情况整理
人工智能·文案创作
龙亘川1 小时前
城市运管服平台下综合办公数字化建设实践与思考
大数据·人工智能·智慧城市·开源软件·数据可视化
IT_陈寒1 小时前
Vue的数组更新把我坑惨了
前端·人工智能·后端
呆呆槑_Xiong1 小时前
2026年GEO优化服务商怎么选?从AI用户增长看企业品牌可见度
人工智能
杨文说AI与数字化1 小时前
拆开 Agent 的账单:为什么“判断”这一层值得一个专用模型
人工智能
2601_965305391 小时前
工厂扬尘噪声在线监测设备安装需要什么条件?从点位、供电到联网的工程清单
人工智能
天远数科1 小时前
零信任架构实战:基于天远风控经营异常预警构建自动化电子签章前置合规网关
运维·人工智能·架构·自动化