Skip to content

Commit

Permalink
feat: Ignore before/after pseudo elements in JSDOM (#380)
Browse files Browse the repository at this point in the history
  • Loading branch information
eps1lon committed Aug 10, 2020
1 parent 895d296 commit 9e46c51
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 84 deletions.
35 changes: 35 additions & 0 deletions .changeset/witty-cycles-pay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
"dom-accessibility-api": minor
---

**BREAKING CHANGE**

Ignore `::before` and `::after` by default.

This was necessary to prevent excessive warnings in `jsdom@^16.3.0`.
If you use this package in a browser that supports the second argument of `window.getComputedStyle` you can set the `computedStyleSupportsPseudoElements` option to true:

```ts
computeAccessibleName(element, {
computedStyleSupportsPseudoElements: true,
});

computeAccessibleDescription(element, {
computedStyleSupportsPseudoElements: true,
});
```

If you pass a custom implementation of `getComputedStyle` then this option defaults to `true`.
The following two calls are equivalent:

```ts
computeAccessibleName(element, {
computedStyleSupportsPseudoElements: true,
});

computeAccessibleName(element, {
getComputedStyle: (element, pseudoElement) => {
// custom implementation
},
});
```
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"jest-environment-jsdom": "^26.2.0",
"jest-junit": "^11.1.0",
"js-yaml": "^3.14.0",
"jsdom": "^16.3.0",
"jsdom": "^16.4.0",
"minimatch": "^3.0.4",
"mocha": "^8.1.1",
"mocha-sugar-free": "^1.4.0",
Expand Down
1 change: 1 addition & 0 deletions scripts/jest/jest.base.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const path = require("path");
module.exports = {
coverageDirectory: path.resolve(__dirname, "../../coverage"),
rootDir: path.resolve(__dirname, "../../sources"),
setupFilesAfterEnv: [require.resolve("./jest.setup")],
testPathIgnorePatterns: [
"/node_modules/",
"/fixtures/",
Expand Down
13 changes: 13 additions & 0 deletions scripts/jest/jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* eslint-env jest */

let spy;
beforeEach(() => {
spy = jest.spyOn(console, "error").mockImplementation((message) => {
console.log(message);
throw new Error(message);
});
});

afterEach(() => {
spy.mockRestore();
});
42 changes: 41 additions & 1 deletion sources/__tests__/accessible-name.js
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,8 @@ describe("options.getComputedStyle", () => {
computeAccessibleName(container.querySelector("button"));

// also mixing in a regression test for the number of calls
expect(window.getComputedStyle).toHaveBeenCalledTimes(3);
// 2 calls for ::after and ::before are skipped in JSDOM
expect(window.getComputedStyle).toHaveBeenCalledTimes(1);
});

it("can be mocked with a fake", () => {
Expand All @@ -439,3 +440,42 @@ describe("options.getComputedStyle", () => {
expect(window.getComputedStyle).not.toHaveBeenCalled();
});
});

describe("options.computedStyleSupportsPseudoElements", () => {
beforeEach(() => {
jest.spyOn(console, "error").mockImplementation(() => {
// swallow
});
});

afterEach(() => {
jest.restoreAllMocks();
});

it("`false` prevents errors in JSDOM from being logged", () => {
const container = renderIntoDocument("<button>test</button>");

computeAccessibleName(container.querySelector("button"), {
computedStyleSupportsPseudoElements: false,
});

expect(console.error).not.toHaveBeenCalled();
});

it("`true` will lead JSDOM to log console errors", () => {
const container = renderIntoDocument("<button>test</button>");

computeAccessibleName(container.querySelector("button"), {
computedStyleSupportsPseudoElements: true,
});

// one for ::before, one for ::after
expect(console.error).toHaveBeenCalledTimes(2);
expect(console.error.mock.calls[0][0]).toMatch(
"Error: Not implemented: window.computedStyle(elt, pseudoElt)"
);
expect(console.error.mock.calls[1][0]).toMatch(
"Error: Not implemented: window.computedStyle(elt, pseudoElt)"
);
});
});
13 changes: 10 additions & 3 deletions sources/accessible-name-and-description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ type FlatString = string & {
*/
export interface ComputeTextAlternativeOptions {
compute?: "description" | "name";
/**
* Set to true if window.computedStyle supports the second argument.
* This should be false in JSDOM. Otherwise JSDOM will log console errors.
*/
computedStyleSupportsPseudoElements?: boolean;
getComputedStyle?: typeof window.getComputedStyle;
}

Expand Down Expand Up @@ -316,6 +321,8 @@ export function computeTextAlternative(
const window = safeWindow(root);
const {
compute = "name",
computedStyleSupportsPseudoElements = options.getComputedStyle !==
undefined,
// This might be overengineered. I don't know what happens if I call
// window.getComputedStyle(elementFromAnotherWindow) or if I don't bind it
// the type declarations don't require a `this`
Expand All @@ -329,7 +336,7 @@ export function computeTextAlternative(
context: { isEmbeddedInLabel: boolean; isReferenced: boolean }
): string {
let accumulatedText = "";
if (isElement(node)) {
if (isElement(node) && computedStyleSupportsPseudoElements) {
const pseudoBefore = getComputedStyle(node, "::before");
const beforeContent = getTextualContent(pseudoBefore);
accumulatedText = `${beforeContent} ${accumulatedText}`;
Expand All @@ -356,8 +363,8 @@ export function computeTextAlternative(
accumulatedText += `${separator}${result}${separator}`;
});

if (isElement(node)) {
const pseudoAfter = getComputedStyle(node, ":after");
if (isElement(node) && computedStyleSupportsPseudoElements) {
const pseudoAfter = getComputedStyle(node, "::after");
const afterContent = getTextualContent(pseudoAfter);
accumulatedText = `${accumulatedText} ${afterContent}`;
}
Expand Down
8 changes: 6 additions & 2 deletions tests/cypress/support/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import {
chai.use((_chai, _utils) => {
function assertAccessibleName(expected) {
const element = _utils.flag(this, "object");
const actual = computeAccessibleName(element);
const actual = computeAccessibleName(element, {
computedStyleSupportsPseudoElements: true,
});

this.assert(
expected === actual,
Expand All @@ -19,7 +21,9 @@ chai.use((_chai, _utils) => {

function assertAccessibleDescription(expected) {
const element = _utils.flag(this, "object");
const actual = computeAccessibleDescription(element);
const actual = computeAccessibleDescription(element, {
computedStyleSupportsPseudoElements: true,
});

this.assert(
expected === actual,
Expand Down
93 changes: 16 additions & 77 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,7 @@
dependencies:
"@babel/types" "^7.11.0"

"@babel/helper-split-export-declaration@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz#2c70576eaa3b5609b24cb99db2888cc3fc4251d1"
integrity sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==
dependencies:
"@babel/types" "^7.10.4"

"@babel/helper-split-export-declaration@^7.11.0":
"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0":
version "7.11.0"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f"
integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==
Expand Down Expand Up @@ -281,7 +274,7 @@
chalk "^2.0.0"
js-tokens "^4.0.0"

"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.1", "@babel/parser@^7.7.5":
"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.1":
version "7.11.3"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.3.tgz#9e1eae46738bcd08e23e867bab43e7b95299a8f9"
integrity sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==
Expand Down Expand Up @@ -860,7 +853,7 @@
dependencies:
regenerator-runtime "^0.13.4"

"@babel/template@^7.10.4", "@babel/template@^7.3.3", "@babel/template@^7.7.4":
"@babel/template@^7.10.4", "@babel/template@^7.3.3":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==
Expand All @@ -869,7 +862,7 @@
"@babel/parser" "^7.10.4"
"@babel/types" "^7.10.4"

"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.7.4":
"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0":
version "7.11.0"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.0.tgz#9b996ce1b98f53f7c3e4175115605d56ed07dd24"
integrity sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==
Expand Down Expand Up @@ -1424,7 +1417,7 @@
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0"
integrity sha512-iIgQNzCm0v7QMhhe4Jjn9uRh+I6GoPmt03CbEtwx3ao8/EfoQcmgtqH4vQ5Db/lxiIGaWDv6nwvunuh0RyX0+A==

"@types/babel__core@^7.0.0":
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7":
version "7.1.9"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.9.tgz#77e59d438522a6fb898fa43dc3455c6e72f3963d"
integrity sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==
Expand All @@ -1435,17 +1428,6 @@
"@types/babel__template" "*"
"@types/babel__traverse" "*"

"@types/babel__core@^7.1.7":
version "7.1.7"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.7.tgz#1dacad8840364a57c98d0dd4855c6dd3752c6b89"
integrity sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==
dependencies:
"@babel/parser" "^7.1.0"
"@babel/types" "^7.0.0"
"@types/babel__generator" "*"
"@types/babel__template" "*"
"@types/babel__traverse" "*"

"@types/babel__generator@*":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.0.tgz#f1ec1c104d1bb463556ecb724018ab788d0c172a"
Expand Down Expand Up @@ -1726,12 +1708,7 @@ acorn-walk@^7.1.1:
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e"
integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==

acorn@^7.1.1:
version "7.2.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe"
integrity sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==

acorn@^7.3.1:
acorn@^7.1.1, acorn@^7.3.1:
version "7.3.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd"
integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==
Expand Down Expand Up @@ -3511,12 +3488,7 @@ fsevents@^1.2.7:
bindings "^1.5.0"
nan "^2.12.1"

fsevents@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805"
integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==

fsevents@~2.1.2:
fsevents@^2.1.2, fsevents@~2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e"
integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==
Expand Down Expand Up @@ -3682,12 +3654,7 @@ has-flag@^4.0.0:
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==

has-symbols@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=

has-symbols@^1.0.1:
has-symbols@^1.0.0, has-symbols@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
Expand Down Expand Up @@ -3887,12 +3854,7 @@ is-buffer@~2.0.3:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623"
integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==

is-callable@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==

is-callable@^1.2.0:
is-callable@^1.1.4, is-callable@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb"
integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==
Expand Down Expand Up @@ -4146,20 +4108,7 @@ istanbul-lib-coverage@^3.0.0:
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec"
integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==

istanbul-lib-instrument@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.0.tgz#53321a7970f076262fd3292c8f9b2e4ac544aae1"
integrity sha512-Nm4wVHdo7ZXSG30KjZ2Wl5SU/Bw7bDx1PdaiIFzEStdjs0H12mOTncn1GVYuqQSaZxpg87VGBRsVRPGD2cD1AQ==
dependencies:
"@babel/core" "^7.7.5"
"@babel/parser" "^7.7.5"
"@babel/template" "^7.7.4"
"@babel/traverse" "^7.7.4"
"@istanbuljs/schema" "^0.1.2"
istanbul-lib-coverage "^3.0.0"
semver "^6.3.0"

istanbul-lib-instrument@^4.0.3:
istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d"
integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==
Expand Down Expand Up @@ -4629,10 +4578,10 @@ jsbn@~0.1.0:
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=

jsdom@^16.2.2, jsdom@^16.3.0:
version "16.3.0"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.3.0.tgz#75690b7dac36c67be49c336dcd7219bbbed0810c"
integrity sha512-zggeX5UuEknpdZzv15+MS1dPYG0J/TftiiNunOeNxSl3qr8Z6cIlQpN0IdJa44z9aFxZRIVqRncvEhQ7X5DtZg==
jsdom@^16.2.2, jsdom@^16.4.0:
version "16.4.0"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.4.0.tgz#36005bde2d136f73eee1a830c6d45e55408edddb"
integrity sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==
dependencies:
abab "^2.0.3"
acorn "^7.1.1"
Expand Down Expand Up @@ -5561,12 +5510,7 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=

picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a"
integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==

picomatch@^2.0.7:
picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7, picomatch@^2.2.1:
version "2.2.2"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
Expand Down Expand Up @@ -6127,12 +6071,7 @@ [email protected], safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==

safe-buffer@^5.0.1, safe-buffer@^5.1.2:
version "5.2.0"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==

safe-buffer@^5.1.0:
safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
Expand Down

0 comments on commit 9e46c51

Please sign in to comment.