Skip to content

Commit

Permalink
Add toPassAxeTests feature (#494)
Browse files Browse the repository at this point in the history
  • Loading branch information
calebeby committed Jun 6, 2022
1 parent 6a05002 commit 730300e
Show file tree
Hide file tree
Showing 12 changed files with 536 additions and 15 deletions.
22 changes: 22 additions & 0 deletions .changeset/early-pigs-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
'pleasantest': minor
---

New assertion: `expect(page).toPassAxeTests()`

This assertion is based on the [`jest-puppeteer-axe`](https://github.com/WordPress/gutenberg/tree/3b2eccc289cfc90bd99252b12fc4c6e470ce4c04/packages/jest-puppeteer-axe) package. (That package already works with Pleasantest, our new feature just formats error messages a little differently)

It allows you to pass a page to be checked with the [axe accessibility linter](https://github.com/dequelabs/axe-core).

```js
test(
'Axe tests',
withBrowser(async ({ utils, page }) => {
await utils.injectHTML(`
<h1>Some html</h1>
`);

await expect(page).toPassAxeTests();
}),
);
```
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Pleasantest is a library that allows you test web applications using real browse
- [Utilities API: `PleasantestUtils`](#utilities-api-pleasantestutils)
- [`jest-dom` Matchers](#jest-dom-matchers)
- [`getAccessibilityTree`](#getaccessibilitytreeelement-elementhandle--page-options-accessibilitytreeoptions--promiseaccessibilitytreesnapshot)
- [`toPassAxeTests`](#expectpagetopassaxetestsopts-topassaxetestsopts)
- [Puppeteer Tips](#puppeteer-tips)
- [Comparisons with other testing tools](#comparisons-with-other-testing-tools)
- [Limitations](#limitationsarchitectural-decisions)
Expand Down Expand Up @@ -830,6 +831,33 @@ Disabling these options can be used to reduce the output or to exclude text that

The returned `Promise` wraps an `AccessibilityTreeSnapshot`, which can be passed directly as the `expect` first parameter in `expect(___).toMatchInlineSnapshot()`. The returned object can also be converted to a string using `String(accessibilityTreeSnapshot)`.

### `expect(page).toPassAxeTests(opts?: ToPassAxeTestsOpts)`

This assertion, based on [`jest-puppeteer-axe`](https://github.com/WordPress/gutenberg/tree/3b2eccc289cfc90bd99252b12fc4c6e470ce4c04/packages/jest-puppeteer-axe), allows you to check a page using the [axe accessibility linter](https://github.com/dequelabs/axe-core).

To use this assertion, you **must install `@axe-core/puppeteer` and `axe-core`**. They are optional peer dependencies for Pleasantest, but are needed for the `toPassAxeTests` assertion.

```js
test(
'Axe tests',
withBrowser(async ({ utils, page }) => {
await utils.injectHTML(`
<h1>Some html</h1>
`);

await expect(page).toPassAxeTests();
}),
);
```

`ToPassAxeTestsOpts` (all properties are optional):

- `include`: `string | string[]`: CSS selector(s) to add to the list of elements to include in analysis.
- `exclude`: `string | string[]`: CSS selector(s) to add to the list of elements to exclude from analysis.
- `disabledRules`: `string | string[]`: The list of [Axe rules](https://github.com/dequelabs/axe-core/tree/v4.4.2/lib/rules) to skip from verification.
- `options`: [`axe.RunOptions`](https://github.com/dequelabs/axe-core/blob/v4.4.2/axe.d.ts#L89): A flexible way to [configure how Axe run operates](https://github.com/dequelabs/axe-core/blob/HEAD/doc/API.md#options-parameter).
- `config`: [`axe.Spec`](https://github.com/dequelabs/axe-core/blob/v4.4.2/axe.d.ts#L195): [Axe configuration object](https://github.com/dequelabs/axe-core/blob/HEAD/doc/API.md#api-name-axeconfigure).

## Puppeteer Tips

Pleasantest uses [Puppeteer](https://github.com/puppeteer/puppeteer) under the hood. You don't need to know how to use Puppeteer in order to use Pleasantest, but a little bit of Puppeteer knowledge might come in handy. Here are the parts of Puppeteer that are most helpful and relevant for Pleasantest:
Expand Down
53 changes: 53 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,21 @@
"dist"
],
"license": "MIT",
"peerDependencies": {
"@axe-core/puppeteer": "^4.4.2",
"axe-core": "^4.4.2"
},
"peerDependenciesMeta": {
"@axe-core/puppeteer": {
"optional": true
},
"axe-core": {
"optional": true
}
},
"devDependencies": {
"@ampproject/remapping": "2.2.0",
"@axe-core/puppeteer": "4.4.2",
"@babel/core": "7.16.7",
"@babel/preset-env": "7.16.8",
"@babel/preset-typescript": "7.16.7",
Expand All @@ -28,6 +41,7 @@
"@vue/compiler-sfc": "3.2.36",
"ansi-regex": "6.0.1",
"aria-query": "*",
"axe-core": "4.4.2",
"babel-plugin-un-cjs": "2.5.0",
"dom-accessibility-api": "0.5.14",
"errorstacks": "2.4.0",
Expand Down
3 changes: 2 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const external = [
'esbuild',
/postcss/,
/mime/,
'@axe-core/puppeteer',
];

/** @type {import('rollup').RollupOptions} */
Expand Down Expand Up @@ -55,7 +56,7 @@ const mainConfig = {
const typesConfig = {
input: 'src/index.ts',
output: [{ file: 'dist/index.d.ts', format: 'es' }],
external: [...external, 'polka'],
external: [...external, 'polka', 'axe-core'],
plugins: [dts({ respectExternal: true })],
};

Expand Down
10 changes: 10 additions & 0 deletions src/accessibility/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ import {
// @ts-expect-error This is a fake file that triggers a rollup plugin
import requiredOwnedElementsMap from 'generated:requiredOwnedElements';
import type { AccessibilityTreeOptions } from '.';
import * as colors from 'kolorist';

export * as colors from 'kolorist';
export { printElement } from '../serialize';

// We haver to tell kolorist to print the colors
// because by default it won't since we are in the browser
// (the colored message gets sent to node to be printed)
colors.options.enabled = true;
colors.options.supportLevel = 1;

const indent = (text: string, indenter = ' ') =>
indenter + text.split('\n').join(`\n${indenter}`);
Expand Down
Loading

0 comments on commit 730300e

Please sign in to comment.