mcpField
A
a11y-playwright-testing

a11y-playwright-testing

github.com/fugaziテスト・品質256139 回インストール2 日前に更新
リポジトリ

a11y-playwright-testing について

Playwright、TypeScript、axe-core を使うチーム向けのアクセシビリティテストスキルです。WCAG 2.2 AA スキャンやキーボード、フォーカス、セマンティクスの検証を支援します。完全な適合確認には手動テストも必要です。

主な機能

  1. 01axe-core による WCAG 2.2 AA スキャン
  2. 02キーボード操作とフォーカスのテスト
  3. 03セマンティクスと ARIA の検証
  4. 04フォームラベルとエラーの確認
  5. 05コントラストとスクリーンリーダーのテストパターン

活用シーン

  1. 01ページやコンポーネントの WCAG 違反確認
  2. 02ダイアログのフォーカストラップと復帰の検証
  3. 03キーボード操作とフォームラベルのテスト
  4. 04アクセシビリティ回帰テストに自動チェックを追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/fugazi/test-automation-skills-agents --skill a11y-playwright-testing

インストール後、Claude Code で/a11y-playwright-testingを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE.txt
references/
aria-patterns-mistakes.md
aria-patterns-widgets-1.md
aria-patterns-widgets-2.md
axe-tags-reference.md
snippets-keyboard-focus-semantic.md
snippets-setup-and-scanning.md
snippets-visual-names-checklist.md
wcag21aa-checklist.md

詳細

Playwright アクセシビリティテスト(TypeScript)

TypeScript と axe-core を使用した Playwright による、自動アクセシビリティテストの包括的なツールキットです。WCAG 2.2 レベル AA(2.1 を包含)の適合性確認、キーボード操作のテスト、セマンティクスの検証、アクセシビリティのリグレッション防止を実現します。

有効化: アクセシビリティテスト、WCAG 準拠、axe-core スキャン、キーボードナビゲーションテスト、フォーカス管理、ARIA の検証、スクリーンリーダーとの互換性に取り組むときに、このスキルが起動します。

このスキルを使用する場面

  • axe-core を使用した、WCAG 2.2 AA 準拠の自動 a11y スキャン
  • Tab/Enter/Space/Escape/矢印キーの操作性を確認するキーボードナビゲーションテスト
  • ダイアログ、メニュー、動的コンテンツのフォーカス管理の検証
  • ランドマーク、見出し、ARIA のセマンティック構造のアサーション
  • ラベル、エラー、説明を対象とするフォームアクセシビリティテスト
  • 色のコントラストと視覚的アクセシビリティの検証
  • スクリーンリーダー互換性テストのパターン
使用しない場面
  • Selenium/Java によるアクセシビリティテスト(accessibility-selenium-testing を使用してください)。
  • Playwright による機能/UI の E2E テスト仕様の作成(playwright-e2e-testing を使用してください)。
  • 適合性の完全な最終確認 — 自動 axe スキャンで検出できる問題は約 30~40%です。手動監査と支援技術によるテストも引き続き必要です。

前提条件

要件詳細
Node.jsv18+ を推奨
Playwright@playwright/test のインストール済み
axe-core@axe-core/playwright パッケージ
TypeScriptプロジェクトで設定済み
クイックセットアップ
# Add axe-core to existing Playwright project
npm install -D @axe-core/playwright axe-core

最初に確認すること

アクセシビリティテストを書く前に、次の点を確認してください。

  1. 対象範囲:対象となるページ/フローはどれですか?明示的に除外するものはありますか?
  2. 規格:WCAG 2.2 AA(デフォルト)ですか、それとも組織固有のポリシーですか?
  3. 優先度:最もリスクの高いコンポーネントはどれですか(フォーム、モーダル、ナビゲーション、チェックアウトなど)?
  4. 例外:既知の制約はありますか(レガシーなマークアップ、サードパーティー製ウィジェットなど)?
  5. 支援技術:手動テストが必要なスクリーンリーダー/ブラウザーはどれですか?

基本原則

1. 自動化の限界

[!] 重要: 自動ツールで検出できるアクセシビリティの問題は約 30~40%です。自動化はリグレッションの防止と一般的な不具合の検出に利用してください。WCAG への完全な適合には、手動監査が必須です。

2. セマンティック HTML を優先

ARIA よりもネイティブ HTML のセマンティクスを優先してください。必要なセマンティクスをネイティブ要素で実現できない場合にのみ、ARIA を使用してください。

// [ok] Semantic HTML - inherently accessible
await page.getByRole("button", { name: "Submit" }).click();

// [no] ARIA override - requires manual keyboard/focus handling
await page.locator('[role="button"]').click(); // Often a <div>
3. ロケーター戦略をアクセシビリティの指標にする

要素をロールまたはラベルで特定できない場合は、アクセシビリティ上の問題であることがよくあります。

ロケーターの結果アクセシビリティの指標
getByRole('button', { name: 'Submit' }) [ok]ボタンにアクセシブルな名前がある
getByLabel('Email') [ok]入力に適切なラベルが付いている
getByRole('navigation') [ok]ランドマークが存在する
locator('.submit-btn') [!]アクセシブルな名前がない可能性がある

主なワークフロー

axe による自動スキャン(WCAG 2.2 AA)
import AxeBuilder from "@axe-core/playwright";
import { test, expect } from "@playwright/test";

test("page has no WCAG 2.2 AA violations", async ({ page }) => {
  await page.goto("/");

  const results = await new AxeBuilder({ page })
    .withTags(["wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "wcag22a", "wcag22aa"])
    .analyze();

  expect(results.violations).toEqual([]);
});
範囲を限定した axe スキャン(コンポーネント単位)
test("form component is accessible", async ({ page }) => {
  await page.goto("/contact");

  const results = await new AxeBuilder({ page })
    .include("#contact-form") // Scope to specific component
    .withTags(["wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "wcag22a", "wcag22aa"])
    .analyze();

  expect(results.violations).toEqual([]);
});
キーボードナビゲーションテスト
test("form is keyboard navigable", async ({ page }) => {
  await page.goto("/login");

  // Tab to first field
  await page.keyboard.press("Tab");
  await expect(page.getByLabel("Email")).toBeFocused();

  // Tab to password
  await page.keyboard.press("Tab");
  await expect(page.getByLabel("Password")).toBeFocused();

  // Tab to submit button
  await page.keyboard.press("Tab");
  await expect(page.getByRole("button", { name: "Sign in" })).toBeFocused();

  // Submit with Enter
  await page.keyboard.press("Enter");
  await expect(page).toHaveURL(/dashboard/);
});
ダイアログのフォーカス管理
test("dialog traps and returns focus", async ({ page }) => {
  await page.goto("/settings");
  const trigger = page.getByRole("button", { name: "Delete account" });

  // Open dialog
  await trigger.click();
  const dialog = page.getByRole("dialog");
  await expect(dialog).toBeVisible();

  // Focus should be inside dialog
  await expect(dialog.getByRole("button", { name: "Cancel" })).toBeFocused();

  // Tab should stay trapped in dialog
  await page.keyboard.press("Tab");
  await expect(dialog.getByRole("button", { name: "Confirm" })).toBeFocused();
  await page.keyboard.press("Tab");
  await expect(dialog.getByRole("button", { name: "Cancel" })).toBeFocused();

  // Escape closes and returns focus to trigger
  await page.keyboard.press("Escape");
  await expect(dialog).toBeHidden();
  await expect(trigger).toBeFocused();
});
スキップリンクの検証
test("skip link moves focus to main content", async ({ page }) => {
  await page.goto("/");

  // First Tab should focus skip link
  await page.keyboard.press("Tab");
  const skipLink = page.getByRole("link", { name: /skip to (main|content)/i });
  await expect(skipLink).toBeFocused();

  // Activating skip link moves focus to main
  await page.keyboard.press("Enter");
  await expect(page.locator('#main, [role="main"]').first()).toBeFocused();
});

POUR 原則のリファレンス

原則注目領域テスト例
知覚可能代替テキスト、キャプション、コントラスト、構造画像の代替テキスト、色のコントラスト比
操作可能キーボード、フォーカス、タイミング、ナビゲーションTab の順序、フォーカスの可視性、スキップリンク
理解可能ラベル、説明、エラー、一貫性フォームのラベル、エラーメッセージ、予測可能な動作
堅牢有効な HTML、ARIA、名前/ロール/値セマンティックな構造、アクセシブルな名前

Axe-Core タグ

デフォルト:wcag2a、wcag2aa、wcag21a、wcag21aa、wcag22a、wcag22aa(WCAG 2.2 AA)。追加チェックには best-practice を使用します。タグの全一覧は references/axe-tags-reference.md を参照してください。


例外処理

例外が避けられない場合:

  1. 対象を限定する - 特定のコンポーネント/ルートのみ
  2. 影響を記録する - 該当する WCAG の達成基準、ユーザーへの影響
  3. 期限を設定する - 担当者と修正日
  4. チケットを追跡する - 修正課題へのリンク
// [no] Avoid: Global rule disable
new AxeBuilder({ page }).disableRules(["color-contrast"]);

// [ok] Better: Scoped exclusion with documentation
new AxeBuilder({ page })
  .exclude("#third-party-widget") // Known issue: JIRA-1234, fix by Q2
  .withTags(["wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "wcag22a", "wcag22aa"])
  .analyze();

トラブルシューティング

問題原因解決策
Axe で違反が 0 件と表示されるが、手動監査に不合格自動化でカバーできるのは約 30~40%手動テストのチェックリストを追加する
動的コンテンツで誤検知が発生するコンテンツが完全に描画されていないスキャン前に状態が安定するまで待つ
色のコントラストが誤って不合格になる背景画像/グラデーション既知の誤検知には exclude を使用する
ロールで要素を見つけられないセマンティック HTML が不足しているマークアップを修正する - これは実際のバグです
フォーカスが表示されない:focus スタイルが不足している視認できるフォーカスインジケーター CSS を追加する
ダイアログでフォーカスがトラップされないフォーカストラップのロジックが不足しているフォーカストラップを実装する(スニペットを参照)
スキップリンクが機能しない対象に tabindex="-1" がないメインコンテンツに tabindex を追加する

CLI クイックリファレンス

コマンド説明
npx playwright test --grep "a11y"アクセシビリティテストのみを実行する
npx playwright test --headedデバッグ用にブラウザーを表示して実行する
npx playwright test --debugInspector を使ってステップ実行する
PWDEBUG=1 npx playwright test一時停止を有効にしたデバッグモード

注意すべき兆候

  • axe スキャンで問題がないことを WCAG に完全準拠していると見なすこと — 自動化でカバーできるのは基準の約 30~40%のみです。
  • ルールを全体的に無効化すること(例:color-contrast)。チケットを記録したうえで、対象を限定した .exclude() を使用してください。
  • ページの状態が安定する前にスキャンすること — 非同期コンテンツによって、誤って「違反 0 件」と表示されます。
  • axe のテストに合格したからとキーボード/フォーカスのテストを省略すること — フォーカス順序とフォーカストラップには明示的なテストが必要です。

参考資料

ドキュメント内容
スニペット:セットアップとスキャンaxe-core のセットアップ、ヘルパー、スキャンのパターン
スニペット:キーボード、フォーカス、セマンティクスキーボード操作、フォーカス管理、セマンティックな構造
スニペット:視覚、名前、チェックリスト視覚的なアクセシビリティ、アクセシブルな名前、重要なページ
WCAG 2.2 AA チェックリストPOUR の原則に基づく手動監査チェックリスト
ARIA パターン:ウィジェット 1基礎、ダイアログ、タブ、メニューウィジェット
ARIA パターン:ウィジェット 2アコーディオン、コンボボックス、ライブリージョン、ツールチップ
ARIA パターン:誤りとリファレンスよくある ARIA の誤りとロールのクイックリファレンス

外部リソース

リソースURL
WCAG 2.2 仕様https://www.w3.org/TR/WCAG22/
WCAG クイックリファレンスhttps://www.w3.org/WAI/WCAG22/quickref/
WAI-ARIA オーサリングプラクティスhttps://www.w3.org/WAI/ARIA/apg/
axe-core ルールhttps://dequeuniversity.com/rules/axe/

検証

  • axe-core の監査に合格 — AxeBuilder.analyze() が重大な違反を 0 件返します
  • キーボード操作をテスト済み — すべてのインタラクティブ要素に Tab キーでアクセスでき、フォーカス順序が論理的です
  • 十分な色のコントラスト — WCAG 2.2 AA の最小コントラスト比を満たしています(通常のテキストは 4.5:1、大きなテキストは 3:1)
  • WCAG 2.2 AA に準拠 — スキャンに wcag22a/wcag22aa タグが含まれています(フォーカスが隠れないこと、ドラッグ操作、ターゲットサイズの最小値)

コメント