以前にaxe DevToolsという拡張機能を使ってみる記事を投稿しましたが、そのコアエンジンにあたるaxe-coreというライブラリを使って、テストの内容や対象ページを設定した上でテストできるようにしてみます。
作成方法
プロジェクトディレクトリなどに移動して、package.jsonを作成します。
1 | npm init -y |
使用するパッケージをインストールします。
1 | npm install puppeteer axe-core @axe-core/puppeteer csv-writer --save |
a11y-test.js というファイルを作成して、以下の内容にします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | const puppeteer = require( 'puppeteer' ); const { AxePuppeteer } = require( '@axe-core/puppeteer' ); const axeLocales = require( 'axe-core/locales/ja.json' ); const createCsvWriter = require( 'csv-writer' ).createObjectCsvWriter; // テスト対象のURLリスト const urls = [ ]; // ルールの設定 const axeRules = [ 'wcag2a' , 'wcag2aa' , 'wcag21a' , 'wcag21aa' , 'wcag22a' , 'wcag22aa' , 'best-practice' ]; // CSVの設定 const csvWriter = createCsvWriter({ path: 'a11y-test_results.csv' , // 出力されるCSVファイルのパス header: [ // CSVのヘッダー情報 { id: 'url' , title: 'URL' }, // 対象のページURL { id: 'violationId' , title: 'Violation ID' }, // 違反したルールのID { id: 'impact' , title: 'Impact' }, // 違反の影響度(critical, serious, moderate, minor) { id: 'html' , title: 'HTML' }, // 違反箇所のHTML { id: 'target' , title: 'Target' }, // 違反対象要素 { id: 'description' , title: 'Description' }, // エラー内容の説明 { id: 'helpUrl' , title: 'Help URL' }, // ルールに関する詳細なヘルプURL ] }); // 対象のURLに対してアクセシビリティテストを実行 async function runAccessibilityTest(url) { // ブラウザを起動して、新しい空白ページを開く const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); try { // 指定したURLに移動 await page.goto(url, { waitUntil: 'networkidle2' // ページが完全にロードされるまで待機 }); // axe-coreを使ってテストを実行 const results = await new AxePuppeteer(page) .withTags(axeRules) // ルールの設定 .configure({ locale: axeLocales // 日本語ローカライズファイルを指定 }) .analyze(); // 違反結果を元に、CSVに出力するためのデータ形式に整形 const violations = results.violations.map( function (violation) { // 各違反について、詳細なノード情報を取得して配列に追加 return violation.nodes.map( function (node) { return { url: url, // 対象のページURL violationId: violation.id, // 違反したルールのID impact: violation.impact, // 違反の影響度(critical, serious, moderate, minor) html: node.html, // 違反箇所のHTML target: node.target, // 違反対象要素 description: violation.description, // エラー内容の説明 helpUrl: violation.helpUrl // ルールに関する詳細なヘルプURL } }); }).flat(); // 整形した違反データをCSVファイルに書き込み await csvWriter.writeRecords(violations); } catch (error) { console.error(`Error testing ${url}:`, error); } finally { // ブラウザを閉じる await browser.close(); } } // 全ての対象URLに対してテストを実行 ( async () => { for (const url of urls) { await runAccessibilityTest(url); } console.log( 'テスト完了しました。' ); })(); |
コード内にあるテスト対象のURLリストやルールの設定は適宜変更してください。
ルール設定の注意点として、例えば’wcag2aa’を指定した場合、’wcag2a’の内容は含まれていないため別途指定が必要になります。
同様に’wcag21aa’を指定した場合も、’wcag2a’や’wcag2aa’の内容は含まれていません。
詳しくはドキュメントにあるタグの項目やルールの項目をご確認ください。
後はa11y-test.jsを実行してやればOKです。
1 | node a11y-test.js |
例として対象URLを「https://cly7796.net/blog/」にして試してみると、以下の内容でa11y-test_results.csvというファイルが生成されました。
1 2 3 4 5 | URL,Violation ID,Impact,HTML,Target,Description,Help URL https://cly7796.net/blog/,region,moderate,"< div class = "" l-sub__box"">",.l-sub__box:nth-child(1),ページのすべてのコンテンツがlandmarkに含まれていることを確認します,https://dequeuniversity.com/rules/axe/4.10/region?application=axe-puppeteer&lang=ja https://cly7796.net/blog/,region,moderate,"< div class = "" l-sub__box"">",.l-sub__box:nth-child(2),ページのすべてのコンテンツがlandmarkに含まれていることを確認します,https://dequeuniversity.com/rules/axe/4.10/region?application=axe-puppeteer&lang=ja https://cly7796.net/blog/,region,moderate,"< div class = "" l-sub__box"">",.l-sub__box:nth-child(3),ページのすべてのコンテンツがlandmarkに含まれていることを確認します,https://dequeuniversity.com/rules/axe/4.10/region?application=axe-puppeteer&lang=ja https://cly7796.net/blog/,region,moderate,"< table id = "" wp-calendar"" class = "" wp-calendar-table"">",#wp-calendar,ページのすべてのコンテンツがlandmarkに含まれていることを確認します,https://dequeuniversity.com/rules/axe/4.10/region?application=axe-puppeteer&lang=ja |
コメントが承認されるまで時間がかかります。