ECC 中 /e2e 命令实战:用 Playwright 完成端到端测试生成、运行与制品报告
导读
本文讲解 ECC(Agent Harness 性能优化系统)在 OpenCode 插件模式下提供的 /e2e 子命令:它由专门的 e2e-runner 专家 Agent 接管,围绕 Playwright 完成从“用户旅程分析 → 测试生成 → 运行与制品采集 → 结果汇报”的完整闭环。读完本文,你将掌握如何在 ECC 的 Command/Agent 框架下落地一套可复用的端到端测试规范——包括稳定的 data-testid 定位策略、自动等待与测试隔离原则、失败截图/视频/trace 的制品管理,以及可供 CI 或评审直接消费的测试报告格式,并可从 .opencode/commands/e2e.md 出发追溯命令定义、对应 Agent 与配套 Skill 的源码级实现。
命令定位:一个专注于 E2E 的 subagent 命令
在 ECC 的 OpenCode 插件体系中,.opencode/commands/ 目录存放可由斜杠触发的子命令。/e2e 命令文件 .opencode/commands/e2e.md 的 frontmatter 定义了它的关键元信息:
description: Generate and run E2E tests with Playwright
agent: e2e-runner
subtask: true
description:向调用方说明该命令的用途——使用 Playwright 生成并运行端到端测试;agent: e2e-runner:命令执行时由 e2e-runner 专家 Agent 接管,而不是由主编码 Agent 直接执行;subtask: true:该命令以子任务方式运行,适合在对话流程中被调度或由/orchestrate等多 Agent 工作流按需唤起。
命令体则以一句指令交代任务输入:Generate and run end-to-end tests using Playwright: $ARGUMENTS,其中 $ARGUMENTS 是由用户补齐的自由参数——例如被测试的功能名、页面路径、关键用户流程描述等。作为对照,.opencode/README.md 的命令清单表中将 /e2e 描述为 “E2E tests”,在 Agent 清单中同样登记了名为 e2e-runner 的 E2E testing 专家,二者相互印证,说明该命令是 ECC 在 OpenCode 侧暴露的一个面向“最后一公里质量保障”的标准入口。
任务四步:从用户旅程到结果报告
命令正文把 e2e-runner 的核心任务固定为四步流水线,这也是任何一次 /e2e 调用的执行主线:
- Analyze user flow:先分析要测试的用户流程,识别真实用户会如何走完一个业务目标;
- Create test journey:用 Playwright 编写对应的测试旅程(test journey),覆盖主路径与关键分支;
- Run tests and capture artifacts:运行测试并在过程中捕获截图、视频、trace 等调试制品;
- Report results:以截图/视频佐证,输出结构化的测试结果报告。
这与 e2e-runner Agent 的职责描述保持一致——Agent 侧将流程细化为 Plan(识别关键旅程并划分 HIGH/MEDIUM/LOW 风险优先级)、Create(POM 模式 + data-testid 定位)、Execute(本地重复运行 3–5 次排查 flaky、隔离不稳定用例、上传制品到 CI)。也就是说:命令文档定义“做什么”,Agent 文档补充“按什么纪律做”。
Playwright 测试骨架:直接可用的模板
命令文档给出了一套完整的测试文件结构模板,这是每次生成测试旅程时的“标准开局”。将其复制为 *.spec.ts 即可运行:
import { test, expect } from '@playwright/test'
test.describe('Feature: [Name]', () => {
test.beforeEach(async ({ page }) => {
// Setup: Navigate, authenticate, prepare state
})
test('should [expected behavior]', async ({ page }) => {
// Arrange: Set up test data
// Act: Perform user actions
await page.click('[data-testid="button"]')
await page.fill('[data-testid="input"]', 'value')
// Assert: Verify results
await expect(page.locator('[data-testid="result"]')).toBeVisible()
})
test.afterEach(async ({ page }, testInfo) => {
// Capture screenshot on failure
if (testInfo.status !== 'passed') {
await page.screenshot({ path: `test-results/${testInfo.title}.png` })
}
})
})
对该模板值得强调的几点语义:
test.describe组织 Feature 级分组,其内部每个test()只描述一个“should …”行为,这与 rules/common/testing.md 中“测试命名应描述被测行为”的要求呼应(例如returns empty array when no markets match query);beforeEach承担 Setup:导航、登录、预置状态都放在这里,保证每个用例从干净状态出发;afterEach内利用testInfo.status:仅当用例失败时才落盘截图,既满足“失败留证”,又避免成功用例产生冗余文件——这等价于 Playwright 配置里screenshot: 'only-on-failure'的手写实现;- 命令文档刻意省略了省略号/占位之外的空实现,方便 Agent 依据
$ARGUMENTS填充真实的选择器与断言逻辑。
需要说明的是:命令模板示例使用了 page.click() / page.fill() 的原始形式并配合 data-testid,而更稳健的做法在 Best Practices 与 e2e-testing Skill 中进一步强调——优先 page.locator(...) 以享受 Playwright 的内置自动等待(详见下文)。
三条最佳实践:定位、等待、隔离
命令文档将 E2E 稳定性的经验收敛为三组原则,它们同时也是 rules/web/testing.md 与 e2e-testing Skill 反复强调的硬纪律。
Selectors:优先 data-testid
- Prefer
data-testidattributes:为元素显式打上测试专用标记,把测试与业务结构解耦; - Avoid CSS classes (they change):class 常因样式重构而变化,直接引用的用例会脆弱地随 UI 改动而失败;
- Use semantic selectors (roles, labels):当无法使用
data-testid时,退而使用getByRole/getByLabel等语义定位器。
优先级链条在 e2e-runner Agent 中表述为:[data-testid="..."] > CSS selectors > XPath。Skill 的 POM 示例也印证了这一选择,例如 this.searchInput = page.locator('[data-testid="search-input"]')。
Waits:等条件,不要等时间
- Use Playwright's auto-waiting:优先使用
locator驱动的操作,因为page.locator(...).click()会自动等待元素可见、稳定、可操作; - Avoid
page.waitForTimeout():固定 sleep 在慢网络/快机器上都会产生误判,应彻底禁用; - Use
expect().toBeVisible()for assertions:以可重试的显式断言代替裸等待。
e2e-testing Skill 给出了 Bad/Good 对照,例如用 waitForResponse(resp => resp.url().includes('/api/search')) 等待真实网络响应,或用 locator.waitFor({ state: 'visible' }) 等待动画结束,rules/web/testing.md 同样要求 “Avoid flaky timeout-based assertions; prefer deterministic waits”。
Test Isolation:用例之间零耦合
- Each test should be independent:任一用例失败不应污染其他用例;
- Clean up test data after:测试创建的数据须在结束时清理(删除、回滚或通过 API 清除);
- Don't rely on test order:测试不得假设前序用例的执行副作用。
需要采集的制品(Artifacts)
命令文档规定运行后至少保留四类调试证据,用于失败归因与回归复盘:
- Screenshots on failure:失败瞬间的页面截图,是最直接的第一现场;
- Videos for debugging:完整录制操作过程,便于复现时间线;
- Trace files for detailed analysis:Playwright Trace 可回放每一步操作、网络与 DOM 状态,适合深挖根因;
- Network logs if relevant:涉及接口问题时补充记录网络请求/响应。
这些能力可直接由 e2e-testing Skill 的 playwright.config.ts 参考配置开启:
use: {
baseURL: process.env.BASE_URL || 'http://localhost:3000',
trace: 'on-first-retry', // 首次重试即记录 trace
screenshot: 'only-on-failure', // 仅失败截图
video: 'retain-on-failure', // 仅失败保留视频
actionTimeout: 10000,
navigationTimeout: 30000,
},
对应地,命令模板中 afterEach 的失败截图、Skill 中 videosPath: 'artifacts/videos/'、browser.startTracing(...) 的 trace 用法,共同构成了从“单点截图”到“全链路 trace”的分级制品策略。
测试分类矩阵:按风险规划旅程
命令文档要求按三类场景设计测试旅程,避免只测“快乐路径”:
-
Critical User Flows(关键用户流程)
- Authentication:登录、登出、注册;
- Core feature happy paths:核心功能的正常路径;
- Payment/checkout flows:支付/结算这类“断不得”的高风险链路。
-
Edge Cases(边界场景)
- Network failures:断网、超时、接口错误下的降级表现;
- Invalid inputs:非法输入的正确拦截与提示;
- Session expiry:会话过期后的引导行为。
-
Cross-Browser(跨浏览器)
- Chrome、Firefox、Safari 三端最小覆盖;
- Mobile viewports:移动端视口验证。
e2e-runner Agent 进一步给出了风险分级的量化参考:HIGH(financial / auth)优先覆盖,MEDIUM(search / nav)其次,LOW(UI polish)最后。Skill 的 projects 配置即为跨浏览器矩阵的落地样例:
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
{ name: 'mobile-chrome', use: { ...devices['Pixel 5'] } },
],
针对支付与交易类场景,e2e-testing Skill 还给出了两个高价值扩展:用 context.addInitScript mock 钱包 Provider(window.ethereum)完成 Web3 连接测试;用 test.skip(process.env.NODE_ENV === 'production', 'Skip on production') 防止真实资金环境误触发交易,并用 waitForResponse(...) + status() === 200 确认链上调用成功。
结果汇报格式:让失败可直接消费
命令文档规定运行结束必须输出统一的文本报告,其格式模板如下:
E2E Test Results
================
PASS: Passed: X
FAIL: Failed: Y
SKIPPED: Skipped: Z
Failed Tests:
- test-name: Error message
Screenshot: path/to/screenshot.png
Video: path/to/video.webm
该模板的价值在于“机器可读 + 人可追踪”:汇总行给出通过/失败/跳过三态统计,失败列表逐条附上错误信息以及对应的截图、视频路径。若需要更正式的报告,e2e-testing Skill 提供了两档增强:在 reporter 中同时输出 HTML、JUnit XML、JSON 三种格式以对接 CI 与测试平台;并给出了 Markdown 版的详细报告模板(含 Date/Duration/Status、失败用例文件行号、推荐修复方向、制品清单)。ECC 的 common/testing.md 规则 同时要求整体测试体系(单元 + 集成 + E2E)满足 80% 覆盖率底线与 TDD 的 RED→GREEN→IMPROVE 循环,E2E 在其上是补足“跨模块集成正确性”的最后防线。
调试技巧:用 --headed 亲眼观察
命令文档在结尾给出实用 Tip:
TIP: Run with
--headedflag for debugging:npx playwright test --headed
在无头模式排查失败困难时,加 --headed 打开浏览器窗口以肉眼观察操作序列。配合 e2e-runner Agent 汇总的常用 CLI,可组成一套完整的调试工具箱:
npx playwright test # 运行全部 E2E 测试
npx playwright test tests/auth.spec.ts # 只跑指定文件
npx playwright test --headed # 打开浏览器调试
npx playwright test --debug # 使用调试器逐步执行
npx playwright test --trace on # 全程开启 trace
npx playwright test --repeat-each=10 # 重复 10 次,用于暴露 flaky
npx playwright test --retries=3 # 失败自动重试 3 次
npx playwright show-report # 本地查看 HTML 报告
与仓库配套体系的衔接
/e2e 命令并非孤立存在,理解它需要看到仓库中的三层配套:
- 命令层:.opencode/commands/e2e.md 定义任务与纪律(本文主体),并在 .opencode/README.md 的 Command 清单中登记;
- Agent 层:agents/e2e-runner.md 定义执行者——优先使用 Vercel Agent Browser(语义化 ref 定位,如
agent-browser click @e1),不可用时回退到 Playwright;同时负责隔离 flaky 用例(test.fixme()/test.skip())、维护 POM、对接 CI,并给出可度量的成功标准(关键旅程 100% 通过、整体通过率 > 95%、flaky 率 < 5%、单轮时长 < 10 分钟); - Skill 层:skills/e2e-testing/SKILL.md 沉淀了完整可复用的模式库:目录组织(
tests/e2e/{auth,features,api}+fixtures+playwright.config.ts)、Page Object Model 完整示例、Playwright 全量配置模板、CI/CD YAML(npx playwright install --with-deps+actions/upload-artifact@v4留存报告 30 天)、Flaky 原因图谱(竞态/网络时序/动画时序)与对应修复范式。
此外,web 项目相关的测试纪律可进一步参考 rules/web/testing.md(视觉回归优先、可访问性与键盘导航检查、最小跨浏览器三件套、320–1920 断点响应式验证);OpenCode 用户如需在自身项目中复刻该命令,可依据 .opencode/README.md 将 .opencode/commands/、.opencode/prompts/ 与 instructions 配置复制到目标工程,或通过 npx ecc-universal install 安装相应能力。
综上,ECC 的 /e2e 命令把“E2E 测试工程化”从一次性的手工脚本提升为可重复执行的 Agent 工作流:命令文档提供骨架与纪律,Agent 注入决策与流程管理,Skill 沉淀配置与模式——三者叠加后,你只需要给出一条用户旅程描述,就能得到一组稳定、可追溯、带完整失败证据的端到端回归资产。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00