question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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

Codesandbox Edit react-testing-library demo (forked)

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:open
  • Created 2 years ago
  • Reactions:6
  • Comments:6

github_iconTop GitHub Comments

2reactions
ahayes91commented, Jun 21, 2022

An update - looks like this was fixed by upgrading Canvas Kit to v7 🎉 Edit react-testing-library demo with CK 7

Will go ahead and close this issue for now - thanks folks!

1reaction
willkleincommented, Jul 26, 2022

@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/3057

If so, this won’t be a dom-testing-library issue or a @workday/canvas-kit-react issue, but something in jsdom or its dependency on nwsapi.

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 for parentElement.

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

Read more comments on GitHub >

github_iconTop Results From Across the Web

getByRole fails with "TypeError: Cannot read property ... - GitHub
getByRole fails with "TypeError: Cannot read property 'parentElement' of null" when using Canvas Kit React button with an icon #1010.
Read more >
TypeError: Cannot read property 'parentElement' of null
Fresh project generated by create-react-app@4: @testing-library/dom version: 5.11.4; Testing Framework and version: <!-- are you using jest, ...
Read more >
React - Material UI test TypeError: Cannot read property 'get ...
Short Answer: In your case, it's because you mocked useContext BUT makeStyles internally uses useContext , hence it cannot find the context ...
Read more >
[Solved]-How to fix " item.item_name is null "-Reactjs
Coding example for the question How to fix " item.item_name is null "-Reactjs. ... How to fix error ,Uncaught TypeError: Cannot read properties...
Read more >
Cannot read property `property` of null in 'react-test-renderer ...
The error originated from one of my component methods, which calls the HTMLElement.focus() method to set focus on a particular input field.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found