動的セレクタの使用
動的に生成されたID、クラス、URLを持つページでアクセシビリティの問題を適切に追跡するためにAxe Watcherを設定する
ページ読み込みごとに動的な要素IDやクラス名を生成するページをテストする際、Axe Watcherはテスト実行間でアクセシビリティの問題が重複しているかどうかを追跡するのが難しい場合があります。この記事では、これらのシナリオを正確に処理するためにWatcherを設定する方法を説明します。動的URLは別の理由で同じ症状を引き起こし、修正方法が動的URLで取り上げられています。
動的セレクタの問題
デフォルトでは、Axe Watcherは、アクセシビリティ問題がどこで発生しているかを識別するために、要素IDやクラスを含むCSSセレクタを使用します。例えば、次のような場所で問題が報告されることがあります。
iframe#main-iframeこの方法は、ページのIDやクラスがページの読み込み間で一貫している場合によく機能します。しかし、多くの最新のWebアプリケーションは、ページのレンダリングごとに変更される動的な識別子を生成します。例えば:
#component-a1b2c3d4.form-field-xyz789
Axe Watcherは各要素のXPathも送信し、Axe Developer Hubはいずれかのセレクターで一致するものを同じ要素として扱います。XPathにはクラス名が含まれないため、クラス名のみが動的なページは特に設定を行わなくても正しく追跡されることが多いです。しかし、XPathにはページ上で一意のIDが含まれるため、//div[@id='component-a1b2c3d4']のようなパスを生成します。したがって、動的IDはCSSセレクターとXPathを同時に変化させ、一致させるための安定した基準がなくなります。
このようにしてテスト実行間で識別子が変わると、Axe Watcherは問題が以前に検出された問題の重複であるのか、新しい発生であるのかを判断することができません。これにより次のような結果が生じる可能性があります。
- 各テストランで、同じ問題が「新規」と「解決済み」の両方として報告される
- アクセシビリティの進捗状況の追跡が不正確になる
- 実際に修正された問題を特定するのが困難
解決策:系統トラッキングを有効にする
動的セレクタを処理するためには、ancestryオプションをあなたのrunOptions設定でtrueに設定してください。有効にすると、Axe WatcherはIDやクラスに頼るのではなく、DOMツリー内の要素の位置を使用して要素をテストランの間で特定します。
ancestryが有効な場合、以前はこのように見えたセレクタが:
iframe#main-iframe代わりにルート要素からの完全なパスを含むようになります:
html > body > div:nth-child(20) > div:nth-child(1) > div > div > ul > li:nth-child(1) > div > span > iframeこの位置セレクタは、IDやクラスが変化してもページの読み込み間で一貫性を保ち、Axe Watcherが重複する問題を正確に追跡できるようにします。
設定例
JavaScriptとTypeScript
ancestryオプションをあなたのaxe設定のrunOptionsに追加してください。
const config = {
axe: {
apiKey: process.env.ACCESSIBILITY_API_KEY,
projectId: process.env.PROJECT_ID,
runOptions: {
ancestry: true
}
}
}Java
AxeRunOptionsオブジェクトでsetAncestry()メソッドを使用してください。
AxeRunOptions runOptions = new AxeRunOptions()
.setAncestry(true);
AxeWatcherOptions options = new AxeWatcherOptions()
.setApiKey(System.getenv("ACCESSIBILITY_API_KEY"))
.setProjectId(System.getenv("PROJECT_ID"))
.setRunOptions(runOptions);
AxeWatcher watcher = new AxeWatcher(options);系統トラッキングを使用する時
アプリケーションが以下の条件を満たすとき、ancestry: trueを有効にします:
- フレームワークを使用して動的コンポーネントIDを生成する場合(React、Vue、Angular)
- CSS-in-JSライブラリを使ってユニークなクラス名を生成する場合
- 自動生成された識別子を持つフォームフィールドや対話型要素がある場合
- 同じ問題のように見えるものについて、テストラン間で「新しい問題」と「解決された問題」のカウントが一致しない場合
考慮すべきトレードオフ
系統トラッキングは動的セレクタの問題を解決しますが、いくつか考慮すべき点もあります:
- セレクタの可読性: 位置セレクタは長くなり、Axe Developer Hubで問題をレビューする際に読みづらくなる可能性があります。
- DOM構造の感受性: ページのDOM構造が大幅に変更された場合(ID/クラスだけでなく)、位置セレクタも変更される可能性があります。
- デバッグ: 問題の調査時に、DOMツリー内の位置よりも意味のあるIDで要素を見つけるほうが簡単な場合があります。
動的識別子を持つほとんどのアプリケーションでは、正確な問題追跡の利点はこれらのトレードオフを上回ります。
動的URL
要素セレクターは、Axe Developer Hubが問題を特定する方法の一部に過ぎません。ページのURLも完全に比較され、クエリ文字列も含まれます。ancestryを有効化しても、この比較には影響しません。
テスト実行間でURLが変動する場合、動的セレクターと同じ症状を引き起こし、より積極的にそうします。URLが以前に見られたことがない場合、それに発見されたすべての問題は、新しいものとして報告され、要素セレクターは全く考慮されません。一般的な原因には以下が含まれます。
- クエリ文字列に含まれるセッションIDや認証トークン
- タイムスタンプやキャッシュ破壊パラメーター、例としては
?v=1738012800 /orders/8f3c1b2a/summaryのようなパス内のランダム化ID- テスト実行ごとに新しいレコード、したがって新しいURLを生成するテストフィクスチャ
比較の前にURLを正規化する設定オプションはないため、これはテストスイートで解決する必要があります。決定論的なURLにナビゲートして、同じページが毎回同じURLを生成するようにする必要があります。実際には、固定されたテストデータをシードすることで、新しいレコードの生成を防ぎ、ページスキャン前に変動するクエリパラメーターを削除または固定することが一般的です。
URLがどうしても安定化できない場合は、ページ自体は正しく追跡されるのではなく、全くスキャンされなくなるという意味になりますが、excludeUrlPatternsで結果から完全に除外することができます。詳細についてはURLを解析から除外するをご覧ください。
参照資料
- JavaScriptとTypeScriptのAPIリファレンス
runOptionsおよびその他の構成オプションの完全なドキュメント AxeRunOptionsクラス ランタイムオプションのJava APIリファレンス- 用語集: 重複 Axe Developer Hubがどのように重複する問題を特定するかの理解
