Gatsbyのアクセシビリティテスト用のプラグインを書きました。
gatsby-plugin-a11y-reportです。
もともとGatsbyにはgatsby-plugin-react-a11yというreact-axeを使ったプラグインがあるのですが、その元となったreact-axeがviolationsしか表示してくれないので、incompleteも表示するように書き直したりしているうちに差分が大きくなりすぎたので独立したような感じです。
また、gatsby develop
時だけでなく、build時にはaxeのレポートを以下のようにlogsディレクトリに出力します。
{"title":"Gatsby Build: A11y Check Start","pages":14,"logging":["violations","incomplete"],"ignore":["/404*","/tag/*"],"device":{"name":"Chrome","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/80.0.3987.0 Safari/537.36","viewport":{"width":1280,"height":600,"deviceScaleFactor":1,"isMobile":false,"hasTouch":false,"isLandscape":false}},"level":"info","service":"axe-report","timestamp":"2020-02-23T08:20:12.697Z"}
{"path":"/offline-plugin-app-shell-fallback","result":"violations","id":"document-title","impact":"serious","description":"各HTMLドキュメントに空ではない<title>要素が含まれていることを確認します","html":"<html>","target":["html"],"level":"error","service":"axe-report","timestamp":"2020-02-23T08:20:19.766Z"}
{"path":"/offline-plugin-app-shell-fallback","result":"violations","id":"html-has-lang","impact":"serious","description":"すべてのHTMLドキュメントにlang属性が存在することを確認します","html":"<html>","target":["html"],"level":"error","service":"axe-report","timestamp":"2020-02-23T08:20:19.767Z"}
~省略~
{"path":"/posts/humane-typography-in-the-digital-age","result":"violations","id":"region","impact":"moderate","description":"ページのすべてのコンテンツがlandmarkに含まれていることを確認します","html":"<div class=\"Post-module--post__footer--1BvmJ\">","target":[".Post-module--post__footer--1BvmJ"],"level":"error","service":"axe-report","timestamp":"2020-02-23T08:20:20.840Z"}
{"title":"Gatsby Build: A11y Check Complete","complete":true,"violations":45,"incomplete":3,"level":"info","service":"axe-report","timestamp":"2020-02-23T08:20:20.855Z"}
gatsby build
をGitのpush時などに自動実行しているような場合にviolationsの数をチェックしてCIするのに便利に使えるかなと思います。
使い方
インストール
通常のGatsbyプラグイン同様、セットアップしたGatsbyサイトのディレクトリで以下のようにプラグインをインストールします。
Puppeteerとexpress、Winstonを内部で利用しているので結構重いプラグインになっています。
npm install --save gatsby-plugin-a11y-report
あるいはYarnを利用してモジュールを追加。
yarn add gatsby-plugin-a11y-report
gatsby.configに設定を追加
インストール出来たらプラグインを利用するようにGatsbyを設定します。
gatsby-config.js
に以下のように設定します。
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: 'gatsby-plugin-a11y-report',
options: {
showInProduction: false,
toastAutoClose: false,
query: `
{
allSitePage(
filter: {
path: { regex: "/^(?!/404/|/404.html|/dev-404-page/)/" }
}
) {
edges {
node {
path
}
}
}
}
`,
ignoreCheck: [
'/404*',
'/tag/*'
],
serverOptions: {
host: 'localhost',
port: '8341'
},
axeOptions: {
locale: 'ja',
},
loggingOptions: {
result: ['violations', 'incomplete']
}
},
},
],
}
オプション設定
以下のオプションはquery
以外すべて省略可能です。
showInProduction
デフォルト:false
トーストとConsoleへの出力をproductionでも行う場合、true
にしてください。(gatsby-react-axe互換。まぁ、一般的にはfalseのまま使うかと思いますが。)
toastAutoClose
デフォルト:false
gatsby develop
時に表示するトーストを一定時間で自動的に閉じる設定です。
エラーにすぐ気が付くようにviolationsの件数などをトースト表示するようにしたのですが、そもそもトーストがaxeのチェックでコントラスト不足だったり、画面遷移時にうまく消えてくれなかったりアクセシビリティ的によろしくない状況でして、この機能は将来廃止するかデフォルトでは非表示にするなどしようかと考えています。
もう少し調整してみるつもりですが。
query
(必須)
GatsbyJSの特徴でもあるGraphQLで、Build時にチェックするサイトのパスを指定します。
filterによりテストでログに残したい対象ページを柔軟に絞り込むことができます。
ignoreCheck
queryのfilterで絞り込めることに気が付かなかったときに作ってしまった機能ですが、正規表現でパスを記述するのこっちのほうが楽な気がするので残してます。作っていきなり後方互換みたいになっていますが、たぶんGraphQL上手な人はいらないやつですが、GraphQLで絞り込んだあとに追加で絞り込みが実行されますので、使い方次第で便利かも。
serverOptions
デフォルト: { host: 'localhost', port: '8341' }
プラグインはBuild時にExpressの検証用サーバを立ち上げますが、その検証サーバのホストとポートを指定します。ちなみにプラグインはPuppeteerで検証サーバにアクセスしてaxeのレポートをログとして出力します。
axeOptions
axeのオプションを指定します。
通常はログに出力するレポートの言語を指定します。指定がない場合はブラウザの設定から推測してロケール設定します。
そのほかの指定可能なオプションはaxe-coreのドキュメントを参照してください。
loggingOptions
デフォルト:result: ['violations']
Build時に出力するログの種類を配列で指定します。指定可能なのは'violations', 'incomplete', 'inapplicable', 'passes'
の4つです。デフォルトではviolations
だけ出力します。
今後の予定
より柔軟にロギングの設定がしやすいようにしたいのですが、gatsby-config
の設定が肥大化するのは避けたいので何か方法を検討中。ほかのプラグインでよさげな方法をとっているものがないか調べてみるつもりですが、何か情報をお持ちの方がいれば教えてください。