accessibility-testing について
accessibility-testing は、開発・QA チームが継続的なテストにアクセシビリティ検証を組み込むためのスキルです。自動スキャンに加え、キーボード、スクリーンリーダー、ARIA 状態、操作パターンのテストを扱います。
主な機能
- 01axe-core と Playwright によるスキャン
- 02キーボード操作とフォーカス挙動の確認
- 03スクリーンリーダー向けコンテンツの検証
- 04ARIA 状態と操作パターンのテスト
- 05ARIA スナップショットによる意味構造の確認
活用シーン
- 01CI でのアクセシビリティ回帰検出
- 02フォームエラーとフォーカス案内の検証
- 03メニューやダイアログの状態テスト
- 04WCAG 目標に照らしたページ監査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ petrkindlmann/ qa-skills --skill accessibility-testingインストール後、Claude Code で/accessibility-testingを入力して読み込まれたか確認します。
同梱ファイルreferences/patterns.mdreferences/recipes.md
詳細
確認事項
まず .agents/qa-project-context.md を確認してください。ファイルが存在する場合は、それを基盤として、すでに回答されている項目は飛ばしてください。
要件とコンプライアンス(目標レベルと監査義務を定めます)
- 必要な WCAG 適合レベルはどれですか。A、AA、AAA のいずれですか。実務上、法的な標準は AA です。
- 適用される法律は何ですか。ADA、EAA/EN 301 549、Section 508、AODA などが該当します。それぞれ WCAG のレベルに対応しています。
- 維持が必要な VPAT やアクセシビリティに関する声明、または企業・政府機関の顧客との契約上のアクセシビリティ条項はありますか。
現状(監査を行うのか、リグレッションを防ぐのかを判断します)
- これまでに監査を実施したことはありますか。指摘事項は何で、すでにバックログに登録されているものは何ですか。
- デザインシステムに、アクセシビリティのガイダンスやアクセシブルなコンポーネントは含まれていますか。
テストインフラ(自動化できることと、手作業で行う必要があることを判断します)
- アクセシビリティの自動テストは、すでに CI で実行されていますか。
- チームではどのスクリーンリーダーをテストに使用していますか。VoiceOver、NVDA、JAWS、TalkBack のいずれですか。
基本原則
-
自動テストで検出できる問題は 30~40%までです。 axe-core は、代替テキストの欠落、コントラスト不足、ラベルの欠落、無効な ARIA を検出します。しかし、代替テキストが適切か、タブの順序が論理的か、カスタムウィジェットを操作できるかは判断できません。axe のテストに合格することは必要ですが、それだけでは十分ではありません。重要なのは、axe には複数の WCAG 2.2 の達成基準(2.4.11 フォーカスが隠されないこと、2.5.7 ドラッグ操作、2.5.8 ターゲットサイズ(一部のみ))に対する自動ルールがないことです。axe の実行結果が緑色でも、2.2 AA に適合しているとは限りません。
-
まずセマンティックな HTML を使い、ARIA は最後の手段にします。 ネイティブ要素(
<button>、<nav>、<input>、<dialog>)には、組み込みのセマンティクス、キーボード操作、スクリーンリーダー対応が備わっています。<div role="button">を使う場合は、tabindex、Enter/Space キーのハンドラー、フォーカススタイル、ARIA 状態も必要です。これらは<button>ならすべて標準で備わっています。適切なネイティブ要素がない場合に限り、ARIA を使用してください。 -
影響の大きい順にテストします。キーボード、スクリーンリーダー、自動テストの順です。 キーボードの問題は、ユーザーが機能を利用できない状態を引き起こします(影響が最も大きい)。スクリーンリーダーの問題は、不適切な読み上げによって混乱を招きます。自動テストでは、機械的に検出できる残りの問題を見つけます。ツールを使いやすいところではなく、最も大きな影響があるところから始めてください。
-
アクセシビリティは機能ではなく、品質特性です。 パフォーマンスやセキュリティと同様に、すべての新しいコンポーネント、すべての PR で継続的にテストしてください。完成した製品にアクセシビリティを後から追加するには、10~100 倍のコストがかかります。アクセシブルでないパターンがコンポーネントライブラリに組み込まれてしまうためです。
-
実際の支援技術でテストします。 ブラウザーの DevTools や axe 拡張機能は開発補助ツールであり、macOS/iOS の VoiceOver、Windows の NVDA、Android の TalkBack の代わりにはなりません。それぞれの動作は異なります。複雑なカスタムウィジェットでは、支援技術を使った手動テストを実施してください。
axe-core + Playwright による自動スキャン
npm view @axe-core/playwright version で確認した正確なバージョンに固定して @axe-core/playwright をインストールします(2026-10-21 時点では 4.14.0。マイナーバージョンは axe-core と連動しているため、更新のたびに新しいルールセットが加わります。自動更新せず、必ずレビューしてください)。再利用可能な checkAccessibility(page, testInfo, options) ヘルパーでラップし、WCAG タグ ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa'] に絞り込みます。スキャンの前に、期待される URL とアプリケーション側で用意した準備完了のアサーションを必須にします。空白ページ、エラーページ、リダイレクトされたページでも axe のチェックを通過する可能性があります。結果全体の JSON を添付し、ルールが一つも評価されなかったスキャンは失敗させ、violations.toHaveLength(0) をアサートします。エクスポートされる scanAccessibility ヘルパーは、既知のギャップのベースライン用に違反の概要を返します。checkAccessibility は違反ゼロを必須とします。すべての主要ページと、モーダルを開いた状態、メニューを展開した状態、サインイン済みアカウントなどのインタラクティブな状態でも実行し、初期読み込みだけにしないでください。修正できないサードパーティのページでは、スキャンを省略するのではなく、既知のルール ID の正確なセットをアサートします。これにより、新たな違反や修正済みの違反があればテストに反映されます。
ルールを抑制するのは、追跡課題やインラインコメントなど、正当な理由を記録した場合に限ります。また、ルールを全体で無効にするのではなく、所有していないサードパーティ製ウィジェットを exclude で除外してください。
インストールコマンド、RGAA タグに関する注意、ヘルパーの全コード、ページループとインタラクティブな状態の仕様、ルールの抑制、CI への統合については、references/recipes.md を参照してください。
手動テストのチェックリスト
自動スキャンは最低限の確認です。以下のチェックには人による確認が必要です(またはキーボード操作を使う Playwright の仕様で確認できます。キーボード操作の仕様については references/recipes.md を参照してください)。
キーボード操作の監査
- Tab の順序が論理的 — LTR では左から右、上から下の順です。予期しないフォーカスの移動はありません。
- すべてのインタラクティブ要素に移動可能 — Tab/Shift+Tab を使います。
- フォーカスインジケーターがすべてのフォーカス要素で見える — 置き換えがないまま
outline: noneを指定していません。 - スキップリンクが機能する — 最初の Tab で「メインコンテンツへスキップ」が表示され、Enter で
<main>にフォーカスが移動します。 - Enter でボタン/リンクが作動し、Space でボタンが作動し、チェックボックスが切り替わる。
- Escape でモーダル、ドロップダウン、ツールチップが閉じる — フォーカスはトリガーに戻ります。
- 矢印キーでタブ、メニュー、ラジオボタングループ、ツリービュー内を移動できます。
- キーボードトラップがない(モーダルダイアログでは、閉じるまでフォーカスを閉じ込めることが意図されており、許容されます)。
- カスタムウィジェットをマウスなしで操作可能(スライダー、日付ピッカー、ドラッグ&ドロップ)。
スクリーンリーダーのテスト
| スクリーンリーダー | OS | ブラウザー | 無料? |
|---|---|---|---|
| VoiceOver | macOS/iOS | Safari | はい(Cmd+F5) |
| NVDA | Windows | Firefox/Chrome | はい |
| JAWS | Windows | Chrome/Edge | いいえ |
| TalkBack | Android | Chrome | はい |
- ページ遷移時にページタイトルが読み上げられます。
- 見出しが移動可能なアウトラインを構成しています(h1 → h2 → h3。レベルを飛ばしていません)。
- 画像に説明的な代替テキストがあります(装飾用の場合は
alt="")。 - フォーム入力にフォーカスしたとき、ラベルが読み上げられます。
- 必須項目が必須として読み上げられ、エラーが該当する入力に関連付けられています。
- ライブリージョンで動的なコンテンツ(トースト、読み込み状態)が読み上げられます。
- ボタン/リンクの目的が読み上げられます(「ここをクリック」などの表現はありません)。
色のコントラストと視覚的な確認
- 通常のテキスト:最低 4.5:1(WCAG AA)。大きなテキスト(18pt 以上/太字 14pt 以上):3:1。
- UI コンポーネントとグラフィックオブジェクト:隣接する色に対して 3:1。
- 情報を色だけで伝えず、アイコン、パターン、テキストを追加します。
フォームとエラーのアクセシビリティ
- すべての入力に、
for/idで関連付けられた表示可能な<label>があります(プレースホルダーはラベルではありません)。 - 必須項目は視覚的にもプログラム上でも示されています(
required/aria-required)。 - エラーでは
aria-describedbyで入力に関連付け、role="alert"で読み上げます。 - 送信に失敗したとき、最初のエラーにフォーカスが移動します。
- 関連する項目は
<fieldset>と<legend>でグループ化されています。
WCAG 2.2 クイックリファレンス
レベル A(必ず修正)
| 基準 | 意味 | よくある問題 |
|---|---|---|
| 1.1.1 非テキストコンテンツ | 画像に代替テキストがある | alt のない <img> |
| 1.3.1 情報と関係性 | HTML のセマンティクスで構造を示す | 見出しのようにスタイル設定された <div> |
| 2.1.1 キーボード | すべての機能をキーボードで操作できる | マウスにしか反応しないカスタムウィジェット |
| 2.4.1 ブロックスキップ | ナビゲーションをスキップするリンク | スキップリンクがない |
| 3.1.1 ページの言語 | <html lang="en"> が設定されている | lang がない |
| 3.3.1 エラーの特定 | エラーがテキストで説明されている | 赤い枠線だけでエラーを表示 |
| 4.1.2 名前、役割、値 | カスタムコントロールが名前と役割を公開する | 役割のない <div onclick> |
レベル AA(最も一般的な法的要件)
| 基準 | 意味 | よくある問題 |
|---|---|---|
| 1.4.3 コントラスト(最低限) | 通常の文字は 4.5:1、大きな文字は 3:1 | 白地に薄い灰色の文字 |
| 1.4.4 テキストのサイズ変更 | 品質を損なわずに 200% まで拡大できる | 高さ固定のコンテナーでテキストが切れる |
| 1.4.11 非テキストのコントラスト | UI コンポーネントは 3:1 | コントラストが低い入力欄の枠線 |
| 2.4.7 フォーカスの可視化 | キーボードフォーカスが見える | 代替手段がない outline: none |
| 2.5.8 ターゲットサイズ | タッチターゲットは最小 24×24px | 小さすぎるアイコンボタン |
| 3.3.2 ラベルまたは説明 | 入力欄にラベルがある | プレースホルダーだけがラベルになっている |
| 3.3.8 アクセシブルな認証 | 認知機能テストがない | 代替手段のない CAPTCHA |
レベル AAA(あると望ましい)
| 基準 | 意味 |
|---|---|
| 1.4.6 コントラスト(強化) | 通常のテキストは 7:1、大きなテキストは 4.5:1 |
| 2.4.9 リンクの目的(リンクのみ) | リンクテキストだけでリンク先が分かる |
| 3.1.5 読解レベル | 中等教育前期の教育レベル |
アクセシブルなパターン
CSS ではなく、アクセシブルツリー(役割、名前、ARIA の状態)をテストしてください。実行可能なテストが必要なパターンは次のとおりです。
- フォーム — エラーが
aria-describedbyで関連付けられ、aria-invalid='true'が設定され、最初のエラーにフォーカスが移動する。 - モーダル/ダイアログ —
aria-modal='true'とaria-labelledbyが設定され、フォーカスが閉じ込められ、Escape キーでフォーカスが戻る。 - インタラクティブな状態 — 開いたドロップダウン(
role="menu"またはrole="listbox"、aria-expanded)、読み込み中のスケルトン(データ取得中はaria-busy='true')、トースト(aria-live='polite')。状態ごとに異なる ARIA が設定されるため、クリックして状態を変化させ、開いた状態の ARIA を検証してください。デフォルトのページスナップショットでは、これらの状態は一度もテストされません。 - データテーブル —
columnheaderの役割があり、aria-sortが現在の並べ替え状態を反映する。 - ランドマーク —
mainはちょうど 1 つあり、banner、navigation、contentinfoが存在する。
上記のすべてのパターンについて、実行可能な完全なテストは references/patterns.md を参照してください。
ARIA スナップショット
Playwright の toMatchAriaSnapshot() はアクセシブルツリーを YAML としてキャプチャし、これと照合します。視覚的な変更によってセマンティクスが気付かないうちに損なわれる回帰(ボタンのように見えるようスタイルを変更した <div>、単なるテキストに格下げされた見出しなど)を検出する最速の方法です。ピクセルではなく構造とアクセシブルな名前を検証するため、visual-testing を補完するものであり、置き換えるものではありません。スナップショットの範囲は安定したコンテナーに限定してください。非同期コンテンツを含むページ全体のスナップショットは不安定になります。ナビゲーションとフォームのスナップショット例は references/patterns.md を参照してください。
法令・規格への準拠マッピング
| 法令/規格 | 地域 | 必要な WCAG レベル | 適用 |
|---|---|---|---|
| ADA | 米国 | AA(裁判例による) | 訴訟(民間人による訴訟提起権) |
| Section 508 | 米国(連邦) | WCAG 2.0 AA | 連邦政府の調達要件 |
| EAA | EU | EN 301 549(WCAG 2.1 AA) | 2025年6月28日から施行されています。 加盟国は積極的に執行しています。民間人による訴訟提起の可否は国によって異なります(DE、FR、IEで特に活発です)。EN 301 549は次回改訂でWCAG 2.2に整合する見込みです。 |
| AODA | カナダ、オンタリオ州 | WCAG 2.0 AA | 1日あたり最大10万ドルの罰金 |
| EN 301 549 | EU | WCAG 2.1 AA | 公共調達要件 |
| Equality Act 2010 | 英国 | WCAG 2.1 AA(ガイダンス) | 訴訟 |
| ISO/IEC 40500:2025 | 国際 | WCAG 2.2と同等(2023年10月) | 調達/RFPの文言に有用です。ISOから無料で入手できます。 |
実務上の目標: 米国またはEUのユーザーにサービスを提供する場合、新規開発ではWCAG 2.2 AAを目標にします。EAAが施行され、EN 301 549は2.2に更新される見込みであり、ISO/IEC 40500:2025(2025年9月公開)によってWCAG 2.2が国際的に規定されているためです。2.2にすぐ対応できない場合、WCAG 2.1 AAが従来の最低基準となります。
WCAG 3の状況: W3Cは2026年3月、WCAG 3の更新された作業草案を公開しました。この草案では「Outcomes」を「Requirements」に改称し、合否を二択で判定する評価方法から移行しています。要件は約174件です。引き続き作業草案の段階であり、勧告候補は2027年第4四半期、勧告は早くとも2028年を目標としています。現時点ではWCAG 2.2に対応し、WCAG 3の動向を追跡しつつ、まだWCAG 3に基づくテストは行わないでください。
収集する監査証跡: ページごとの自動スキャン結果、テスターと日付を記録した手動チェックリスト、支援技術のバージョンを記載したスクリーンリーダーの結果、アクセシビリティに関する声明、エンタープライズ営業向けのVPAT、既知の問題に対する修正計画です。法令/VPAT/同意のマッピング全体については、compliance-testingを参照してください。
アンチパターン
自動テストのみを行う
axeを実行し、違反がゼロだったことを確認して、製品にアクセシビリティがあると判断することです。自動化ツールは実際の問題の60~70%を見逃し、複数のWCAG 2.2基準をまったくチェックしません。対策: axeの実行ごとにキーボードとスクリーンリーダーのチェックリストも実施し、スキャンだけでなく両方をリリースのゲートにします。
ARIAの過剰使用
ネイティブのセマンティクスをすでに持つ要素にrole、aria-label、aria-describedbyを追加し、読み上げが二重になることです。対策: 冗長なARIAを削除し、ネイティブ要素を使います。<button>にrole="button"は必要ありません。
キーボード利用者を無視する
マウスやタッチでは操作できても、キーボードでは操作できない機能です。クリックのみで操作するドロップダウン、キーボード操作の手段がないドラッグ&ドロップ、ホバー時のみ表示されるツールチップなどがあります。対策: マウスで行えるすべての操作にキーボードでの代替手段を用意し、keyboard.spec.tsテストでカバーします(references/recipes.mdを参照)。
アクセシビリティを後付けする
製品が「完成」するまで待つと、アクセシビリティに対応していないパターンがコンポーネントライブラリに組み込まれ、修正コストが10~100倍になります。対策: 完了の定義にaxeチェックを加え、すべての新しいコンポーネントがマージ前にアクセシビリティのゲートを通るようにします。
アクセシビリティを任意のものとして扱う
「誰も苦情を言っていない」という理由でa11yチケットの優先度を下げることです。障害のあるユーザーは、使えない製品を通じて苦情を伝えることができず、黙って離れてしまいます。また、米国のウェブアクセシビリティ訴訟は2018年以降、年々増加しています。対策: 機能上のバグと同じ重大度ルールを適用し、a11yをリリース阻害要因として追跡します。リリース準備状況の確認では、未解決のa11y問題を報告します。
通常の利用ケースだけをテストする
初期状態のページだけをスキャンし、異なるARIA情報を持つモーダル、展開したドロップダウン、エラーメッセージ、読み込み中のスケルトンを見逃すことです。対策: テストで各インタラクティブな状態を操作し(クリックしてメニューを開く、フェッチを実行するなど)、変更後のDOMに対してスキャンを再実行します。
失敗モード
| 症状 | 考えられる原因 | 対処または確認 |
|---|---|---|
| axe で違反が 0 件と判定されるが、ページをキーボードで操作できない | 自動スキャンでは操作性やフォーカス順序をテストしない | キーボード監査を実行し、keyboard.spec.ts を追加します |
toMatchAriaSnapshot が不安定になる | スナップショットの対象範囲に動的コンテンツや並べ替えられるリストが含まれている | 安定したコンテナーに対象を絞り、部分スナップショットを使用します |
| コントラストのルールには合格するが、グラデーション/オーバーレイ/画像上のテキストが読みにくい | axe では単色ではない背景とのコントラストを計算できない | 該当ケースは手動で確認するか、コントラストピッカーを使用します |
| axe には合格するが、WCAG 2.2 AA 監査には不合格となる | axe には 2.4.11 のルールがなく、2.5.7 はなく、2.5.8 は一部のみ対応している | フォーカスが隠れないこと、ドラッグ操作の代替手段、ターゲットサイズを手動で確認します |
検証
テストスイートが実際にページを検証していることを確認します。誤った URL、エラーページをスキャンする axe、到達しないスナップショットなどにより、実質的に何も検証せずに合格する a11y テストは、テストがないよりも悪い状態です。
- axe が実際のコンテンツをスキャンしていることを確認します。 違反があるとわかっているページ(例:一時的に
<label>を削除したページ)をヘルパーに指定して実行します。テストは FAIL となり、ルール名が表示される必要があります。
欠陥を仕込んだページでも合格する場合、AxeBuilder は誤った DOM(リダイレクト先、空白ページ、または誤ったセレクター)をスキャンしています。緑色の結果を信頼する前に修正してください。npx playwright test e2e/tests/a11y/pages.spec.ts - キーボードの仕様が 404 ではなくアプリに到達することを確認します。
npx playwright test e2e/tests/a11y/keyboard.spec.tsを実行し、スキップリンクのテストのトレースを開きます。最初の Tab でスキップリンクに移動する必要があり、どこにも移動しない状態ではいけません。ページが読み込まれていないために「合格」するテストは、誤った成功です。 - CI ゲートがブロックすることを確認します。 ブランチに重大な違反を 1 つ導入してプッシュします。
a11yジョブがゼロ以外の終了コードを返し、PR チェックを失敗させる必要があります。その後、変更を元に戻します。 - ARIA スナップショットを抜き取り確認します。
--update-snapshotsを指定してtoMatchAriaSnapshotを 1 回実行し、その後、指定せずにもう一度実行します。2 回目は合格する必要があります。不安定になる場合は、スナップショットの対象範囲に非同期または並べ替えられるコンテンツが含まれています。対象を安定したコンテナーに絞ってください。
完了条件
- axe-core が E2E テストスイートに統合され、テスト戦略で特定された主要なユーザー向けページすべてで自動実行されている。
- CI で axe の重大または深刻な違反が 0 件と報告され、違反が導入された場合はマージがブロックされる(ワークフローについては
references/recipes.mdを参照)。 - すべてのインタラクティブなフロー(フォーム、モーダル、ドロップダウン、ナビゲーションメニュー)について、エンドツーエンドのキーボードナビゲーションがテストされている。
- 少なくとも 1 つのドロップダウン/メニュー(
aria-expanded+role)、1 つの読み込み領域(aria-busy)、1 つのライブ領域(aria-live)について、インタラクティブな状態の ARIA が検証されている。 - ブランドパレット全体の色のコントラストが、WCAG AA の基準(通常のテキストは 4.5:1、大きなテキストと UI コンポーネントは 3:1)に照らして検証されている。
- 複雑なカスタムウィジェット(日付ピッカー、データテーブル、ドラッグ&ドロップ)について、使用したスクリーンリーダーとそのバージョンを含むテスト記録が文書化されている。
関連スキル
- playwright-automation — axe スキャンとキーボード/ARIA スナップショットテストの両方に使うテストランナーです。このスキルでは、その上にアクセシビリティ固有のパターンを追加します。
- compliance-testing — Cookie 同意(GDPR/CMP)、VPAT の生成、EAA/Section 508 の報告など、法規制への適合性テストを扱います。同意バナーや正式なコンプライアンス文書については、こちらを参照してください。WCAG 適合性テストについては、このスキルを使用してください。
- visual-testing — ピクセル差分によるスクリーンショット回帰テストです。視覚的なレンダリングの変更にはこちらを使用し、セマンティックツリーの回帰にはこのスキルの ARIA スナップショットを、a11y 固有の色のしきい値にはコントラスト検証を使用してください。
- ci-cd-integration — CI で a11y テストを実行し、違反があればマージをブロックします。
- risk-based-testing — 最初に監査するページやコンポーネントの優先順位を決めます。