eslint-plugin-testing-library: Library incorrectly report no-node-access when referencing props.children

Library complains Avoid direct Node access. Prefer using the methods from Testing Library. for the following code props.children:

I want to be able to insert children, or a default node.

return (
  <>
    { // Other elements here. }
    {'children' in props ? (
      props.children
    ) : (
      <MyComponent {...props} disabled={disabled} />
    )}
  </>
)

See https://stackoverflow.com/q/67099835/481207

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 16 (4 by maintainers)

Commits related to this issue

Most upvoted comments

Hello, this is still an issue, even for simple objects that have children key. For example I have this object that I use in tests:

const navItemWithChildren = {
  title: 'Cars',
  children: [
    {
      title: 'Add car',
    },
    {
      title: 'All cars',
    },
  ],
};

and I use this object in assertion like this:

expect(
      screen.getByText(navItemWithChildren.children[0].title),
    ).toBeVisible();

I get eslint error 41:44 error Avoid direct Node access. Prefer using the methods from Testing Library testing-library/no-node-access This is totally a false positive

I have opened a PR (#658) that deals with the most common and asked for cases (asked by @Snapperfish, @JustFly1984, @SevenOutman and @scottstern).

Unfortunately, this PR does not fix the errors on a) destructured props (mentioned by @Belco90) …

function ComponentB({ children }) {
  // this should NOT be reported
  if (children) {
    // ...
  }

  // this should NOT be reported
  return <div>{children}</div>
}

or b) an object that has a property named children (example from @titenis but @thepuzzlemaster and @sterlingwalsh had a similar cases)

const navItemWithChildren = {
  title: 'Cars',
  children: [
    {
      title: 'Add car',
    },
    {
      title: 'All cars',
    },
  ],
};

render(<NavItem props={navItemWithChildren} />);

expect(screen.getByText(navItemWithChildren.children[0].title),).toBeVisible();

I am somewhat sure that both of these remaining cases a) and b) can be resolved, but I don’t have all this code figured out yet. I’ll open new issue(s) about these when this issue is closed 📝

Unfortunately, this PR does not fix the errors on a) destructured props (mentioned by @Belco90) …

  // this should NOT be reported
  if (children) {
    // ...
  }

  // this should NOT be reported
  return <div>{children}</div>
}

Turns out, that this code does not produce an error for this rule, so I haven’t opened an issue for this, but added it to valid unit tests for this rule (in #684 ).

or b) an object that has a property named children (example from @titenis but @thepuzzlemaster and @sterlingwalsh had a similar cases)

I have opened issue #683 for this scenario.

I am somewhat sure that both of these remaining cases a) and b) can be resolved, but I don’t have all this code figured out yet. I’ll open new issue(s) about these when this issue is closed

Happy to take care of this in separate issues.

Any update on this issue? Same problem here when mocking components with jest.fn

jest.mock('@/features/auth', () => ({
  Gate: jest.fn((props) => props.children), // Got "Avoid direct Node access. Prefer using the methods from Testing Library."
}));

I am running into the same issue in my test. I have a helper method which renders my component, of which i can pass in a partial props object to override any defaults the test is using. I am trying to reference the children property of a button element that is being created, but getting the warning, which seems unnecessary in this case.

I’m just trying to avoid hard-coding the children string in multiple places in my test file.

it(`'editDisabled' prop should disable the 'edit' and 'auxiliary' buttons`, () => {
    const auxiliaryProps = { children: 'auxButton' }
    setup(getEditableInput({ auxiliaryProps, editDisabled: true })) // Sets up some spies and calls render()
    const editButton = screen.getByRole('button', { name: 'edit' })
    // eslint-disable-next-line testing-library/no-node-access
    const auxButton = screen.getByRole('button', { name: auxiliaryProps.children })
    expect(editButton.getAttribute('disabled')).not.toBeNull()
    expect(auxButton.getAttribute('disabled')).not.toBeNull()
  })

I got same false negative in one of projects I work on. props.children should be valid. added ignore comment meanwhile.