From b513ef6df5f69108872f0c6835cc1ba664dabdb3 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 21 Nov 2019 17:38:46 +0000 Subject: [PATCH] A11y: Add axe-puppeteer tests (#302) --- editor.html | 2 +- tests/jest.config.js | 4 +- tests/package-lock.json | 37 +++++++++++++++ tests/package.json | 3 ++ tests/spec/puppeteer-axe-spec.js | 80 ++++++++++++++++++++++++++++++++ 5 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 tests/spec/puppeteer-axe-spec.js diff --git a/editor.html b/editor.html index 94dd2248..772525f6 100644 --- a/editor.html +++ b/editor.html @@ -180,7 +180,7 @@

{{ title }}

{{ hint }}

-
+
/setup-tests.js'], // A list of paths to modules that run some code to configure or set up the testing framework before each test - // setupFilesAfterEnv: [], + setupFilesAfterEnv: [ + "@wordpress/jest-puppeteer-axe" + ], // A list of paths to snapshot serializer modules Jest should use for snapshot testing // snapshotSerializers: [], diff --git a/tests/package-lock.json b/tests/package-lock.json index 28633b76..7d90795c 100644 --- a/tests/package-lock.json +++ b/tests/package-lock.json @@ -148,6 +148,14 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, + "@babel/runtime": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.2.tgz", + "integrity": "sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, "@babel/template": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", @@ -469,6 +477,15 @@ "integrity": "sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==", "dev": true }, + "@wordpress/jest-puppeteer-axe": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-puppeteer-axe/-/jest-puppeteer-axe-1.3.0.tgz", + "integrity": "sha512-rQg88X4cgN3UKSUazAlI4q6+nQfTIBe8I3l31GUGlUOeTNjmvJOO6+sFJDGsP4/h8XLYhOZe4j2Y9m0OMa02eQ==", + "dev": true, + "requires": { + "axe-puppeteer": "^1.0.0" + } + }, "abab": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.2.tgz", @@ -644,6 +661,21 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, + "axe-core": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-3.4.0.tgz", + "integrity": "sha512-5C0OdgxPv/DrQguO6Taj5F1dY5OlkWg4SVmZIVABFYKWlnAc5WTLPzG+xJSgIwf2fmY+NiNGiZXhXx2qT0u/9Q==", + "dev": true + }, + "axe-puppeteer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/axe-puppeteer/-/axe-puppeteer-1.0.0.tgz", + "integrity": "sha512-hTF3u4mtatgTN7fsLVyVgbRdNc15ngjDcTEuqhn9A7ugqLhLCryJWp9fzqZkNlrW8awPcxugyTwLPR7mRdPZmA==", + "dev": true, + "requires": { + "axe-core": "^3.1.2" + } + }, "babel-jest": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", @@ -4019,6 +4051,11 @@ "util.promisify": "^1.0.0" } }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", diff --git a/tests/package.json b/tests/package.json index 33f81568..d42051a0 100644 --- a/tests/package.json +++ b/tests/package.json @@ -17,6 +17,9 @@ }, "dependencies": {}, "devDependencies": { + "@wordpress/jest-puppeteer-axe": "^1.3.0", + "axe-puppeteer": "1.0.0", + "@babel/runtime": "^7.7.2", "jest": "^24.9.0", "node-forge": "0.8.2", "node-static": "^0.7.11", diff --git a/tests/spec/puppeteer-axe-spec.js b/tests/spec/puppeteer-axe-spec.js new file mode 100644 index 00000000..eb76a014 --- /dev/null +++ b/tests/spec/puppeteer-axe-spec.js @@ -0,0 +1,80 @@ +/* Puppeteer tests for the A11y. */ +const { AxePuppeteer } = require('axe-puppeteer'); +const puppeteer = require('puppeteer'); + +describe("Puppeteer accessibility tests for the Python Editor.", function() { + 'use strict'; + + const editorURL = 'http://localhost:5000/editor.html'; + const helpURL = 'http://localhost:5000/help.html'; + let browser = null; + + beforeAll(async () => { + // Setup a headless Chromium browser. + // Flags allow Puppeteer to run within a container. + browser = await puppeteer.launch({ + headless: true, + args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"] + }); + }); + + afterAll(async () => { + browser.close(); + }); + + test( 'Checks the editor.html page with Axe', async () => { + // First, run some code which loads the content of the page. + const page = await browser.newPage(); + await page.goto(editorURL); + await new AxePuppeteer(page).analyze(); + await expect(page).toPassAxeTests({ + // disable tab-index as we have values greater than 0 + // and h1 as we aren't using this heading + disabledRules: [ 'tabindex', 'page-has-heading-one' ], + }); + await page.close(); + }); + + test( 'Checks the Load/Save modal with Axe', async () => { + const page = await browser.newPage(); + await page.goto(editorURL); + await page.waitForSelector("#command-files"); + await page.click("#command-files"); + await new AxePuppeteer(page).analyze(); + await expect(page).toPassAxeTests({ + // exclude everything else in main + exclude: '.main', + // disable checking for h1 as we aren't using this heading + disabledRules: [ 'page-has-heading-one' ], + }); + await page.close(); + }); + + test( 'Checks the Load/Save modal with Axe', async () => { + const page = await browser.newPage(); + await page.goto(editorURL); + await page.waitForSelector("#command-snippet"); + await page.click("#command-snippet"); + await new AxePuppeteer(page).analyze(); + await expect(page).toPassAxeTests({ + // exclude everything else in main + exclude: '.main', + // disable checking for h1 as we aren't using this heading + disabledRules: [ 'page-has-heading-one' ], + }); + await page.close(); + }); + + test( 'Checks the help.html page with Axe', async () => { + const page = await browser.newPage(); + await page.goto(helpURL); + await new AxePuppeteer(page).analyze(); + await expect(page).toPassAxeTests({ + // exclude code highlighter + exclude: '.hljs-comment', + // disable checking for h1 as we aren't using this heading + disabledRules: [ 'page-has-heading-one' ], + }); + await page.close(); + }); +});