Javascript automated testing and a11y doc (#4873)

* Add jext-axe package and introduce a11y testing

Automated a11y testing is NOT comprehensive. We cannot expect this to
even scratch the surface of potential a11y issues.

However, we can expect to find a percentage of issues that are currently
flying under the radar. Adopting some automation around a11y testing
also allows us to use CI to find a11y regressions -- which should be
really handy.

I've never really used Jest before, and Preact seems to make it a little
more complicated, but as far as I can tell, this is a decent way to add
at least some minor automated a11y testing.

* Add doc about automated a11y tests
This commit is contained in:
Jacob Herrington 2019-11-22 07:32:01 -06:00 committed by Ben Halpern
parent e5ee2f9013
commit c6c5421163
5 changed files with 155 additions and 2 deletions

View file

@ -1,6 +1,7 @@
import { h } from 'preact';
import { deep } from 'preact-render-spy';
import fetch from 'jest-fetch-mock';
import { axe, toHaveNoViolations } from 'jest-axe';
import Onboarding from '../Onboarding';
import BioForm from '../components/BioForm';
@ -16,6 +17,9 @@ function flushPromises() {
}
describe('<Onboarding />', () => {
beforeAll(() => {
expect.extend(toHaveNoViolations);
});
beforeEach(() => {
fetch.resetMocks();
});
@ -74,6 +78,12 @@ describe('<Onboarding />', () => {
expect(onboardingSlides).toMatchSnapshot();
});
test('should not have basic a11y violations', async () => {
const results = await axe(onboardingSlides.toString());
expect(results).toHaveNoViolations();
});
test('should move to the next slide upon clicking the next button', () => {
onboardingSlides.find('.next-button').simulate('click');
expect(onboardingSlides.state().currentSlide).toBe(1);

View file

@ -0,0 +1,35 @@
---
title: Accessibility Tests
---
# Accessibility Tests
Accessibility testing is a form of automated and manual testing that helps us
identify some of the potential accessibility concerns on DEV.
Many a11y issues are not obvious to everyone who contributes to the DEV project,
therefore leaning on tools to help us identify these issues is a good practice.
It's a good idea to use browser plugins while you're developing to keep an eye
out for these issues, as well as including automated tests to catch regressions
in future changes.
The [aXe devtools](https://www.deque.com/axe) extension is a great place to get
started. It works in both Firefox and Chrome. Use an extension like this one to
find potential a11y issues in your workflow.
## Automated testing in Preact
An overarching a11y testing strategy isn't currently in place for the DEV
application, but there are some automated tools you can take advantage of in
this project.
It is important to note that automated accessibility testing is only effective
at finding ~30% of accessibility issues. It's important to do manual a11y
testing as well.
When you're writing Preact components, you can include some basic a11y testing
in your unit tests with [jest-axe](https://github.com/nickcolley/jest-axe).
If you're still curious
[there are some great talks on accessibility for developers](https://www.youtube.com/watch?v=8E9AEZjglqI).

View file

@ -5,6 +5,7 @@ items:
- integration-tests.md
- unit-functional-tests.md
- preact-tests.md
- accessibility-tests.md
- code-coverage.md
- codeclimate.md
- skip-ci.md

View file

@ -77,6 +77,7 @@
"faker": "^4.1.0",
"husky": "^3.1.0",
"jest": "^23.5.0",
"jest-axe": "^3.2.0",
"jest-fetch-mock": "^2.1.2",
"jsdom": "^15.2.1",
"lint-staged": "^9.4.3",

110
yarn.lock
View file

@ -225,6 +225,15 @@
resolved "https://registry.yarnpkg.com/@github/clipboard-copy-element/-/clipboard-copy-element-1.1.1.tgz#5d58f970ab89a5ee86b402b04f7765e324b8089b"
integrity sha512-+kIpoWk2INRk8r22q/8GPgS6KG+YyWwmIfSbKuMgzKXt0cyt6m5K3HG2sZiVVWSVqZ458cLU74JrOJRevXvxQA==
"@jest/types@^24.9.0":
version "24.9.0"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59"
integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==
dependencies:
"@types/istanbul-lib-coverage" "^2.0.0"
"@types/istanbul-reports" "^1.1.1"
"@types/yargs" "^13.0.0"
"@nodelib/fs.scandir@2.1.1":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.1.tgz#7fa8fed654939e1a39753d286b48b4836d00e0eb"
@ -678,6 +687,26 @@
"@types/minimatch" "*"
"@types/node" "*"
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff"
integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==
"@types/istanbul-lib-report@*":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#e5471e7fa33c61358dd38426189c037a58433b8c"
integrity sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==
dependencies:
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-reports@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a"
integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==
dependencies:
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-lib-report" "*"
"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
@ -698,6 +727,18 @@
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8"
integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==
"@types/yargs-parser@*":
version "13.1.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228"
integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==
"@types/yargs@^13.0.0":
version "13.0.3"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.3.tgz#76482af3981d4412d65371a318f992d33464a380"
integrity sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ==
dependencies:
"@types/yargs-parser" "*"
abab@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f"
@ -858,7 +899,7 @@ ansi-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
ansi-regex@^4.1.0:
ansi-regex@^4.0.0, ansi-regex@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
@ -1181,6 +1222,11 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
axe-core@3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-3.3.1.tgz#3d1fa78cca8ead1b78c350581501e4e37b97b826"
integrity sha512-gw1T0JptHPF4AdLLqE8yQq3Z7YvsYkpFmFWd84r6hnq/QoKRr8icYHFumhE7wYl5TVIHgVlchMyJsAYh0CfwCQ==
axobject-query@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9"
@ -2806,7 +2852,7 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2:
chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@ -4006,6 +4052,11 @@ detect-port-alt@1.1.6:
address "^1.0.1"
debug "^2.6.0"
diff-sequences@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5"
integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==
diff@^3.2.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
@ -6788,6 +6839,16 @@ istanbul-reports@^1.5.1:
dependencies:
handlebars "^4.0.3"
jest-axe@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/jest-axe/-/jest-axe-3.2.0.tgz#0f7a0132565289432936421cf38b7b8504690835"
integrity sha512-QSQwSwG72/cpmhJU0fBsaUUvu9mb2uAqhccGQVG6JbIV8sK+aIXh8hYl7vxraMF/I6soQod1aqSdD/j7LjpVFQ==
dependencies:
axe-core "3.3.1"
chalk "2.4.2"
jest-matcher-utils "24.8.0"
lodash.merge "4.6.2"
jest-changed-files@^23.4.2:
version "23.4.2"
resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.4.2.tgz#1eed688370cd5eebafe4ae93d34bb3b64968fe83"
@ -6867,6 +6928,16 @@ jest-diff@^23.6.0:
jest-get-type "^22.1.0"
pretty-format "^23.6.0"
jest-diff@^24.8.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da"
integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==
dependencies:
chalk "^2.0.1"
diff-sequences "^24.9.0"
jest-get-type "^24.9.0"
pretty-format "^24.9.0"
jest-docblock@^23.2.0:
version "23.2.0"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7"
@ -6912,6 +6983,11 @@ jest-get-type@^22.1.0:
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4"
integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==
jest-get-type@^24.8.0, jest-get-type@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e"
integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==
jest-haste-map@^23.6.0:
version "23.6.0"
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.6.0.tgz#2e3eb997814ca696d62afdb3f2529f5bbc935e16"
@ -6951,6 +7027,16 @@ jest-leak-detector@^23.6.0:
dependencies:
pretty-format "^23.6.0"
jest-matcher-utils@24.8.0:
version "24.8.0"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz#2bce42204c9af12bde46f83dc839efe8be832495"
integrity sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==
dependencies:
chalk "^2.0.1"
jest-diff "^24.8.0"
jest-get-type "^24.8.0"
pretty-format "^24.8.0"
jest-matcher-utils@^23.6.0:
version "23.6.0"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz#726bcea0c5294261a7417afb6da3186b4b8cac80"
@ -7641,6 +7727,11 @@ lodash.memoize@^4.1.2:
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
lodash.merge@4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
lodash.pick@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
@ -10172,6 +10263,16 @@ pretty-format@^23.6.0:
ansi-regex "^3.0.0"
ansi-styles "^3.2.0"
pretty-format@^24.8.0, pretty-format@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9"
integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==
dependencies:
"@jest/types" "^24.9.0"
ansi-regex "^4.0.0"
ansi-styles "^3.2.0"
react-is "^16.8.4"
pretty-format@^3.5.1:
version "3.8.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385"
@ -10605,6 +10706,11 @@ react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
react-is@^16.8.4:
version "16.12.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c"
integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==
react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"