浏览器自动化测试框架

一个基于Node.js和TypeScript的浏览器自动化测试框架,支持通过JSON格式的测试步骤与Playwright MCP服务器交互,实现AI驱动的测试生成与执行。

  • by ankpuroh
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 ankpuroh/PlaywrightMCP

使用说明

剧作家MCP自动化框架

一个复杂的Node.js+TypeScript自动化框架,通过Playwright MCP(模型上下文协议)服务器执行AI生成的JSON测试步骤。该框架实现了AI驱动的测试生成与浏览器自动化的无缝集成。

🎯 概述

该框架通过Playwright MCP接口弥合了人工智能生成的测试规范(JSON)和实际浏览器自动化之间的差距。所有浏览器交互都完全通过MCP工具调用进行,而不是使用本机Playwright API。

主要特点

  • 基于JSON的测试步骤:测试定义为JSON数组,便于人工智能生成和人类可读性
  • MCP集成:通过stdio传输与Playwright MCP服务器通信
  • 规划师上游工作流程:可选 playwright-test-planner JSON转换前创建探索性计划的代理
  • 类型安全:带Zod模式验证的完整TypeScript实现
  • 选择器分辨率:可通过以下方式配置元素定位器 selectors.json
  • 运行时自我修复:失败时,捕获已清理的DOM,通过LLM生成XPath,验证唯一性,重试一次,并持久保存已修复的定位器
  • 本地LLM选项:支持当地Olama进行离线自我修复
  • LLM辅助定位器发现: discover-locators 使用LLM第一定位器生成和启发式回退
  • 并行套件执行:使用可配置的workers运行标记的套件
  • 丰富的日志记录:具有结构化输出的综合执行日志
  • 工件管理:自动截图和日志收集
  • CLI接口:基于yargs的简单命令行工具
  • 步骤执行器:按顺序将JSON操作转换为MCP工具调用

📦 建筑

automation-framework/
├── src/
│   ├── schema/          # Zod validation schemas
│   │   └── stepSchema.ts
│   ├── executor/        # Core execution engine
│   │   ├── mcpClient.ts       (MCP server connection & tool calls)
│   │   ├── executor.ts        (Individual step execution)
│   │   ├── selfHealLLM.ts     (LLM provider integration for XPath healing)
│   │   └── runner.ts          (Complete flow execution)
│   ├── cli/             # CLI interface
│   │   └── index.ts
│   └── utils/           # Helper utilities
│       ├── logger.ts
│       └── file.ts
├── config/
│   ├── selectors.json   # Element locator mappings
│   └── env.json         # Environment configuration
├── tests/
│   └── sample.json      # Example test flow
├── artifacts/           # Generated (logs, screenshots)
└── package.json

🚀 快速开始

代理工作流(推荐)

将存储库代理管道用于新场景:

  1. playwright-test-planner 在下创建markdown测试计划 specs/.
  2. Converter agent 将计划转换为框架JSON/数据/定位器/元数据工件。
  3. Executor 运行生成的测试 npm run run-test 或 npm run run-suite.

1.安装

npm install

2.构建TypeScript

npm run build

3.运行测试

npm run run-test -- --file tests/sample.json

或者使用自定义选项:

npm run run-test -- \
  --file tests/MyFlow.json \
  --selectors config/selectors.json \
  --pom config/locators/pageObjects.json \
  --dataCommon config/TestData/common.json \
  --dataDomain config/TestData/domain.myapp.json \
  --data config/TestData/testdata.myflow.json \
  --dataset qa \
  --output ./my-artifacts \
  --selfHeal true

框架自动启动捆绑的MCP服务器 node playwright-mcp-server.js.使用 --mcp 只有当你想覆盖该命令时。

自愈和发现LLM设置(可选)

自我修复仅在元素操作因缺少/无效定位器而失败时调用LLM。 定位器发现(discover-locators)还首先对未解决的目标使用LLM,如果LLM未配置或验证失败,则自动回退到启发式发现。

提供商优先级:

  1. OPENAI_API_KEY (OpenAI)
  2. OLLAMA_BASE_URL 或 OLLAMA_MODEL (当地Ollama)

Olama本地设置示例:

# Start Ollama service and pull model once
ollama serve
ollama pull llama3.1

# Optional env overrides
set OLLAMA_BASE_URL=http://127.0.0.1:11434
set OLLAMA_MODEL=llama3.1

如果没有配置提供程序,自愈和定位器发现都会退回到非LLM启发式发现。

页面对象模型+参数化数据

  • --pom 加载页面对象别名(例如 SamplePage.searchInput)
  • 使用分层优先级解析数据:
    • 场景数据: --data
    • 域数据: --dataDomain (逗号分隔的文件)
    • 通用数据: --dataCommon
  • 优先顺序: scenario > domain > common
  • --dataset 应用数据文件中的结构化数据集变体 defaults + datasets
  • --strictData (默认为true)当缺少任何占位符时,运行失败

电子邮件友好报告

每次执行后,框架都会生成:

  • report-email.html (标准电子邮件就绪HTML报告)
  • report-email.txt (电子邮件客户端的纯文本摘要)

🏷️ 标记为测试用例执行

创建套件文件(请参见 config/TestMetaData.json)其中每个测试用例都有 tags 以及可选的数据层路径。

运行套件中的所有测试用例:

npm run run-suite -- --suite config/TestMetaData.json

仅运行选定的标记组:

npm run run-suite -- --suite config/TestMetaData.json --tags smoke,login

排除标记组:

npm run run-suite -- --suite config/TestMetaData.json --excludeTags slow,flaky

运行一个具有共享数据层的套件:

npm run run-suite -- \
  --suite config/TestMetaData.json \
  --dataCommon config/TestData/common.json \
  --dataDomain config/TestData/domain.myapp.json \
  --dataset qa

并行运行一个套件:

npm run run-suite -- --suite config/TestMetaData.json --workers 3

当 --workers 大于 1,自动禁用自愈以避免并发写入 config/selectors.json.

自愈以原子方式(临时文件+替换)写入定位器更新,以保持定位器文件的一致性。

📋 JSON测试模式

每个测试流都是遵循此模式的一系列步骤:

{
  id: string;                    // Unique step identifier
  action: string;                // Action type (see below)
  target: string;                // Element logical name or selector
  value?: string;                // Optional value for fill/press
  assert?: string;               // Expected value for assertions
  metadata?: {
    originalEnglish?: string;    // Original AI instruction
  };
}

支持的操作

该框架支持中定义的完整操作集 src/schema/stepSchema.ts.

动作 描述
navigate 导航到URL
click 点击元素
fill 在字段中键入文本
press 按键盘键
waitFor 等待文本/时间
assertText 验证快照中是否存在文本
assertVisible 通过MCP可见性检查验证元素可见性
screenshot 捕获屏幕
select 选择下拉选项(点击回退)
waitForSelector 等待元素存在
wait 等待固定秒数
reload_window 重新加载当前页面
quit 关闭浏览器
get_value 读取输入值
clear_text 清除输入字段
assert_value 断言输入值
is_element_visible 返回可见性状态
element_exists 返回存在状态
scroll_page 滚动页面
focus_then_downarrow 聚焦,然后按向下箭头
send_downarrow_then_tab 聚焦,然后按下箭头和Tab键
select_dropdown_by_index 按索引选择选项
mat_select_by_value 按值选择材质样式
mat_scroll_to_value 按值滚动/选择材质样式
click_n_switch_tab 点击并切换选项卡
switch_to_tab 切换到选项卡索引
wait_for_new_tab 等待新标签
switch_to_latest_tab 切换到最新选项卡
click_and_switch_to_new_tab 单击并切换到最新选项卡
get_all_tabs_info 返回所有标签信息

🔧 配置

选择器.json

将逻辑元素名称映射到定位器表达式(CSS/XPath):

{
  "searchButton": "button[type='submit']",
  "searchInput": "input[type='search']",
  "loginButton": "button.login-btn",
  "usernameField": "input#username",
  "passwordField": "input#password"
}

自愈更新支持:

  • JSON定位文件(.json)
  • Java属性样式文件(.properties)
  • Types/JavaScript对象定位器文件(.ts, .js)

分层测试数据文件

当前的框架主要从以下分层文件中解析占位符 config/TestData/:

{
  "defaults": {
    "baseUrl": "https://example.com"
  },
  "datasets": {
    "qa": {
      "baseUrl": "https://qa.example.com"
    }
  }
}

使用 --dataCommon, --dataDomain, --data,以及可选的数据集标志,用于在运行时解析占位符。

📝 测试流程示例

[
  {
    "id": "step-1",
    "action": "navigate",
    "target": "https://example.com",
    "metadata": {
      "originalEnglish": "Navigate to the application"
    }
  },
  {
    "id": "step-2",
    "action": "click",
    "target": "loginButton",
    "metadata": {
      "originalEnglish": "Click on login button"
    }
  },
  {
    "id": "step-3",
    "action": "fill",
    "target": "usernameField",
    "value": "testuser@example.com",
    "metadata": {
      "originalEnglish": "Enter username"
    }
  },
  {
    "id": "step-4",
    "action": "fill",
    "target": "passwordField",
    "value": "SecurePassword123",
    "metadata": {
      "originalEnglish": "Enter password"
    }
  },
  {
    "id": "step-5",
    "action": "press",
    "value": "Enter",
    "metadata": {
      "originalEnglish": "Submit login form"
    }
  },
  {
    "id": "step-6",
    "action": "waitFor",
    "target": "Dashboard",
    "metadata": {
      "originalEnglish": "Wait for dashboard to load"
    }
  },
  {
    "id": "step-7",
    "action": "assertText",
    "assert": "Welcome back",
    "metadata": {
      "originalEnglish": "Verify login success"
    }
  },
  {
    "id": "step-8",
    "action": "screenshot",
    "target": "dashboard",
    "metadata": {
      "originalEnglish": "Capture dashboard screenshot"
    }
  }
]

🔌 MCP集成详细信息

MCP工具映射

该框架将JSON操作映射到Playwright MCP工具:

JSON操作 MCP工具 工具参数
导航 mcp_microsoft_pla_browser_navigate { url }
点击 mcp_microsoft_pla_browser_click { ref, element }
填充 mcp_microsoft_pla_browser_type { ref, text, element }
报刊 mcp_microsoft_pla_browser_press_key { key }
等待 mcp_microsoft_pla_browser_wait_for { text?, time? }
屏幕截图 mcp_microsoft_pla_browser_take_screenshot { type, fullPage?, filename? }
assertText mcp_microsoft_pla_browser_snapshot {}
assertVisible mcp_microsoft_pla_browser_is_visible { ref }

内部自愈工具:

工具 目的
mcp_microsoft_pla_browser_get_dom 返回已清理的DOM(脚本/样式/内联处理程序已删除)
mcp_microsoft_pla_browser_validate_xpath 返回用于唯一性验证的XPath匹配计数

MCP客户端方法

// Connection
await client.connect();
await client.disconnect();

// Navigation & Interaction
await client.navigate(url);
await client.click(ref, element);
await client.fill(ref, text, element);
await client.pressKey(key);

// Assertions & Capture
await client.waitFor(text?, time?);
await client.screenshot(filename?, fullPage?);
await client.getSnapshot();

// Server Management
await client.listTools();        // List available tools
await client.close();             // Close browser

📊 执行流程

┌─────────────────────────────────────────────────────┐
│  1. Load & Validate JSON Test File                   │
│     (Zod schema validation)                          │
└────────────────────┬────────────────────────────────┘
                     ↓
┌─────────────────────────────────────────────────────┐
│  2. Load Configuration                               │
│     (selectors.json, env.json)                       │
└────────────────────┬────────────────────────────────┘
                     ↓
┌─────────────────────────────────────────────────────┐
│  3. Connect to Playwright MCP Server                 │
│     (stdio transport)                                │
└────────────────────┬────────────────────────────────┘
                     ↓
┌─────────────────────────────────────────────────────┐
│  4. Execute Each Step Sequentially                   │
│     ┌──────────────────────────────────────────┐    │
│     │ Step N:                                  │    │
│     │ - Resolve selector from selectors.json   │    │
│     │ - Call appropriate MCP tool              │    │
│     │ - Log result & timing                    │    │
│     │ - Capture screenshots on error           │    │
│     └──────────────────────────────────────────┘    │
└────────────────────┬────────────────────────────────┘
                     ↓
┌─────────────────────────────────────────────────────┐
│  5. Generate Summary & Artifacts                     │
│     (logs, screenshots, execution report)            │
└─────────────────────────────────────────────────────┘

📂 生成的工件

每次测试运行后,框架都会创建:

artifacts/{execution-id}/
├── execution.log              # Detailed step-by-step logs
├── screenshot-step-*.png      # Screenshots for each step
└── summary.json               # Execution summary (if implemented)

🛠️ CLI命令

运行json

从JSON文件执行测试流。

用途:

npm run run-test -- --file <path> [options]

选项:

  • --file, -f (必填):JSON测试文件的路径
  • --selectors, -s:selectors.json的路径(默认: ./config/selectors.json)
  • --pom, -p:pageObjects.json的路径(默认值: ./config/locators/pageObjects.json)
  • --data, -d:场景级数据文件路径
  • --dataCommon:通用/基础数据文件路径
  • --dataDomain:逗号分隔的域数据文件路径
  • --dataset:结构化数据文件的数据集密钥
  • --datasetCommon:公用层的数据集键覆盖
  • --datasetDomain:域层的数据集键覆盖
  • --strictData:缺少占位符时失败(默认值: true)
  • --selfHeal:运行时定位器自愈(默认值: true)
  • --output, -o:工件/日志的输出目录
  • --mcp, -m:MCP服务器命令(默认值: node playwright-mcp-server.js)
  • --help, -h:显示帮助
  • --version, -v:显示版本

示例:

# Run with defaults
npm run run-test -- --file tests/sample.json

# Custom output directory
npm run run-test -- --file tests/login.json --output ./test-results

# Custom selectors
npm run run-test -- --file tests/sample.json --selectors ./custom-selectors.json

# Custom MCP command
npm run run-test -- --file tests/sample.json --mcp "node server.js"

🔍 日志记录

该框架在多个级别提供详细的日志记录:

  • 信息:执行流程的一般信息
  • 成功:成功完成步骤
  • 错误:步骤失败和异常
  • 警告:非关键问题
  • 调试:详细的调试信息

所有日志如下:

  • 控制台上印有彩色图案
  • 已保存到 execution.log 在工件目录中
  • 具有时间戳和元数据结构

🧪 步骤执行器详细信息

这 StepExecutor 类处理单个步骤的执行:

  1. 选择器分辨率:在中查找逻辑名称 selectors.json,如果未找到,则使用原始选择器
  2. 操作映射:通往适当MCP工具调用的路径
  3. 错误处理:根据上下文捕获异常
  4. 截图捕捉:保存带有步骤ID和时间戳的屏幕截图
  5. 断言:使用基于快照的文本检查和基于选择器的可见性检查

📈 错误处理

该框架优雅地处理错误:

  • 验证错误:在模式验证过程中被捕获,并显示详细消息
  • 连接错误:详细记录MCP服务器连接问题
  • 执行错误:在不停止后续步骤的情况下记录每个步骤的失败
  • 文件错误:清除丢失或格式错误的文件的消息

🔐 最佳实践

  1. 唯一步骤ID:为每个步骤使用描述性的唯一标识符
  2. 选择器管理:使selectors.json保持有序和最新
  3. 元数据:包括调试的原始英文说明
  4. 断言:使用断言来验证预期行为
  5. 截图:截取战略截图进行视觉验证
  6. 错误恢复:计划测试流程以处理预期故障

🐛 故障排除

MCP服务器未连接

✗ Error: Failed to connect to MCP server
Solution: By default, the CLI starts `node playwright-mcp-server.js` automatically. If you override `--mcp`, verify that custom command is valid.

未找到选择器

✗ Error: Element not found
Solution: Check selectors.json mapping or verify element exists on page

无效的JSON

✗ Error: ZodError: Invalid step schema
Solution: Validate JSON structure against TestStepSchema

未生成任何工件

Solution: Ensure output directory path is valid and writable

📚 发展

构建

npm run build

开发模式

npm run dev -- run-json --file tests/sample.json

清洁构建工件

npm run clean

🔑 关键技术

  • TypeScript:类型安全实施
  • @模型上下文协议/sdk:MCP客户端库
  • 黄道带:运行时架构验证
  • 纱线:CLI参数解析
  • 粉笔:彩色控制台输出
  • fs额外:增强的文件操作
  • 纳米ID:唯一ID生成

📄 许可证

麻省理工学院

🤝 与GitHub Copilot集成

该框架旨在与GitHub Copilot中的AI生成的JSON测试步骤配合使用:

  1. 生成步骤:使用Copilot从自然语言生成JSON测试步骤
  2. 验证:框架根据严格模式进行验证
  3. 执行:框架通过Playwright MCP执行
  4. 审查:日志和屏幕截图提供审计跟踪

副驾驶提示示例:

Generate a JSON test flow for logging in to an application.
Use the following action types: navigate, fill, click, press, waitFor, assertText, screenshot
For selectors, use these logical names: usernameField, passwordField, submitButton

🚀 下一步

  1. 安装依赖项: npm install
  2. 构建TypeScript: npm run build
  3. 运行样本测试: npm run run-test -- --file tests/sample.json
  4. 创建自己的测试JSON文件
  5. 与CI/CD管道集成

已准备好使用AI生成的测试步骤进行自动化! 🎯