1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Playwright MCP の browser_snapshot がアクセシブルネームを欠落させ、誤検出の原因になりうる

1
Posted at

概要

Claude Code で利用しているアクセシビリティ検証スキルを試した際、Playwright MCP のスナップショット出力(aria snapshot ベース)が、Puppeteer で取得した Chrome の AX 情報には存在するアクセシブルネームを欠落させるケースを見つけました。

この差異により、スナップショットだけを根拠にした a11y レビューでは、「見出しやリンクにアクセシブルネームがない」という false positive が発生する可能性があります。

この記事では、確認した現象と検証結果、検証スキルへの改善案をメモとして残します。あわせて、代替候補として検討した vercel-labs/agent-browser との出力サイズの比較結果も紹介します。

再現手順

対象は、Gaji-Labo の Web サイトのトップページにある h1 です。

DOM 構造は次のようになっています。

<h1 class="Header_Header__LogoInner__2TrFE">
  <span class="..." aria-label="Gaji-Labo(ガジラボ)">
    <svg>...</svg>
  </span>
</h1>

1. Playwright MCP の browser_snapshot

Playwright MCP の browser_snapshot では、見出しのアクセシブルネームが空になりました。

- link [ref=e6] [cursor=pointer]:
  - /url: /
  - heading [level=1] [ref=e7]   # nameが空

2. Puppeteer で取得したスナップショット

Puppeteer の page.accessibility.snapshot() で Chrome の AX 情報に基づくスナップショットを取得すると、同じ見出しにアクセシブルネームが存在しました。

{
  "role": "heading",
  "name": "Gaji-Labo(ガジラボ)",
  "level": 1
}

再現に使用したスクリプトは次のとおりです。

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.goto('https://www.gaji.jp/', {
    waitUntil: 'networkidle2',
  });

  const snapshot = await page.accessibility.snapshot();

  const findH1 = (node) => {
    if (node.role === 'heading' && node.level === 1) {
      return node;
    }

    for (const child of node.children || []) {
      const result = findH1(child);

      if (result) {
        return result;
      }
    }
  };

  console.log(findH1(snapshot));
  // name: "Gaji-Labo(ガジラボ)"

  await browser.close();
})();

3. agent-browser の snapshot

参考として、agent-browser でも同じページのスナップショットを取得しました。

- heading "Gaji-Labo(ガジラボ)" [level=1, ref=e10]

この h1 の role・name・level は、Puppeteer で取得したスナップショットと一致しました。

何が起きているのか

今回の結果について、次のように考えています。

  • Puppeteer で取得したスナップショットでは、h1 の name from content を計算する際に、子孫の span に指定された aria-label が名前に寄与しています
  • Playwright の aria snapshot は、Chrome の AX ツリーをそのまま直列化したものではありません。Playwright 側のロジックでツリーと名前を生成しているため、本件では Puppeteer で取得した結果との差異が生じています
  • 暗黙の generic ロールを持つ span への aria-label 指定自体は、WAI-ARIA 1.2 に適合しません
  • 一方、AccName 1.2 の子孫再帰アルゴリズム上、その値が祖先である h1 の名前に寄与する挙動は説明できます

つまり、サイト側の ARIA 適合性・実装の堅牢性と、Chrome が公開している名前をレビューツールが欠落させる問題は、分けて考える必要があります。

今回扱いたいのは後者です。サイト側に改善の余地がある場合でも、Chrome の AX 情報に存在する名前を検証ツールが空名として扱うと、レビュー結果の正確性が損なわれます。

a11y レビューへの影響

Playwright MCP のスナップショットだけを根拠にレビューすると、次のような誤検出が起こる可能性があります。

  • 見出しが内容を説明していないとして、WCAG 2.4.6 の違反候補を誤報告する
  • 親のリンクにもアクセシブルネームがないとして、WCAG 2.4.4 や 4.1.2 の違反候補を誤報告する
  • Chrome の AX 情報では名前が公開されている要素を、空名として判定する

このことから、aria snapshot で name が空になっているだけでは、アクセシブルネームが存在しないと確定できません。

agent-browser との出力サイズ比較

Playwright MCP よりコンテキストを削減できる可能性があると聞き、agent-browser への置き換えも検討しました。

しかし、今回検証した 2 ページでは、a11y レビューに必要なフルツリーを取得すると、Playwright MCP よりも出力サイズが増えました。

インタラクティブ要素だけを抽出する snapshot -i では出力を削減できましたが、見出しやランドマークなどの構造を含むページ全体のレビューには情報が不足します。

ページ Playwright MCP browser_snapshot agent-browser snapshot(フル) agent-browser snapshot -i
gaji.jp トップ 26,935 31,518(+17%) 9,352(−65%)
gaji.jp/services 10,416 13,604(+31%) 3,343(−68%)

※各出力は同じ単位・計測方法で比較する必要があります。公開時には、UTF-8 バイト数または文字数のどちらかに統一して再計測します。

今回の結果だけで agent-browser 全体の出力効率を評価することはできません。ただし、少なくとも検証した 2 ページでは、フルツリー利用時のコンテキスト削減は確認できませんでした。

再現性

測定結果は次のとおりです。

  • agent-browser のフルスナップショットは、6 回の試行すべてで同じ結果になりました
  • Playwright MCP のスナップショットは、2 回の試行で同じ結果になりました
  • h1 の名前欠落も、2 回の試行で同じ結果になりました

少なくとも今回の試行では、ページを取得するたびに結果が変わる現象ではありませんでした。

検証スキルへの改善案

今回の結果を踏まえ、Claude Code にアクセシビリティ検証させる場合には、次の対応を追加するのがよさそうです。

aria snapshot の制約を明記する

SKILL.md に、次の趣旨の注意書きを追加します。

aria snapshot では、Chrome の AX 情報に存在するアクセシブルネームが欠落する場合があります。見出しやリンクなどの name が空であることを根拠に指摘する場合は、別の方法で確認してから報告してください。

空名を検出した場合の二次検証を追加する

references に、次の検証フローを追加します。

  1. Playwright MCP のスナップショットで、見出しやリンクなどの name が空になっている要素を抽出する
  2. 対象要素に限定して、Puppeteer の page.accessibility.snapshot() などで Chrome の AX 情報を確認する
  3. 両者の結果が異なる場合は、スナップショットだけを根拠に問題として報告しない
  4. 重大な指摘として扱う場合は、必要に応じて代表的なブラウザと支援技術でも手動確認する

agent-browser は任意の二次検証手段とする

agent-browser では、今回の h1 について Puppeteer と同じ name が出力されました。そのため、任意の二次検証手段として利用できる可能性があります。

一方、今回検証したページでは、フルスナップショットの出力サイズが Playwright MCP よりも増えました。標準のバックエンドとして置き換えるのではなく、精度を確認するための任意の手段として位置づけるのが妥当だと考えています。

まとめ

Claude Code のアクセシビリティ検証スキルで Playwright MCP を利用したところ、Puppeteer で取得した Chrome の AX 情報には存在するアクセシブルネームが、aria snapshot では欠落するケースを確認しました。

この結果から、検証スキルでは、aria snapshot の空名をそのままアクセシビリティ上の問題と判断しないことが重要です。空名を根拠に指摘する場合は、Chrome の AX 情報などを使った二次検証を挟む必要があります。

また、agent-browser は二次検証手段として利用できる可能性があるものの、今回検証した 2 ページでは、フルツリー利用時のコンテキスト削減は確認できませんでした。

検証環境は次のとおりです。

  • macOS
  • Playwright MCP(2026 年 7 月時点)
  • agent-browser 0.32.3
  • Puppeteer 付属の Chromium

主要な再現情報と検証手順は、本文に記載しています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?