テストを書き直さずに再利用する
Playwright テストを読み、Hermes Agent が同じ流れを実際のステージングで確認する CLI だ。既存の E2E を置き換えるのではなく、mock ベースのテストと実際の画面の間にある隙間を補うために作った。
mock の値や selector をそのまま再生すると、わずかな文言変更でも壊れやすい。そこでテストからユーザーの意図だけを取り出し、画面の文脈を読む作業は Agent に任せた。
Playwright spec → QA シナリオ → ステージング探索 → 判定と根拠
アノテーションで安全な範囲を決める
新しい DSL は作らず、既存テストに短いアノテーションだけを追加する。
// @qa-page: dashboard
import { expect, test } from "@playwright/test";
// @qa-live-policy: readonly
test("shows the current plan", async ({ page }) => {
await expect(page.getByTestId("plan-name")).toBeVisible();
});
CLI は spec をシナリオに変換し、Agent が残した画面の根拠とともに pass、fail、manual_review、skip のいずれかで整理する。
設計思想
テストは再生スクリプトである前に、意図の原本である
Playwright コードをステージングでそのまま再生しない。mock 値と selector は CI では有用だが、実データの前ではすぐ古くなる。「ユーザーが何を見られるべきか」だけを取り出し、ライブシナリオへ変換する。
決定的なテストは残す
Playwright CI と API 契約テストが基本の回帰検証だ。Agent は、実データ・文言・DOM 状態のように毎回変わり得る部分を見る補助レイヤーであり、どちらか一方を選ぶ構造ではない。
曖昧さも一つの結果である
AI 判定で最も避けたいのは、もっともらしい誤答だ。根拠が足りなければ pass や fail に押し込まず、manual_review に渡す。誤った合格より、分からないと明示する方が安全だと考えた。
安全範囲を推論に任せない
各テストに readonly や safe-interaction-no-confirm といったポリシーを記述する。決済・購読変更・mock 認証フローは遮断し、認証情報は設定ファイルや CLI 引数ではなく環境変数で渡す。
判定より根拠を残す
結果は Markdown と JSON で保存する。どの画面を見て、なぜその判定になったのかを後から確認できる必要がある。review も保存済みの判定を読み直し、ブラウザを再度開かない。
任せないこと
spec → abstract-ai → judge → review → slack の流れを npm パッケージと CLI として公開した。nightly QA には組み込めるが、決定的な回帰テスト、API 契約テスト、QA エンジニアの代わりにはしない。