Skip to main content
Glama
l0s3r-Q

browser-test-mcp

by l0s3r-Q
README.md
# browser-test-mcp

**Playwright × browser-use 共生浏览器自动化测试 MCP Server**

把两个顶级开源项目融合为一个 MCP server:AI 智能决策与精确测试执行共生,两层工具操作**同一个浏览器实例**,随时无缝切换。

```
┌──────────────────────────────────────────────────────────┐
│  browser-test MCP(单进程,59 个工具)                      │
│                                                            │
│  AI 层:browser-use(官方代码原封不动,16 个工具)           │
│    browser_navigate / browser_click / browser_type /       │
│    browser_get_state / retry_with_browser_use_agent ...    │
│  ──────────────────────────────────────────────────────── │
│  精确层:playwright-python(官方 API 薄封装,43 个工具)     │
│    pw_navigate / pw_fill / pw_click / pw_assert_*          │
│    pw_wait_* / pw_screenshot / pw_network / pw_trace ...   │
│  ──────────────────────────────────────────────────────── │
│  共享会话:playwright 启动 chromium(CDP 调试端口)          │
│  browser-use 通过 cdp_url 连接同一浏览器实例                 │
└──────────────────────────────────────────────────────────┘
```

## 核心特性

- **共生**:AI 层(browser-use)自主探索复杂页面,精确层(Playwright)做确定性操作与断言——两层**各自管理独立的浏览器实例**,互不干扰、可任意顺序切换
- **多会话并发安全**:每个 server 进程(Reasonix 每个对话一个进程)自动分配独立 CDP 端口(pid 随机偏移 + 空闲探测)与独立 browser-use 数据目录,**多个对话同时使用浏览器测试互不冲突**
- **测试完整**:导航、填表、点击、断言(文本/可见/URL/数量)、等待、网络捕获、截图、登录态复用、trace 调试
- **内置 stealth 反检测**:自研零依赖模块,10 个维度伪装(webdriver/plugins/userAgentData/chrome 对象/canvas/WebGL/Client Hints…),bot.sannysoft.com 专业检测站零失败项
- **无头默认**:后台跑测试不弹窗(`BROWSER_TEST_HEADLESS=0` 可开有头)
- **不改上游一行代码**:融合全部通过组合 + 运行时配置注入实现

## 多会话并发架构(v0.2)

```
Reasonix 对话 A ──► browser-test server 进程 A ──► chromium A(CDP 端口: pid 偏移 + 探测)
Reasonix 对话 B ──► browser-test server 进程 B ──► chromium B(CDP 端口: pid 偏移 + 探测)
        │                    │                              │
        └── 各自独立:CDP 端口 / browser-use 数据目录 / 页面会话
```

设计要点:
- **CDP 端口隔离**:`PlaywrightBridge.__init__` 用 `os.getpid() % 1000` 做端口起始偏移 + 空闲探测,两个进程不可能选到同一端口(即使同时启动)
- **browser-use 数据目录隔离**:`user_data_dir` 按 `os.getpid()` 生成独立临时目录,避免多进程共享 `~/.config/browseruse` 互锁
- **两层浏览器实例分离**:AI 层(browser-use)与精确层(playwright)各自管理独立 chromium。早期版本试图共享同一浏览器(CDP 连接),实测 browser-use 的 `Target.setAutoAttach` 会销毁 playwright 的 page/context 引用导致两层互相踩踏——分离后彻底解决
- **启动失败自动重试**:`ensure_browser` 最多尝试 3 个端口,处理探测与启动之间的竞态

## 快速开始

```bash
pip install -r requirements.txt
playwright install chromium        # 首次下载浏览器(可选:channel=chrome 用系统 Chrome)
python server.py                   # 直接跑(stdio 模式)
```

### 注册到任意 MCP 客户端

```jsonc
// Claude Desktop / Cursor / Reasonix 等
{
  "mcpServers": {
    "browser-test": {
      "command": "python",
      "args": ["/path/to/browser-test-mcp/server.py"],
      "env": {
        "OPENAI_API_KEY": "sk-...",                    // AI 层 Agent 需要(可选)
        "OPENAI_BASE_URL": "https://api.deepseek.com", // OpenAI 兼容 provider(可选)
        "BROWSER_USE_LLM_MODEL": "deepseek-v4-flash",  // AI 层模型(可选)
        "BROWSER_TEST_HEADLESS": "1"                    // 1=无头(默认)0=有头
      }
    }
  }
}
```

### 冒烟测试

```bash
PYTHONIOENCODING=utf-8 python test_smoke.py   # 59 工具 + 共享会话验证
python test_fusion.py                          # 两层交叉操作验证
```

## 工具清单

**AI 层(browser-use,16 个)**:`browser_navigate`、`browser_click`、`browser_type`、`browser_get_state`、`browser_extract_content`、`browser_get_html`、`browser_screenshot`、`browser_scroll`、`browser_go_back`、`browser_list_tabs`、`browser_switch_tab`、`browser_close_tab`、`browser_list_sessions`、`browser_close_session`、`browser_close_all`、`retry_with_browser_use_agent`

**精确层(Playwright,43 个)**:

| 类别 | 工具 |
|------|------|
| 浏览器 | `pw_browser_info`、`pw_close_browser` |
| 导航 | `pw_navigate`、`pw_reload`、`pw_go_back`、`pw_go_forward` |
| 页面 | `pw_list_pages`、`pw_new_page`、`pw_switch_page`、`pw_close_page` |
| 元素 | `pw_click`、`pw_fill`、`pw_press`、`pw_select_option`、`pw_check`、`pw_uncheck`、`pw_hover`、`pw_dblclick`、`pw_clear_input`、`pw_upload_files`、`pw_drag_and_drop` |
| 读取 | `pw_get_text`、`pw_get_attribute`、`pw_get_value`、`pw_get_url`、`pw_get_title`、`pw_get_html`、`pw_evaluate`、`pw_screenshot` |
| 等待 | `pw_wait_for_selector`、`pw_wait_for_url`、`pw_wait_for_load_state` |
| 断言 | `pw_assert_text`、`pw_assert_visible`、`pw_assert_url`、`pw_assert_count` |
| 网络 | `pw_network_requests`、`pw_clear_network_log`、`pw_wait_for_response` |
| 登录态 | `pw_save_storage_state`、`pw_load_storage_state` |
| 调试 | `pw_trace_start`、`pw_trace_stop` |

## 环境变量

| 变量 | 默认 | 说明 |
|------|------|------|
| `BROWSER_TEST_HEADLESS` | `1` | 无头模式;`0` = 有头(调试看界面) |
| `BROWSER_TEST_CDP_PORT` | `9222` | CDP 调试端口(browser-use 连接用) |
| `BROWSER_TEST_USER_AGENT` | Chrome/150 | UA 覆盖(可改) |
| `BROWSER_TEST_CHANNEL` | 空 | 用系统浏览器:`chrome` / `msedge`(指纹更真实) |
| `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` | 无 | AI 层 LLM |
| `OPENAI_BASE_URL` | 空 | OpenAI 兼容 provider 地址 |
| `BROWSER_USE_LLM_MODEL` | 空 | AI 层模型名 |
| `BROWSER_USE_ADD_SCHEMA_TO_SYSTEM_PROMPT` | `0` | `1` = schema 进 system prompt(兼容不支持 response_format 的 provider) |
| `BROWSER_USE_DONT_FORCE_STRUCTURED_OUTPUT` | `0` | `1` = 不强制结构化输出(配合上行) |
| `BROWSER_USE_REMOVE_MIN_ITEMS_FROM_SCHEMA` | `0` | `1` = 移除 schema 中 minItems(部分 provider 兼容) |

## 标准测试工作流

```
1. pw_navigate(url)                 打开被测页面
2. pw_wait_for_selector / pw_assert_url   确认页面就绪
3. pw_fill(selector, value)         填表单
4. pw_click(selector)               触发交互
5. pw_wait_for_response / pw_wait_for_url 等待结果(接口/跳转)
6. pw_assert_text / pw_assert_*     断言,记录 PASS/FAIL
7. pw_screenshot                    留证
8. pw_close_browser                 清理
```

页面复杂时用 `retry_with_browser_use_agent` 交给 AI 智能体自主完成,再用精确层断言。

## 反爬对抗

内置 `stealth.py` 反检测模块(零第三方依赖),自动注入 10 个维度伪装:
`navigator.webdriver`、plugins(真实 PluginArray)、userAgentData、languages/platform/硬件参数、window.chrome(含 iframe)、canvas 噪声、WebGL 参数、permissions、Client Hints 头(UA + Sec-CH-UA 一致性)、locale/timezone。

- ✅ bot.sannysoft.com 专业 WebDriver 检测站:**零失败项**
- ⚠️ 能力边界:百度等顶级风控为**服务端模型判定**,对自动化环境会降级隐藏交互元素(实测多层对抗后仍被识别)。对策:自家/中小站点直接可用;强风控大站用有头模式 + 持久化 profile 养号,或连真实用户浏览器会话
- 📌 合规:仅用于自己/授权项目的自动化测试

## 文件结构

```
browser-test-mcp/
├── server.py          # MCP stdio 入口
├── fusion_server.py   # 融合层:官方 AI 层工具 + 精确层工具合并
├── pw_bridge.py       # Playwright 精确层(43 工具 + 浏览器生命周期)
├── stealth.py         # 自研反检测模块
├── requirements.txt
├── skill/SKILL.md     # Reasonix skill 手册
├── test_smoke.py      # stdio 冒烟测试(59 工具 + 共享会话断言,CI 使用)
└── test_fusion.py     # 两层交叉操作测试
```

## 上游

- [microsoft/playwright](https://github.com/microsoft/playwright)(Apache-2.0)
- [browser-use/browser-use](https://github.com/browser-use/browser-use)(MIT)
- [microsoft/playwright-python](https://github.com/microsoft/playwright-python)(Apache-2.0)

本项目为两者功能的融合封装(组合 + 运行时注入,不改上游源码),License: MIT

Maintenance

ActivitySlowing
ResponsivenessNo issues