本番アプリのE2E・リンク死活・スクショをPlaywright×AIで自動化する
Playwright×AIによるE2E自動化とは、外部リンクの死活・表示速度・レイアウト崩れといった「壊れていないこと」を、人手ではなく機械とAIエージェントに検証させる仕組みを指します。 私たちは公式サイトの pnpm verify に Playwright のE2Eスモークを組み込み、全外部リンクの404を0件に強制し、LCP<2.5s・CLS<0.1 をしきい値ゲートにしています。本番デプロイ後は scripts/prod-smoke.mjs と curl の200確認で二段構えの疎通チェックを回しています。本記事は、4プロダクトと公式サイトを1人+AIで運用する立場から、実コード構成と運用を公開する一次体験の記録です。
なぜ個人開発でこそE2E自動化が効くのか
答えは、1本の死リンク・1本の壊れた記事が、公開そのものをブロックする品質ゲートを作れるからです。
チームがいれば人の目でレビューが回りますが、1人+AIで複数プロダクトを運用すると手作業のチェックは真っ先に破綻します。そこで「検証が緑になるまで公開できない」ゲートを機械に持たせました。リンク切れやCLSの悪化を見つけるのではなく、見つからない限り前に進めない構造にする、という考え方です。この単位(1ループ=本番に出せる検証済みの1改善)を守る開発体制は、6日間でプロダクトを本番公開した記録にまとめています。
Playwrightスモークで何を強制しているか
pnpm verify を叩くと、ビルドの後に Playwright のスモークが走り、次の3点をしきい値ゲートとして判定します。
- 外部リンクの死活: ページ内の全リンクを収集し、各URLへリクエストして 404を0件に強制。1件でも死んでいれば verify は赤で止まります
- 表示速度(LCP): Largest Contentful Paint が 2.5秒未満
- レイアウト安定性(CLS): Cumulative Layout Shift が 0.1未満。読み込み中に要素が飛ぶ崩れを検知します
しきい値の考え方はおおまかに次の形です。
// verify 内スモークの判定(抜粋・簡略)
const dead = links.filter(r => r.status >= 400);
if (dead.length > 0) throw new Error(`dead links: ${dead.length}`);
if (metrics.lcp >= 2500) throw new Error(`LCP ${metrics.lcp}ms`);
if (metrics.cls >= 0.1) throw new Error(`CLS ${metrics.cls}`);しきい値は Google の Core Web Vitals 推奨値を参照しています。数値は各自で一次ソースを確認すべきですが、基準を明文化して機械に判定させること自体が、個人開発では大きな効きどころです。
AIエージェントに目視QAをどう任せるか
数値では拾えない「見た目のおかしさ」は、AIエージェント(Claude Code)に実レンダリングを目視QAさせます。型は単純で、スクリーンショット→批評→修正を1周として回します。
- エージェントが Playwright で本番相当の画面を開き、スクショを撮る
- その画像を design-review 役のエージェントに渡し、余白・コントラスト・視線誘導・崩れを批評させる
- 指摘をコードに反映し、再度スクショを撮って収束を確認する
ポイントは、同じエージェントに書かせてレビューさせないことです。実装役と検証役を分けて独立した目で批評させ、盲点の共有を避けます。数値ゲート(スモーク)と主観ゲート(目視QA)を分業させる切り分けです。
デプロイ後の疎通確認はなぜ二段構えなのか
「ビルドは緑なのに本番だけ壊れる」障害が実在するからです。CIのゲートとは別に、本番URLを直接叩く確認を重ねています。
- `scripts/prod-smoke.mjs`: デプロイ直後に本番の主要導線を Playwright で実機確認し、コンソールエラー0を通過条件にする
- 公開前の `curl` 200: 記事を配信する blog-drip の運用では、公開処理の前に対象URLへ
curlで200が返ることを確認し、返らなければ配信を止める
CI環境の緑と本番の実際の応答は別物です。二段構えは、環境差や反映の遅延で起きる「緑なのに落ちている」を本番側でもう一度捕まえるためです。
AIに任せてよい検証と、人間が握る領域はどこか
線引きははっきりしています。機械的に判定できる検証はAIに、後戻りできない判断は人間にです。
任せてよいのは、リンク死活・速度・崩れの数値判定、実機スモーク、スクショの一次批評まで。公開の最終GO・課金・法務や表現の妥当性は人間が握ります。
失敗例も残します。画像処理ライブラリのLinuxバイナリがデプロイに含まれずAPIが500を返した障害がありました。実機スモークが即検知して事なきを得ましたが、「デプロイ直後に必ず本番を叩く」ルールがなければ公開後まで気づけなかった障害です。自動化は検知を速めますが、何を守るかを決めるのは人間だ、というのが実感です。
よくある質問
Q. E2Eテストと今回のスモークは何が違いますか? A. 網羅的なE2Eテストは全機能の振る舞いを検証しますが、ここでのスモークは「壊れていないこと」を高速に確認する軽い関門です。個人開発では、まず公開をブロックできる最小のスモーク(リンク死活・速度・崩れ)から始めるのが現実的です。
Q. 外部リンクの死活チェックは重くなりませんか? A. リンク数に比例しますが、並列でリクエストすれば数十本規模なら数秒で終わります。外部サイト側の一時的失敗を誤検知しないよう、リトライの調整は必要です。
Q. LCP<2.5s・CLS<0.1 という数値の根拠は? A. Google の Core Web Vitals「良好」推奨値を参照しています。適正値はプロダクトによって変わるため、各自で一次ソースを確認し基準として明文化するのが安全です。
Q. AIの目視QAはどこまで信用できますか? A. 崩れやコントラストの一次批評までは実用的ですが、公開判断は人間が行います。実装役とレビュー役を別エージェントに分けて精度を上げています。
#Playwright#E2Eテスト#AI開発#個人開発