qualityforge について
QualityForge は Playwright ベースのブラウザー QA 基盤で、テスト証拠と品質ゲートの共通化を必要とするチーム向けです。読み取り専用 MCP サーバーにより、AI エージェントはアプリを操作せずに失敗や実行履歴を確認できます。
主な機能
- 01トレース、スクリーンショット、失敗時の動画を取得
- 02失敗を標準化された不具合アーティファクトに変換
- 03明示的なしきい値による品質ゲート
- 04サニタイズしたコンソール・ネットワーク信号の収集
- 05実行履歴と品質傾向の追跡
- 06MCP ツール、リソース、トリアージ用プロンプトを提供
活用シーン
- 01保存された証拠からブラウザーテストの失敗を診断
- 02失敗が不安定か再発しているかを確認
- 03コンソール、ネットワーク、ページのエラーを調査
- 04アクセシビリティ監査結果を確認
MCP 対応
実行概要、失敗、不具合、傾向、アクセシビリティ監査を扱うツールに加え、リソースと `triage_failure` プロンプトを備えた読み取り専用の stdio MCP サーバーを提供します。アプリを操作する権限を与えず、収集済みの QA 証拠をエージェントに公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
QualityForge
現代の Web アプリケーション向け、エビデンスを重視したブラウザー品質自動化。
QualityForge は Playwright を基盤とするオープンソースのフレームワークです。失敗した実行から、マシンが読み取れるエビデンスを生成します。トレース、スクリーンショット、動画を含む正規化された不具合アーティファクト、明示的なしきい値を備えた品質ゲート、コンソール、ネットワーク、ページエラーのシグナル取得を実現します。さらに、AI アシスタントに操作権限を与えることなく、これらすべてを渡す読み取り専用 MCP サーバーも備えています。
ステータス — 安定版、公開済み。
[email protected]は 2026-10-21 から npm で公開されています(2026-10-15 の0.1.0が最初の安定版リリースです)。不具合コントラクトは 1.6.0 のdefect.v1です。0.x系ではマイナー更新での破壊的変更が引き続き許容されるため、インストールするバージョンを固定してください。
目次
- これが必要な理由
- 利用できる機能
- クイックスタート
- デモアプリ
- エビデンスパイプライン
- 不具合アーティファクト
- MCP サーバー
- 設定
- コマンド
- CI で適用されるルール
- ドキュメント
- コントリビューション
これが必要な理由
多くのチームでは、プロジェクトごとに一度限りの UI テストが積み重なっていきます。セレクターは重複し、失敗時のエビデンスは共有されず、プロジェクト横断で品質を把握する方法もありません。QualityForge はその代わりとなる再利用可能なコアです。設定、エビデンス形式、品質ゲートをそれぞれ一つにまとめ、あらゆる Web アプリケーションを対象にできます。
差別化要因は「AI がテストを書くこと」ではありません。Playwright はすでにそのためのエージェントを提供しています。QualityForge の強みは、失敗した実行とあらゆるエージェントの間にあるエビデンスレイヤーです。不具合アーティファクトを一つのスキーマに正規化し、読み手に操作権限を与えることなく読み取れるようにします。
利用できる機能
- エビデンスパイプライン。 初回リトライ時のトレース、失敗時のスクリーンショットと動画を、Chromium、Firefox、WebKit で取得します。実行が失敗しても、アーティファクトは公開されます。
- 単一の正規化された不具合形式。
defect.v1、コントラクト 1.4.0。Playwright のerror-context.mdを重複させるのではなく、その内容を拡張する、失敗ごとのバージョン管理・検証済みアーティファクトです。 - 品質ゲート。 コレクターは spec × project ごとに分割し、重複 ID を拒否します。中断されたスイートはテストごとの不具合ではなく、一つの障害として扱い、しきい値に違反するとゼロ以外の終了コードを返します。
- シグナル取得。 コンソールエラー、捕捉されなかったページエラー、失敗したリクエスト、400 を超える HTTP エラーを、発生元で機密情報をマスキングしてカテゴリごとの上限付きで取得します。
signals.droppedの件数により、切り詰められた取得結果が完全なものに見えることはありません。 - 読み取り専用 MCP サーバー。 プロトコル 2026-07-28 に対応し、13 個のツール、リソース、
triage_failureプロンプトを提供します。実際の stdio 経由で OpenCode v2.0.16 との連携を検証済みです。 - 実行履歴。 実行ごとに簡潔なファイルを一つ作成するため、「これは回帰なのか、それとも以前からこうだったのか」という問いに答えられます。
- 自己検証する CI。 6 つのジョブ(lint と型チェック、Node 22 と 24 でのユニットテスト、3 種類のブラウザーでのスイート実行)に加え、実際の 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 は同梱のデモアプリを自動的に起動するため、新しいクローンでも設定やサードパーティのネットワーク依存なしでテストが成功します。HTML レポートは npm run report で開けます。実際の失敗を証拠とともに確認し、不具合の成果物を収集し、エージェントを接続して、独自のアプリケーションにテストスイートを適用するまでの手順については、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
これは意図的に失敗させる2つのテストを実行し、ゼロ以外の終了コードを返します。その後、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 は特に興味深い成果物です。アシスタントへの指示として「理由を説明する、簡潔にする、ベストプラクティスを守る」と記述され、その後にテスト名、ファイルの場所、エラー、期待値との差分が続きます。これはエージェントが必要とする生の素材であり、追加コストはかかりません。
CI でデバッグする際は、スクリーンショットや動画よりもトレースビューアーを優先してください。各アクション時点の DOM スナップショットに加え、ネットワークログ全体を確認できます。
不具合アーティファクト
失敗したテストは、何も再実行せずに後から失敗内容を読み取れる場合にのみ役立ちます。QualityForge は、それぞれの失敗を正規化されたバージョン管理済みの 1 つのアーティファクトに変換します。
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 エラー)は、同梱のフィクスチャによって実行中に収集されます。「要素が見つからない」は症状ですが、「ページで TypeError が発生した」は原因だからです。詳細な仕様については、docs/defect-schema.md をご覧ください。
アクセシビリティは、そのアーティファクトのフィールドではなく、別個の 2 つ目の測定です。npm run a11y:audit はページに対して axe-core を実行し、a11y-audit.v1 を書き出します。各ルールにつき最大 10 個のノードを記録し、破棄した件数を明記します。html はページのコンテンツを含むため構造だけに簡略化し、ノードを区別するために必要な target は保持します。詳細については、docs/a11y-schema.md をご覧ください。
npm run defects:collect は CI 品質ゲートも兼ねています。ゲートに合格すると 0、しきい値に違反すると 1、収集自体を実行できなかった場合は 2 で終了します。
パッケージのインストール
npm i [email protected]
latest はこのリリースを指しています。それでもタグ名を信用せず、使用したいバージョンを固定してください。npm では latest の削除が禁止されているため、タグは先に進むことしかできません。また、npm i qualityforge だけを実行すると、テストしたバージョンではなく、タグが指すバージョンがインストールされます。
利用側のプロジェクトではビルドからフィクスチャをインポートします。Playwright は node_modules 内の TypeScript をトランスパイルしないため、フィクスチャは exports のサブパスとして提供されます。
import { expect, test } from "qualityforge/fixtures/quality-context.js";
このインポートを 1 か所変更するだけで統合は完了します。コンソール、ページエラー、ネットワークのキャプチャーが自動的に開始されます。キャプチャーされるすべてのデータは、取得元で秘匿化されます。URL はクエリ文字列と認証情報を取り除いてスキーム、ホスト、パスを保持し、コンソールテキストではトークンと JWT を置き換え、機密性の高いヘッダー値をマスクしつつ名前は保持します。また、各カテゴリの記録数は 40 件までに制限されます。
@playwright/test はピア依存関係です。利用側のプロジェクトで用意する必要があり、不足している場合は npm 7 以降が自動的にインストールします。このフィクスチャの実行には @playwright/test が必要だからです。宣言されている範囲は ^1.63.0 です。CI で検証するバージョンは 1.63.0 で、devDependencies に正確に固定されています。npm run package:check は、パッケージからピア依存関係の宣言がなくなった場合、または npm が利用側のプロジェクトにインストールしなくなった場合に失敗します。
bin エントリーでは、利用側のプロジェクトが実行する 2 つのコマンドを公開します。いずれも、他者のコードをレジストリから取得できないことが確実な npx --no-install 経由で実行します。
npx --no-install qualityforge [flags] # the collector
npx --no-install qualityforge-mcp [--root <dir>] [--history <dir>]
MCP サーバー
npm run mcp は、プロトコル 2026-07-28 を使用する読み取り専用の MCP サーバーを stdio 経由で起動します。エージェントに、何が、どこで失敗し、失敗時にページがどうなっていたかという証拠レイヤーを渡します。以下のブロックを使って接続し、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 | コンソール、ネットワーク、ページエラーのシグナルを含む、1 件の不具合の全情報 |
quality_flaky_tests | 実行間で失敗したスペック。不安定、失敗、新規、または解消済み |
quality_get_trend | 実行ごとの合格率、傾向、所要時間、失敗した個別スペックの数 |
quality_list_audits | 記録済みのアクセシビリティ監査(新しいものから順)と、問題がないかどうか |
quality_get_audit | 各ルールについて、実ノードに対して保持された件数を含む、1 件の監査の全情報 |
最新の実行サマリーや任意の不具合に関するリソースに加え、仮説より先に事実を求める 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 は実装されていません。initialize を一度も送信しないクライアントでも tools/list を取得できる必要があるため、2025-11-25 のハンドシェイクには引き続き対応しています。
Kilo と MiMo は、単にテストされていないだけではなく、判断によりサポート対象外です。 オーナーは 2026-10-03 に、これらへの対応を追求しないと決定しました。3 つ目のクライアントに必要となるサーバー側の作業は、実在する 1 つのクライアントに投じるほうが適切だからです。これらを使う場合、上記のブロックが受け入れられるかどうかは、このドキュメントには記載されていません。
設定
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 ブロックを設定すると、実行ごとにコンパクトなファイルが 1 つ保存されます。これにより、「これはリグレッションなのか、それとも以前からこうだったのか」という疑問に答えられます。
"history": { "directory": "quality-history", "keep": 200 }
artifacts/ とは異なり、履歴は意図的にコミットします。履歴エントリーは件数と結果を記録した数百バイトのデータであり、実行した価値を示す唯一のものだからです。各エントリーには、合格しなかった仕様が記録されます。また、2 つの MCP ツールが履歴を読み取ります。quality_flaky_tests は、復旧した仕様と一度も復旧しなかった仕様を区別し、quality_get_trend は指定期間の傾向を報告します。実行回数が 4 回未満の場合は 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 は、それぞれ独立したスクリプトです。そのため、verify は Node だけをインストールした環境でも実行できます。mcp:live には opencode バイナリも必要です。これがない場合、チェックはスキップされず失敗します。クライアントなしでひそかに合格するライブクライアントチェックでは、飾りにしかならないためです。
CI で適用されるルール
page.waitForTimeout()はリンタールールで禁止されています。不安定なテストの主な原因であるため、実際の条件を待つようにしてください。test.only()とdescribe.only()は禁止されています。CI では、残りのテストスイートが気付かれないままスキップされてしまいます。@typescript-eslint/no-floating-promisesはエラーです。Playwright の呼び出しでawaitを忘れると、テストが何も検証しないままひそかに実行されてしまいます。- セレクターポリシーは助言ではなく、リンターによる強制ルールです。リテラルの
locator()引数で CSS、XPath、text=の省略記法を使うと、npm run lintは失敗します。優先順位(ロール、ラベル、テキストの順で、data-testidは最後)はdocs/selectors-and-testid.mdに記載されています。 - フォーマットと型チェックに合格する必要があります。
このリポジトリのすべてには、同じルールが適用されます。実環境で実行し、正しい理由で失敗することを確認するまでは、何も完了していません。 レポート、プロトコルフレーム、ランナーの判定に関する主張は、手書きのフィクスチャではなく、実際の生成元と照合して検証します。
ドキュメント
docs/quick-start.md— 新しくクローンしてから、エージェントが実際の失敗を読み取るまでの手順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— 複数のエージェントがこのリポジトリで競合せずに作業する方法AGENTS.md— このリポジトリで作業するコーディングエージェント向けのルールCHANGELOG.md— リリース履歴
読むためではなく、プロジェクトを始めるためのテンプレートはこちらです。 https://github.com/ninelegsdog/qualityforge-template では、このパッケージを Git からインストールし、新しくクローンした状態でテストがすべて成功することを確認でき、MCP ブロックもあらかじめ記述されています。
コントリビューション
セットアップ、プルリクエストのルール、テストに関する要件、AI 支援によるコントリビューションに関する期待事項については、CONTRIBUTING.md をご覧ください。バグ報告または機能リクエストには issue テンプレートを使い、プルリクエストを作成する際は PULL_REQUEST_TEMPLATE.md を使ってください。
セキュリティ上の問題については、まず SECURITY.md をお読みください。公開 issue は作成しないでください。
ライセンス
Apache-2.0 — LICENSE をご覧ください。率直に対応し、善意を前提としてください。コミュニティの行動規範は CODE_OF_CONDUCT.md に記載されています。
なぜ証拠を優先するのか?
一般的なテストランナーは「失敗しました」と伝えます。QualityForge は「なぜ失敗したのか」を伝え、エージェントや人がすばやく分析できるようにアーティファクトを収集します。
失敗時のアーティファクト
- Screenshot — 失敗した瞬間のページ状態のスクリーンショット
- Trace/Video — 再現用の Playwright トレース
- Logs — コンソールログとネットワークイベント
- HAR — ネットワークトラフィック(任意)
- Context — URL、ビューポート、手順、期待値
エージェントとの連携
読み取り専用の MCP サーバーが付属しています。エージェントは失敗時のアーティファクトを読み取り、コンテキストを把握して、推測に頼らず的確な修正案を提示できます。
本番環境での使用
QualityForge は、botkit-farm を通じて、本番稼働中の Telegram ボット 9 個からなる BotKit エコシステムの検証に使用されています。MCP サーバーにより、AI エージェントはコードを変更するための直接アクセスなしに、すべての証拠(トレース、スクリーンショット、ネットワークログ)を用いてテスト失敗を分析できます。
エージェント向けインフラへの注力
より広範なエージェント型開発インフラの一環として構築されています。AI コーディングエージェント向けのハーネス、品質ゲート、検証を優先するワークフローを提供します。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。