关于 qualityforge
QualityForge 是基于 Playwright 的浏览器 QA 框架,面向需要统一测试证据和质量门禁的团队。其只读 MCP 服务让 AI Agent 检查失败记录和运行历史,但不能操作应用。
主要功能
- 01捕获 trace、截图和失败视频
- 02将失败整理为标准缺陷产物
- 03按明确阈值设置质量门禁
- 04收集并脱敏控制台与网络信号
- 05跟踪运行历史和质量趋势
- 06提供 MCP 工具、资源与分诊提示词
适用场景
- 01根据保存的证据诊断浏览器测试失败
- 02判断故障是否间歇出现或反复发生
- 03检查控制台、网络和页面错误
- 04查看无障碍审计结果
MCP 相关
提供基于 stdio 的只读 MCP 服务,包含运行摘要、失败、缺陷、趋势和无障碍审计工具,并提供资源及 `triage_failure` 提示词。它向 Agent 提供已收集的 QA 证据,但不授予操作应用的能力。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
QualityForge
面向现代 Web 应用、以证据为先的浏览器质量自动化。
QualityForge 是构建在 Playwright 之上的开源基础框架,可将失败的运行转化为机器可读的证据:包含跟踪记录、屏幕截图和视频的规范化缺陷产物;具有明确阈值的质量门禁;对控制台、网络和页面错误信号的捕获;以及一个只读 MCP 服务,可将所有信息交给 AI 助手,同时不赋予其执行操作的能力。
状态 — 稳定,已发布。
[email protected]自 2026-10-21 起已发布到 npm(0.1.0于 2026-10-15 发布,是首个稳定版本),缺陷契约为 1.6.0 版的defect.v1。0.x系列仍允许在次版本中进行破坏性变更,因此请固定安装的版本。
目录
存在的原因
大多数团队最终都会为每个项目积累大量一次性的 UI 测试:选择器重复、没有共享的失败证据,也无法跨项目查看质量。QualityForge 提供了可复用的核心方案:使用一份配置、一种证据格式和一套质量门禁,适用于任意 Web 应用。
它的差异化之处不在于“AI 编写测试”。Playwright 已经内置了相关 Agent。它的核心是失败的运行与任意 Agent 之间的证据层:将缺陷产物规范化为统一的架构,让读取者无需获得执行操作的能力也能读取。
你将获得什么
- 证据流水线。 在首次重试时记录跟踪信息,失败时截取屏幕截图并录制视频,支持 Chromium、Firefox 和 WebKit。即使运行失败,也会发布其产物。
- 统一的规范化缺陷格式。
defect.v1,契约 1.4.0:每次失败都会生成一个带版本、经过验证的产物,它扩展了 Playwright 的error-context.md,而不是重复其中的内容。 - 质量门禁。 收集器按 spec × project 拆分,拒绝重复 ID,将中止的套件视为一次服务中断,而非每项测试各算一个缺陷;当阈值被违反时,以非零状态退出。
- 信号捕获。 捕获控制台错误、未捕获的页面错误、失败的请求以及状态码高于 400 的 HTTP 错误;在源头进行脱敏,按类别限制数量,并提供
signals.dropped计数,确保截断后的捕获结果不会被误认为完整。 - 只读 MCP 服务。 使用协议 2026-07-28,提供十三个工具、资源和一个
triage_failure提示词;已通过真实 stdio 与 OpenCode v2.0.16 验证。 - 运行历史。 每次运行生成一个精简文件,回答“这是回归问题,还是一直如此”。
- 会自检的 CI。 六个任务:lint 和类型检查、在 Node 22 和 24 上运行单元测试、在三个浏览器上运行套件;另有一个任务会安装真实的 OpenCode 客户端,并验证通过线路传输的帧。
快速开始
开发需要 Node.js 22 或更高版本——Node 20 已于 2026 年 3 月结束生命周期,而且 "engines": ">=22.0.0" 明确说明了这一点,而不是承诺对安装过程网开一面。CI 使用 Node 22 和 24,最低版本取两者中较低的那个。.nvmrc 为贡献者指定了 22:在这台机器上,某个 Node 24.21.0 构建版本会导致 tsc 以段错误退出,而且可以稳定复现。如果你使用版本管理器,请先运行 nvm use。
平台。 CI 在 Linux 上运行,因此 Linux 是经过验证的平台。核心代码采用跨平台编写方式——全程使用 path.sep 和 path.relative,不调用仅适用于 POSIX 的接口——所以 Windows 和 macOS 应该也能运行,但_尚未经过测试_。请将它们视为未经验证的平台,而不是受支持的平台。
git clone https://github.com/ninelegsdog/qualityforge.git
cd qualityforge
npm ci
npx playwright install --with-deps chromium
npm test
npm test 会自动启动随附的演示应用,因此全新克隆后无需配置,也不依赖第三方网络即可顺利运行。运行 npm run report 打开 HTML 报告。有关逐步操作指南——查看带有证据的真实故障、收集缺陷产物、连接 Agent、让套件测试你自己的应用——请参阅
docs/quick-start.md,或
docs/quick-start.ru.md。
演示应用
fixtures/ 是一个小型多页面应用,旨在为套件提供实际测试对象。它不是模拟应用:它会渲染、验证并获取数据。
| 路由 | 功能 |
|---|---|
/ | 概览页面,包含标题、状态读数,以及从 /api/items 获取的实体列表 |
/docs | 包含证据策略的文档页面 |
/contact | 包含客户端验证和无障碍错误报告的表单 |
/api/items | 为实体列表提供数据的 JSON 载荷 |
/boom | 故意返回 500,用于测试证据流水线 |
每个控件都有标签,每条消息都有角色,每个测试所需的元素都有稳定的标识——套件断言的是用户能感知到的内容,而不是标记结构。
证据流水线
项目的核心承诺是:故障发生时会留下足够的证据用于诊断,而且这一承诺经过了测试,而非仅仅宣称:
QUALITYFORGE_EVIDENCE_CHECK=1 npx playwright test tests/smoke/evidence-pipeline.spec.ts
这会运行两个故意失败的测试,并以非零状态码退出。之后,test-results/ 中会为每次故障包含以下内容:
| 产物 | 生成原因 |
|---|---|
test-failed-1.png | screenshot: "only-on-failure" |
video.webm | video: "retain-on-failure" |
trace.zip | trace: "on-first-retry"——本地运行不会重试,因此请在本地添加 --trace on |
error-context.md | 结构化故障摘要:测试名称、位置、错误、预期值、实际值 |
error-context.md 最值得关注:它以给助手的指令形式写成——“说明原因、简洁作答、遵守最佳实践”——随后列出测试名称、文件位置、错误和预期值差异。这是 Agent 所需的原始素材,而且无需额外成本。
在 CI 上调试时,优先使用追踪查看器,而不是截图和视频:它能提供每个操作对应的 DOM 快照,以及完整的网络日志。
缺陷产物
只有在无需重新运行任何内容、稍后仍能读取失败信息时,失败的测试才有用。QualityForge 会将每次失败转换为一个标准化、带版本的产物:
npm test # writes artifacts/json/playwright-results.json
npm run defects:collect # writes artifacts/defects/<runId>/
{
"id": "form-validation-smoke-shows-an-error-when-email-is-empty",
"status": "failed",
"test": { "file": "tests/smoke/form-validation.smoke.spec.ts", "line": 15 },
"failure": {
"message": "Error: expect(locator).toHaveText(expected) failed\n\nExpected: \"Email is required\"",
"errorContextRef": "test-results/.../error-context.md",
},
"evidence": { "screenshot": "test-results/.../test-failed-1.png" },
"context": { "commit": "43c761f", "baseUrl": "http://127.0.0.1:4311" },
"flakiness": { "verdict": "unknown", "attempts": 1 },
}
该产物有意扩展 Playwright 的 error-context.md,而不是重复其中的内容:它会记录该文件的路径,并添加稳定标识、运行关联信息、VCS 上下文、证据指针和不稳定性判定。signals 块——控制台错误、未捕获的页面错误、失败的请求、状态码高于 400 的 HTTP 错误——由捆绑的 fixture 实时收集,因为“找不到元素”是症状,而“页面抛出了 TypeError”才是原因。完整规范请参阅
docs/defect-schema.md。
无障碍性是一项独立的第二种测量,而不是该产物中的一个字段:npm run a11y:audit 会对页面运行 axe-core,并写入 a11y-audit.v1——每条规则最多保留十个节点,并注明丢弃的数量;将 html 精简为结构,因为它包含页面内容;保留 target,因为没有它就无法区分各个节点。请参阅
docs/a11y-schema.md。
npm run defects:collect 也可作为 CI 质量门禁:门禁通过时退出码为 0,违反阈值时为 1,完全无法运行收集时为 2。
安装软件包
npm i [email protected]
latest 指向此版本。无论如何,都应固定到所需版本,而不是信任标签名称:npm 不允许移除 latest,因此标签只能向前移动;裸命令 npm i qualityforge 会安装标签当前指向的版本,而不是你测试过的版本。
使用该软件包的项目会从构建产物导入 fixture——Playwright 拒绝转译 node_modules 下的 TypeScript,因此该 fixture 通过 exports 中的子路径发布:
import { expect, test } from "qualityforge/fixtures/quality-context.js";
只需更改这一处导入即可完成全部集成:控制台、页面错误和网络捕获都会自动启用。所有捕获的数据都会在源头进行脱敏——URL 保留协议、主机和路径,并移除查询字符串和凭据;控制台文本中的令牌和 JWT 会被替换;敏感标头值会被遮盖,但标头名称会保留——并且每个类别最多捕获 40 条记录。
@playwright/test 是一个对等依赖:使用该软件包的项目需自行提供;如果缺少该依赖,npm 7+ 会自动安装,因为没有它 fixture 就无法运行。声明的版本范围是 ^1.63.0;CI 验证的版本是 1.63.0,并在 devDependencies 中精确固定;如果软件包不再声明该对等依赖,或 npm 不再为使用方安装它,npm run package:check 就会失败。
bin 条目会发布使用该软件包的项目要运行的两个命令——始终通过 npx --no-install 运行,因为它可以确保不会为了获取别人的代码而访问注册表:
npx --no-install qualityforge [flags] # the collector
npx --no-install qualityforge-mcp [--root <dir>] [--history <dir>]
MCP 服务
npm run mcp 会通过 stdio 启动只读 MCP 服务,使用协议
2026-07-28。它向 Agent 提供证据层:出了什么问题、问题出在哪里,以及页面在出问题时的状态。
已在 Linux 上连接并通过 OpenCode v2.0.16 验证,配置如下;根据决策,Kilo 和 MiMo 不在范围内——详见本节末尾。
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"qualityforge": {
"enabled": true,
"type": "local",
"command": ["node", "/absolute/path/to/qualityforge/dist/mcp/index.js"],
},
},
}
安装了此软件包的项目无需提供路径:
["npx", "--no-install", "qualityforge-mcp"] 会从
node_modules/.bin 启动同一服务。该命令指向 dist/,而 npm ci 会构建此目录
(prepare 会运行 tsc);如果安装时使用了
--ignore-scripts,则运行 npm run build。随后,opencode mcp list 会报告连接状态;
请多运行几次再作判断——该状态只是对仍在建立中的连接的采样,并非最终结论。
| 工具 | 说明 |
|---|---|
quality_get_latest_run | 计数、门禁、每个维度的判定、策略链、历史判定 |
quality_list_failures | 精简记录:ID、状态、测试位置、偶发性 |
quality_get_defect | 单个缺陷的完整信息,包括控制台、网络和页面错误信号 |
quality_flaky_tests | 各次运行中失败的测试规格:偶发失败、持续失败、新增或已消失 |
quality_get_trend | 每次运行的通过率、趋势方向、持续时间、不同的失败测试规格 |
quality_list_audits | 已记录的无障碍审计,按时间从新到旧排列,并标明是否全部通过 |
quality_get_audit | 单次审计的完整信息,包含每条规则针对真实节点保留的计数 |
此外还有最新运行摘要和任意缺陷的资源,以及一个会先询问事实再提出假设的
triage_failure 提示词。
连接前须知
- 先生成产物。 找不到产物根目录时,服务会以状态码 1 退出,而提示信息会写入
stderr,客户端会将其丢弃——因此你只能看到
failed: Connection closed。请先运行测试套件和npm run defects:collect,或传入--root <dir>。 - 使用绝对路径。 客户端会从_你的_项目目录启动服务,而不是从此检出目录启动,因此相对路径的根目录会解析到不存在的位置。
- 明确指定运行器。 配置指向
dist/,因此连接时不会进行转译:此处initialize的响应时间约为 0.24 秒,而["npx", "tsx", …, "src/mcp/index.ts"]约为 2.4 秒;OpenCode 文档记载的默认 MCP 超时为 5000 ms。 - 两种配置形式都能连接。 上文展示的扁平形式
mcp.<name>和 V2 文档记载的mcp.servers.<name>均已在 v2.0.16 上连接成功。区别在于写入的是哪个文件,而不是能否正常工作。
从结构上确保只读
服务中不存在写入路径:没有任何工具会修改数据,存储层也不提供任何修改方法。只读是结构上的保证,而非承诺。
客户端提供的每个路径都被视为不可信,因为客户端侧的路径允许列表只是便利措施,并非安全边界。绝对路径、百分号解码前后的 .. 路径遍历、NUL 字节,以及解析后指向根目录之外的符号链接,都会被拒绝;拒绝消息也绝不会回显文件系统布局,因为它可能出现在对话记录中。
为何手写协议。 我们对官方 @modelcontextprotocol/sdk 进行了核查,而非想当然地假定其支持:版本 1.32.0 声明了 LATEST_PROTOCOL_VERSION = "2025-11-25",但不包含 server/discover、resultType、ttlMs/cacheScope 或 subscriptions/listen——它并未实现 2026-07-28。仍接受 2025-11-25 握手,因为即使客户端从未发送 initialize,仍应能获取 tools/list。
Kilo 和 MiMo 经决定不予支持,这不只是未经测试。所有者于 2026-10-03 决定不再跟进:第三个客户端所需的服务端工作,最好投入到唯一实际存在的客户端上。如果你使用它们,本文档并未说明上方的阻止措施是否会被接受。
配置
config/project.json 声明项目名称、被测来源、证据策略、门槛阈值以及产物的写入位置。加载时会对其进行验证,并一次性报告所有问题及其确切路径:
Configuration error: Invalid configuration in /…/config/project.json
- thresholds.maxFailureRate must be a number between 0 and 1, got "high"
- baseUrl must not contain credentials, a query string or a fragment
运行历史
可选的 history 区块会为每次运行保存一个精简文件,从而回答“这是回归问题,还是一直如此”:
"history": { "directory": "quality-history", "keep": 200 }
有意将其提交到仓库中,与 artifacts/ 不同:每条历史记录只有几百字节的计数和结果,而它是让一次运行值得进行的唯一依据。每条记录都会记录哪些规格未通过,并由两个 MCP 工具读取:quality_flaky_tests 会区分后来恢复的规格和始终未恢复的规格;quality_get_trend 会报告一段时间内的趋势,并在运行次数少于四次时返回 unknown。若不设置,历史记录功能将关闭,不会额外写入任何内容。
命令
npm test # full suite
npm run test:smoke # Chromium only
npm run test:unit # unit tests, no browser launched
npm run test:debug # Playwright Inspector, step through a test
npm run report # open the HTML report
npm run report:clean # remove generated output
npm run build # compile src/ to dist/ (an install runs this for you)
npm run defects:collect # build defect artifacts from the last run
npm run defects:check # prove two report-shape rules on a real Playwright run
npm run a11y:audit # audit a page for accessibility, into artifacts/a11y/<runId>/
npm run mcp # start the read-only MCP server on stdio
npm run mcp:check:all # drive the server over real stdio and check it
npm run mcp:schema # cross-check capabilities against the client's binary
npm run mcp:live # connect the real opencode client and assert the wire
npm run verify # lint + typecheck + build + format check (CI runs this first)
基于 Python 的检查项——mcp:check*、mcp:schema、mcp:live、defects:check、docs:numbers、docs:support、docs:tools 和 ci:validate——分别放在独立脚本中,因此只安装了 Node 也能运行 verify。mcp:live 还需要 opencode 二进制文件;若缺少该文件,检查会失败而不是跳过——没有客户端却悄悄通过的实时客户端检查,只是摆设。
CI 中强制执行的规则
- lint 规则禁止使用
page.waitForTimeout()。它是导致测试不稳定的主要原因;应等待真实条件。 - 禁止使用
test.only()和describe.only()。在 CI 中,它们会悄悄跳过套件的其余部分。 @typescript-eslint/no-floating-promises属于错误。Playwright 调用漏写await会导致测试悄悄地什么也没断言。- 选择器策略由 lint 强制执行,并非建议:在字面量
locator()参数中使用 CSS、XPath 和text=简写都会导致npm run lint失败。选择器层级——先角色,再标签,再文本,最后才是data-testid——见docs/selectors-and-testid.md。 - 格式检查和类型检查必须通过。
本仓库中的一切都遵循同一条规则:只有在真实环境中运行,并观察到它因正确的原因而失败后,才算完成。 关于报告、协议帧和运行器判定的说法,都会对照真实生成方进行核验,绝不依赖手写的测试样例。
文档
docs/quick-start.md— 从全新克隆到 Agent 读取真实故障的分步指南docs/architecture.md— 各部分如何协同工作docs/defect-schema.md—defect.v1契约docs/a11y-schema.md—a11y-audit.v1契约docs/selectors-and-testid.md— 定位器策略docs/client-support.md— 哪些客户端连接到了 MCP 服务,以及观察到了什么docs/roadmap.md— 未来发展方向,以及不会涉及的方向docs/parallel-work.md— 多个 Agent 如何在此代码仓库中协作而不互相冲突AGENTS.md— 在此代码仓库中工作的编码 Agent 规则CHANGELOG.md— 版本历史
如果你想基于此项目启动项目,而不是阅读文档:模板 https://github.com/ninelegsdog/qualityforge-template 会从 git 安装此软件包, 在全新克隆后即可成功运行,并且已写好 MCP 配置块。
参与贡献
参见 CONTRIBUTING.md — 环境搭建、拉取请求规则、测试要求,
以及 AI 辅助贡献的要求。使用问题模板提交缺陷报告或
功能请求;提交拉取请求时,请使用
PULL_REQUEST_TEMPLATE.md。
安全问题:请先阅读 SECURITY.md — 不要为此公开提交问题。
许可证
Apache-2.0 — 参见 LICENSE。坦诚行事,并假定他人出于善意:
社区准则见 CODE_OF_CONDUCT.md。
为什么优先收集证据?
普通测试运行器只会说“失败”。QualityForge 会告诉你“为什么失败”——收集证据,便于 Agent 或人工快速分析。
失败时收集的证据
- Screenshot — 失败时页面状态的截图
- Trace/Video — 用于重现问题的 Playwright 跟踪记录
- Logs — 控制台日志和网络事件
- HAR — 网络流量(可选)
- Context — URL、视口、步骤、预期结果
与 Agent 集成
附带只读 MCP 服务。Agent 可以读取失败证据、了解上下文,并提出有针对性的修复方案,无需猜测。
已用于生产环境
QualityForge 用于验证 BotKit 生态系统中的 9 个生产级 Telegram 机器人,验证工作通过 botkit-farm 进行。MCP 服务使 AI Agent 能够利用完整证据(跟踪记录、截图、网络日志)分析测试失败,而无需直接访问代码或修改代码。
专注于 Agent 基础设施
作为更广泛的 Agent 开发基础设施的一部分构建——为 AI 编码 Agent 提供工具链、质量门禁和验证优先的工作流。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。