CLIで使う
コードの代わりにコマンドで実行します。テストフレームワークもNodeスクリプトも不要なので、パイプラインの1ステップや、ビルド成果物の簡単なチェックに向いています。
最初のスキャン
$ npm install -g @surea11y/cli$ surea11y scan ./index.html$ surea11y scan https://example.com/ --wcag 2.2
Node.js^20.19.0 || ^22.13.0 || >=24.0.0が必要です。概要には、スキャンを実行した@surea11y/coreのリリースが示されます。
$ surea11y scan ./index.htmlsurea11y scan: file:///path/to/index.htmlengine: @surea11y/core 1.14.1pass: 16 fail: 4 cantTell: 4 notApplicable: 121occurrences by tier: fail: 4 cantTell: 4needs review: likely fail: 1 likely pass: 0 needs a person: 3FAIL (4 rule(s)):button-name-present (serious, 1 fail occurrence(s))- html > body > main > buttonThis button has no accessible name.hint: Give the button visible text, or name it with aria-label, so screenreader users know what it does.contrast-enhanced (serious, 1 fail occurrence(s))- html > body > main > pElement has insufficient color contrast (AAA) of 2.85:1 (foreground:#999999, background: #ffffff, font size: 16px, font weight: normal).Expected contrast ratio of 7:1 (normal text).hint: Change the text color, the background color, or both, so thecontrast ratio reaches at least 7:1.contrast-minimum (serious, 1 fail occurrence(s))- html > body > main > pElement has insufficient color contrast of 2.85:1 (foreground: #999999,background: #ffffff, font size: 16px, font weight: normal). Expectedcontrast ratio of 4.5:1 (normal text).hint: Change the text color, the background color, or both, so thecontrast ratio reaches at least 4.5:1.img-alt-present (serious, 1 fail occurrence(s))- html > body > main > imgThis <img> has no alt attribute.hint: Add an alt attribute that says what the image shows, or alt="" ifthe image is purely decorative.LIKELY FAIL — confirm (1 occurrence(s)):- heading-order (minor): html > body > main > h3This heading jumps from level 1 to level 3, skipping a level.why: The heading skips a level after the one before it.cantTell — needs human review (4 rule(s)): heading-order, link-name-quality,manual-review, page-title-patternscriteria (WCAG 2.2):fail 1.1.1 Non-text content: text alternatives; 1.4.3 Contrast: minimum;1.4.6 Contrast: enhanced; 4.1.2 Name, role, value: accessible namecantTell 1.2.1 Audio-only and video-only (prerecorded): transcript; 1.2.2Captions (Prerecorded); 1.3.1 Info and Relationships; 1.3.4Orientation; 1.3.5 Identify Input Purpose; 1.4.1 Use of Color;1.4.2 Audio Control; 1.4.4 Resize Text; 1.4.5 Images of Text;1.4.12 Text Spacing; 2.1.1 Keyboard; 2.1.3 Keyboard (No Exception);2.2.1 Timing Adjustable; 2.2.2 Pause, Stop, Hide; 2.2.4Interruptions; 2.4.1 Bypass Blocks; 2.4.2 Page titled; 2.4.3 Focusorder; 2.4.4 Link Purpose (In Context); 2.4.6 Headings and Labels;2.4.7 Focus visible; 2.4.9 Link Purpose (Link Only); 2.5.8 Targetsize: minimum; 3.1.1 Language of page; 3.1.2 Language of Parts;3.2.5 Change on Request; 3.3.1 Error Identification; 3.3.2 Labelsor Instructions; 3.3.8 Accessible Authentication (Minimum); 4.1.2Name, role, value: ARIA validity; 4.1.3 Status MessagesnotApplicable: 2A criterion that passes here means the checks that ran found nothing in it,not that the page conforms.
needs reviewの行は、確認する人がその問いをどう扱うかで問いを分類します。likely fail(この例の見出しレベルの飛びのように、ページの証拠が失敗を示しているもの)、likely pass、needs a personの3つです。不適合の可能性が高いものは、そちらに傾いている理由とともに一覧になり、--jsonとレポートの各問いには、答えるための手順(howToCheck)が含まれます。
criteriaのブロックは、同じスキャンをWCAGの達成基準ごとに読み直したものです。「1.4.3で不合格か」という、よくある問い方に合わせています。fail、cantTellの順に並び、notApplicableは件数だけを示します。@surea11y/core1.14からは、passとして示される達成基準はありません。達成基準が合格になるのは、そのルールが基準の求めることをすべてチェックする場合だけで、完全にチェックできるとされた基準はまだないため、ルールがすべて合格した基準もcantTellになり、残りを人が確認します。このブロックが終了コードを変えることはなく、--compactでは件数だけを示します。失敗したルールがない場合、サマリーの最後に、それはページが適合しているという意味ではないことと、人がまだ確認することが示されます。
複数のページ、またはサイトマップ
複数のページを指定するか、ファイルに一覧にする(1行に1つのパスかURL、#でコメント)か、サイトマップをスキャンの対象にします。
$ surea11y scan ./dist/index.html ./dist/pricing.html$ surea11y scan --urls pages.txt$ surea11y scan --sitemap https://example.com/sitemap.xml # up to 50 pages; --max-pages to change it
サマリーにはページごとのセクションがあり、最後の行で失敗のあったページを数えます。どれか1ページでも失敗すれば、実行全体が失敗します。--jsonは配列を出力し、--sarifと--junitはすべてのページをまとめた1つのファイルを書き出し、--htmlはページごとにレポートを書き出します(report.html、report-2.html…)。ベースラインは、既知の失敗がそれぞれどのページにあったかを記録します。サイトマップはURLでもローカルファイルでもよく、gzip圧縮されていてもかまいません。サイトマップインデックスは1階層下までたどります。スキャンできないページがあると、何かを書き出す前にそのページを示して、終了コード2で実行を止めます。
実際のブラウザーで
既定では、CLIは静的なHTMLを読みます。JavaScriptで内容をレンダリングするページには、プロジェクトにPlaywrightをインストールして--browserを付けます。各ページがヘッドレスのChromiumで開かれ、スクリプトが実行され、スキャンはレンダリングされた内容を、レイアウトを測るルールのための実際のレイアウトとともに見ます。エンジンは同じ@surea11y/coreで、レポート、ベースライン、パック、カスタムルールを含むすべてのオプションが使えます。
$ npm install --save-dev playwright$ npx playwright install chromium$ surea11y scan https://app.example.com/ https://app.example.com/settings --browser
読み込み後にデータを取得するアプリでは、スキャンにそのデータを待たせることができます。また、スマートフォンの幅やダークモードで、あるいは複数の値のすべての組み合わせでスキャンできます。
$ surea11y scan https://app.example.com/orders --browser --wait-for "#orders-table"$ surea11y scan https://example.com/ --browser --width 320 --color-scheme dark$ surea11y scan https://example.com/ --browser --width 1280,320 --color-scheme light,dark
--wait-forは最大30秒待ち(--wait-timeoutで変更できます)、要素が表示されなければ終了コード2で実行を止めます。複数の幅やカラースキームを指定すると、ページを1回だけ読み込み、ページごとに1つの結果にスキャンをまとめます。各ルールの判定結果は最も悪いものになり、各検出結果は見つかった組み合わせとともに1回だけ示されます(seen in:)。
各ページの読み込み前に、CLIはcoreのinternalsフックとリスナーフックをインストールします。そのため、スキャンはWebコンポーネントがElementInternalsで設定した名前と、スクリプトから追加されたクリックハンドラーも判定します。EnterキーやSpaceキーが届かないrole="button"は失敗します。--live-regionsはライブリージョンフックを追加し、テキストが入った状態で追加された、スクリーンリーダーが読み上げないことの多いステータスメッセージについて確認を求めます。--no-hooksは最初の2つのフックを使いません。サマリーには、各スキャンのビューポート、カラースキーム、フックが示されます。CLIはクリック、入力、ログインをしません。その後に初めて表示される内容には、いずれかのバインディングでブラウザーを操作してください。ページ内のフレームはまだスキャンしません。
実行するものを選ぶ
--wcagは、WCAGの適合性の目標に対応するルールを、各達成基準がそのバージョンで持つレベルに従って選択します。--wcag-levelはその目標のレベルを設定します(指定しなければAA)。--best-practicesは、regionやheading-orderなど、WCAGの達成基準を検査しないルールを追加します。単独で使うと、それらのルールだけを実行します。--profileは、en301549-v4.1.1やパック独自のものなど、適合性プロファイルを実行します。
$ surea11y scan ./dist/index.html --wcag 2.2 # WCAG 2.2, Level A and AA$ surea11y scan ./dist/index.html --wcag 2.1 --wcag-level A # WCAG 2.1, Level A$ surea11y scan ./dist/index.html --wcag 2.2 --best-practices # and the best practices
WCAG 2.2で削除された4.1.1「構文解析」は、2.1の目標には含まれ、2.2の目標には含まれません。--rulesと--tagsは目標のルールに追加され、--exclude-rulesはその後に適用されます。--profileと併用すると、--best-practicesはそのルールを追加し、プロファイルも引き続き適用されます。--wcag、--rules、--tagsはプロファイルの代わりにルールを選ぶため、--profileをこれらのいずれかと併用すると終了コード2で終了します。これらはrunOnly.wcag、runOnly.bestPractices、engineOptions.profileに対応します(エンジンオプションを参照)。
チェックを自分で指定する
両方を指定すると、--rulesと--tagsは両方に一致するルールを実行します。「この領域に加えて、これらのチェックも」としたい場合は--include-mode orを指定します。どちらかに一致するルールを実行します。これを付けないと、下のスキャンはルールを1つも実行しません。contrast-computableにはformsのタグがないためです。その場合、何もチェックせずに合格するのではなく、終了コード2で終了します。
$ surea11y scan ./dist/form.html --tags forms --rules contrast-computable --include-mode or
チェックを指定したスキャンは、それらのチェックが属するWCAGの達成基準を、すべてのレベルで報告します。contrast-computableは1.4.3(AA)と1.4.6(AAA)をチェックするため、AAを満たすサイトでも、目指していないAAAの達成基準が不合格として表示されることがあります。--wcagを付けない場合、--wcag-levelは、実行するルールを変えずに、報告する達成基準のレベルを設定します。
$ surea11y scan ./index.html --rules contrast-computable --wcag-level AAsurea11y scan: file:///path/to/index.htmlengine: @surea11y/core 1.14.1WCAG level reported: AApass: 1 fail: 0 cantTell: 0 notApplicable: 0occurrences by tier: fail: 0 cantTell: 0criteria (WCAG 2.2 AA):cantTell 1.4.3 Contrast: minimum (partly checked: 1 of 2 checks not selected)A criterion that passes here means the checks that ran found nothing in it,not that the page conforms.No rule failed, which is not a claim that the page conforms: the automated rulesfound nothing definite. A person still checks the cantTell findings, keyboarduse, how a screen reader reads the page, and the content itself.
1.4.3は一部だけチェック済みです。もう1つのチェックであるcontrast-minimumが選ばれていないため、その判定結果は実行されたチェックだけに基づきます。また、失敗したルールがないため、サマリーの最後に、それはページが適合しているという意味ではないことが示されます。ルールIDとレベルは大文字小文字を区別しません(--rules IMG-ALT-PRESENT、--wcag-level aa)。--include-modeはengineOptions.includeModeに、--wcagなしの--wcag-levelはengineOptions.wcagLevelに対応します。
パック
--packは、パック(ルール、規格、チェックリストと、それらのプロファイル)を、作業ディレクトリのプロジェクトから解決されるパッケージ名か、パスで読み込みます。--profileはそのプロファイルの1つを実行します。複数のパックでスキャンするには--packを繰り返します。
$ surea11y scan ./dist/index.html --pack @acme/a11y-policy --profile acme-web-2026$ surea11y scan ./dist/index.html --pack ./acme-policy-pack.js --profile acme-web-2026
概要には、実行されたプロファイルとパックが示され、--jsonではそれらがengine.profileとengine.packsに入ります。見つからない、読み込めない、またはエンジンがスキップしたパックは、レポートを書き出さずに終了コード2で終了します。そのため、パックのチェックが実行されないままスキャンが合格することはありません。
重大な問題でだけ失敗させる
--fail-on-severity(critical、serious、moderate、minor)を付けると、その重大度以上で失敗したルールがある場合にだけ実行が失敗します。--baselineと組み合わせると、新しいものだけが対象です。失敗はすべて引き続き報告され、サマリーではそのレベル未満のものに印が付きます。これで、まず重大な問題でブロックし、未対応の問題が減るにつれてゲートを厳しくしていけます。
$ surea11y scan --urls pages.txt --fail-on-severity serious
不適合の可能性が高い問い
--fail-on-leanを付けると、不適合の可能性が高い問い(coreのleaningFailures())でも実行が失敗します。--fail-on-severityを指定した場合は、そのレベル以上のものだけが対象です。--lean-fail-wcag-onlyは、WCAGの達成基準に対応付けられたルールのものだけを数え、ベストプラクティスを除きます。このオプションを付けると、--junitはそのようなルールを失敗したテストとして、--sarifはそのような検出結果をerrorとして報告し、--write-baselineは現在の不適合の可能性が高いものも記録するので、--baselineは新しいものだけでブロックします。傾きは証拠であって証明ではなく、検出結果が傾くかどうか、どちらに傾くかはcoreのマイナーリリースで変わることがあるため、オプトインになっています。
$ surea11y scan ./dist/index.html --fail-on-lean --lean-fail-wcag-only$ surea11y scan ./dist/index.html --fail-on-lean --write-baseline baseline.json # once, commit it$ surea11y scan ./dist/index.html --fail-on-lean --baseline baseline.json # in CI, from then on
コンパクトな結果
--compactは、passとnotApplicableの各結果を、ルール、判定結果、種類だけにします(engineOptions.output.detail: 'findings')。CIのアーティファクトとして結果を保存するための、より小さな--jsonです。概要、終了コード、ベースライン、HTML・SARIF・JUnitのレポートは、付けない場合と同じです。
$ surea11y scan ./dist/index.html --compact --json > result.json
終了コードと制限事項
--fail-on-leanを付けない限り、cantTellは終了コードに影響しません。0は失敗となる判定結果なし、1はいずれかのページにfailが1件以上ある場合(--baselineを付けてスキャンした場合は、新しいfailが1件以上ある場合。CIゲートで使うケースです。--fail-on-severityはそのレベル以上のものだけを数えます。何が「既知」で何が「新規」とみなされるかはベースライン/許可リストを参照)、2は使い方の誤りまたはスキャンのエラー、あるいは何もチェックしないか、求められたより少なくしかチェックしないスキャンです。既知のルールやタグを1つも示さない--rules/--tagsのリスト、何にも一致しない--contextのセレクター、実行されなかったカスタムルールやパック、適用されなかった--profileがこれに当たります。core 1.13で書き出したベースラインは、1.14が原因ごとに分けた理由コードの検出結果にも引き続き一致します。--migrate-baseline baseline.jsonで新しいコードに書き直せます。
--browserを付けない場合、CLIが読むのは静的なHTMLだけです。ローカルファイルか、HTTP(S) GETで取得した生のレスポンスボディを読み、ページのJavaScriptは一切実行しません。どちらのモードもクリック、入力、ログインはしません。その後に初めて表示される内容には、いずれかのバインディングを使うか、自分で操作するブラウザーに対してエンジンを直接呼び出してください(GitHubにある連携ガイドINTEGRATION.mdのPattern 2を参照)。
フラグの完全なリファレンス、カスタムルールの契約、パック、CIのレシピはdocs/CLI.mdにあります。CIパイプラインのテンプレートについてはCI連携を参照してください。