toBeInTheDOM matcher only ensures instanceof HTMLElement, expected to check that the element is attached to a full DOM tree · Issue #9 · testing-library/dom-testing-library (original) (raw)

Relevant code or config

https://github.com/kentcdodds/dom-testing-library/blob/f77f943a1887756372993eaf6ee3b054f2f58b91/src/jest-extensions.js#L18-L26

https://github.com/kentcdodds/dom-testing-library/blob/f77f943a1887756372993eaf6ee3b054f2f58b91/src/jest-extensions.js#L63-L85

(copy of the linked code)

function checkHtmlElement(htmlElement) { if (!(htmlElement instanceof HTMLElement)) { throw new Error( The given subject is a ${getDisplayName( htmlElement, )}, not an HTMLElement, ) } }

// ...

const extensions = { toBeInTheDOM(received) { if (received) { checkHtmlElement(received) } return { pass: !!received, message: () => { const to = this.isNot ? 'not to' : 'to' return getMessage( matcherHint( ${this.isNot ? '.not' : ''}.toBeInTheDOM, 'element', '', ), 'Expected', element ${to} be present, 'Received', received, ) }, } },


What you did:

  1. Used .toBeInTheDOM() in a test with an element disconnected from the DOM, like here; the test passed, surprisingly.
  2. Reviewed the source code of jest-extensions.js

What happened:

Discovered that toBeInTheDOM does not check that the element is attached to a full DOM tree.

Reproduction repository:

This repository's tests.

Problem description:

toBeInTheDOM, according to its name, has to ensure that the given element is in the DOM, i.e. attached to the full DOM tree, not hanging as a standalone element or in a standalone subtree.

Suggested solution:

Find out if the element is actually attached to a DOM document via element.ownerDocument.contains(element), and report an assertion failure if it's not.