English · Español
@matware/e2e-runner
The AI-native E2E test runner that writes, runs, and debugs tests for you.
______________________________________________________________________
E2E跑步者 是一个零代码浏览器测试框架,其中的测试是纯JSON文件——没有Playwright脚本,没有Cypress样板,也没有需要学习的测试框架。定义要点击、键入和断言的内容,然后运行者对共享的Chrome池并行执行。
但真正与众不同的是 深度人工智能集成。内置 MCP服务器,Claude Code可以从对话中创建测试,运行它们,阅读结果,捕获屏幕截图,甚至直观地验证页面看起来是否正确——所有这些都不需要离开聊天室。粘贴GitHub问题URL,并获得可运行的测试。这就是工作流程。
这是一个测试
[
{
"name": "login-flow",
"actions": [
{ "type": "goto", "value": "/login" },
{ "type": "type", "selector": "#email", "value": "user@test.com" },
{ "type": "type", "selector": "#password", "value": "secret" },
{ "type": "click", "text": "Sign In" },
{ "type": "assert_text", "text": "Welcome back" },
{ "type": "screenshot", "value": "logged-in.png" }
]
}
]没有进口。不 describe/it。无编译步骤。只是一个描述用户行为的JSON文件,运行者使其发生。
______________________________________________________________________
代理技能
为任何编码代理(Claude Code、Cursor、Codex、Copilot和 40+更多):
npx skills add fastslack/mtw-e2e-runner这为您的代理提供了创建、运行和调试JSON驱动的E2E测试的知识,无需阅读文档。
浏览所有可用技能 技能s.sh
______________________________________________________________________
入门指南
先决条件: Node.js>=20,Docker正在运行,你的应用程序在已知的端口上。
快速启动
npm install --save-dev @matware/e2e-runner
npx e2e-runner init # creates e2e/tests/ with a sample test
npx e2e-runner pool start # starts Chrome in Docker
npx e2e-runner run --all # runs the sample test或者在一个命令中完成所有操作:
curl -fsSL https://raw.githubusercontent.com/fastslack/mtw-e2e-runner/main/scripts/quickstart.sh | bash设置后,编辑 e2e.config.js 设置应用程序的端口:
export default {
baseUrl: 'http://host.docker.internal:3000', // change 3000 to your port
};为什么?host.docker.internal? Chrome在Docker中运行,无法访问localhost在你的机器上。这个主机名弥补了这一差距。在Linux(Docker引擎,而非桌面)上,您可能需要--add-host=host.docker.internal:host-gateway或者直接使用您的局域网IP。
添加克劳德代码(可选)
claude plugin marketplace add fastslack/mtw-e2e-runner
claude plugin install e2e-runner@matware这为Claude 13 MCP提供了工具、斜线命令和专用代理。直说吧 *“运行所有E2E测试”* 或 *“为登录流创建测试”*.
添加OpenCode(可选)
cp node_modules/@matware/e2e-runner/opencode.json ./
mkdir -p .opencode && cp -r node_modules/@matware/e2e-runner/.opencode/* .opencode/看 打开代码.md 了解详情。
接下来是什么?
- 测试格式 --学习完整的动作词汇
- Claude代码集成 --设置人工智能驱动的测试
- 目视验证 --用简明的英语描述预期的页面
- 待测试问题 --将bug报告转化为可执行测试
- 网络仪表盘 --实时监控测试
______________________________________________________________________
你得到了什么
🧪 零代码测试 --您团队中的任何人都可以读取和写入的JSON文件。没有JavaScript,没有编译,没有框架锁定。
🤖 AI驱动的测试 --Claude Code通过13个MCP工具本机创建、执行和调试测试。让它“测试结账流程”,它构建JSON,运行它,并返回报告。
🐛 测试管道问题 -粘贴一个GitHub或GitLab问题URL。运行者获取它,生成E2E测试,运行它们,然后告诉你: *bug已确认* 或 *不可复现*.
👁️ 视觉验证 --用简单的英语描述页面应该是什么样子。AI会捕获屏幕截图,并根据您的描述判断通过/失败。无需像素差异设置。
🧠 学习系统 --跟踪测试运行的稳定性。检测不稳定的测试、不稳定的选择器、缓慢的API和错误模式,然后提出可操作的见解。
⚡ 并行执行 --对共享的Chrome池(无浏览器/Chrome)同时运行N个测试。串行模式可用于共享状态的测试。
📊 实时仪表盘 --实时执行视图、运行历史记录和通过率图表、基于哈希的搜索截图库、可扩展的网络请求日志。
🔁 智能重试 --具有可配置延迟的测试级和操作级重试。有缺陷的测试会被自动检测和标记。
📦 可重复使用的模块 --将通用流(登录、导航、设置)提取到参数化模块中,并用引用它们 $use.
🏗️ CI就绪 --JUnitXML输出,失败时退出代码1,自动捕获错误截图。附带了GitHub操作示例。
🌐 多项目 --一个仪表板汇总了所有项目的测试结果。一个Chrome池为所有人提供服务。
🐳 便携的 --Chrome在Docker中运行,测试是存储库中的JSON文件。适用于任何使用Node.js和Docker的机器。
______________________________________________________________________
测试格式
每 .json 归档 e2e/tests/ 包含一系列测试。每个测试都有一个 name 和顺序 actions:
[
{
"name": "homepage-loads",
"actions": [
{ "type": "goto", "value": "/" },
{ "type": "assert_visible", "selector": "body" },
{ "type": "assert_url", "value": "/" },
{ "type": "screenshot", "value": "homepage.png" }
]
}
]套件文件可以使用数字前缀进行排序(01-auth.json, 02-dashboard.json).这 --suite 标志与前缀匹配或不匹配,因此 --suite auth 发现 01-auth.json.
可用操作
| 操作 | 字段 | 描述 |
|---|---|---|
goto | value | 导航到URL(相对于 baseUrl 或绝对) |
click | selector 或 text | 按CSS选择器或可见文本内容单击 |
type / fill | selector, value | 清除字段并键入文本 |
wait | selector, text,或 value (ms) | 等待元素、文本或固定延迟 |
screenshot | value (文件名) | 截图 |
select | selector, value | 选择下拉选项 |
clear | selector | 清除输入字段 |
press | value | 按键盘键(Enter, Tab等等) |
scroll | selector 或 value (px) | 滚动到元素或按像素量 |
hover | selector | 将鼠标悬停在元素上 |
evaluate | value | 在浏览器上下文中执行JavaScript |
navigate | value | 浏览器导航(back, forward, reload) |
clear_cookies | -- | 清除当前页面的所有Cookie |
断言
| 操作 | 字段 | 描述 |
|---|---|---|
assert_text | text | 断言文本存在于页面上的任何位置(子字符串) |
assert_element_text | selector, text,可选 value: "exact" | 断言元素的文本包含(或完全匹配)预期的文本 |
assert_url | value | 断言当前URL路径或完整URL。路径(/dashboard)仅与路径名进行比较 |
assert_visible | selector | 断言元素存在并且可见 |
assert_not_visible | selector | 断言元素隐藏或不存在 |
assert_attribute | selector, value | 检查属性: "type=email" 为了价值, "disabled" 为了生存 |
assert_class | selector, value | 断言元素有一个CSS类 |
assert_input_value | selector, value | 断言输入/选择/textarea .value 包含文本 |
assert_matches | selector, value (正则表达式) | 断言元素文本与正则表达式模式匹配 |
assert_count | selector, value | 断言元素计数:精确("5"),或操作员(">3", ">=1", " CLI,或 ACTION_RETRIES env var.重试之间的延迟: actionRetryDelay (默认500ms)。 |
______________________________________________________________________
串联试验
共享状态的测试(例如,修改同一记录的两个测试)可以在并行运行时进行竞争。将它们标记为序列:
{ "name": "create-patient", "serial": true, "actions": [...] }
{ "name": "verify-patient-list", "serial": true, "actions": [...] }串行测试一次运行一个 之后 所有并行测试都完成了——在不减缓独立测试的情况下防止干扰。
______________________________________________________________________
测试经过身份验证的应用程序
最简单的方法——像真实用户一样通过UI登录:
{
"hooks": {
"beforeEach": [
{ "type": "goto", "value": "/login" },
{ "type": "type", "selector": "#email", "value": "test@example.com" },
{ "type": "type", "selector": "#password", "value": "test-password" },
{ "type": "click", "text": "Sign In" },
{ "type": "wait", "selector": ".dashboard" }
]
},
"tests": [...]
}对于带有JWT的SPA,直接注入令牌跳过登录表单:
{ "type": "set_storage", "value": "accessToken=eyJhbGciOiJIUzI1NiIs..." }或者在config中全局设置:
// e2e.config.js
export default {
authToken: 'eyJhbGciOiJIUzI1NiIs...',
authStorageKey: 'accessToken',
};每个测试都在一个 新的浏览器上下文,因此auth状态在测试之间会自动清除。
更多策略: 基于Cookie的身份验证、HTTP头注入、OAuth/SSO绕过、可重用的身份验证模块和基于角色的测试——请参阅 docs/authentication.md
______________________________________________________________________
可重复使用的模块
将公共流提取到参数化模块中:
// e2e/modules/login.json
{
"$module": "login",
"description": "Log in via the UI login form",
"params": {
"email": { "required": true, "description": "User email" },
"password": { "required": true, "description": "User password" }
},
"actions": [
{ "type": "goto", "value": "/login" },
{ "type": "type", "selector": "#email", "value": "{{email}}" },
{ "type": "type", "selector": "#password", "value": "{{password}}" },
{ "type": "click", "text": "Sign In" },
{ "type": "wait", "value": "2000" }
]
}在测试中使用:
{
"name": "dashboard-loads",
"actions": [
{ "$use": "login", "params": { "email": "user@test.com", "password": "secret" } },
{ "type": "assert_text", "text": "Dashboard" }
]
}模块支持参数验证(所需参数快速失败)、条件块({{#param}}...{{/param}})嵌套组合和循环检测。
______________________________________________________________________
排除图案
从中跳过探索性或草稿测试 --all 跑:
// e2e.config.js
export default {
exclude: ['explore-*', 'debug-*', 'draft-*'],
};个人套房运行(--suite)不受排除模式的影响。
______________________________________________________________________
目视验证
描述页面应该是什么样子——从截图来看,人工智能判断通过/失败:
{
"name": "dashboard-loads",
"expect": "Patient list with at least 3 rows, no error messages, sidebar with navigation links",
"actions": [
{ "type": "goto", "value": "/dashboard" },
{ "type": "wait", "selector": ".patient-list" }
]
}测试操作完成后,运行者会自动捕获验证屏幕截图。MCP响应包括截图哈希值——Claude Code检索它并根据您的 expect 描述。不需要API密钥。
______________________________________________________________________
待测试问题
将GitHub和GitLab问题转化为可执行的E2E测试。粘贴问题URL并自动获取可运行的测试。
它是如何工作的:
- 获取 --通过以下方式提取问题详细信息(标题、正文、标签)
gh或glab命令行界面 - 生成 --AI根据问题描述创建JSON测试操作
- 跑 --可选择立即执行测试,以验证错误是否可重复
# Fetch and display
e2e-runner issue https://github.com/owner/repo/issues/42
# Generate a test file via Claude API
e2e-runner issue https://github.com/owner/repo/issues/42 --generate
# Generate + run + report
e2e-runner issue https://github.com/owner/repo/issues/42 --verify
# -> "BUG CONFIRMED" or "NOT REPRODUCIBLE"在Claude Code中,只需问:
“获取问题#42并为其创建E2E测试”
Bug验证逻辑: 生成的测试断言 正确的 行为。测试失败=确认错误。所有测试均通过=不可重复。
认证: GitHub需要 gh CLI,GitLab需要 glab CLI。支持自托管GitLab。
______________________________________________________________________
学习系统
运行者从每次测试运行中学习——随着时间的推移积累有关测试套件的知识。
通过以下方式查询见解 e2e_learnings MCP工具:
| 查询 | 返回 |
|---|---|
summary | 完整健康概述:通过率、不稳定测试、不稳定选择器、API问题 |
flaky | 仅在重试后通过的测试 |
selectors | 故障率高的CSS选择器 |
pages | 存在控制台错误、网络故障、加载时间问题的页面 |
apis | 具有错误率和延迟的API端点(自动规范化:UUID、哈希、ID) |
errors | 最常见的错误模式,分类 |
trends | 随时间变化的通过率(当所有数据都来自一天时,自动切换到每小时) |
test: | 深入查看特定测试的历史记录 |
| `page: | |
| ` | 深入查看特定页面的历史记录 |
selector: | 深入查看特定选择器的历史记录 |
储存和出口:
- SQLite(
~/.e2e-runner/dashboard.db)--默认设置为零 - Neo4j知识图——可选,用于基于关系的分析。通过管理
e2e_neo4jMCP工具或docker compose - Markdown报告(
e2e/learnings.md)--每次运行后自动生成
测试说明: 每次测试运行都会生成一个人类可读的逐步叙述,在CLI输出和仪表板中可见。
______________________________________________________________________
网络仪表盘
用于运行测试、查看结果、屏幕截图和网络日志的实时UI。
e2e-runner dashboard # Start on default port 8484
e2e-runner dashboard --port 9090 # Custom port现场执行
实时监控测试,包括逐步进度、持续时间和活跃员工数量。
测试套件
浏览多个项目中的所有测试套件。只需单击一下即可运行单个套件或所有测试。
运行历史
使用内置图表跟踪通过率趋势。单击任何一行以展开每个测试结果、屏幕截图哈希和错误的完整详细信息。
运行详细信息
使用PASS/FAIL徽章扩展视图,使用可复制的哈希值截图缩略图(ss:77c28b5a)、格式化控制台错误和网络请求日志。
屏幕截图库
使用哈希搜索浏览所有捕获的屏幕截图。包括动作截图、错误截图和验证截图。
池状态
监控Chrome池健康状况:可用插槽、正在运行的会话、内存压力。
______________________________________________________________________
电脑屏幕截图工具
按需捕获任何URL的屏幕截图——无需测试套件:
e2e-runner capture https://example.com
e2e-runner capture https://example.com --full-page --selector ".loaded" --delay 2000通过MCP e2e_capture 工具支架 authToken 和 authStorageKey 对于经过身份验证的页面,它在导航之前将令牌注入localStorage。
每个截图都会得到一个确定性哈希值(ss:a3f2b1c9).使用 e2e_screenshot 通过哈希检索任何屏幕截图——它返回带有元数据(测试名称、步骤、类型)的图像。
______________________________________________________________________
人工智能集成
克劳德代码
claude plugin marketplace add fastslack/mtw-e2e-runner
claude plugin install e2e-runner@matware这为Claude 13提供了MCP工具、工作流技能和3个斜线命令(/e2e-runner:run, /e2e-runner:create-test, /e2e-runner:verify-issue)以及3名专业代理(测试分析仪、测试创建者、测试改进者)。
仅安装MCP (仅限工具,无技能/命令/代理):
claude mcp add --transport stdio --scope user e2e-runner \
-- npx -y -p @matware/e2e-runner e2e-runner-mcp开源代码
cp node_modules/@matware/e2e-runner/opencode.json ./
mkdir -p .opencode && cp -r node_modules/@matware/e2e-runner/.opencode/* .opencode/看 打开代码.md 了解详情。
MCP工具
| 工具 | 说明 |
|---|---|
e2e_run | 运行测试(全部、按套件或按文件) |
e2e_list | 列出可用的测试套件 |
e2e_create_test | 创建新的测试JSON文件 |
e2e_create_module | 创建可重用模块 |
e2e_pool_status | 检查Chrome池运行状况 |
e2e_screenshot | 按哈希值检索屏幕截图 |
e2e_capture | 捕获任何URL的屏幕截图 |
e2e_dashboard_start | 启动web仪表板 |
e2e_dashboard_stop | 停止web仪表板 |
e2e_issue | 获取问题并生成测试 |
e2e_network_logs | 查询运行的网络日志 |
e2e_learnings | 查询稳定性见解 |
e2e_neo4j | 管理Neo4j知识图 |
池的启动/停止仅限于CLI,不通过MCP公开。
______________________________________________________________________
网络错误处理
显式断言
地方 assert_no_network_errors 在关键页面加载后:
{ "type": "goto", "value": "/dashboard" },
{ "type": "wait", "selector": ".loaded" },
{ "type": "assert_no_network_errors" }全局标记
集 failOnNetworkError: true 自动失败任何具有网络错误的测试:
e2e-runner run --all --fail-on-network-error禁用(默认)时,运行程序仍会收集和报告网络错误——当测试通过但出现网络错误时,MCP响应会包含一个警告。
完整网络日志记录
所有XHR/fetch请求都通过以下方式捕获:URL、方法、状态、持续时间、请求/响应标头和响应正文(截断为50KB)。可在仪表板中查看,并带有可扩展的请求详细信息行。
MCP钻下流量:
1. e2e_run → compact networkSummary + runDbId
2. e2e_network_logs(runDbId) → all requests (url, method, status, duration)
3. e2e_network_logs(runDbId, errorsOnly: true) → only failed requests
4. e2e_network_logs(runDbId, includeHeaders: true) → with headers
5. e2e_network_logs(runDbId, includeBodies: true) → full request/response bodies这 e2e_run 无论捕获了多少请求,响应都保持紧凑(~5KB)。使用 e2e_network_logs 与返回 runDbId 根据需要深入了解细节。
______________________________________________________________________
钩子
在生命周期点运行操作。在配置中全局定义或按套件定义:
{
"hooks": {
"beforeAll": [{ "type": "goto", "value": "/setup" }],
"beforeEach": [{ "type": "goto", "value": "/" }],
"afterEach": [{ "type": "screenshot", "value": "after.png" }],
"afterAll": []
},
"tests": [...]
}重要提示:beforeAll在测试开始前关闭的单独浏览器页面上运行。使用beforeEach用于测试所需的状态(Cookie、本地存储、身份验证令牌)。
______________________________________________________________________
命令行界面
# Run tests
e2e-runner run --all # All suites
e2e-runner run --suite auth # Single suite
e2e-runner run --tests path/to.json # Specific file
e2e-runner run --inline '' # Inline JSON
# Pool management (CLI only, not MCP)
e2e-runner pool start # Start Chrome container
e2e-runner pool stop # Stop Chrome container
e2e-runner pool status # Check pool health
# Issue-to-test
e2e-runner issue # Fetch issue
e2e-runner issue --generate # Generate test via AI
e2e-runner issue --verify # Generate + run + report
# Dashboard
e2e-runner dashboard # Start web dashboard
# Other
e2e-runner list # List available suites
e2e-runner capture # On-demand screenshot
e2e-runner init # Scaffold projectCLI选项
| 标志 | 默认值 | 描述 |
|---|---|---|
--base-url | http://host.docker.internal:3000 | 应用程序基本URL |
--pool-url | ws://localhost:3333 | chrome池websocket URL |
--concurrency | 3 | 平行测试工人 |
--retries | 0 | 重试失败的测试N次 |
--action-retries | 0 | 重试失败的操作N次 |
--test-timeout | 60000 | 每次测试超时 |
--timeout | 10000 | 默认操作超时 |
--output | json | 报告: json, junit, both |
--env | default | 环境概况 |
--fail-on-network-error | false | 网络错误导致测试失败 |
--project-name | dir name | 项目显示名称 |
______________________________________________________________________
配置
创建 e2e.config.js 在项目根目录中:
export default {
baseUrl: 'http://host.docker.internal:3000',
concurrency: 4,
retries: 2,
actionRetries: 1,
testTimeout: 30000,
outputFormat: 'both',
failOnNetworkError: true,
exclude: ['explore-*', 'debug-*'],
hooks: {
beforeEach: [{ type: 'goto', value: '/' }],
},
environments: {
staging: { baseUrl: 'https://staging.example.com' },
production: { baseUrl: 'https://example.com', concurrency: 5 },
},
};配置优先级(最高获胜)
- CLI标志
- 环境变量
- 配置文件(
e2e.config.js或e2e.config.json) - 默认值
当 --env 设置后,匹配的配置文件将覆盖所有内容。
______________________________________________________________________
CI/CD
JUnit XML
e2e-runner run --all --output junitGitHub 操作
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx e2e-runner pool start
- run: npx e2e-runner run --all --output junit
- uses: mikepenz/action-junit-report@v4
if: always()
with:
report_paths: e2e/screenshots/junit.xml______________________________________________________________________
程序化API
import { createRunner } from '@matware/e2e-runner';
const runner = await createRunner({ baseUrl: 'http://localhost:3000' });
const report = await runner.runAll();
const report = await runner.runSuite('auth');
const report = await runner.runFile('e2e/tests/login.json');
const report = await runner.runTests([
{ name: 'quick-check', actions: [{ type: 'goto', value: '/' }] },
]);______________________________________________________________________
需求
- Node.js >= 20
- 码头工人 (适用于Chrome池)
许可证
版权所有2025 Matias Aguirre(fastlack)
根据Apache许可证2.0版授权。看 许可证 了解详情。
