📝 Disallow direct Node access.
💼 This rule is enabled in the following configs:
angular,
dom,
marko,
react,
svelte,
vue.
Disallow direct access or manipulation of DOM nodes in favor of Testing Library's user-centric APIs.
This rule aims to disallow direct access and manipulation of DOM nodes using native HTML properties and methods — including traversal (e.g. closest, lastChild) as well as direct actions (e.g. click(), select()). Use Testing Library’s queries and userEvent APIs instead.
Note
This rule does not report usage of focus() or blur(), because imperative usage (e.g. getByText('focus me').focus() or .blur()) is recommended over fireEvent.focus() or fireEvent.blur().
If an element is not focusable, related assertions will fail, leading to more robust tests. See Testing Library Events Guide for more details.
Examples of incorrect code for this rule:
import { screen } from '@testing-library/react';
screen.getByText('Submit').closest('button'); // chaining with Testing Library methodsimport { screen } from '@testing-library/react';
screen.getByText('Submit').click();import { screen } from '@testing-library/react';
const buttons = screen.getAllByRole('button');
expect(buttons[1].lastChild).toBeInTheDocument();import { screen } from '@testing-library/react';
const buttonText = screen.getByText('Submit');
const button = buttonText.closest('button');Examples of correct code for this rule:
import { screen } from '@testing-library/react';
const button = screen.getByRole('button');
expect(button).toHaveTextContent('submit');import { screen } from '@testing-library/react';
userEvent.click(screen.getByText('Submit'));import { render, within } from '@testing-library/react';
const { getByLabelText } = render(<MyComponent />);
const signinModal = getByLabelText('Sign In');
within(signinModal).getByPlaceholderText('Username');import { screen } from '@testing-library/react';
function ComponentA(props) {
// props.children is not reported
return <div>{props.children}</div>;
}
render(<ComponentA />);// If is not importing a testing-library package
document.getElementById('submit-btn').closest('button');This rule has one option:
-
allowContainerFirstChild: disabled by default. When we have container with rendered content then the easiest way to access content itself is by usingfirstChildproperty. Use this option in cases when this is hardly avoidable."testing-library/no-node-access": ["error", {"allowContainerFirstChild": true}]
Correct:
const { container } = render(<MyComponent />);
expect(container.firstChild).toMatchSnapshot();