Axe DevTools Cypressでテストを書く
CypressでAxe DevTools for Webを使ったアクセシビリティテストを書く
Axe DevToolsを使用したアクセシビリティスキャンの結果を生成するのは、1行のコードで簡単に行うことができます。これらの結果は生のまま利用することも、アサーションライブラリと併用することも、アクセシビリティレポートを作成するのに使用することもできます。
@axe-devtools/cypressはCypress 4から13までをサポートしています。これらの手順はCypress 10.0で導入されたプロジェクトのレイアウトについて説明しています。もしCypress 9以前を使用している場合は、cypress/integrationにスペックを配置し、cypress/plugins/index.jsでプラグインを登録し、cypress/support/index.jsにインポートを追加してください。
前提条件
Axe DevTools を使用してページをテストするには、まずプロジェクトにインストールされている必要があります。このステップをまだ完了していない場合は、インストールガイドを参照してください。
プロジェクト構成
.
├── package.json
├── cypress.config.js
├── cypress
│ ├── e2e
│ │ └── test.cy.js
│ └── support
│ └── e2e.js
└── results
└── broken-workshop.jsonCypress 10.0ではcypress.jsonの設定ファイルがcypress.config.js(またはcypress.config.ts)に置き換えられ、cypress/integrationのスペックディレクトリがcypress/e2eに名前が変更され、cypress/support/index.jsはcypress/support/e2e.jsに名前が変更され、cypress/pluginsディレクトリは設定ファイルのsetupNodeEvents関数に置き換えられました。スペックファイルは.spec.jsではなく.cy.jsサフィックスを使用します。
resultsディレクトリには、テストによって書かれたJSONスキャン結果が格納されます。Cypressは最初の書き込み時にそれを作成するので、自分で追加する必要はありません。
セットアップ
Axe DevTools Cypress を使用するには、以下が必要です。セットアップは JavaScript と TypeScript の両方で示されています。Cypress はどちらの拡張子も読み込むため、TypeScript プロジェクトでは、それぞれの.jsの代わりに cypress.config.ts、cypress/support/e2e.ts、.cy.tsスペックファイルを使用します。
JavaScript
次の行をcypress/support/e2e.jsに含めてください:
import '@axe-devtools/cypress';cypress.config.jsファイル内には、以下を追加する必要があります:
const { defineConfig } = require('cypress');
const axeDevtoolsCypressPlugin = require("@axe-devtools/cypress/dist/plugin");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
axeDevtoolsCypressPlugin(on);
return config;
}
}
});TypeScript
TypeScript が Cypress と Node の型を認識するために、スペックと一緒にtsconfig.jsonを追加してください。
{
"compilerOptions": {
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress", "node"]
},
"include": ["**/*.ts"]
}cypress/support/e2e.tsに次の行を含めてください。パッケージをインポートすることにより、cy.axeAnalyze()、cy.getAxeResults()、およびその他の Axe DevTools コマンドの型も登録されるので、@axe-devtools/cypress には別途@types/パッケージは不要です。
import '@axe-devtools/cypress';cypress.config.tsファイル内に次を追加する必要があります。プラグインは CommonJS エントリーポイントとして公開されているため、TypeScript でもrequireでロードしてください。
import { defineConfig } from 'cypress';
const axeDevtoolsCypressPlugin = require('@axe-devtools/cypress/dist/plugin');
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
axeDevtoolsCypressPlugin(on);
return config;
}
}
});サンプルファイルの完成版
各it()ブロックの内部でcy.axeAnalyze()とcy.getAxeResults()を呼び出し、他のテストの結果が上書きされないように、各テストにユニークなファイル名を使用してください。
JavaScript
e2eディレクトリのtest.cy.jsファイルにこのコードを追加してください:
describe('Axe DevTools Cypress', () => {
it('Scans the home page for accessibility issues', () => {
// Visit the page to test
cy.visit('https://broken-workshop.dequelabs.com')
// Run an accessibility scan on the current page
cy.axeAnalyze()
// Write results to a uniquely named file; use a different name for each test to avoid overwriting
cy.getAxeResults().then(results => {
cy.writeFile('./results/broken-workshop.json', results)
})
})
})TypeScript
test.cy.tsファイルをe2eディレクトリに追加してください。パッケージが登録するコマンドタイプはresultsに型AxeDevToolsResults | nullを与えるので、nullを受け入れないcy.writeFile()に渡す前に絞り込んでください。
describe('Axe DevTools Cypress', () => {
it('Scans the home page for accessibility issues', () => {
// Visit the page to test
cy.visit('https://broken-workshop.dequelabs.com')
// Run an accessibility scan on the current page
cy.axeAnalyze()
// Write results to a uniquely named file; use a different name for each test to avoid overwriting
cy.getAxeResults().then(results => {
if (!results) {
throw new Error('cy.getAxeResults() returned no results')
}
cy.writeFile('./results/broken-workshop.json', results)
})
})
})すぐに実行可能な TypeScript プロジェクトがAxe DevTools API の例のリポジトリにあります。
テストの実行
テストを書きながらCypressアプリを開くか、CIでスイートをヘッドレスで実行できるようにpackage.jsonにスクリプトを追加してください:
{
"scripts": {
"test": "cypress run",
"test:open": "cypress open"
}
}Run all specs in cypress/e2e headlessly with npm test, or open the interactive Cypress app with npm run test:open. To run a single spec, pass the --spec flag: npx cypress run --spec cypress/e2e/test.cy.js.
クロスオリジンとサンドボックス化されたIframes
cy.axeAnalyze()はaxe-coreをテスト対象のページとアクセス可能な各iframeに注入します。Cypressが注入できないiframe、例えばクロスオリジンiframeやsandbox属性を持つiframeはスキップされます:スキャンは続行され、テストを失敗させることなくページの残りの部分の結果を報告します。スキップされたiframe内のコンテンツは解析されないため、それらのページのカバレッジが必要な場合は、自分のスペックで直接テストしてください。
