基于MCP协议与Playwright的AI智能体自动化测试实践
1. 项目概述:当AI智能体遇上浏览器自动化
最近在折腾一个挺有意思的组合:用Trae AI智能体,通过MCP(Model Context Protocol)协议,去驱动Playwright这个强大的浏览器自动化框架。这听起来可能有点绕,但简单来说,就是让一个能理解你自然语言指令的AI,去帮你执行那些繁琐、重复的网页操作和测试任务。比如,你想测试一个电商网站的登录、搜索、加购、下单流程是否正常,以前可能需要写一堆脚本,现在可能只需要告诉Trae:“帮我测一下从登录到下单的全流程,检查每个页面的关键元素和跳转逻辑。” 剩下的,它就能通过Playwright去执行了。
Trae,你可以把它理解为一个高度集成的AI智能体工作台。它本身不直接写代码或操作浏览器,但它能“思考”和“规划”任务。而Playwright,是微软开源的一个现代浏览器自动化库,支持Chromium、Firefox和WebKit,能精准地模拟用户点击、输入、滚动等行为,并且自带等待机制,对动态网页非常友好。MCP协议则是连接两者的“桥梁”和“翻译官”,它定义了一套标准,让像Trae这样的AI应用能够安全、可控地调用外部工具(在这里就是Playwright)。
这个组合的核心价值在于,它将 自然语言意图 直接转化为了 可执行的自动化操作 ,极大地降低了编写和维护自动化测试脚本的门槛。尤其适合测试人员、产品经理或者开发者,在快速验证想法、进行探索性测试或者构建复杂测试流时使用。你不是在“编程”,而是在“描述任务”,让AI和自动化工具去完成脏活累活。
2. 核心组件深度解析:Trae、Playwright与MCP
要玩转这个组合,首先得把每个组件的角色和它们之间的协作关系搞清楚。这就像组建一个特种小队,你得知道每个队员擅长什么,以及他们之间如何通讯。
2.1 Trae:智能体的“大脑”与指挥中心
Trae的核心是一个基于大语言模型的智能体平台。它接收你的自然语言指令,例如“测试用户登录功能”,然后进行任务分解、规划和推理。它会想:“要测试登录,我需要先打开登录页面,找到用户名和密码输入框,填入测试数据,点击登录按钮,最后验证是否跳转到了正确页面。”
但Trae自己不会直接去打开浏览器。这时,它就需要“手”和“脚”。在Trae的架构里,这些“手”和“脚”就是通过 Skills 或 MCP Server 来扩展的。你可以把Trae看作项目经理,它制定计划(生成任务序列),然后通过标准的指令(MCP协议)分派给各个专业的执行者(MCP Server)。
注意 :网上常看到“Trae Work”、“Trae IDE”的讨论。简单理解,Trae Work可能更偏向于一个集成了多种AI能力和协作功能的云端工作空间,而Trae IDE则可能是一个本地开发环境,专注于让开发者更便捷地构建和调试AI智能体及其技能(Skills)。对于我们这个场景,无论是哪个版本,核心都是利用其智能体能力来调用MCP服务。
2.2 Playwright:可靠高效的“执行者”
Playwright是我们自动化操作的执行层。它之所以强大,有几个关键点:
- 多浏览器支持 :一套API支持Chromium、Firefox和WebKit。这意味着你可以用同一份脚本测试网站在不同浏览器引擎下的表现,对于跨浏览器兼容性测试至关重要。
- 自动等待 :这是它相对于Selenium等老牌工具的一大优势。Playwright的大多数操作(如
click,fill)内置了智能等待,它会等待元素可操作(可见、启用、稳定)后再执行,极大减少了需要手动添加sleep或显式等待的情况,让脚本更健壮。 - 强大的选择器 :除了常规的CSS和XPath,Playwright提供了许多面向测试的便捷选择器,如按文本内容(
text=)、按测试ID(data-testid)定位,让元素定位更直观、更不易因前端样式改动而失效。 - 网络拦截与模拟 :可以轻松拦截和修改网络请求,模拟慢速网络、离线状态,或者直接注入Mock数据,这对于测试边缘场景非常有用。
- 丰富的录制工具 :
playwright codegen命令可以启动一个浏览器,记录你的操作并实时生成对应代码,是快速创建脚本原型的利器。
安装Playwright很简单,通常一行命令搞定: npm init playwright@latest 。它会引导你完成项目初始化、浏览器安装(Chromium, Firefox, WebKit)等步骤。如果安装浏览器慢,可以考虑配置环境变量 PLAYWRIGHT_DOWNLOAD_HOST 使用国内镜像源。
2.3 MCP协议:关键的“通信官”与安全边界
MCP(Model Context Protocol)是这里最核心、也最容易被忽视的环节。你可以把它理解为AI世界里的“USB协议”或“驱动标准”。
MCP解决了什么问题? 在没有MCP之前,如果我们想让AI(如Claude、GPT)去操作一个外部工具(如浏览器、数据库、文件系统),通常需要:
- 将工具的API文档和上下文全部塞进AI的提示词中,这很快会耗尽token限制。
- 让AI直接生成调用这些API的代码,然后由另一个系统执行。但这存在安全风险,AI可能生成危险代码(如
rm -rf /)。
MCP提供了一种标准化的方式:
- 服务端(MCP Server) :每个工具(如Playwright操作工具、文件系统工具、SQL查询工具)都实现为一个MCP Server。这个Server封装了工具的所有安全操作接口。
- 客户端(MCP Client) :像Trae这样的AI应用作为Client。Client通过标准协议与Server通信,查询Server提供了哪些“工具”(Tools),然后请求Server执行某个工具。
- 安全隔离 :AI(Trae)永远不直接执行代码,它只是向MCP Server发送结构化的请求。真正的执行发生在Server端,Server可以内置安全检查、权限控制。例如,一个Playwright的MCP Server可以限制只能访问
*.example.com的域名。
在这个项目中,我们需要一个 Playwright MCP Server 。这个Server暴露出一系列安全的“工具”给Trae调用,比如 open_browser , navigate_to , click_element , get_text 等。Trae通过MCP协议发现这些工具,并在需要时调用它们。
3. 系统搭建与核心技能配置实操
理论讲完了,我们来动手搭一个能跑起来的系统。这里假设你已经有了基本的Node.js和Python环境。
3.1 环境准备与基础安装
首先,我们需要两个核心部分:Playwright环境,和一个Playwright的MCP Server。
步骤一:初始化Playwright项目 在一个新的目录下,初始化一个Node.js项目并安装Playwright。
mkdir playwright-mcp-demo && cd playwright-mcp-demo
npm init -y
npm install @playwright/test
# 安装Playwright自带的浏览器(Chromium, Firefox, WebKit)
npx playwright install
安装完成后,可以运行 npx playwright codegen https://example.com 来测试录制功能是否正常。
步骤二:寻找或构建Playwright MCP Server 这是关键一步。目前,一个成熟、开源的通用Playwright MCP Server可能还不像其他工具那样普及。我们有几种思路:
- 使用现有实现 :在GitHub或NPM上搜索
playwright-mcp-server或mcp-server-playwright。可能会找到社区项目。例如,一个简单的Server可能提供browser_open,page_goto,element_click等基本工具。 - 自行构建(推荐用于理解原理) :这是更可控的方式。我们可以用Node.js或Python快速搭建一个简单的MCP Server。这里以Node.js为例,利用
@modelcontextprotocol/sdk。
首先安装MCP SDK:
npm install @modelcontextprotocol/sdk
然后创建一个简单的Server文件 playwright-mcp-server.js :
const { Server } = require('@modelcontextprotocol/sdk/server/index.js');
const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');
const { playwright } = require('playwright'); // 引入playwright
class PlaywrightMCPServer {
constructor() {
this.server = new Server(
{
name: 'playwright-mcp-server',
version: '0.1.0',
},
{
capabilities: {
tools: {},
},
}
);
this.browser = null;
this.context = null;
this.page = null;
// 定义工具
this.server.setRequestHandler('tools/list', async () => {
return {
tools: [
{
name: 'open_browser',
description: 'Open a Chromium browser instance',
inputSchema: {
type: 'object',
properties: {
headless: { type: 'boolean', description: 'Run in headless mode', default: true }
}
}
},
{
name: 'navigate_to',
description: 'Navigate the current page to a URL',
inputSchema: {
type: 'object',
properties: {
url: { type: 'string', description: 'The URL to navigate to' }
},
required: ['url']
}
},
{
name: 'click_element',
description: 'Click on an element using a CSS selector',
inputSchema: {
type: 'object',
properties: {
selector: { type: 'string', description: 'CSS selector for the element' }
},
required: ['selector']
}
},
// ... 可以继续添加 fill_text, get_text, screenshot 等工具
]
};
});
// 处理工具调用
this.server.setRequestHandler('tools/call', async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case 'open_browser':
this.browser = await playwright.chromium.launch({ headless: args.headless !== false });
this.context = await this.browser.newContext();
this.page = await this.context.newPage();
return { content: [{ type: 'text', text: 'Browser opened successfully.' }] };
case 'navigate_to':
if (!this.page) throw new Error('Browser not open. Call open_browser first.');
await this.page.goto(args.url);
return { content: [{ type: 'text', text: `Navigated to ${args.url}` }] };
case 'click_element':
if (!this.page) throw new Error('Browser not open.');
await this.page.click(args.selector);
return { content: [{ type: 'text', text: `Clicked element: ${args.selector}` }] };
default:
throw new Error(`Unknown tool: ${name}`);
}
} catch (error) {
return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
}
});
}
async run() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error('Playwright MCP Server running on stdio...');
}
}
const server = new PlaywrightMCPServer();
server.run().catch(console.error);
这个Server通过stdio(标准输入输出)与Trae通信,提供了三个最基础的工具。你需要用 node playwright-mcp-server.js 来运行它,但通常不是直接运行,而是配置到Trae中。
3.2 在Trae中配置MCP Server
这是将大脑(Trae)和手脚(Playwright MCP Server)连接起来的一步。具体配置方式取决于你使用的Trae版本(Work或IDE)。
通用思路(以配置文件为例): 许多支持MCP的AI应用(包括Trae的某些版本)允许通过一个配置文件(如 mcp_config.json 或Trae的设置界面)来添加MCP Server。
你需要指定:
- Server 命令 :启动你的Playwright MCP Server的命令。例如,如果上述Server代码保存在
server.js,那么命令就是node /path/to/playwright-mcp-server.js。 - 传输方式 :通常是
stdio(标准输入输出),这也是上面代码示例使用的。
在Trae IDE或类似环境中,你可能在设置里找到“MCP Servers”或“External Tools”的配置项,添加一个新的Server,填入名称、命令和参数。
实操心得 :
- 首次配置时,建议先在终端单独运行一下你的MCP Server命令,确保它能正常启动不报错(比如Playwright依赖的浏览器是否安装好)。
- Trae与MCP Server的通信是持续的。配置成功后,在Trae的对话界面,你应该能通过某种方式(如输入
/tools或类似指令)看到Server提供的工具列表。这意味着Trae已经“发现”了Playwright的能力。 - 如果Trae提示找不到工具或连接失败,检查Trae的日志或控制台输出,通常会有详细的错误信息,比如Node路径不对、MCP Server脚本有语法错误等。
4. 从指令到自动化:编写与执行测试流程
环境搭好了,现在来看看如何让Trae真正干活。我们通过一个完整的例子来串联。
4.1 定义测试场景与Trae指令
假设我们要测试一个简单的登录流程。目标网站是 https://demo.testfire.net/ (一个经典的测试银行网站)。
你的自然语言指令给Trae可以是: “请使用Playwright工具,测试demo.testfire.net的登录功能。使用用户名‘jsmith’和密码‘Demo1234’进行登录,登录成功后检查页面是否包含‘Accounts Overview’文本。请按步骤执行并告诉我结果。”
4.2 Trae的思考与工具调用链
Trae接收到这个指令后,内部会进行任务规划,可能会生成如下执行计划(并通过MCP调用工具):
- 调用
open_browser:{“headless”: false}// 我们让浏览器显示出来,方便观察 - 调用
navigate_to:{“url”: “https://demo.testfire.net/”} - 等待页面加载 :Trae可能会调用一个
wait_for_selector工具(如果我们的Server实现了),或者基于已知的页面结构,直接进行下一步。 - 填写用户名 :调用
fill_text工具(需在Server中实现):{“selector”: “#uid”, “text”: “jsmith”} - 填写密码 :调用
fill_text工具:{“selector”: “#passw”, “text”: “Demo1234”} - 点击登录按钮 :调用
click_element工具:{“selector”: “input[name=’btnSubmit’]”} - 验证结果 :调用
get_text工具(需实现)来获取页面特定区域的文本,或者调用element_visible工具检查“Accounts Overview”这个文本元素是否存在。
4.3 扩展MCP Server实现关键工具
为了让上述流程跑通,我们需要完善之前的Playwright MCP Server,增加 fill_text 、 get_text 和 wait_for_selector 工具。在 tools/list 中添加它们:
// 在tools列表中追加
{
name: 'fill_text',
description: 'Fill text into an input field identified by selector',
inputSchema: {
type: 'object',
properties: {
selector: { type: 'string' },
text: { type: 'string' }
},
required: ['selector', 'text']
}
},
{
name: 'get_text',
description: 'Get the text content of an element',
inputSchema: {
type: 'object',
properties: {
selector: { type: 'string' }
},
required: ['selector']
}
},
{
name: 'wait_for_selector',
description: 'Wait for an element matching the selector to appear',
inputSchema: {
type: 'object',
properties: {
selector: { type: 'string' },
timeout: { type: 'number', default: 30000 }
},
required: ['selector']
}
}
在 tools/call 处理函数中增加对应的case:
case 'fill_text':
if (!this.page) throw new Error('Browser not open.');
await this.page.fill(args.selector, args.text);
return { content: [{ type: 'text', text: `Filled '${args.text}' into ${args.selector}` }] };
case 'get_text':
if (!this.page) throw new Error('Browser not open.');
const text = await this.page.textContent(args.selector);
return { content: [{ type: 'text', text: `Text content: ${text}` }] };
case 'wait_for_selector':
if (!this.page) throw new Error('Browser not open.');
await this.page.waitForSelector(args.selector, { timeout: args.timeout });
return { content: [{ type: 'text', text: `Selector ${args.selector} is now present.` }] };
现在,重启你的MCP Server。Trae在规划任务时,就能利用这些更丰富的工具了。
4.4 执行与结果反馈
当Trae通过MCP协议按顺序调用这些工具后,每个工具的执行结果(成功或错误信息)会返回给Trae。Trae会收集这些结果,并最终组织成一段连贯的自然语言回复给你:
“已成功执行登录测试流程:
- 浏览器已打开。
- 已导航至 https://demo.testfire.net/。
- 已在用户名输入框(#uid)填入‘jsmith’。
- 已在密码输入框(#passw)填入‘Demo1234’。
- 已点击登录按钮。
- 等待并检测到页面中包含‘Accounts Overview’文本。 测试通过,登录功能正常。”
如果中途出错(比如元素找不到),Trae也会收到错误信息,并可能尝试重试或直接向你报告问题所在,例如:“在尝试点击登录按钮时失败,错误信息:Timeout 30000ms exceeded waiting for selector input[name=’btnSubmit’] 。”
5. 高级技巧、优化与避坑指南
把基础流程跑通只是第一步。要想在实际项目中稳定、高效地使用,还需要注意很多细节。
5.1 选择器策略:让自动化更健壮
元素定位是Web自动化的基石,也是脚本最容易失效的地方。Playwright提供了多种选择器,我们的MCP Server应支持最常用的几种,并在Trae的指令中引导使用最佳实践。
| 选择器类型 | 示例 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| CSS Selector | #login-button .submit-btn |
速度快,通用性强 | 可能随前端样式改动而变 | 有稳定ID或Class的元素 |
| XPath | //button[@id=’login’] |
功能强大,灵活性高 | 表达式复杂,性能稍差,易脆 | CSS无法定位的复杂结构 |
| Text Selector | text=”登录” |
直观,符合用户视角 | 受语言、文本变化影响大 | 定位按钮、链接文本 |
| Test ID Selector | data-testid=”submit-btn” |
最稳定 ,专为测试设计 | 需要开发配合添加属性 | 强烈推荐,协作项目首选 |
实操心得 :
- 在向Trae描述任务时,尽量使用 唯一的、语义化的标识 。例如,与其说“点击那个蓝色的按钮”,不如说“点击ID为‘submit’的按钮”或“点击文本为‘登录’的按钮”。
- 在你的MCP Server中,可以设计一个更强大的
click工具,它内部尝试多种选择器策略(如先试data-testid,再试text),提高成功率。 - 对于动态加载的内容,务必在操作前使用
wait_for_selector或类似工具,确保元素已经就绪。
5.2 状态管理与错误恢复
一个复杂的测试流程可能包含多个步骤和页面。我们的简易MCP Server使用 this.page 保存当前页面状态,这很脆弱。页面崩溃、意外弹窗都可能导致状态丢失。
优化方案 :
- 会话管理 :在Server中维护一个会话映射(
sessionId -> {browser, context, page})。Trae在开始一个新“会话”时调用create_session工具,后续所有操作都附带sessionId。这样可以支持并行测试。 - 自动截图与日志 :在每一个工具调用(尤其是可能失败的操作)前后,自动截图并保存日志。当Trae报告错误时,你可以直接查看当时的屏幕截图,快速定位问题。可以在Server中实现一个
take_screenshot工具,或在错误处理中自动调用。 - 重试机制 :在网络不稳定或页面加载慢的情况下,简单的失败并不代表功能有问题。可以在Server端为关键操作(如
click,wait_for_selector)内置重试逻辑(例如,重试3次,每次间隔1秒)。
5.3 提升Trae指令的“智商”
Trae的规划能力取决于你的指令清晰度和它背后的模型能力。为了让合作更顺畅:
- 指令要具体、原子化 :与其说“测试购物流程”,不如拆解成“1. 登录;2. 搜索商品‘iPhone’;3. 进入商品详情页;4. 加入购物车;5. 进入结算页”。Trae更容易将原子化的步骤映射到具体的工具调用。
- 提供上下文和示例 :你可以先给Trae一些“示范”。例如:“我将要测试一个网站。它的登录按钮选择器是
#loginBtn,成功登录后页面会有h1.user-welcome元素。现在,请用测试数据‘user1’/‘pass123’执行登录测试。” 这能帮助Trae更好地理解页面结构。 - 处理不确定性 :有时元素选择器不唯一。可以教Trae:“如果找不到
#submitBtn,请尝试找button:has-text(‘提交’)。” 这需要你的MCP Server支持更灵活的工具调用,或者Trae自身具备多方案尝试的逻辑。
5.4 常见问题与排查技巧
在实际操作中,你肯定会遇到各种问题。下面是一个快速排查清单:
| 问题现象 | 可能原因 | 排查步骤 |
|---|---|---|
| Trae无法发现MCP Server工具 | 1. MCP Server配置命令错误 2. Server启动失败 3. Trae未正确加载配置 |
1. 在终端手动运行Server命令,看是否报错。 2. 检查Trae的配置路径、命令参数是否正确。 3. 重启Trae,查看日志中是否有MCP连接信息。 |
| 工具调用超时或无响应 | 1. Playwright操作本身超时 2. 网络或页面加载慢 3. Server进程卡死 |
1. 增加工具的默认超时时间(如 waitForSelector 的timeout)。 2. 在Server代码中添加更详细的console.error日志。 3. 检查浏览器进程是否正常。 |
| 元素找不到(Selector失效) | 1. 页面结构已变化 2. 元素在iframe内 3. 页面未完全加载 |
1. 使用 playwright codegen 重新录制,获取新的选择器。 2. 对于iframe,需要先 page.frameLocator() 定位。 3. 在操作前显式添加 wait_for_selector 或 wait_for_load_state 工具。 |
| 浏览器无法启动 | 1. Playwright浏览器未安装 2. 系统缺少依赖(如Linux缺少lib) 3. 端口或用户权限问题 |
1. 运行 npx playwright install 。 2. 查看Playwright官方文档的系统依赖说明。 3. 尝试以 headless: true 模式启动。 |
| Trae规划的逻辑错误 | 指令模糊,Trae误解意图 | 将复杂指令拆分成多个简单、清晰的步骤。在Trae执行前,让它复述一遍它的计划,确认无误后再执行。 |
一个关键的避坑技巧 :在开发调试阶段, 始终让浏览器以非无头模式运行 ( headless: false )。这样你能亲眼看到每一步发生了什么,当脚本失败时,你能立即看到浏览器停在哪一步、页面是什么状态,这是最直观的调试方式。
6. 超越测试:场景扩展与未来展望
虽然我们以“网页自动化测试”为标题,但“Trae + Playwright MCP”的能力远不止于此。任何需要通过浏览器完成的重复性、规则性的工作,都可以尝试用这个组合来简化。
场景扩展 :
- 数据抓取与监控 :让Trae每天定时访问某个价格页面,抓取特定元素下的数字,并整理成报告。相比写爬虫,你用自然语言描述抓取规则即可。
- 自动化运维与巡检 :对于内部管理系统,让Trae登录后,依次点击几个菜单,检查关键指标是否在正常范围内,截图存档。
- RPA(机器人流程自动化) :自动完成一些跨网页的办公流程,如在A网站下载报表,登录B系统上传数据。Trae可以协调多个MCP Server(可能对应不同网站或工具)完成复杂工作流。
- 无障碍测试 :结合Playwright的审计能力,让Trae自动运行Lighthouse等工具,检查页面的可访问性问题。
关于MCP生态 :MCP协议的魅力在于其标准化。你为Playwright写的这个MCP Server,理论上也可以被其他支持MCP的AI智能体(如Claude Desktop、某些定制的GPTs)使用。同样,你也可以为Trae接入其他MCP Server,比如操作数据库的、管理文件的、调用API的,从而打造一个拥有“多模态”能力的超级智能体助手。
这个组合目前可能还有些前沿,需要一定的动手搭建能力,特别是需要一个稳定可靠的Playwright MCP Server。但随着MCP生态的成熟,未来可能会出现更多开箱即用的Server。到那时,我们只需要在Trae里点选配置,就能轻松赋予AI智能体操控数字世界的能力。而现在,通过自己动手搭建和理解整个过程,你不仅能解决眼前的问题,更是在积累未来人机协作的新范式。
更多推荐

所有评论(0)