Claude Code MCP Playwright デバッグ

Claude Code に Playwright MCP を繋いで CSS の修正結果を確認していたとき、直した CSS が反映されず「修正が効いていない」と何度も誤判定した。実際にはコードは正しく、ブラウザが古い CSS をキャッシュから読んでいただけだった。location.reload(true) でリロードしても直らず、原因の切り分けに回り道した。

結論として、Playwright 経由の検証では CDP(Chrome DevTools Protocol)でキャッシュを無効化してからリロードすると確実になる。

reload(true) では足りない

ビルドした CSS をブラウザで確認するとき、素朴には次のようにリロードする。

await page.evaluate('() => { location.reload(true); return "ok"; }');

この reload(true) の引数は現在のブラウザでは無視される(かつては強制リロードの意味があったが、今は非対応)。結果、外部 CSS ファイルはキャッシュから読まれたままになる。ビルド済みファイルはサーバー上で更新されているのに、ページが掴んでいるのは前の版、という食い違いが起きる。

厄介なのは、ファイル自体をサーバーから取り直すと新しい内容が返ってくることだ。実際、リンク要素の href を fetch で叩くと更新後の CSS が返る。つまり「サーバーは新しい、ページは古い」という状態で、コードを疑う方向に引っ張られてしまう。

CDP でキャッシュを無効化する

Playwright には CDP セッションを開く newCDPSession があり、Network.setCacheDisabled でそのページのネットワークキャッシュを無効化できる。これを立ててからリロードすると、CSS を含む全リソースが取り直される。

const cdp = await page.context().newCDPSession(page);
await cdp.send('Network.setCacheDisabled', { cacheDisabled: true });
await page.reload({ waitUntil: 'networkidle' });

Claude Code から Playwright MCP を使う場合は、生の Playwright コードを実行できるツール経由でこの3行を渡す。一度キャッシュを無効化しておけば、以降その画面での確認は常に最新のリソースで行われるので、CSS を直す→ビルド→確認、のループが安定する。

もう一つの確実な手

CDP を使わない場合は、リンク要素を新しい href(クエリ文字列で毎回変える)で差し込み直す手もある。

const link = [...document.querySelectorAll('link[rel=stylesheet]')]
  .find(l => /style\.css/.test(l.href));
const fresh = link.href.split('?')[0] + '?v=' + performance.now();
// fresh を href に持つ link 要素を作って head に append する

ただしこれは対象の CSS ファイルを狙って差し替える必要があり、ページ全体の再取得にはならない。画面全体を確実に最新化したいなら CDP の方が単純だ。

ローカル開発でビルド成果物をブラウザ確認するとき、「直したのに変わらない」の相当数はブラウザキャッシュが犯人になる。自動化された検証ではリロードを信じず、キャッシュを明示的に無効化してから見る習慣にしておくと、無駄な原因調査を減らせる。