getByRole fails with "TypeError: Cannot read property 'parentElement' of null" when using Canvas Kit React button with an icon
See original GitHub issue@testing-library/react
version: 12.1.2@workday/canvas-kit-react
version “^6.3.3”@workday/canvas-system-icons-web
version “^2.0.6”- Testing Framework and version: jest 26.6.3 (but that doesn’t seem to matter, this fails on the template Codesandbox too)
- DOM Environment: default jsdom, running Codesandbox tests in Chrome Version 97.0.4692.71 (Official Build) (x86_64)
Relevant code or config:
// CanvasKitButton.js
import React from "react";
import { TertiaryButton } from "@workday/canvas-kit-react/button";
import { chevronUpSmallIcon } from "@workday/canvas-system-icons-web";
export default () => (
<TertiaryButton
icon={chevronUpSmallIcon}
iconPosition="right"
onClick={() => {}}
size="small"
>
CanvasKitButton
</TertiaryButton>
);
// CanvasKitButtonWithoutIcon.js
import React from "react";
import { TertiaryButton } from "@workday/canvas-kit-react/button";
export default () => (
<TertiaryButton onClick={() => {}} size="small">
CanvasKitButton
</TertiaryButton>
);
// Test code
import "@testing-library/jest-dom/extend-expect";
import React from "react";
import { render } from "@testing-library/react";
import CanvasKitButton from "../CanvasKitButton";
import CanvasKitButtonWithoutIcon from "../CanvasKitButtonWithoutIcon";
test("This fails with TypeError", () => {
const { getByRole } = render(<CanvasKitButton />);
expect(getByRole("button", { name: "CanvasKitButton" })).toBeInTheDocument();
});
test("This passes", () => {
const { getByRole } = render(<CanvasKitButtonWithoutIcon />);
expect(getByRole("button", { name: "CanvasKitButton" })).toBeInTheDocument();
});
What you did:
When trying to use getByRole
queries in my application using Canvas Kit, I found that if I had buttons on my page with icons, the getByRole
queries were borking out with a very strange error: “TypeError: Cannot read property ‘parentElement’ of null”.
When I remove the icon or mock the underlying icon library, the test passes.
I found a similar error here but no solution other than to change to a different query: https://spectrum.chat/testing-library/help-react/getbyrole-error-cannot-read-property-parentelement-of-null~0b78b6db-b99f-414e-b9ed-38990d6dd717
What happened:
Repo error:
FAIL src/CanvasKitButton.test.js
✕ This fails with TypeError (177 ms)
✓ This should pass (108 ms)
TypeError: Cannot read property 'parentElement' of null
at Array.Resolver (eval at compile (node_modules/nwsapi/src/nwsapi.js:768:17), <anonymous>:3:140)
at match_assert (node_modules/nwsapi/src/nwsapi.js:1351:13)
at Object._matches [as match] (node_modules/nwsapi/src/nwsapi.js:1369:16)
at exports.matchesDontThrow (node_modules/jsdom/lib/jsdom/living/helpers/selectors.js:29:36)
at matches (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:50:10)
at node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:35:18
at Array.forEach (<anonymous>)
at handleSheet (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:26:13)
at Array.forEach (<anonymous>)
at exports.forEachMatchingSheetRuleOfElement (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:46:11)
Codesandbox error:
Cannot read properties of null (reading 'parentElement')
TypeError: Cannot read properties of null (reading 'parentElement')
at Array.Resolver (eval at compile (https://un6lk.csb.app/static/js/jsdom-16.3.0.min.js:236:17232), <anonymous>:3:140)
at match_assert (https://un6lk.csb.app/static/js/jsdom-16.3.0.min.js:236:30554)
at Object._matches [as match] (https://un6lk.csb.app/static/js/jsdom-16.3.0.min.js:236:30873)
at exports.matchesDontThrow (https://un6lk.csb.app/static/js/jsdom-16.3.0.min.js:37:1612417)
at matches (https://un6lk.csb.app/static/js/jsdom-16.3.0.min.js:37:1620955)
at https://un6lk.csb.app/static/js/jsdom-16.3.0.min.js:37:1620677
at Array.forEach (<anonymous>)
at handleSheet (https://un6lk.csb.app/static/js/jsdom-16.3.0.min.js:37:1620484)
at Array.forEach (<anonymous>)
at exports.forEachMatchingSheetRuleOfElement (https://un6lk.csb.app/static/js/jsdom-16.3.0.min.js:37:1620853)
at Window.getComputedStyle (https://un6lk.csb.app/static/js/jsdom-16.3.0.min.js:37:49816)
at isHidden (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:66:56)
at computeTextAlternative (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:314:13)
at computeMiscTextAlternative (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:231:28)
at computeTextAlternative (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:413:20)
at computeMiscTextAlternative (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:231:28)
at computeTextAlternative (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:413:20)
at computeMiscTextAlternative (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:231:28)
at computeTextAlternative (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:413:20)
at computeMiscTextAlternative (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:231:28)
at computeTextAlternative (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:413:20)
at computeMiscTextAlternative (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:231:28)
at computeTextAlternative (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:402:20)
at computeAccessibleName (https://un6lk.csb.app/node_modules/dom-accessibility-api/dist/accessible-name.js:427:25)
at eval (https://un6lk.csb.app/node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js:1190:68)
at Array.filter (<anonymous>)
at queryAllByRole (https://un6lk.csb.app/node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js:1186:6)
at eval (https://un6lk.csb.app/node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js:795:24)
at eval (https://un6lk.csb.app/node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js:783:24)
at Object.eval (https://un6lk.csb.app/src/__tests__/CanvasKitButton.test.js:26:10)
at https://codesandbox.io/static/js/3.c68bd71c0.chunk.js:1:336366
at new Promise (<anonymous>)
at t.callAsyncFn (https://codesandbox.io/static/js/3.c68bd71c0.chunk.js:1:336025)
at https://codesandbox.io/static/js/7.cdfc7986d.chunk.js:1:6524
at c (https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:3629)
at Generator._invoke (https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:3382)
at Generator.forEach.t.<computed> [as next] (https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:3986)
at r (https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:206)
at u (https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:417)
at https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:476
at new Promise (<anonymous>)
at https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:357
at https://codesandbox.io/static/js/7.cdfc7986d.chunk.js:1:6791
at https://codesandbox.io/static/js/7.cdfc7986d.chunk.js:1:5456
at c (https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:3629)
at Generator._invoke (https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:3382)
at Generator.forEach.t.<computed> [as next] (https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:3986)
at r (https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:206)
at u (https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:417)
at https://codesandbox.io/static/js/vendors~app~embed~sandbox~sandbox-startup.bcc15d438.chunk.js:1:476
Reproduction:
Github repository: https://github.com/ahayes91/canvas-kit-react-testing-library/blob/main/src/CanvasKitButton.test.js
Problem description:
- getByRole should pass regardless of whether an icon is provided on the button or not
- Cryptic errors make it hard to debug if it’s your code or the test that is wrong
- New engineers using @testing-library/react are put off by scary errors 😂
Suggested solution:
I don’t have one I’m afraid, but when I went digging into the stack trace, I changed the nswapi logging in my local node modules node_modules/jsdom/lib/jsdom/living/helpers/selectors.js
file:
exports.matchesDontThrow = (elImpl, selector) => {
const document = elImpl._ownerDocument;
if (!document._nwsapiDontThrow) {
document._nwsapiDontThrow = initNwsapi(elImpl);
document._nwsapiDontThrow.configure({
LOGERRORS: true,
VERBOSITY: true,
IDS_DUPES: true,
MIXEDCASE: true
});
}
return document._nwsapiDontThrow.match(selector, idlUtils.wrapperForImpl(elImpl));
};
Which gave this error when I reran the tests, which was interesting but then I found myself pretty stumped without better knowledge of the underlying libraries:
FAIL src/CanvasKitButton.test.js
✕ This fails with TypeError (77 ms)
✕ This should pass (39 ms)
● This fails with TypeError
SyntaxError: '@namespace "http://www.w3.org/1999/xhtml";
html' is not a valid selector
at emit (node_modules/nwsapi/src/nwsapi.js:565:17)
at Object._matches [as match] (node_modules/nwsapi/src/nwsapi.js:1409:9)
at exports.matchesDontThrow (node_modules/jsdom/lib/jsdom/living/helpers/selectors.js:29:36)
at matches (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:50:10)
at node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:35:18
at Array.forEach (<anonymous>)
at handleSheet (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:26:13)
at exports.forEachMatchingSheetRuleOfElement (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:45:3)
at getComputedStyleImplementation (node_modules/jsdom/lib/jsdom/browser/Window.js:802:5)
at isHidden (node_modules/dom-accessibility-api/sources/accessible-name-and-description.ts:84:16)
● This should pass
SyntaxError: '@namespace "http://www.w3.org/1999/xhtml";
html' is not a valid selector
at emit (node_modules/nwsapi/src/nwsapi.js:565:17)
at Object._matches [as match] (node_modules/nwsapi/src/nwsapi.js:1409:9)
at exports.matchesDontThrow (node_modules/jsdom/lib/jsdom/living/helpers/selectors.js:29:36)
at matches (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:50:10)
at node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:35:18
at Array.forEach (<anonymous>)
at handleSheet (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:26:13)
at exports.forEachMatchingSheetRuleOfElement (node_modules/jsdom/lib/jsdom/living/helpers/style-rules.js:45:3)
at getComputedStyleImplementation (node_modules/jsdom/lib/jsdom/browser/Window.js:802:5)
at isHidden (node_modules/dom-accessibility-api/sources/accessible-name-and-description.ts:84:16)
Issue Analytics
- State:
- Created 2 years ago
- Reactions:6
- Comments:6
An update - looks like this was fixed by upgrading Canvas Kit to v7 🎉
Will go ahead and close this issue for now - thanks folks!
@tpict Hey, I looked into this further. We actually still have the problem testing a component in our library,
@workday/canvas-kit-react
, even on the latest version. I debugged this and dug deeper and couldn’t reproduce it initially with a non-Canvas Kit element, even replicating some styles, but not all. So I dove into the libraries in play and mapped the function calls to the stack trace, and I think this is the issue that’s cropping up: https://github.com/jsdom/jsdom/issues/3057If so, this won’t be a
dom-testing-library
issue or a@workday/canvas-kit-react
issue, but something injsdom
or its dependency onnwsapi
.I’m going to follow this rabbit hole into those utility and see what I can figure out!
jsdom
had all the obvious null checks forparentElement
.It might even be this issue that was fixed in
nwsapi
and we need to bump versions up the dependency tree: https://github.com/dperini/nwsapi/issues/46