記事一覧に戻る

Playwright でスクショを撮らせたら、コーディングエージェントの UI 崩れ修正が10倍楽になった

E2E テストに Playwright を整備して、コーディングエージェントに変更後のスクリーンショットを撮らせるようにしたら、UI 崩れの修正サイクルが劇的に短くなった話。

2026年6月11日2 min read
Playwright
E2E
AI Agent
Testing
Frontend

この記事を共有

TL;DR

  • コーディングエージェントは DOM やコードは読めるけど、実際の見た目は見ていない。だから UI 崩れに気づけない。
  • Playwright で「指定ページのスクショを撮るだけ」の仕組みを整備して、エージェントに撮影 → 画像を確認 → 直す、をループさせた。
  • 「直す → 撮る → 自分で見て判断する」が回り出した瞬間、UI 崩れの修正がめちゃくちゃ楽になった。体感で10倍。
  • 大事なのは凝った E2E ではなく、エージェントが自分で見られるフィードバックループを渡すこと。

UI 崩れの修正がいちばんしんどい

コーディングエージェントに普通のロジックを書かせるのはだいぶ安定してきた。
テストがあれば、エージェントは赤を緑にするまで自分で回せる。

でも UI 崩れだけは別だった。

  • ボタンが微妙にはみ出す
  • ダークモードだけ文字が背景に溶ける
  • ある画面幅でレイアウトが2段に割れる
  • gap が効いてなくて要素がくっつく

この手の不具合は、コードを読んでも気づけないことが多い。
そして厄介なのが、エージェントに「直して」と言っても、直ったかどうかをエージェント自身が確認できないところだ。

結局こっちがブラウザを開いて、目で見て、「まだ崩れてる」と差し戻す。
このラリーがいちばん時間を食っていた。

エージェントは画面を見ていない

冷静に考えると当たり前で、エージェントが見ているのは基本的にテキストだ。

  • ソースコード
  • DOM 構造
  • クラス名

つまり「この div にこの Tailwind クラスが付いている」までは分かる。
でも、それが実際にどう描画されているかは見ていない。

人間がフロントを直すときは、ほぼ必ず画面を見ている。
それなのにエージェントには画面を渡していなかった。これが歪みの正体だった。

やったこと: スクショを撮る土台を渡す

立派な E2E スイートを作りたかったわけではない。
ほしかったのは「指定したページのスクショを撮って、ファイルに吐く」だけの最小の仕組み。

Playwright を入れる。

npm install -D @playwright/test
npx playwright install chromium

撮影対象を配列で並べて、ループで撮るだけのスペックを置く。

// e2e/screenshots.spec.ts
import { test, expect } from '@playwright/test';

const pages = [
  { name: 'home', path: '/' },
  { name: 'blog', path: '/blog' },
  { name: 'blog-post', path: '/blog/knip-dead-code-cleanup' },
  { name: 'projects', path: '/projects' },
];

const themes = ['light', 'dark'] as const;

for (const { name, path } of pages) {
  for (const theme of themes) {
    test(`screenshot ${name} (${theme})`, async ({ page }) => {
      await page.emulateMedia({ colorScheme: theme });
      await page.goto(path);
      await page.waitForLoadState('networkidle');
      await page.screenshot({
        path: `e2e/__shots__/${name}-${theme}.png`,
        fullPage: true,
      });
    });
  }
}

package.json にコマンドを足しておく。

{
  "scripts": {
    "shots": "playwright test e2e/screenshots.spec.ts"
  }
}

これで npm run shots を叩くと、各ページ・ライト/ダークのスクショが e2e/__shots__/ に並ぶ。

エージェントにループを渡す

ポイントはここからで、スクショを撮るだけでは意味がない
撮った画像をエージェント自身に見せて、判断させるところまでをセットにする。

最近のコーディングエージェント(Claude Code など)は画像ファイルを読める。
なので、エージェントへの指示をこういう形にした。

  1. UI を変更する
  2. npm run shots を実行する
  3. 出力された e2e/__shots__/*.png自分で開いて確認する
  4. 崩れていたら直して 2 に戻る
  5. 崩れがなくなったら完了

これだけで挙動がガラッと変わった。

エージェントが「ボタンが右にはみ出てますね」と自分で気づいてmax-width を足して、もう一度撮って、「直りました」と言う。
今まで人間がやっていた目視チェックのラリーが、ループの中に閉じた。

なぜ10倍楽になったのか

差し戻し回数が減ったのが大きい。

これまでは「直して」と言うたびに、こっちがブラウザを開いて確認していた。
1回の修正に人間の目視が1回必要だった。

スクショのループを渡してからは、エージェントが自分で何往復もしてから「できました」と持ってくる。
人間の確認は最後の1回でよくなった。

副次的に良かったこと。

  • ダークモード崩れみたいな「気づきにくいやつ」を早い段階で拾える
  • 「この画面幅で崩れる」を再現条件ごとスクショに残せる
  • レビュー時に before / after の画像を貼りやすい
  • 文章で「中央寄せにして」と説明するより、画像を見せたほうが早い

エージェントにとってもこっちにとっても、画像は最強の共通言語だった。

ハマったところ

万能ではないので、いくつか注意。

  • 撮るタイミング。アニメーションやフォント読み込み中に撮ると毎回ブレる。waitForLoadState('networkidle') や、必要なら明示的な待機を入れる。
  • 差分は人間が見たほうがいい場面もある。エージェントは「崩れてないか」は得意だけど、「デザインとして良いか」は別の話。最後は人間が見る。
  • スクショを撮りすぎない。全ページ・全幅・全テーマを撮ると遅いし、画像が多すぎて逆に見落とす。まずは崩れやすい数枚から。
  • ピクセル完全一致の比較までは要らないことが多いtoHaveScreenshot() での厳密比較は便利だけど、最初は「撮って目で見る」だけで十分効く。

まとめ

UI 崩れの修正がしんどかった原因は、エージェントが画面を見ていなかったこと。

立派な E2E を組む必要はなくて、「スクショを撮って、エージェント自身に見せる」最小ループを渡すだけでよかった。
それだけで、修正の往復がエージェントの中で完結して、体感で10倍楽になった。

フロントをエージェントに任せていて崩れに困っているなら、まず Playwright で1枚撮らせてみるところから試す価値がある。

参考