mcpField
Q
qe-browser

qe-browser

github.com/proffesor-for-testing测试与质量51956 次安装今天更新
代码仓库

关于 qe-browser

qe-browser 是面向 QE 与 CI 浏览器测试的 Vibium 封装,提供类型化断言、批量执行、视觉差异和页面提示注入扫描等专用能力。它也支持基于语义意图的元素查找。

主要功能

  1. 0116 类页面状态断言
  2. 02批量执行并在失败时停止
  3. 03与基线进行像素差异比较
  4. 04扫描页面中的提示注入
  5. 05按语义意图查找元素

适用场景

  1. 01验证登录流程及页面状态
  2. 02在 CI 中运行视觉回归测试
  3. 03检查不可信页面的提示注入
  4. 04通过批处理运行端到端步骤

MCP 相关

底层 Vibium 提供 MCP 服务,可供 MCP 客户端执行导航、页面映射和交互。QE 专用断言、批处理、视觉差异、注入扫描和意图评分仍通过本 Skill 的脚本使用。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/proffesor-for-testing/agentic-qe --skill qe-browser

安装后在 Claude Code 中输入/qe-browser确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

evals/
qe-browser.yaml
fixtures/
package.json
serve-skills.js
references/
assertion-kinds.md
migration-from-playwright.md
schemas/
output.json
scripts/
assert.js
batch.js
check-injection.js
intent-score.js
package.json
smoke-test.sh
validate-config.json
visual-diff.js
scripts/lib/
vibium.js

详细介绍

QE Browser

由 AQE 维护的轻量级 Vibium 封装,增加了 QE 专用原语:类型化断言、批量执行、与基线进行视觉差异比较、提示词注入扫描和语义意图评分。

引擎: Vibium——单个约 10MB 的 Go 二进制文件,基于 WebDriver BiDi(W3C 标准)构建,采用 Apache-2.0 许可证,并发布于 npm/PyPI/Maven Central。首次使用时会自动启动后台守护进程,并自动下载 Chrome for Testing。

为什么选 Vibium,而不是 Playwright?

  • 10MB 二进制文件,而 Playwright 安装约为 300MB
  • WebDriver BiDi 标准(而非 CDP)——面向 Firefox/Safari,具备前瞻性
  • 每条命令都支持 --json 模式(符合 AQE 的结构化输出规则)
  • 内置 MCP 服务:npx -y vibium mcp
  • 一流的语义定位器:find text|label|placeholder|testid|role|xpath|alt|title

平台支持(已于 2026-04-09 针对 Vibium v26.3.18 验证)

平台npm install -g vibiumvibium go <url>smoke-test.sh
macOS arm64(Apple Silicon 原生)✅✅✅
macOS x64(Intel)✅✅✅
Linux x86_64✅✅✅
Windows x64✅✅尚未测试
Linux ARM64(aarch64)✅ 二进制文件本身⚠️ 需要变通方案✅ 使用变通方案后
Linux ARM64 变通方案

Google Chrome for Testing 不提供 linux-arm64 版本。Vibium 在 aarch64 主机上会回退到 chrome-linux64(x86_64),在 Rosetta 下运行时会因 failed to open elf at /lib64/ld-linux-x86-64.so.2 而失败。要在 Linux ARM64 codespace 或容器中运行 qe-browser:

# 1. Install Vibium normally — the vibium binary itself IS native ARM64
npm install -g vibium

# 2. Install Debian's native ARM64 chromium + chromedriver
sudo apt-get update
sudo apt-get install -y chromium chromium-driver

# 3. Symlink Vibium's broken cached binaries to the native system ones.
#    Run after `vibium install` (auto-runs on first `vibium go`).
for dir in ~/.cache/vibium/chrome-for-testing/*/; do
  # Newer Vibium layout (v26.3.x): chromedriver and chrome at the root
  if [ -e "$dir/chromedriver" ]; then
    rm -f "$dir/chromedriver" "$dir/chrome"
    ln -s /usr/bin/chromedriver "$dir/chromedriver"
    ln -s /usr/bin/chromium     "$dir/chrome"
  fi
  # Older Vibium layout: chromedriver-linux64/ and chrome-linux64/ subdirs
  if [ -e "$dir/chromedriver-linux64/chromedriver" ]; then
    rm -f "$dir/chromedriver-linux64/chromedriver" "$dir/chrome-linux64/chrome"
    ln -s /usr/bin/chromedriver "$dir/chromedriver-linux64/chromedriver"
    ln -s /usr/bin/chromium     "$dir/chrome-linux64/chrome"
  fi
done

# 4. Verify
vibium --headless go https://httpbin.org/html
vibium --headless title  # → "Herman Melville - Moby-Dick"

此变通方案已在运行 chromium 146.0.7680.177-1~deb12u1 的 Debian bookworm aarch64 上验证可用。请关注上游进展——当 Vibium 添加 --browser-path 标志,或 Google 发布 linux-arm64 版 Chrome for Testing 后,本节内容便不再适用。

无头模式

辅助脚本(assert.js、batch.js、visual-diff.js、check-injection.js、intent-score.js)会自动为每次 vibium 调用注入 --headless,因为 qe-browser 技能面向 QE/CI 使用场景,通常没有显示服务器。Vibium 本身默认“显示界面”——在无头容器中不带 --headless 运行 vibium go 会因 Missing X server or $DISPLAY 而失败。

交互式调试时可选择不启用无头模式:

QE_BROWSER_HEADED=1 node .claude/skills/qe-browser/scripts/assert.js --checks '...'

直接调用 vibium(而非通过辅助脚本调用)时,如果你在容器中运行,请自行传入 --headless:

vibium --headless go https://example.com
vibium --headless title

激活条件

  • QE 技能需要导航到网页、读取网页、与网页交互或捕获网页时
  • 针对已存储的基线运行视觉回归测试时
  • 断言页面状态(URL、文本可见性、控制台错误、网络故障)时
  • 验证安全问题的可利用性(渗透测试)时
  • 扫描不可信网页中的提示词注入时
  • 使用明确的通过/失败门槛运行批量自动化时

核心工作流

每项由浏览器驱动的 QE 任务都遵循相同流程:

  1. 导航 — vibium go <url>
  2. 映射 — 使用 vibium map 获取元素引用(@e1、@e2、…)
  3. 交互 — vibium click @e1、vibium fill @e2 "text"
  4. 验证 — 使用此技能的 assert.js 运行类型化检查,或使用 vibium diff map 查看变化
  5. 如果 DOM 发生变化,则重新映射
# Typical login flow verification
vibium go https://app.example.com/login
vibium map --json > /tmp/refs.json
vibium fill @e1 "$USERNAME"
vibium fill @e2 "$PASSWORD"
vibium click @e3
vibium wait url "/dashboard"
node .claude/skills/qe-browser/scripts/assert.js --checks '[
  {"kind": "url_contains", "text": "/dashboard"},
  {"kind": "no_console_errors"},
  {"kind": "no_failed_requests"}
]'

引用生命周期——使用 diff map

DOM 发生变化时,Vibium 引用会失效。Vibium 提供了 vibium diff map,可以显示自上次调用 map 后新增、移除或重新定位的内容,无需手动为引用进行版本管理。在任何会改变 DOM 的交互之后:

vibium click @e3
vibium diff map --json   # shows added/removed/moved refs

这种方式比跟踪版本号更简洁——你会得到结构化差异,可以直接将其传递给下一步操作。

QE 原语(此技能的附加价值)

所有脚本都位于 .claude/skills/qe-browser/scripts/,并通过 shell 调用 vibium。这些脚本要求 vibium 位于 PATH 中(由 aqe init 安装)。

assert.js — 支持 16 种检查类型的类型化断言
node scripts/assert.js --checks '[
  {"kind": "url_contains", "text": "/dashboard"},
  {"kind": "text_visible", "text": "Welcome"},
  {"kind": "selector_visible", "selector": "#user-menu"},
  {"kind": "value_equals", "selector": "input[name=email]", "value": "[email protected]"},
  {"kind": "no_console_errors"},
  {"kind": "no_failed_requests"},
  {"kind": "response_status", "url": "/api/user", "status": 200},
  {"kind": "element_count", "selector": ".result", "op": ">=", "count": 5}
]'

全部 16 种类型:url_contains、url_equals、text_visible、text_hidden、selector_visible、selector_hidden、value_equals、attribute_equals、no_console_errors、no_failed_requests、response_status、request_url_seen、console_message_matches、element_count、title_matches、page_source_contains。

完整参考:references/assertion-kinds.md。

如果有任何检查失败,退出代码为非零。输出为 JSON:{ "passed": N, "failed": M, "results": [...] }。

batch.js — 多步骤执行,失败时停止
node scripts/batch.js --steps '[
  {"action": "go", "url": "https://example.com/login"},
  {"action": "fill", "ref": "@e1", "text": "[email protected]"},
  {"action": "fill", "ref": "@e2", "text": "secret"},
  {"action": "click", "ref": "@e3"},
  {"action": "wait_url", "pattern": "/dashboard"},
  {"action": "assert", "checks": [{"kind": "no_console_errors"}]}
]' --summary-only

与每一步都调用一次 vibium 相比,可减少往返次数。支持 --stop-on-failure(默认为 true)和 --summary-only。

visual-diff.js — 与存储的基准图像进行像素差异比较
# First run — creates baseline
node scripts/visual-diff.js --name "homepage"

# Subsequent runs — compare
node scripts/visual-diff.js --name "homepage" --threshold 0.05

# Scope to an element
node scripts/visual-diff.js --name "hero" --selector "#hero"

# Reset baseline after intentional change
node scripts/visual-diff.js --name "homepage" --update-baseline

基准图像存储在 .aqe/visual-baselines/ 中(项目本地,默认由 git 忽略)。使用 pixelmatch 进行像素比较;返回相似度百分比和差异图像路径。

check-injection.js — 提示词注入扫描器

扫描当前页面内容,查找已知的提示词注入模式(忽略先前指令、隐藏文本中的系统提示词等)。移植自 gsd-browser 的启发式扫描器(MIT/Apache)。

vibium go https://untrusted-page.com
node scripts/check-injection.js --include-hidden --json

返回按严重程度排序的发现结果。适用于 pentest-validation、injection-analyst 和 aidefence-guardian。

intent-score.js — 15 种语义意图

基于启发式评分发现元素,无需与大模型往返交互。移植自 gsd-browser 的 intent.rs:59-385(MIT/Apache)。

node scripts/intent-score.js --intent accept_cookies
node scripts/intent-score.js --intent submit_form --scope "#login-form"
node scripts/intent-score.js --intent primary_cta

意图:submit_form、close_dialog、primary_cta、search_field、next_step、dismiss、auth_action、back_navigation、fill_email、fill_password、fill_username、accept_cookies、main_content、pagination_next、pagination_prev。

返回评分和选择器排名前 5 的候选项。可用于关闭 Cookie 横幅、查找登录表单,以及在无需映射整个页面的情况下浏览向导。

常见 QE 模式

模式 1 — CI 中的视觉回归
vibium go "$STAGING_URL"
vibium wait load
node scripts/visual-diff.js --name "homepage-$(uname -m)" --threshold 0.02
# Non-zero exit if diff exceeds threshold
模式 2 — 带显式断言的 E2E 流程
node scripts/batch.js --steps @flows/login-flow.json
node scripts/assert.js --checks @assertions/post-login.json
模式 3 — 无需与 axe 往返交互的无障碍审计
vibium go "$URL"
vibium a11y-tree --json > a11y.json
# Analyze a11y.json with axe-core or in-skill rules
模式 4 — 重用身份验证状态
# Once: log in and save state
vibium go https://app.example.com/login
vibium fill "input[name=email]" "$USERNAME"
vibium fill "input[name=password]" "$PASSWORD"
vibium click "button[type=submit]"
vibium wait url "/dashboard"
vibium storage -o .aqe/auth/myapp.json

# Every subsequent run
vibium storage restore .aqe/auth/myapp.json
vibium go https://app.example.com/dashboard
模式 5 — 渗透测试漏洞利用验证
vibium go "$TARGET"
node scripts/check-injection.js --include-hidden > injection-report.json
vibium record start --name "exploit-$(date +%s)"
# Perform exploit steps via vibium commands
vibium record stop -o evidence.zip
模式 6 — 语义化关闭 Cookie 横幅
vibium go "$URL"
# Heuristic scoring — no LLM needed
ACCEPT=$(node scripts/intent-score.js --intent accept_cookies --json | jq -r '.candidates[0].selector // empty')
[ -n "$ACCEPT" ] && vibium click "$ACCEPT"

MCP 集成

Vibium 自带 MCP 服务。使用方法:

claude mcp add vibium -- npx -y vibium mcp

当 Vibium MCP 工具可用(mcp__vibium__*)时,核心的导航、映射、点击和填充操作优先使用这些工具,而不是通过 Shell 调用。继续使用此技能的 scripts/ 处理 QE 专用原语(断言、批处理、视觉差异、注入、意图)——这些功能不属于 Vibium。

回退策略

如果未安装 vibium(例如尚未运行 aqe init,或用户选择不安装),qe-browser 辅助脚本会自动实现相应契约。**无需搜索错误字符串。**每个脚本都会:

  1. 捕获 lib/vibium.js 在二进制文件不在 PATH 中时抛出的 VibiumUnavailableError
  2. 输出结构化的 skipped 封装(见下方输出契约),在顶层设置 vibiumUnavailable: true,并将 output.reason 设为 "browser-engine-unavailable"
  3. 以退出代码 2 退出(已跳过,与 0=成功和 1=失败不同)
  4. 绝不会静默回退到 Playwright 或 puppeteer-extra

通过 Shell 调用这些辅助脚本的下游技能可以根据结构化字段进行分支:

node .claude/skills/qe-browser/scripts/assert.js --checks "$CHECKS"
EXIT=$?
case $EXIT in
  0) echo "passed" ;;
  1) echo "failed" ; cat last-output.json ;;
  2) echo "skipped — vibium not installed; run \`aqe init\` or \`npm install -g vibium\`" ;;
esac

也可以在 Node 中:

const result = JSON.parse(stdout);
if (result.vibiumUnavailable) {
  // Surface skipped status to the caller; do NOT mark as failed
  return { status: 'skipped', reason: result.output.reason };
}

从 Playwright 迁移

如果你有现成的 Playwright 测试:

// Playwright
await page.goto('https://example.com');
await page.fill('input[name=email]', '[email protected]');
await page.click('button[type=submit]');
await expect(page).toHaveURL(/dashboard/);

可改为:

# qe-browser
vibium go https://example.com
vibium fill "input[name=email]" "[email protected]"
vibium click "button[type=submit]"
vibium wait url "/dashboard"
node .claude/skills/qe-browser/scripts/assert.js --checks '[
  {"kind": "url_contains", "text": "/dashboard"}
]'

完整迁移指南:references/migration-from-playwright.md。

输出契约

所有脚本都会输出结构化 JSON 封装。status 有三种有效值:

success(退出代码 0)
{
  "skillName": "qe-browser",
  "version": "1.0.0",
  "timestamp": "2026-04-09T12:00:00Z",
  "status": "success",
  "trustTier": 3,
  "output": {
    "operation": "assert",
    "summary": "All 6 assertions passed",
    "assert": { ... }
  },
  "metadata": { "executionTimeMs": 142 }
}
failed(退出代码 1)

结构相同;status: "failed" 表示真实的断言失败或操作错误。output.* 块包含各项检查的详细信息。

已跳过(退出代码 2)— F1 契约

当 vibium 未安装在 PATH 中时发出。顶层的 vibiumUnavailable: true 是下游技能的规范信号。

{
  "skillName": "qe-browser",
  "version": "1.0.0",
  "timestamp": "2026-04-09T12:00:00Z",
  "status": "skipped",
  "trustTier": 3,
  "vibiumUnavailable": true,
  "output": {
    "operation": "assert",
    "summary": "vibium binary not found on PATH. Install via `npm install -g vibium` or run `aqe init`.",
    "reason": "browser-engine-unavailable",
    "error": "vibium binary not found on PATH...",
    "remediation": [
      "Install vibium globally: `npm install -g vibium`",
      "Or re-run `aqe init` to install via the AQE bootstrap",
      "Set QE_BROWSER_HEADED=1 only for interactive debugging (not the cause here)"
    ]
  },
  "metadata": { "executionTimeMs": 0 }
}
退出代码摘要
退出代码状态含义
0success所有断言均通过/操作已完成
1failed确实发生断言失败或操作错误
2skippedvibium 不可用;属于环境问题,而非测试结果

CI 工具可使用退出代码区分“测试确实失败”(阻止构建)和“由于未安装浏览器引擎,我们无法运行测试”(发出警告,但不阻止构建)。

使用 scripts/validate-config.json 和 schemas/output.json 进行验证。

致谢

  • 提示词注入扫描器和意图评分逻辑移植自 gsd-browser(MIT/Apache-2.0)。
  • 引擎:Vibium(Apache-2.0)。

评论

支持 Markdown