エンジンオプション

どのランナー(runDomRulesInPage、runa11yCoreInPage)も、同じ4つの引数(pageUrl, contextSelector, engineOptions, runOnly)を取ります。このページではengineOptionsとrunOnlyのすべてを説明します。ページをWCAGのバージョンとレベルに照らしてチェックするには、まずrunOnly.wcagから始めてください。

実行するルールの選択

何に照らしてテストするかを指定すれば、エンジンがルールを選びます。何も選択しなければ、既定のルールが実行されます。既定のルールとは、規格やパックのオプトインルールを除くすべてのルールです。オプトインルールは有効にしたときにだけ実行されます(オプトインルールを参照)。

実行するもの渡すもの
既定のルール:有効にしていないオプトインルールを除くすべてのルール何も渡さない:runOnlyはnull
WCAGの適合性の目標:あるバージョンの、あるレベル以下の達成基準のルールrunOnly: { wcag: { version: '2.2', level: 'AA' } }
同じものと、WCAGの達成基準を検査しないベストプラクティスのルールrunOnly: { wcag: { version: '2.2', level: 'AA' }, bestPractices: true }
ベストプラクティスのルールだけrunOnly: { bestPractices: true }
WCAGを基にした規格(EN 301 549、Section 508)engineOptions: { profile: 'en301549-v4.1.1' }
同じものと、ベストプラクティスのルールengineOptions: { profile: 'en301549-v4.1.1' }、runOnly: { bestPractices: true }
// WCAG 2.2 AA, with the best practices:
runDomRulesInPage(url, null, {}, {
wcag: { version: '2.2', level: 'AA' },
bestPractices: true
});

どのルールもWCAGの達成基準を検査するか、ベストプラクティスであるかのどちらかです。そのため{ wcag: { version: '2.2', level: 'AAA' }, bestPractices: true }は、WCAG 2.2で削除された4.1.1「構文解析」のルールを除くすべてのルールを実行します。1つの達成基準、ルールのリスト、除外など、より細かい指定は「高度な選択:タグとルールID」を参照してください。それらのフィールドは上のものと組み合わせられます。ルールを指定するスキャンは、それらが検査する達成基準も報告します(「スキャンが報告する達成基準」)。

WCAGの目標で選ぶ(runOnly.wcag)

runOnly.wcagはWCAGのバージョンと適合レベルを指定し、その目標の達成基準のルールを選択します。

// WCAG 2.2 Level A and AA:
runDomRulesInPage(url, null, {}, { wcag: { version: '2.2', level: 'AA' } });
  • versionは'2.0'、'2.1'、'2.2'のいずれか、levelは'A'、'AA'、'AAA'のいずれかです(大文字小文字は問いません)。
  • ルールが選択されるのは、それが示す達成基準のいずれかが目標に含まれる場合です。つまり、そのバージョンで有効であり(そのバージョンまでに導入され、そのバージョンまでに削除されていない)、達成基準がそのバージョンで持つレベルで、目標のレベル以下である場合です。レベルは@surea11y/core/wcagのWCAG_CRITERIAから取得され、バージョンごとのレベルを持ちます。
  • そのため、2.2で削除された4.1.1「構文解析」は、{ version: '2.1' }の目標には含まれ、{ version: '2.2' }の目標には含まれません。duplicate-idは前者では実行され、後者では実行されません。バージョンのタグでは後者でも実行されます。
  • どの達成基準も示さないルール(ベストプラクティスのルール)は、どの目標にも含まれません。それらはbestPractices: true(次の節)で、個別のルールはtagsかincludeRuleIdsで追加してください。wcagと併用すると、これらはすべてルールを追加で選択し、目標のルールとそれらが選択するものの和集合になります。excludeTags、excludeRuleIds、excludeTestIdsは、いつもどおりその後に適用されます。
  • engineOptions.wcagVersionが設定されていない限り、目標のバージョンが実行のWCAGの対象(engine.wcagVersion)になります。目標のレベルは、レベルのタグと同じように、報告されるWCAGの集約を決めます。ただしengineOptions.wcagLevelが設定されている場合は別です(「チェックを指定するスキャンのレベルを示す」)。
  • 目標はルールを含めるものなので、tagsと同じくengineOptions.profileの代わりにルールを選択します。getProfileWcagTarget(profile)はプロファイルが相当する目標を返し(「適合性プロファイル」を参照)、getChecksForRunOnly(runOnly, engineOptions)はwcagを持つrunOnlyが実行するルールを、getRulesForRunOnly(runOnly, engineOptions)はそれが報告する集約を列挙します。
  • それ以外の値は、何が誤っているかを示してINVALID_RUN_ONLYを投げます。runOnly.wcag.version must be "2.0", "2.1" or "2.2", not "3.0".
// WCAG 2.1 AA, plus the best-practice rules, without one of them:
{ wcag: { version: '2.1', level: 'AA' }, tags: ['best-practice'], excludeRuleIds: ['region'] }

ベストプラクティスを追加する(runOnly.bestPractices)

bestPractices: trueはベストプラクティスのルールを選択します。region、landmark-one-main、heading-order、page-has-heading-one、skip-link、tabindex、image-redundant-altなど、WCAGの達成基準を示さないルールです。これらはbest-practiceのタグを持つルールなので、そのタグを追加するのと同じです。これらのルールの検出結果は望ましい実践についてのもので、WCAGの不合格ではありません。どのWCAGの集約もそれを算入しません。ほとんどはcantTellを報告しますが、検出結果そのものがバリアであるものはfailを報告します。名前のない見出しに対するempty-headingがそうです。

  • wcag、tags、ルールIDと併用すると、それらが選択するものにこれらのルールを追加します。除外はその後に適用されるため、excludeRuleIds: ['region']は引き続きregionを除きます。
  • 単独で使うと、ベストプラクティスのルールだけを選択します。
  • falseまたは省略した場合は何も追加しません。単独の{ bestPractices: false }は空の選択なので、{}と同じく既定のルールが実行されます。
  • それ以外の値はINVALID_RUN_ONLYを投げます。runOnly.bestPractices must be true or false, not "yes".
  • engineOptions.profileと併用すると、プロファイルのルールにベストプラクティスのルールを追加し、プロファイルも引き続き適用されます。そのルール、集約、対応付け、engine.profileは、併用しない場合と同じです。profile: 'en301549-v4.1.1'と{ bestPractices: true }を指定すると、その規格とベストプラクティスが実行されます。ベストプラクティスのルールはWCAGの達成基準を検査しないため、プロファイルのどの集約にも算入されません。
// WCAG 2.1 AA and the best practices, without one of them:
{ wcag: { version: '2.1', level: 'AA' }, bestPractices: true, excludeRuleIds: ['region'] }

適合性プロファイル

engineOptions.profileは、タグセットを書き出す代わりに適合性の目標を名前で指定します。

プロファイル実行するルールのタグWCAGの対象getProfileWcagTarget理由
wcag22-aawcag2a, wcag2aa, wcag21a, wcag21aa, wcag22a, wcag22aa2.2{ version: '2.2', level: 'AA' }WCAG 2.2のレベルAとAA
en301549-v4.1.1wcag22-aaと同じ2.2{ version: '2.2', level: 'AA' }EN 301 549 V4.1.1の第9章はWCAG 2.2のAとAAを再掲しています
en301549-v3.2.1wcag2a, wcag2aa, wcag21a, wcag21aa2.1{ version: '2.1', level: 'AA' }EN 301 549 V3.2.1の第9章はWCAG 2.1のAとAAを再掲しています(4.1.1構文解析を含む)
section508wcag2a, wcag2aa2.0{ version: '2.0', level: 'AA' }改訂版のSection 508基準はWCAG 2.0のAとAAを取り込んでいます

getProfileWcagTarget(profile)は、プロファイルのタグセットが相当するrunOnly.wcagの目標を返し、プロファイルでない名前にはnullを返します。プロファイルは引き続き表のとおりタグで選択します。wcag22-aaではduplicate-id(4.1.1)が実行されてfailにはならず、{ wcag: getProfileWcagTarget('wcag22-aa') }ではそれが除かれます。

runDomRulesInPage(url, null, { profile: 'en301549-v3.2.1' }, null);
非推奨

en301549-v4.1.1とen301549-v3.2.1はEN 301 549のパック@surea11y/pack-en301549に移り、core 2.0.0で削除されます。それまでは従来どおり動作し、プロセスごとに1回console.warnを出します。パックを渡すと(packs: [en301549])、スキャンは同じ名前をパックから取り、通知は出しません。パックのプロファイルは、WCAGの集約の代わりに条項ごとに結果を1つ報告します。coreが規格を非推奨にする手順を参照してください。

パックの規格やチェックリストは、独自のプロファイルをこの一覧に加えます。

WCAGの対象バージョンは、手書きのタグセットと同じようにタグから決まります(後述の「WCAGバージョンによる絞り込み」を参照)。そのためen301549-v3.2.1はWCAG 2.1を、en301549-v4.1.1はWCAG 2.2を対象にします。en301549-v3.2.1では重複したidが今もfailになりえます。そのプロファイルが4.1.1の文言を維持するためです(keepsParsing、後述)。en301549-v4.1.1ではなりません。パックのプロファイルは、代わりにwcagVersionで自身のバージョンを示せます(パック)。規格が対応付けたルールだけを実行するプロファイルには、バージョンを示すWCAGのタグがないためです。名前の大文字と小文字は区別しません。プロファイルを使った実行は、それをengine.profileとして返します。

優先順位:ルールを含める指定はすべて、プロファイルの代わりにルールを選びます。wcag、tags、includeRuleIds、includeTestIdsを持つrunOnly、またはengineOptions.rules/.tags/.testsのincludeです。除外はプロファイルの上に引き続き適用されます。runOnlyの除外(excludeTags、excludeRuleIds、excludeTestIds。そのためバインディングのdisableTags()はプロファイルを置き換えるのではなく絞り込みます)でも、runOnlyのフィルターがない場合のengineOptionsの除外(tags.exclude、rules.exclude、tests.exclude)でも同じです。また、明示的なengineOptions.wcagVersionは、プロファイルが示す、または指定するバージョンより常に優先されます。効果のないプロファイル(不明な名前や、上記のように上書きされたもの)はエラーではありません。実行は指定がなかったものとして続き、理由を示すconsole.warnを出力し、engine.profileは含まれません。runOnly.bestPractices: trueはこの種の「含める」指定ではありません。プロファイルのルールにベストプラクティスのルールを追加し、プロファイルは適用されます(「ベストプラクティスを追加する」)。

規格のプロファイルは、その規格がWCAGの達成基準を免除したり、WCAGのチェックを独自のものに置き換えたりする場合に、ルールを除外することもあります。プロファイルが指定するルール、すべての達成基準が免除されるルール、免除された達成基準のWCAGの集約は実行されず、ルールカタログからも除かれます。プロファイルが残す達成基準も検査するルールは引き続き実行され(2.4.4を免除するプロファイルのもとで、2.4.4と4.1.2を検査するlink-name-present)、engine.profileExcludesが除外したものを示します。現在、何かを除外する組み込みのプロファイルはありません。

プロファイルが選ぶのは、実行するルールだけです。それらに合格すれば名前の由来となった規格を満たすかどうかについては何も示しません。ほとんどの達成基準には、自動化されたルールでは扱えない人の判断が必要です(このエンジンにはわからないことを参照)。

EN 301 549のプロファイルは、mappings: ['en301549:V4.1.1'](またはV3.2.1)を渡したのと同じように、対象バージョンのEN 301 549の条項も有効にします。後述の「ほかの規格」を参照してください。どの規格のプロファイルも、同じように自身のバージョンを有効にします。mappedRulesを持つプロファイルは、タグにかかわらず、その規格が対応付けられているルールも実行します。heading-orderやskip-linkのようにWCAGとの対応付けがないルールには、選択に使えるWCAGのタグがないためです。独自の要件を持つ規格や組織のチェックリストは、パックとしてエンジンに加わり、独自のプロファイル名、ルール、集約を持ち込みます。エンジン自体にそのような規格は同梱されていません。

オプトインルール

一部のルールは、WCAGが求めていない、規格独自の要件を確認します。例えば国内規格がdoctypeを求めたり、bgcolorのような表示用の属性を禁止したりする場合です。そのようなルールのfailはその規格の不合格であってWCAGの不合格ではないため、これらのルールはデフォルトでは無効です。各ルールは規格のルールタグを持ち、選択がそれを求めたときだけ実行されます。

  • そのタグを含む、規格のプロファイルによって
  • そのタグによって(tags: { include: '<tag>' }。単独でもほかと組み合わせても)
  • そのidによって(rules: { include: '<rule id>' }、またはrunOnly.includeRuleIds)
  • そのルールをまとめる、規格独自の集約のidによって(rules: { include: '<rollup id>' }は、オプトインかどうかにかかわらず、その集約のルールを実行します)
  • 後述のengineOptions.optInRulesで解除することによって

それ以外ではオプトインルールは選ばれません。デフォルトの実行、WCAGのタグセット、WCAGやEN 301 549のプロファイル、WCAGの集約のidのどれでもありません。除外はほかのルールと同じように適用されます。タグだけを選ぶと、その規格独自のルールは実行されますが、その規格が対応付けられているWCAGのルールは実行されません。つまり「その規格がWCAGを超えて何を求めるか」には答えますが、その規格に対する監査にはなりません。監査には規格のプロファイルを使ってください。タグだけの場合、規格独自の集約は、ルールが実行されなかった要件についてcantTellを報告します。そのタグを持つ、customRulesで追加したルールも同じ制限に従います。現在、エンジンに組み込まれた規格にオプトインルールを持つものはありません。パックの名前空間のタグはこのように働きます。

すべてのルールを実行する(optInRules)

どの規格に属するかにかかわらずエンジンのすべてのルールを実行するには、プロファイルを省き、オプトインルールを解除します。

runDomRulesInPage(url, null, { optInRules: 'all' }, null);

'all'はすべての規格のオプトインルールを解除し、タグのリストを渡すとそのタグのルールだけを解除します。解除するのは制限だけで、どのルールを実行するかは引き続きほかの選択が決めます。そのため、上のようにフィルターもプロファイルもなければ、すべてのルールとすべての規格の集約が実行されます。profile: 'wcag22-aa'の下では、オプトインルールはWCAGのタグを持たないため、実行されるのは引き続きWCAGのルールだけです。除外は通常どおり適用されます。オプトインのタグでないタグはconsole.warnを出して無視します。解除できるのはこのエンジンオプションだけです。runOnlyにはoptInTagsキーがないため、そこに渡すと未知のキーとなり、単独ならINVALID_RUN_ONLYを投げ、runOnlyが読むキーと並んでいれば警告を出して無視されます。メッセージはengineOptions.optInRulesを案内します。

これは、開発中やサイトを調べるときに、エンジンが報告できるものをすべて見るためのものです。適合性の目標ではありません。このような実行は、WCAGが認めていてほかの規格だけが禁じていることでもページを不合格にします。結果はそれを示します。engine.optInRulesは実行されたルールのタグを列挙し、HTMLレポート、SARIF、JUnitはそれをプロファイルの横に表示します。結果にほかの規格の番号は追加しません。そのためにはmappingsを渡してください。例えば{ optInRules: 'all', mappings: ['<key>'] }です。

ほかの規格(mappings)

各結果のmeta.normativeMappingsは、それが確認するWCAGの達成基準を示します。engineOptions.mappingsは、それぞれに対応するほかの規格の要件を追加します。デフォルトでは何も追加しません。監査の対象でない規格の条項は、SARIFのタグ、JUnitのプロパティ、レポートのすべてでノイズになるからです。

値追加されるもの
'en301549'各達成基準に対応するEN 301 549第9章の条項(それを含むすべてのバージョン:V3.2.1とV4.1.1)
'en301549:V3.2.1', 'en301549:V4.1.1'同じものを、そのバージョンだけについて
runDomRulesInPage(url, null, { mappings: ['en301549:V3.2.1'] }, null);
非推奨

en301549の対応付けはEN 301 549のパック@surea11y/pack-en301549に移り、core 2.0.0で削除されます。それまでは従来どおり動作し、プロセスごとに1回console.warnを出します。パックを渡すと、mappings: ['en301549']は同じ名前で、すべての結果に同じエントリーを付け、通知は出しません。

配列またはカンマ区切りの文字列を受け付け、名前とバージョンの大文字と小文字は区別しません。profile: 'en301549-v4.1.1'の下ではV4.1.1の条項は指定しなくても含まれ、mappingsでさらに追加できます。エンジンに表がない名前やバージョンはconsole.warnを出して無視します。ほかの規格を含む実行は、それを正規の表記でengine.mappingsに示します(["en301549:V3.2.1"]、すべてのバージョンなら["en301549"])。

変わるのは結果が示す内容だけで、実行されるルールやその判定結果は変わりません。ルールカタログも同じオプションに従います。getChecksCatalog(engineOptions)、getCheckDefById(ruleId, engineOptions)、getChecksForRunOnly(runOnly, engineOptions)、getRulesCatalog(engineOptions)、getRulesForRunOnly(runOnly, engineOptions)、getCompositeRuleById(id, engineOptions)は、そのオプションでスキャンした場合と同じ規格を(適用される場合はプロファイルも含めて)示すため、カタログのエントリーと結果は常に一致します。オプションがなければ、WCAGだけを示します。customRulesで追加したルールは、宣言した対応付けをそのまま保ちます。条項の内容と2つのバージョンの違いはWCAG適合性との対応を参照してください。

高度な選択:タグとルールID

以下のフィールドは、ルールが持つタグとルールIDで選択します。1つの達成基準(tags: ['wcag1412'])、ルールのリスト、除外、独自のタグセットなど、WCAGの目標とbestPracticesでは表せないものに使ってください。これらはwcagやbestPracticesと組み合わせられます。含めるものはそれらが選択するものに追加され、除外するものはその後に取り除かれます。

指定する方法は互いに独立して2つあります。第4引数(runOnly)と、engineOptions.rules/.tags/.tests/.includeModeです。runOnlyにフィルターが1つでも含まれていればそちらが無条件に優先され、そうでなければエンジンはengineOptionsを使います。両方が適用されると期待して混在させないでください。どちらか一方を選びます。engineOptions.rules、.tags、.testsは{ include, exclude }を受け取ります。リストや文字列をそのまま渡すと、含めるリストになります。

runOnly(第4引数)で指定する

runDomRulesInPage(url, null, {}, {
includeRuleIds: ['img-alt-present', 'button-name-present'],
excludeRuleIds: ['region'],
tags: ['wcag412'],
excludeTags: ['best-practice'],
includeMode: 'and' // 'and' (default) | 'or' — see below
});

単なる配列や文字列も省略形として使えます。runOnly: ['img-alt-present', 'button-name-present']はそれらのルールを実行し(複合ルールのIDはその構成ルールを含みます)、runOnly: ['wcag2a', 'wcag2aa']は{ tags: ['wcag2a', 'wcag2aa'] }と同じ意味になります。1つの配列にルールIDとタグを混ぜることはできません。また、どの値もルール(組み込み、複合、またはengineOptions.customRulesのいずれか)かタグを指している必要があります。それ以外の値があると例外を投げるので、タイプミスのせいですべてのルールが、あるいはどのルールも、気づかれないまま実行されることはありません。IDとタグを組み合わせたり除外したりするには、オブジェクト形式を使ってください。1.10.0より前は、単なる配列は無視され、すべてのルールが実行されていました。

フィールド型意味
wcag{ version, level }WCAGの適合性の目標です。そのバージョンの、そのレベル以下の達成基準のルールを実行します。前述の「WCAGの目標で選ぶ」を参照してください。
bestPracticesbooleantrueにするとベストプラクティスのルールを追加します。前述の「ベストプラクティスを追加する」を参照してください。
includeRuleIdsstring[]これらのルールIDだけを実行します(複合ルールのIDの場合は、その子であるアトミックルールも実行します)。
excludeRuleIdsstring[]これらは実行しません。includeの後に適用されます。
includeTestIds / excludeTestIdsstring[]照合の仕方は上と同じです。ルールは内部で「テスト」(実行可能な最小単位)と呼ばれているため別のフィールドとして残されていますが、現在の機能はincludeRuleIds/excludeRuleIdsとまったく同じです。
tagsstring[]これらのタグを少なくとも1つ持つルールだけを実行します(例:wcag412、wcag2aa、best-practice)。
excludeTagsstring[]これらのタグのいずれかを持つルールは実行しません。includeの後に適用されます。
includeMode'and' | 'or'IDによるincludeとタグによるincludeを両方指定した場合の扱いです。'and'(デフォルト)ではルールが両方を満たす必要があり、'or'ではどちらかを満たせば実行されます。一方の軸しか使わない場合は関係ありません。

いずれも配列とカンマ区切りの文字列のどちらでも指定でき、後述のengineOptionsの形式と揃えてあります。includeRuleIds: 'img-alt-present, button-name-present'とincludeRuleIds: ['img-alt-present', 'button-name-present']は同じ意味です。

名前は、ここでも後述のengineOptions.rules/.tagsでも検証されます。含めるリスト(includeRuleIds、includeTestIds、tags、旧来のvalues、rules.include、tags.include)のどの値もルールやタグ(ルールか集約が持つもの。そのため、集約だけが持つ規格のタグも既知です)を指していない場合は、code: 'INVALID_RUN_ONLY'と、フィールドと値を示すメッセージを伴う例外を投げます。そのままでは何も選ばれず、ルールを1つも実行しない実行は問題のないスキャンのように見えてしまうからです。名前はすべて存在するのに、部分どうしが打ち消し合う選択(含めると同時に除外されたルールや、includeMode: 'and'のもとで共通するルールのないルールとタグ)も、ルールを1つも実行しません。スキャンはその部分を示して警告し、strictOptionsのもとではINVALID_RUN_ONLYを投げます。includeModeは'and'か'or'です。それ以外の値は警告を出して'and'として読まれ、strictOptionsのもとではエラーを投げます。ブラウザーのバインディングでは.includeMode('or')で設定します。何も指していない値でも、ほかに有効な値と並んでいる場合や除外リストにある場合は、console.warnを出したうえで無視されます。1.10.0より前は、こうした値はすべて何の通知もなく無視されていました。

WCAGのバージョンとレベルを表す9つのタグ(wcag2aからwcag22aaaまで)は、ルールが持っているかどうかにかかわらず常に既知です。現在、ルールを1つも持たないものがあります(wcag21aaa、wcag22a、wcag22aaa)。それらの達成基準には自動化されたルールがないためで、タイプミスではありません。含めるリストでほかの値と並んでいる場合、このようなタグは警告ではなくconsole.infoで注記されます。

[surea11y] runOnly.tags: no rules for WCAG 2.2 Level A ("wcag22a"); its criteria need manual review.

engineOptions.logUntestedWcag: falseにすると、この行は出力されません。含めるリストのすべての値がこのようなタグの場合は何も実行されないため、理由を示して引き続きINVALID_RUN_ONLYを投げます。独自にルールを選択するrunOnly.wcagの目標やbestPractices: trueと併用した場合は、注記だけになります。除外リストでは何もしません。

ルールIDにはエンジンのプレフィックスを付けません(例:'img-alt-present')。後方互換性のため、同じIDに旧来のa11ycore-プレフィックスを付けた形式('a11ycore-img-alt-present')も照合できます。IDはタグと同じく大文字小文字を問わずに照合されます。'IMG-ALT-PRESENT'はimg-alt-presentを選択し、これはルールを指定するすべてのリスト(各形式のrunOnly、engineOptions.rulesとengineOptions.tests、含めるものと除外するもの)で同じです。大文字小文字だけが違うIDを持つルールはないため、誤ったルールが選ばれることはありません。

runOnlyの値全体として、{ type, values }形式も受け付けます。{ type: 'tag', values: ['wcag2a', 'wcag2aa'] }は{ tags: ['wcag2a', 'wcag2aa'] }と、{ type: 'rule', values: ['img-alt-present'] }は{ includeRuleIds: ['img-alt-present'] }と同じ意味です('tags'と'rules'も使えます)。valuesはカンマ区切りの文字列でもよく、その名前はほかのルールIDやタグと同じように検証され、並べて指定したほかのキー(excludeTags、excludeRuleIdsなど)も引き続き適用されます。名前のSetは、それが持つリストとして読まれます。オブジェクト形式が読むキーと並んでいる、読まないキーは、警告を出して無視されます。それ以外のtypeはINVALID_RUN_ONLYを投げます。数値や真偽値のrunOnlyや、エンジンが読むキーを1つも持たないオブジェクト({ includeRuleId: [...] })も同様です。これらはいずれも、以前はすべてのルールを実行していました。空の配列、文字列、オブジェクトは、これまでどおり既定の選択を意味します。

スキャンが報告する達成基準

スキャンは、選択がその達成基準の集約(rulesResults)を選択する場合に、それを報告します。WCAGの目標やバージョンとレベルのタグ、プロファイル、集約自身のID、または選択なしがそうです。さらに、選択が単独で指定したルールが実行された場合は、そのルールが検査する各達成基準の集約も報告します。単独で指定するとは、次のいずれかです。

  • IDによって(includeRuleIds、includeTestIds、rules.include、またはプロファイル自身のルールのリスト)
  • WCAGのタグでないタグによって(カスタムルール、パック、規格のタグ。WCAGのタグとは、バージョンとレベルのタグ、wcag244のような達成基準のタグ、wcag22-removedなので、wcagteamのような独自のタグはWCAGのタグではありません)
  • optInRulesによって
  • ベストプラクティスのルールとして(bestPractices)

規格のプロファイルが、その規格が対応付けているという理由だけで実行するルール(mappedRules)は、単独ではなくその規格のために指定されたものです。規格の要件は追加しますが、WCAGの達成基準は追加しません。そのため、規格が求めるものだけを実行するプロファイルは、その規格だけを報告します(パック)。プロファイルのrulesリストが指定するルールは、そのWCAGの達成基準も追加します。1.12.0より前は、達成基準ではなくルールを指定したスキャンのrulesResultsは空でした。

// The unnamed link fails link-name-present, and with it 2.4.4 and 4.1.2:
runDomRulesInPage(url, null, {}, { includeRuleIds: ['link-name-present'] });
// rulesResults: wcag-2.4.4-link-purpose-in-context: fail, wcag-4.1.2-name: fail
  • 判定は集約自身のものです。不合格のルールは達成基準を不合格にします。スキャンがその達成基準のほかのルールを除いた場合、合格したルールがあっても達成基準は合格になりません。reasonCodeがcomposite.rollup.cantTell.notSelectedChildのcantTellになり、スキャンが選択しなかった各ルールは、貢献したルールの中にnotSelected: true付きのmissingとして列挙されます。すべてが選択されて合格しても、WCAGの達成基準はcantTell(composite.rollup.cantTell.partialCheck)のままです。どの達成基準についても、そのルールはまだ求められることのすべてをチェックしていないためです(WCAG適合性との対応を参照)。HTMLレポートはその下に「一部のみ確認」と、選択されなかったチェックの件数を表示します。出力スキーマを参照してください。
  • 達成基準のタグは、その達成基準自身を指定します。tags: ['wcag244']は2.4.4を報告し、そのルールが検査するほかの達成基準(link-name-presentなら4.1.2)は報告しません。集約のID、WCAGの目標、バージョンやレベルのタグ、WCAGのプロファイルによって加わったルールは、達成基準を追加しません。そこでは選択自体が達成基準を指定しているからです。そのため、達成基準を選択するスキャンの報告は以前と変わりません。
  • 実行のWCAGのバージョンとレベルが適用されます。達成基準が追加されるのは、engine.wcagVersionで有効な場合(duplicate-idだけでは2.2で4.1.1は追加されず、wcagVersion: '2.1'なら追加されます)、かつ目標と同じように実行のレベル以下の場合だけです。レベルは、指定されていればengineOptions.wcagLevel(次の節)、なければ選択が与えるレベル(runOnly.wcag.level、またはルールIDと並べたバージョンとレベルのタグ)です。どちらもなければ、すべてのレベルが報告されます。
  • 除外が適用されます。選択が除外する集約(excludeRuleIds: ['wcag-4.1.2-name']、またはタグ)は追加されません。呼び出し側が除外したルールは選択されなかったものとして扱われます。プロファイルが除外するルールは達成基準を狭めます。そのルールはnotSelectedなしのmissingになり、プロファイルが免除する達成基準は決して追加されません。
  • 規格独自の集約(要件ごとに1つ)も同じように追加されますが、その規格が対象になっている場合だけです。適用されたプロファイルがその規格を対象とするか、選択がそのタグを指定するか、optInRulesがそれを解除している場合です。WCAGのスキャンに、誰も求めていない規格の要件が表示されることはありません。適用されなかったプロファイルや、mappingsだけでは、規格は対象になりません。その規格のプロファイルのもとではプロファイルのバージョンだけが追加され、プロファイルなしで解除した場合は、タグで選択したスキャンと同じくすべてのバージョンが追加されます。これは組み込みの規格やチェックリストと同じく、パックのものにも当てはまります。ルールを指定するチェックリストのプロファイル(tags: []、rules: [...])は、それらのWCAGの達成基準と自身の項目を得ます。
  • スキャン前の一覧。getRulesForRunOnly(runOnly, engineOptions)は、その選択とオプションでのスキャンが報告する集約を、追加されるものも含めてgetRulesCatalogのエントリーとして列挙します。スキャン自身の集約の処理で求めるため、両者は一致します。ルールを列挙するのはgetChecksForRunOnlyです。getRulesCatalog(engineOptions)は、選択にかかわらず、そのオプションで利用できるすべての集約を列挙します。ツールは、スキャンを実行する前に何を検査するかを記録できます。ブラウザーのバインディングのビルダーは、同じ一覧をplannedChecks()とplannedCriteria()として提供します。

チェックを指定するスキャンのレベルを示す(wcagLevel)

WCAG 2.2 AAを意図し、一部のチェックだけを実行するスキャンは、それらのチェックを指定し、バージョンをengineOptions.wcagVersionで示します。これではレベルが示されないため、それらのチェックの達成基準はすべてのレベルで報告されます。contrast-computableは1.4.3(AA)と1.4.6(AAA)を検査するので、両方が報告されます。engineOptions.wcagLevelはレベルを示します。

// Only the contrast checks of a WCAG 2.2 AA scan: 1.4.3 is reported, 1.4.6 is not.
runDomRulesInPage(url, null,
{ wcagVersion: '2.2', wcagLevel: 'AA' },
{ includeRuleIds: ['contrast-computable'] });
  • 値。'A'、'AA'、'AAA'のいずれかで、大文字小文字は問いません。それ以外の値はconsole.warn(engineOptions.wcagLevel: ignoring "AA+"; use "A", "AA" or "AAA". ...)を出して無視され、strictOptionsのもとではINVALID_ENGINE_OPTIONSを投げます。実行は有効なレベルを'A'、'AA'、'AAA'の表記でengine.wcagLevelとして報告します。オプションがない場合、engine.wcagLevelは選択が示すレベルで、何も示さなければ含まれません。
  • 決めるのは何を報告するかで、何を実行するかは決して決めません。何を実行するかは、オプションがない場合と同じく選択が決めます。選択が指定した、そのレベルより上のチェックも実行され、自身の結果を報告します。rulesResultsから除かれるのは、そのレベルより上の達成基準だけです。
  • 指定したチェックのために追加された達成基準だけでなく、すべてのWCAGの集約に適用されます。全体のスキャン、プロファイル、タグによる選択でwcagLevel: 'AA'を指定すると、AAAの達成基準はrulesResultsから除かれますが、それらのチェックは引き続き実行され、checksResultsで報告されます。これはwcagVersionとは異なります。wcagVersionは選択が選んだ集約を決して除きません。2.2のスキャンは引き続き4.1.1を報告し、そのルールはcantTellに強制変換されます。オプションのないスキャンの報告は以前と変わりません。
  • 選択が示すレベルより優先されます(runOnly.wcag.level、またはバージョンとレベルのタグが示す最も高いレベル)。明示的なwcagVersionがタグの示すバージョンより優先されるのと同じです。両者の食い違いは、wcagVersionと目標のバージョンの食い違いと同じく警告されません。engine.wcagLevelが、達成基準の絞り込みに使われたレベルを示します。
  • IDで指定した集約は指定どおり報告されます。wcagLevel: 'AA'とともにincludeRuleIds: ['wcag-1.4.6-contrast-enhanced']を指定すると、1.4.6が報告されます。このオプションが示すのはどの達成基準を報告するかであって、呼び出し側が求めたものを除くことではありません。選択自身のタグが示すレベルは、オプションがない場合と同じく、指定した集約にも引き続き適用されます。
  • 規格独自の集約にはWCAGのレベルがなく、このオプションの影響を受けません。パックのプロファイルはレベルを示せません(そのタグがレベルを示します)。呼び出し側がwcagLevelを渡せます。
  • getRulesForRunOnly(runOnly, engineOptions)もこれに従うため、スキャンが報告するものを列挙します。無効な値にはスキャンと同じように警告し、strictOptionsのもとではエラーを投げます。

オプションがなくても、ルールIDと並べたバージョンとレベルのタグはレベルを示します。デフォルトのincludeMode: 'and'は、指定したルールのうちそれらのタグのいずれかを持つものを残すからです。{ includeRuleIds: ['contrast-computable'], tags: wcagTags('2.2') }はcontrast-computableを実行し、1.4.3だけを報告します。ただし、タグは何を実行するかも決めます。WCAGのタグを持たない指定したルール(regionのようなベストプラクティスのルールや、WCAGのタグのないカスタムルール)や、AAAの達成基準だけを検査するルールは実行から除かれ、どのルールも持たないバージョンとレベルのタグ(wcag22a)はconsole.infoで注記されます。wcagLevelは、何を実行するかを変えずにレベルを示します。ブラウザーのバインディングでは、ビルダーの.wcagLevel('AA')で設定します。

WCAGバージョンによる絞り込み(2.0、2.1、2.2)

すべてのルールと複合ルールには、そのレベルとWCAGの導入バージョンを示すタグがちょうど1つ付いています。WCAG 2.0からある達成基準にはwcag2a/wcag2aa/wcag2aaa、WCAG 2.1で新たに導入されたもの(例:1.3.5入力目的の特定)にはwcag21a/wcag21aa/wcag21aaa、WCAG 2.2で新たに導入されたもの(例:2.5.8ターゲットのサイズ(最低限))にはwcag22a/wcag22aa/wcag22aaaが付きます。ルールに付くのは、その達成基準が実際に導入されたバージョンのタグだけです。2.1で導入された達成基準にwcag2aaが併せて付くことはありません。WCAG 2.0を対象とする適合では、その達成基準は存在しないからです。

runOnly.wcagは1つのフィールドで適合性の目標を選択し(前述)、2.2では4.1.1を除きます。タグの場合、バージョンは累積的です(2.1 = 2.0 + 新規、2.2 = 2.0 + 2.1 + 新規)。そのため、WCAGのバージョンを対象に適合を検証するには、タグの集合を組み合わせて指定します。あとはtagsに対するエンジンのOR照合(どれか1つに一致すればルールが含まれる)が処理します。

// WCAG 2.0 AA only (excludes every 2.1/2.2-introduced SC, even at level AA):
{ tags: ['wcag2a', 'wcag2aa'] }
 
// WCAG 2.1 AA conformance (2.0 baseline + everything 2.1 added, both at A and AA):
{ tags: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'] }
 
// WCAG 2.2 AA conformance (2.0 baseline + 2.1 additions + 2.2 additions):
{ tags: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22a', 'wcag22aa'] }
 
// Just the SCs 2.2 introduced, nothing else:
{ tags: ['wcag22a', 'wcag22aa', 'wcag22aaa'] }

1つだけ逆向きの達成基準があります。WCAG 2.2ではSC 4.1.1(構文解析)が削除されました。追加ではなく削除された唯一の達成基準です。これに対応するルールは、他の2.0由来のルールと同じく2.0の導入バージョンタグ(wcag2a)を持ち、さらにwcag22-removedも持ちます。そのため上のバージョン別のタグの集合では、本来含まれるべきでない2.2対象のスキャンにもこのルールが含まれてしまいます。

これについて何かする必要はありません。エンジンはスキャンごとに対象のWCAGバージョンを決定し、対象が2.2の場合、wcag22-removedのルールはfailを報告できません。ルールは実行され、見つけた検出箇所もすべて報告しますが、判定結果はcantTellに強制変換され、結果にはその理由を示すwcagVersionScopeフィールドが付きます(出力スキーマを参照)。黙って捨てられるものは何もなく、2.2のスキャンが2.2に存在しない達成基準によってゲートされることもありません。

2.0または2.1を対象にした場合も同じです。WCAG 2.0と2.1に対する2023年の正誤表は、HTMLやXMLのコンテンツについて4.1.1を常に満たされているものとするため、ルールは不合格にせず確認を求め、wcagVersionScope.byは"errata"になります。唯一の例外は、en301549-v3.2.1のように規格が4.1.1の文言を維持しているプロファイルです(規格のプロファイルのkeepsParsing。パックを参照)。そこでは重複したidが今もfailになりえます。core 1.14.0以降の動作で、それ以前は2.0や2.1を対象にすると不合格になりました。

対象バージョンは次の順で決まります。

  1. engineOptions.wcagVersion:指定されていれば'2.0'、'2.1'、'2.2'のいずれか。
  2. 実行が適用するパックのプロファイルのwcagVersion(指定されている場合)。対応付けたルールだけを実行するプロファイルを持つ、WCAG 2.1に基づく規格はWCAGのタグを選択しないため、バージョンを自ら示します。プロファイル自身のタグが示すバージョンより優先されます。効果のないプロファイル(自分で指定した選択に上書きされたもの)はバージョンを持ち込みません。
  3. runOnly.wcagの目標のバージョン。
  4. 自分で指定したフィルター内の導入バージョンタグ:wcag21a/wcag21aaまでの集合なら2.1、wcag22*タグを1つでも含めば2.2、wcag2*タグだけなら2.0とみなします。数えるのはこの9つのタグだけです。達成基準のタグ(wcag411)やbest-practiceからはバージョンは分かりません。
  5. それ以外の場合は、このエンジンのデフォルトの対象である'2.2'。
// Nothing to declare: a plain run already targets 2.2, so a duplicate id
// comes back cantTell rather than fail.
runDomRulesInPage(url, null, {}, null);
 
// Conformance-testing against 2.1, where SC 4.1.1 still exists:
runDomRulesInPage(url, null, { wcagVersion: '2.1' }, null);
 
// Same thing, implied by the tag set — no extra option needed:
runDomRulesInPage(url, null, {}, { tags: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'] });

決定された対象バージョンはすべての結果にengine.wcagVersionとして返されるので、スキャンで実際にどれが使われたかを確認できます。

2.2ではこのルールを一切表示したくない場合は、明示的に除外してください。タグはまさにそのために残してあります。

// WCAG 2.2 AA conformance, with the removed criterion left out entirely:
{
tags: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22a', 'wcag22aa'],
excludeTags: ['wcag22-removed']
}

現在このタグを持つルールはduplicate-idだけです。除外しなければ、実際にある問題を報告します。IDの重複は、規格の定めにかかわらず<label for>、フラグメントリンク、getElementByIdを壊します。ただ、2.2の適合性の違反にはならないというだけです。

engineOptionsで指定する(runOnlyなし)

同じ絞り込みを、engineOptions内にネストしたカンマ区切りの文字列(または配列)で表します。

runDomRulesInPage(url, null, {
rules: { include: 'img-alt-present, button-name-present', exclude: 'region' },
tags: { include: 'wcag412', exclude: 'best-practice' },
includeMode: 'and'
}, null);

rules.include/.exclude、tags.include/.exclude、tests.include/.exclude(rulesの別名)、およびトップレベルのincludeModeは、上記のrunOnlyのフィールドとまったく同じように動作します。カンマ区切りの文字列は自動的にトリムと重複除去が行われ、空のトークンは捨てられます。rules: ['img-alt-present']のように、リストや文字列をそのまま渡すと、含めるリストとして読まれます。

engineOptions:その他のオプション

const engineOptions = {
strictOptions: false, // default false — true throws on an unknown option or a value of the wrong type
locale: 'en', // default 'en'; de-DE falls back to de, then to en per string
wcagVersion: '2.2', // default '2.2' — the conformance target
wcagLevel: 'AA', // optional — the level of the criteria reported
profile: 'wcag22-aa', // optional — a named conformance target
mappings: ['en301549'], // optional — standards besides WCAG to name on each result
optInRules: 'all', // optional — also run rules other standards add beyond WCAG
messages: { de: { /* key: text */ } }, // optional caller-supplied dictionaries; win over built-in ones
includeHiddenElements: false, // default false — set true to evaluate hidden/collapsed subtrees too
includeShadowDom: true, // default true — opt OUT with false to skip open shadow roots
fragment: false, // default false — set true when the scan target isn't a real page
excludeSelectors: ['#cookie-banner', '.third-party-widget'], // array or comma-separated string
styleSheetTexts: [{ href: 'https://cdn.example/site.css', text: '/* its CSS */' }], // sheets the page can't read
timestamp: '2026-07-20T12:00:00Z', // optional — engine has no built-in clock
perfStats: false, // default false — internal timing counters, debug-only shape
profileRules: false, // default false — per-rule timings; needs perfStats
 
contrast: {
mode: 'strictConformance', // 'strictConformance' (default) | 'auditorAssist'
rootCanvasFallback: '#ffffff', // a canvas to measure on in place of the page's own; unset, the page's color scheme gives it
rootCanvasFallbackSet: true // echoed on each result: whether rootCanvasFallback was given; read back, false means the default
},
visibilityMode: undefined, // 'styleOnly' | 'styleAndGeometry'; unset: geometry with a layout, else styles
 
policyContract: 'a11y', // 'a11y' (default) | 'generic' | inline contract object
policy: { // optional overrides on top of policyContract
coerceManualFailToCantTell: true
},
 
output: {
includeSelector: true, // set false to suppress auto-filled selectors
includeHtml: true,
detail: 'full' // 'findings': pass/notApplicable results keep only rule, outcome, type
},
 
rules: {
'some-rule-id': {
excludeSelectors: ['.some-noisy-widget'] // narrows candidates for THIS rule only
}
},
 
probes: { /* optional host-supplied evidence */ },
 
customRules: [ /* runtime-registered rules, see below */ ],
packs: [ /* rules and standards from outside core, see Packs */ ],
 
// Only read by runa11yCoreAcrossFrames. Ignored by runDomRulesInPage/runa11yCoreInPage.
pingWaitTime: 500, // ms to wait for a child frame to answer a ping
frameWaitTime: 60000 // ms to wait for a child frame's full scan result
};
オプション意味
strictOptionsデフォルトはfalseです。trueにすると、スキャンの前にすべてのオプションを確認し、エンジンが読まないキーや、型が誤っているか集合の外にある値があればINVALID_ENGINE_OPTIONSを投げます。後述の「オプションの誤りを見つける」を参照してください。
locale任意の文字列を指定できます。サブタグ付きのコードはまずベース言語にフォールバックするので、de-DEはdeを使い、それもなければ英語になります。個々の文字列も同じ順にフォールバックする(指定したロケール → en → ルールに書かれた英語の原文)ため、翻訳が一部しかないロケールでも文字列が欠けることはありません。こうしたフォールバックは文字列そのものからは分からないので、実際に何が起きたかは結果のengine.localeに記録されます。指定した言語が使われたかを確かめたいときはここを確認してください。詳しくはロケールを参照してください。
wcagVersion'2.0'、'2.1'、'2.2'のいずれかで、そのスキャンがどのバージョンのWCAGへの適合を検証するかを指定します。省略すると、実行が適用するパックのプロファイルが示すバージョン(そのwcagVersion)になり、それがなければ導入バージョンタグから推定されるバージョン、タグから何も推定できなければ'2.2'になります。このオプションが変えるのは、スキャンが報告する達成基準と、SC 4.1.1(構文解析)についてwcag22-removedタグの付いたルールがfailにならない理由です。4.1.1は2.2で削除され、2.0と2.1ではそれぞれの正誤表により常に満たされているものとされます。ただし、en301549-v3.2.1のように、規格が4.1.1を維持しているプロファイルのもとでは例外です。前述の「WCAGバージョンによる絞り込み」を参照してください。それ以外の値は、型を問わず(数値の2.1、'3.0')、代わりに実行が対象とするバージョンを示すconsole.warnを出して無視されます。
wcagLevel省略可:'A'、'AA'、'AAA'のいずれか(大文字小文字は問いません)で、実行が報告する達成基準のWCAGレベルを指定します。それより上のWCAGの集約は、ルールは実行されたままrulesResultsから除かれます。何を実行するかは決して変えません。選択が示すレベルより優先されます。IDで指定した集約は指定どおり報告されます。engine.wcagLevelとして返し、オプションがない場合は選択が示すレベルがあればそれを保持します。それ以外の値はconsole.warnを出して無視され、strictOptionsのもとではエラーを投げます。前述の「チェックを指定するスキャンのレベルを示す」を参照してください。
profile名前付きの適合性の目標(省略可):'wcag22-aa'、'en301549-v4.1.1'、'en301549-v3.2.1'、'section508'、またはパック独自のもの。ほかに含める指定がない場合に、対応するタグセットでルールを選び、WCAGの対象バージョンはそのタグから決まります。効果があった場合はengine.profileとして返し、なかった場合はコンソールに警告を出して無視します。前述の「適合性プロファイル」を参照してください。
mappingsmeta.normativeMappingsが要件を示す、WCAG以外の規格(省略可):'en301549'、'en301549:V3.2.1'、'en301549:V4.1.1'、またはパックの規格のキーを、配列またはカンマ区切りの文字列で指定します。デフォルトはなしで、結果はWCAGだけを示します。EN 301 549のプロファイルは自身のバージョンを追加します。いずれかが適用された場合はengine.mappingsとして返します。前述の「ほかの規格」を参照してください。
logUntestedWcagデフォルトはtrueです。falseにすると、含めるリストでほかの値と並んでいる、どのルールも持たないWCAGのバージョンとレベルのタグ(wcag22a)についてのconsole.infoの注記を出力しません。前述の「runOnlyで指定する」を参照してください。
optInRules省略可:'all'、またはオプトインルールのタグのリストを、配列またはカンマ区切りの文字列で指定します。それらのルールを規格のプロファイルの外で解除し、何を実行するかは引き続きほかの選択が決めます。ほかの選択では実行されなかったルールを実行した場合はengine.optInRulesとして返し、不明なタグはコンソールに警告を出して無視します。前述の「すべてのルールを実行する」を参照してください。
messages省略可能な{ [locale]: { key: text } }です。エンジン組み込みの辞書より先に参照されるため、個々の文字列を上書きしたり、ビルドに含まれていない言語を補ったりできます。指定しなかったキーは通常どおりフォールバックするので、一部だけの上書きでも問題ありません。スタンドアロンのブラウザー用バンドルはこの仕組みでロケールの別ファイルを受け取ります。ページ内ランナーはシリアライズされていてファイルを読めないため、ページのコンテキストに辞書を渡す方法はこれしかありません。ほかのオプションと違い、各結果のengineOptionsには返されません。使われた辞書はengine.localeが示します。詳しくはロケールを参照してください。
includeHiddenElementsデフォルトはfalseです。ヘルパーのクエリは、display:none、[hidden]、閉じた<details>(最初の<summary>を除くすべて。深さを問いません)、content-visibility:hiddenとhidden="until-found"のコンテンツ、[inert]のサブツリー内のコンテンツ(描画はされるため、コントラストやテキストの間隔など見た目に関するルールは引き続き判定します)、非表示のレンダリング専用ホスト要素など、構造やCSSの仕組みで隠された要素を除外します(その子孫も除外されます)。runa11yCoreAcrossFramesは、このように隠されたフレームをスキャンしません。trueにすると、こうした非表示・折りたたみ状態のサブツリーも評価の対象になります(旧来の、静的マークアップ向けの動作)。これは共通のクエリが返す範囲を広げるものです。それでもほとんどのルールはアクセシビリティツリーにあるものだけを判定します。非表示の要素にはチェックすべき名前もロールもないため、そうしたルールでは何も変わりません。意味があるのは、壊れたID参照など、マークアップそのものを扱うルールです。
includeShadowDomデフォルトはtrueで、helpers.queryAllSmartを使うルールはオープンなシャドウルートの中まで走査します。falseにするとライトDOMだけをスキャンします。クローズドなシャドウルートには、どちらの設定でも到達できません。それを公開するDOM APIが存在しないためです。エンジンが読めるコンテンツを持たないカスタム要素から名前が来ている可能性がある要素(ボタン、リンク、メニュー項目、オプション、タブ、ツリー項目、summary、ツールチップ)は、不合格にせず確認を求めます(cantTell、name_closedContent)。
fragmentデフォルトはfalseです。いくつかのルール(page-title-present、html-lang-attr-present、html-xml-lang-mismatch、aria-hidden-body、css-orientation-lock、meta-refresh-no-exceptions、meta-refresh-timing-absent、meta-viewport-zoom-enabled、meta-viewport-large、page-title-patterns、region、bypass-blocks-present、landmark-one-main、page-has-heading-one)は、実際のページなら1つだけ存在するはずのプロパティの有無を確認します。contextSelectorでスキャン範囲をドキュメント全体より狭くした場合(解決されたルートにdocument.documentElementが含まれない場合)、これらのルールは正しくnotApplicableを報告します。範囲を絞ったサブツリーが独自の<title>や<html lang>などを持つことは、そもそも想定されていないからです。fragment: trueは、範囲の指定だけでは判別できないケースのためのものです。スキャン対象は渡されたドキュメントの全体だが、もともと実際のページを表すものではない場合(単独でパースしたコンポーネントの断片など)がこれに当たります。この設定により、範囲を絞っていなくても同じようにnotApplicableになります。
excludeSelectorsこれらのセレクターのいずれかに一致する要素(とその子孫。シャドウルートの中にあるものや、その中にあるフレームのドキュメントも含みます)は、すべてのルールで完全にスキップされます。Cookieバナーやサードパーティの埋め込み、自分では管理できない、ノイズが多いと分かっているウィジェットに便利です。特定のルール1つだけから除外したい場合は、後述のrules[ruleId].excludeSelectorsを使ってください。セレクターの配列か、セレクターリストを持つ文字列を指定します。文字列はセレクターの間のカンマでだけ区切られるので、'#cookie-banner, img:not(.a, .b)'は['#cookie-banner', 'img:not(.a, .b)']と同じです。各セレクターは個別に適用されます。有効なCSSでないセレクターはconsole.warnを出して何も除外せず、ほかのセレクターは引き続き適用されます。
styleSheetTextsページが読み取れないスタイルシートのテキストです。[{ href, text }]の形で、別オリジンのスタイルシートをURLで示し、そのCSSを渡します。CSSを読むルール(css-orientation-lock、css-hidden-focus、css-focus-indicator-suppressed)は、スタイルシートの代わりにこれを読みます。各結果のengineOptionsは、テキストを除いたスタイルシートのhref([{ href }])としてこれを返します。preloadStyleSheets()はサーバーが共有しているものをページの中から取得し、runa11yCoreInPageAsyncはスキャンの前にそれらを取得します。ブラウザーを操作するツールは、それ以外のものをページの外から取得できます。GitHubにあるcoreの統合ガイドの「Style sheets from another origin」を参照してください。core 1.14.0以降です。
timestamp結果のトップレベルのtimestampフィールドにそのまま渡されます。エンジン自身はタイムスタンプを生成しません(決定論的であるための設計です)。文字列でない値(Date、数値)はconsole.warnを出して無視されます。new Date().toISOString()を渡してください。
contrast.modestrictConformance(デフォルト):実際に描画される背景色を確実に計算できない場合、コントラストのルールは何も報告しません(notApplicableまたはスキップ)。誤ったfailを防ぐためです。auditorAssist:その安全マージンを一部手放して、より多くの検出結果を返します。フラグが立ったケースを人間の監査担当者が再確認することを前提としたモードで、無人で動かすCIのゲートには向きません。不透明な背景を描画しないページは、このケースには当たりません。その背後のキャンバスはページ自身のカラースキームから決まるため、そのテキストはどちらのモードでも推測なしに計測されます。ページのキャンバスが分からない場所(フレームの中、強制カラーのもと)では、auditorAssistはテキストをcontrast.rootCanvasFallbackの上で計測し、ROOT_CANVAS_FALLBACKとして記録します。
contrast.rootCanvasFallback不透明な背景を描画しないページのためのキャンバスの色です。指定しない場合、コントラストのルールはどちらのモードでも、そのようなページのテキストをブラウザーがその背後に描画するキャンバスの上で計測します。ページが描画されるカラースキームのキャンバスで、それはページ自身のcolor-scheme(ルート、または<meta>の形式)が決めます。何も宣言しないページは、ユーザーの好みにかかわらずライトで、白の上に描画されます。light darkはライトのユーザーには白の上、ダークのユーザーにはダークなキャンバスの上に描画され、そのテキストは両方のスキームで計測され、どちらかで不合格なら不合格になります(data.details.colorSchemeがどちらかを示します)。システムカラーを解決しないjsdomのもとでは、エンジンはChromiumの色を使い、そこで色を割り出せないテキストは確認が必要なものとして扱います(COLOR_SCHEME_NOT_RENDERED)。指定すると、白を含め、その色がすべてのスキームでページのキャンバスの代わりになります。テキストはその上で1回計測され、想定として記録されます(ROOT_CANVAS_FALLBACK)。ページのキャンバスが分からないのは、親ページが透けて見えることがあるキャンバスを持つフレームの中と、強制カラーのもとです。そこではcontrast-computableが確認を求め、コントラスト比のルールはテキストを対象外にします。ただしauditorAssistはこの色の上で計測します。各結果のengineOptions.contrastは、使った色を返します。指定がなければ白です。
contrast.rootCanvasFallbackSet各結果に返される値です。contrast.rootCanvasFallbackが呼び出し側の指定ならtrue、デフォルトの白ならfalseです(指定した値が使える色でなかった場合もfalse)。入力として指定する必要はありません。結果に返されたオプションをそのまま渡し直すと元のとおりに読まれるので、falseなら返された白はデフォルトのままです。trueでもfalseでもない値は警告を出し、指定がなかったものとして読まれます。core 1.14.0以降です。
visibilityMode3つのコントラストルール(contrast-minimum、contrast-enhanced、contrast-computable)が、テキストノードを実際にチェック対象とするかどうかをどれだけ厳密に判断するかを制御します。他のルールはこのオプションを読みません。指定しない場合(デフォルト)、ページにレイアウトがあれば(ブラウザーでのスキャンはすべてそうです)'styleAndGeometry'、ない場合(jsdom)は'styleOnly'になります。読み手に見えるのは見える場所に描画されたテキストだけで、それを判断できるのはレイアウトだけだからです。'styleOnly':対象かどうかをCSSだけで判断します(display、visibility、opacity、祖先による非表示など)。'styleAndGeometry':それに加えて実際のレイアウトをチェックします(getClientRects()/getBoundingClientRect())。クライアント矩形を持たないテキストや、幅または高さがゼロのテキストも除外されます。ページの完全に上側や左側にあり、スクロールしても届かないテキスト(left: -9999pxの手法)や、overflow: hiddenまたはclipの祖先に完全に切り取られたテキスト(height: 0; overflow: hidden、表示範囲外のカルーセルのスライド)も同様です。スクロールするボックス(auto、scroll)は、読み手がそのテキストまでたどり着けるため、除外の理由になりません。<select>の選択肢は、その<select>がページ上にある位置で判断されます。どちらのモードでも、フォントサイズが0のテキストや完全に透明な色のテキストは、何も描画されないため除外されます。ただし、グリフを通して背景を見せる透明なテキスト(そのテキストか祖先のbackground-clip: text)は除外されません。背景が単色ならその色で計測され、グラデーションや画像なら確認が必要なものとして扱われます。ブラウザーで、以前のリリースと同じように計算済みスタイルだけからテキストをチェックするには'styleOnly'を指定してください。素のjsdom(runDomRulesInPage)には本物のレイアウトエンジンがないため、'styleAndGeometry'で加わるのは主にgetBoundingClientRect()によるサイズゼロのチェックで、本当の意味でのクリッピングやオーバーフローの検出にはなりません。既知の制限事項を参照してください。
policyContractPOLICY.mdを参照してください。許可される判定結果と確度の値、そして手動ルールがfailになるはずだった場合にcantTellへ強制変換するかどうかを制御します。
output.includeSelector / .includeHtmlエンジンによるselector/htmlの自動補完を抑制します。すべてのルールが検出箇所を自前で組み立てるのをやめ、要素を報告する方式に移行して以降(1.5.0)、ほぼすべてのルールがこの自動補完を通ります。そのためincludeSelector: false / includeHtml: falseを指定すると、ほぼすべてのルールからセレクターとHTMLスニペットが取り除かれます。ただし、いくつかのルールは今もrunInPageの中でこれらのフィールドを自分で組み立てており、影響を受けません。contrast-minimum/contrast-enhanced(検出結果が要素ではなくテキストの連なりであるため)、page-title-present、identical-links-same-purposeなどがそうです。つまり出力は大幅に絞られますが、結果のどこにもセレクターやHTMLが含まれないことまでは保証されません。
output.detail'full'(デフォルト)または'findings':より小さな結果です。何かを報告するチェック結果(fail、cantTell、検出箇所を列挙するもの)だけを完全なまま残し、それ以外のpassとnotApplicableは、ruleId、outcome、typeと、ある場合はそのmarginまたはerrorだけを保持します。集約と判定は変わらず、レポーターはこれを完全な結果として読みます。コアのカタログで補えないルールは完全なまま残ります。packs付きのスキャンのすべてのルール、カスタムルール、スキャンのmessagesが文言を変えるルールです。engine.outputDetailを参照してください。TypeScriptでは、このような結果はCompactScanResultです。
rules[ruleId]そのルールにctx.configとして渡されます。またexcludeSelectorsに限っては、ルールが実行される前にエンジン自身が読み取ります。後述の「ルール単位のexcludeSelectors」を参照してください。それ以外のキーは受け渡されるだけです。同梱されているルールで、ここからほかに何かを受け取るものはありません。ルールが宣言する設定(contrast-minimumのしきい値など)はその規格のものなので、呼び出し側が渡した値は破棄されます。WCAG 1.4.3を示す結果は、常に4.5:1で判定されます。別のしきい値を持つ規格には、独自のルールであるバリアントがあり、パックがそれを提供できます。キーはルールIDと同じように、大文字小文字を問わず、また旧来のa11ycore-プレフィックス付きでも照合されます。スキャンのどのルールも示さないキーには、最も近いIDとともに警告が出ます。
packs@surea11y/core/packによるパック(省略可):コアの外から来るルール、コアのルールのバリアント、規格やチェックリスト、メッセージで、スキャンに加わります。リストで指定します。NodeのrunDomRulesInPageとカタログ関数ではパックのオブジェクト、runa11yCoreInPageではpackScriptがページに登録したパックのname@versionです。それ以外の値ではパックは実行されず、警告が出ます。strictOptionsのもとではcode: 'INVALID_ENGINE_OPTIONS'付きのエラーを投げます。engine.packsとして返します。パックを参照してください。
probesサイトのほかのページなど、1ページのスキャンでは見えないもののために、ホストアプリケーションが渡す、JSONとして安全な省略可能の証拠オブジェクトです。ルールが読む前にエンジンが制限します(ctx.inputs.probes)。深さは6階層、配列は200項目、オブジェクトは50キー、文字列は2,000文字までです。page-title-patternsはcrawl.pageTitles({ pages: [{ url, title }] })を読み、サイト全体で汎用的なタイトルやテンプレートのままのタイトルを探します。パックのルールは独自のprobesを読むことがあり、それはパックが説明します。
perfStats / profileRulesデバッグ専用です。perfStats: trueを指定すると、結果のperfStatsフィールドに内部カウンターが返されます。profileRules: trueを指定すると、そこにさらにルールごとの所要時間の内訳が加わります。profileRulesだけを指定しても何も起きません。内訳を格納するオブジェクトを作るのはperfStatsです。この形は安定した出力契約に含まれないため、これに依存しないでください。また、profileRulesは出力を非決定論的にする唯一のオプションです。カウンターは同一の実行間で変わりませんが、実時間の計測値は変わります。実行間で結果の差分を取る場合はオフにしておいてください。profileRulesを指定すると、共有のキャッシュ(計算済みスタイルとアクセシビリティツリー上の対象判定)は最初のルールの前に満たされ、perfStats.warmUpMsとして別に計測されます。そのため、そのコストが最初にページをたどるルールに計上されることはありません。
pingWaitTime / frameWaitTimeruna11yCoreAcrossFramesだけが読み取ります(INTEGRATION.mdを参照)。子フレームを到達不能とみなすまでに、pingへの応答(デフォルト500ms)とスキャン全体の要求への応答(デフォルト60000ms)をそれぞれどれだけ待つかを指定します。runDomRulesInPage/runa11yCoreInPageでは無視されます。

オプションの誤りを見つける(strictOptions)

エンジンが読まないオプションは、そのまま受け渡されます。カスタムルールはctx.engineOptionsから独自の設定を読めますし、後のリリースで削除されたオプションがスキャンを壊すこともありません。そのため、デフォルトでは綴りを誤ったオプションは無視され、スキャンはそれがないものとして実行されます。それを知らせるものが2つあります。

  • 常に、既知のキーと1文字か2文字だけ違う(大文字小文字は問いません)キーは、入れ子のキーも含めて警告されます。lcoaleには[surea11y] engineOptions: unknown option "lcoale" (did you mean "locale"?); ignored.が出ます。
  • 常に、型が誤っている値は警告されたうえで指定がなかったものとして読まれます。オブジェクトでないengineOptionsも同様です。オン/オフのオプション(includeShadowDom、includeHiddenElements、fragment、perfStats、profileRules、output.includeHtml、output.includeSelector)はtrueかfalseを受け取り、コマンドラインでの表記である'true'、'false'、'1'、'0'、1、0も受け取ります。perfStats: 'false'はオフです。
  • strictOptions: trueを指定すると(または'true'、'1'、1)、スキャンの前にすべてのオプションが確認され、誤りがあればcode: 'INVALID_ENGINE_OPTIONS'付きのエラーを投げてそれぞれを示します。problemsはそれらを{ path, kind, message, suggestion }として列挙します。対象は、engineOptionsやそのオブジェクトのいずれかにある未知のキー(kind: 'unknown')と、includeHiddenElements: 'yes'やcontrast.mode: 'strict'のように型が誤っているか集合の外にある値(kind: 'invalid')です。
runDomRulesInPage(url, null, { strictOptions: true, lcoale: 'de' }, null);
// Error: engineOptions: unknown option "lcoale" (did you mean "locale"?). (strictOptions)

engineOptionsを受け取るカタログ関数(getChecksCatalog、getRulesCatalog、getCheckDefById、getCompositeRuleById、getChecksForRunOnly、getRulesForRunOnly、getTestsForRunOnly)も、同じ方法、同じ文言でそれを確認します。getRulesForRunOnly(runOnly, { wcagLevel: 'AA+' })は警告を出し、レベルを指定がなかったものとして読み、そのオプションでのスキャンが報告するものを列挙します。strictOptions: trueを指定すると、スキャンと同じようにINVALID_ENGINE_OPTIONSを投げます。自分自身を打ち消す選択(同じルールを含めると同時に除外する、共通するルールのない部分を組み合わせる)も、スキャンと同じように知らされます。警告が出て、strictOptionsのもとではINVALID_RUN_ONLYになります。

確認しないもの:ルール自身の設定(rules[ruleId])、messagesのキー、エンジンが読まずに受け渡すprobes、そして独自の確認を持つカスタムルール(skippedCustomRules)です。TypeScriptでは、StrictEngineOptionsは、任意のキーをコンパイルできるようにするインデックスシグネチャを持たない同じオプションの集合なので、綴りを誤ったオプションはそこでもエラーになります。

ルール単位のexcludeSelectors

トップレベルのexcludeSelectorsはすべてのルールに適用されます。ある要素を1つのルールからだけ除外し、他のルールでは引き続きチェックする、ということはできません。rules[ruleId].excludeSelectorsはこの隙間を埋めるもので、そのルールだけの対象候補を絞り込みます。グローバルなリストを置き換えるのではなく、常にそれに追加する形で働きます。

const engineOptions = {
excludeSelectors: ['#cookie-banner'], // applies to every rule, as always
rules: {
'aria-required-children': {
excludeSelectors: ['mat-select', 'mat-stepper', 'mat-horizontal-stepper', 'mat-vertical-stepper']
},
'aria-allowed-attr': {
excludeSelectors: ['mat-progress-spinner']
}
}
};

これが必要になる理由:Angular Materialの<mat-select>は、内部のARIA構造の組み立て方が原因で、コンポーネント自体には問題がないのにaria-required-childrenでだけ誤検出を起こします。グローバルなexcludeSelectorsしかなければ、この誤検出を消す方法はexcludeSelectors: ['mat-select']だけです。しかしそうするとmat-selectはcontrast-minimumやaria-allowed-attrを含む他のすべてのルールからも見えなくなり、何の問題もなかったチェックのカバレッジまで黙って失われます。上の例なら、誤判定する1つのルールを除くすべてのルールからmat-selectが引き続き完全に見えます。

あるルールに実際に適用される除外は、グローバルなリストとそのルール独自のリストの和集合です。どちらかに一致する要素は、そのルールの対象候補から外れます。不合格になりうる要素がすべてこの方法で除外されたルールは、occurrences: []とともにoutcome: 'pass'または'notApplicable'(対象がない場合のそのルール自身の慣例に従います)を報告します。空のoccurrences配列を伴うoutcome: 'fail'になることはありません。組み込みルールのfailは、必ず何が不合格だったかを示すからです(例外を投げたルールは別のケースで、errorを設定したcantTellを報告します。出力スキーマを参照)。

グローバルなオプションと同じ形式を受け付けます。配列(['mat-select', 'mat-stepper'])またはカンマ区切りの文字列('mat-select, mat-stepper')です。

バインディングパッケージ(@surea11y/binding-baseと、それをラップするPlaywright/Puppeteer用のパッケージ)を使っている場合は、.exclude()ビルダーメソッドにルール単位の形式がすでにあるかどうかを、そのバインディング自身のREADMEで確認してください。ここで説明しているのはエンジンレベルのengineOptionsの形式で、すべてのバインディングが対応しているわけではありません。

レシピ:実際のシナリオに合わせたオプションの組み合わせ

CIゲート:WCAG 2.2 AAのみ、自分では管理できないサードパーティのウィジェットは無視する

runDomRulesInPage(url, null, {
excludeSelectors: ['#cookie-banner', '.intercom-launcher']
}, { wcag: { version: '2.2', level: 'AA' } });

ベストプラクティスのルールも実行するには、wcagと並べてbestPractices: trueを追加してください。WCAGのゲートでは通常、それらは失敗させずに報告します。ただし一部はfailになりうる(empty-heading)ため、failが1つでもあれば失敗させるゲートは、それらでも失敗します。

人間の監査担当者が実際のブラウザーでコントラストを詳しく確認する:誤検出への備えを一部手放して、より多くの検出結果を得ます。実際のブラウザーでは、コントラストのルールはすでに計算済みスタイルだけでなくレイアウトもチェックするので、設定が必要なのはコントラストのモードだけです。例ではPuppeteerのpage.evaluate(複数の引数を受け付けます)を使っています。Playwrightの場合は、先に4つの位置引数を1つのオブジェクトにまとめてください。INTEGRATION.mdを参照してください。

const result = await page.evaluate(runa11yCoreInPage, url, null, {
contrast: { mode: 'auditorAssist' }
}, null);

UIの変更後に1つの領域だけを再スキャンし、シャドウDOMはスキップする:変更したウィジェットだけを確認したいコンポーネント単位のテストで役立ちます。

runDomRulesInPage(url, '#checkout-form', {
includeShadowDom: false
}, { includeRuleIds: ['form-control-programmatic-label-present', 'button-name-present'] });

スナップショットテスト用の出力:timestampを固定して、結果自体のタイムスタンプが実行ごとに変わらないようにし、perfStatsとprofileRulesはオフのままにします。これらの所要時間は実行ごとに変わり、その形は安定した出力に含まれません。スナップショットには、毎回同じDOM、同じオプション、同じ描画条件(ブラウザー、ビューポート、フォント)も必要です。タイムスタンプを固定するだけでは、2つの結果は同一になりません。

runDomRulesInPage(url, null, {
timestamp: '2026-01-01T00:00:00Z'
}, null);

組み込みルールと並べて組織独自のカスタムルールを使う(この呼び出しに限る):

runDomRulesInPage(url, null, {
customRules: [{
id: 'org-no-inline-onclick',
meta: { title: 'No inline onclick handlers', defaultSeverity: 'moderate' },
runInPage(ctx) {
// queryAllSmart applies excludeSelectors, the scope's shadow roots and
// the hidden-content filter; queryAll is the plain light-DOM query.
// ctx.helpers.dom reads the DOM so the page's markup can't redirect it.
const dom = ctx.helpers.dom;
const els = ctx.helpers.queryAllSmart('[onclick]');
const occurrences = els.map((el) => ({
selector: ctx.helpers.buildSelector(el),
html: dom.outerHTML(el),
summary: 'Inline onclick handler found.',
hint: 'Move event handling into an external script.'
}));
 
return { ruleId: ctx.rule.ruleId, outcome: occurrences.length ? 'fail' : 'pass', severity: 'moderate', occurrences };
}
}]
}, null);

customRules:実行時に登録するルール

同梱のルールはすべて、ビルド時にsrc/core.jsに組み込まれます。engineOptions.customRulesは実行時のための抜け道で、その呼び出しに限って登録されるルール記述子の配列です。静的なカタログには何も追加されず、呼び出しをまたいで残るものもありません。カタログ関数も同じengineOptionsを受け取り、それを使ったスキャンが持つものを列挙します。getChecksCatalog(engineOptions)は有効なカスタムルールを、各上書きを組み込みルールの位置に置いて列挙し、getCheckDefById(id, engineOptions)はそれらを見つけ、getChecksForRunOnly(runOnly, engineOptions)はスキャンと同じようにそれらを選択し、getRulesForRunOnly(runOnly, engineOptions)はそれらが追加する集約を列挙します。これは回避すべき制限ではなく、意図した設計です。surea11yはもともと呼び出しごとに新しいengineOptionsを受け取り、変更可能なグローバル設定を持ちません。カスタムルールもこの呼び出し単位のモデルに従います。

ライブラリーを直接呼び出すのが1つの方法ですが、CLIでも--custom-rules <path>(ローカルファイル。スキャンごとに1回読み込まれます)で利用できます。CLIのドキュメントを参照してください。

カスタムルールは、パックのルールと同じく組み込みルールの後に実行され、渡されるctx.helpers、ctx.engineOptions、ctx.inputs.probesは読み取り専用です。それらに何かを設定したり削除したりすると例外が投げられる(そのルールはそのエラーとともにcantTellとして報告されます)ため、ほかのルールが見るものを変えることはできません。ページを変更してはいけません。変更したルールはconsole.warnで示されます。結果はカタログの順序を保ちます。ルールが何を投げても何を返しても、スキャンは結果を返し、ルールの結果は単純なデータに変換されるため、スキャンの結果はJSONとして書き出したり複製したりできます。

記述子は内部のルールモジュールがexportするものと同じ形です。このエンジンのルールファイルの書き方を知っていれば、このAPIもすでに知っていることになります。

{
id: 'my-org-custom-rule', // required
meta: { title, description, tags, defaultSeverity, defaultConfidence, /* same fields as a rule module's meta */ },
runInPage(ctx) { /* same ctx shape and same return contract as any built-in rule */ },
applicability(ctx) { return true; }, // optional, same contract as a built-in rule's applicability
data: { /* optional, JSON-serializable */ }
}
  • runInPage/applicabilityには、実際の関数と関数のソース文字列(つまりfn.toString())のどちらも渡せます。engineOptionsが現在のJSレルムの外に出ない場合(素のNode/jsdomでの利用)は実際の関数を渡してください。外に出る場合は文字列を渡します。たとえばPlaywrightのpage.evaluate(runa11yCoreInPage, { engineOptions })呼び出しでは、engineOptionsがJSON/構造化クローンの境界を越えるため、生きたFunction参照は渡せませんが、文字列なら渡せます。エンジンは文字列をnew Functionで関数に戻します。ビルド時にすべての組み込みルールのソースをページ内ランナーに埋め込むのと同じ仕組みです。どの関数のソースでも使えます。アロー関数、function宣言、上の例のような省略記法のメソッド(runInPage(ctx) {…}、asyncも可)のいずれでもかまいません。省略記法のメソッドのtoString()は、それだけでは式になりませんが、それでも扱えます。関数に戻すにはevalが許可されている必要があるため、Content Security Policyで'unsafe-eval'を禁止しているページでは、文字列で渡したルールはスキップされ、そのskippedCustomRulesの理由はポリシーが原因であることを示します。その場合は実際の関数を渡してください。
  • metaには、ビルド時のルールとまったく同じデフォルト値の補完と検証が行われます。不要なものは省略してかまいません。defaultSeverityのデフォルトはmoderate、defaultConfidenceはmedium、typeはautomaticなどです。値が決められた範囲(minor/moderate/serious/critical、high/medium/low、automatic/manual。大文字小文字は区別しません)から外れているmetaは検証に失敗し、そのルールはスキップされます。ルールが範囲外のseverityを返した場合は、そのルールのデフォルトに置き換えられ、errorに注記が付きます。
  • カスタムルールのidが組み込みルールと重複した場合は、両方を実行するのではなく、そのスキャンでは組み込みルールを上書きします。同名のカスタムルールは、意図した上書きであるのと同じくらい偶然の衝突である可能性もあるため、衝突は必ず2つの方法で知らされます。該当するIDを示すconsole.warnと、結果のトップレベルにあるoverriddenBuiltinIds配列(衝突がなければ空)です。出力スキーマを参照してください。IDは大文字小文字を問わずに照合されます。カスタムルールIMG-ALT-PRESENTはimg-alt-presentを上書きしてそのIDを引き継ぎ、2つ目の警告が両方の綴りを示します。
  • 実行されたカスタムルールは、meta.wcagScまたはmeta.normativeMappingsのWCAGのエントリーを通じて、組み込みルールと同じように、対応する各達成基準のWCAGの集約(rulesResults)に算入されます。不合格になったものは集約を不合格にします。集約は貢献したルールの中でそれにcustom: trueを付け、data.details.customChecksIdsに列挙します。選択が単独で(そのIDやタグのいずれかで)指定し、実行されたカスタムルールは、選択がその達成基準を1つも指定していなくても、その達成基準の集約を報告します(「スキャンが報告する達成基準」)。上書きは、それ自身の対応付けが示す場所に算入されます。その達成基準に対応していれば組み込みルールの代わりに算入され、どれにも対応していなければどの集約にも算入されず、外れた集約を示す警告が出ます。
  • カスタムルールは、組み込みルールと同じように、IDとmeta.tagsで選択されます。スキャンがスキップしたカスタムルールを指定するrunOnlyは、スキップされた理由とともにINVALID_RUN_ONLYを投げます。customRulesはリストです。単独で渡したルールは実行されず、skippedCustomRulesに列挙されます。プロファイルやWCAGの目標のもとでは、best-practiceのタグを持つルールや、WCAGのタグを持たないルールは実行に含まれません。それらはconsole.warnとともにskippedCustomRulesに列挙され、検査する達成基準のタグ('wcag111')を付けるか、runOnly.bestPractices: trueを追加すると実行されます。選択が除外したカスタムルール(excludeRuleIds: ['org-b']、rules.excludeなど)もそこに列挙されます。理由はexcluded by the selection.で、excluded: trueが付き、警告は出ません。上書きは、組み込みルールが実行されたはずの場所ではどこでも実行されます。
  • カスタムルールも組み込みルールと同じようにマージンを報告できます。meta.margin({ measure, unit, limit })を宣言し、marginCandidatesを返してください(GitHub上のルール作成ガイドRULE_AUTHORING.mdのmeta.marginを参照)。形式が正しくないmeta.marginは無視され、そのルールはマージンを報告しませんが、スキャンは続行します。
  • 無効な記述子(idがない、または文字列でない、runInPageが関数でも関数に戻せるソース文字列でもない、applicabilityを関数に変換できない、deprecationのないdeprecated: trueなどmetaが検証に失敗する、リスト内の別のカスタムルールと同じIDを持つ、複合ルールのIDを使っている)は、ルール名と理由を示すconsole.warnを出してスキップされ、結果のskippedCustomRulesに記録されます。組み込みルールを含むスキャンの残りは通常どおり実行されます。これは直すべき検証の抜けではありません。カスタムルールは呼び出し側が渡す任意のコードなので、「問題のあるエントリだけを安全側に倒して除外し、スキャンは中断しない」ほうが安全なデフォルトです。例外を投げた組み込みルールが、スキャン全体をクラッシュさせずにそのルールのcantTellにとどめられるのと同じ考え方です。
  • ルールは同期的に実行されます。Promiseを返すrunInPageやapplicability(async関数)は、その旨を示すerror付きのcantTellとして報告されます。結果オブジェクト以外を返すrunInPageも同様です。pass、fail、cantTell、notApplicable以外のoutcome('failed'など)はcantTellになり、errorに返された値が示されます。ルールのtypeはそのmetaから決まります。戻り値のtypeは無視され、errorに注記が付きます。
  • 結果は他のルールとまったく同じようにchecksResultsに現れます。{ __node }だけを付けたfail/cantTellの検出箇所に対してselector/html/structuralPathが自動補完される点も同じです(出力スキーマを参照)。
  • failは何が不合格だったかを示します。検出箇所のないカスタムルールのfail(ページ全体の不合格)は、ドキュメント要素に1つの検出箇所を付けて報告されます(selector: 'html'、理由コードFAIL_WITHOUT_OCCURRENCE)。そのため、JUnit、SARIF、ベースライン、HTMLレポートはそれを本来の不合格として表示します。

パック:コアの外にあるルールと規格

パックは、ルール、コアのルールのバリアント、規格やチェックリストと、それらが使うメッセージを、コアをビルドせずに、それ自身のパッケージとして提供します。パックはengineOptions.packsでスキャンに渡します。スキャンは、ビルドがコア自身のルールに使うのと同じ手順でパックを組み込んで用意したエンジンで実行されるため、パックの規格、プロファイル、集約、オプトインルールは、組み込みのものと同じように動作します。エンジンは同じパックのオブジェクトでの次のスキャンのために保持されるため、すべてのページに同じパックを渡すクロールでは、パックの準備は1回で済みます。

const { runDomRulesInPage, getChecksCatalog } = require('@surea11y/core');
const acmePolicy = require('./acme-policy-pack');
 
const result = runDomRulesInPage(url, null, { packs: [acmePolicy], profile: 'acme-web-2026' });
result.engine.packs; // ['@acme/a11y-policy@1.0.0']
getChecksCatalog({ packs: [acmePolicy] }); // core's rules and the pack's

コアと両立しないパック(そのcoreの範囲がこのバージョンを含まない、名前空間のないルールID、コアが持つ辞書のキー)は、console.warnを出してスキップされ、結果のskippedPacksに{ name, reason }として列挙され、スキャンはそのパックなしで実行されます。strictOptionsのもとではcode: 'INVALID_ENGINE_OPTIONS'付きのエラーを投げます。互いに衝突するパックはエラーを投げます。ページ内では、まずpackScript(packs)でパックを登録し、engineOptions.packsでname@versionとして指定します。パックが持つもの、各バインディング、test-matchers、CLIからの使い方、パックの書き方はパックにあります。

contextSelector(ランナーの第2引数。engineOptionsのフィールドではありません)

スキャン範囲を1つ以上のサブツリーに絞るCSSセレクター(またはセレクターの配列)です。document.querySelectorAllで解決され(最初の一致だけでなく、すべての一致が対象)。ドキュメント全体をスキャンするにはnullを渡します。

  • 何にも一致しないセレクターは、何もスキャンしません。ページ単位のルールも含め、すべてのルールがnotApplicableを報告し、結果のcontextMatchがそのことを示します。{ elementCount: 0, unmatchedSelectors: ['#mian'] }(出力スキーマを参照)。実行時にはconsole.warnも出力されます。ページにない範囲を、ページ全体に広げることはしません。求めていないコンテンツについての結果、しかもページ全体のpassを含む結果は、求めた部分についての結果のように読めてしまうからです。配列の場合、何にも一致しないセレクターはunmatchedSelectorsに記録され、ほかのセレクターは通常どおりスキャンされます。そのため、Cookieバナーのように、ページにあるときとないときがあるコンテンツもリストに含めておけます。1.10.0より前は、何にも一致しない範囲はドキュメント全体にフォールバックし、結果にはそのことが何も示されませんでした。
  • ブラウザーが解析できないセレクターは、例外を投げます。単独でも配列内でも、どのルールも実行される前にcontextSelector: "#main[" is not a valid CSS selector.というエラーになります。このエラーはcode: 'INVALID_CONTEXT_SELECTOR'と、失敗したセレクターであるselectorを持ちます。何にも一致しないセレクターと違い、これは常に呼び出し側の誤りです。runa11yCoreAcrossFramesも同じエラーでrejectします。page.evaluate(Playwright、Puppeteer)を越えたエラーにはメッセージしか残らないため、メッセージにオプション名とセレクターが含まれています。1.10.0より前は、無効なセレクターはスキップされ、単独で指定した場合はドキュメント全体がスキャンされていました。
  • セレクター、セレクターの配列、null以外のものは、同じエラーを投げます。エラーは渡されたものを示します。要素、NodeList、{ include, exclude }オブジェクト、数値、文字列でない配列の項目(contextSelector[1] must be a CSS selector, not the number 5.)がこれに当たります。代わりにその要素に一致するセレクターを渡し、excludeで除くはずだったものはengineOptions.excludeSelectorsに指定してください。
  • 単一の文字列自体をカンマ区切りのセレクターリストにできます(通常のCSSと同じく和集合として扱われます)。'#a, #b'は#aと#bの両方をスキャンします。
  • 文字列の配列を渡すと、各セレクターに一致したものの和集合をスキャンします。['#a', '.card']は'#a, .card'と同じ動作です。配列形式は、リストをプログラムで組み立てる呼び出し側のためにあります。
  • シャドウDOM:includeShadowDom(デフォルト)が有効なら、範囲にはその中のシャドウルートが含まれ、範囲自体がシャドウホストであればそのシャドウルートも含まれます。セレクターはドキュメントに対して照合されるため、シャドウルートの内側の要素は選択できません。代わりにそのホストを範囲に指定してください。
  • 重なり合う領域や入れ子になった領域は自動的に重複除去されます。一致した複数のルートから到達できる要素も、領域ごとではなく1回だけ報告されます。
  • 範囲を絞った結果の意味:ほとんどのルールは要素を1つずつ判定し、範囲内の要素をページ全体のスキャンとまったく同じように判定します。周囲のページに依存するルールは2種類あります。ページ全体を対象とするルール(page-title-present、landmark-one-main、そのほか前述のfragmentに挙げたもの)はnotApplicableを報告します。ページ全体で要素どうしを比較するルール(landmark-unique、landmark-no-duplicate-banner、同-contentinfoと-main、landmark-banner-is-top-level、同-complementary-、-contentinfo-、-main-is-top-level、accesskeys、heading-order、identical-links-same-purpose、identical-iframes-same-purpose)は、範囲内で見つけたものは報告します。範囲内で名前が重複している2つのランドマークは、どのページでも重複しているからです。ただしpassの代わりにnotApplicableを報告します。スキャンが見たのはページの一部だけなので、ページに問題がないとは言えないからです。duplicate-idとduplicate-id-ariaは、重複相手が範囲外にあることもあるため、範囲内の各要素をドキュメント全体と比較し、IDがほかのどこかにも現れる範囲内の要素を報告します。これらのpassは、範囲内のどの要素もページ上のほかの要素とIDを共有していないという意味です。範囲外だけにある重複のペアは、ほかのルールと同じく報告されないため、ページ全体に重複がないという意味にはなりません。target-size-minimumは、間隔に関する例外がターゲットの隣に何があるかで決まるため、範囲内のターゲットをドキュメント内のどこにある隣接要素とも比べて判定します。text-spacing-content-lossは範囲内のテキストを判定し、それがページ上のどこかのテキストと重なるようになるかを確認します。