Nycki
Nycki

Reputation: 970

With React Testing Library and Jest, how do I assert that text does not visibly exist?

I have some text like "Message failed to send" that I want to assert will not appear on screen. According to this answer, I should avoid compound logic in my assertions. And according to the React Testing Library guiding principles, I should write tests based on the user experience. So it seems like I should do something like this:

test('it does not display an error', () => {
  render(<App />);
  expect(screen).not.toDisplayText('failed to send');
});

This matcher doesn't seem to exist, though, and I can't find one equivalent to it.

It seems like "this text does not exist and I don't care why" should be a pretty common query, but I can't find a clean way to test for it. Right now I'm just switching which test I use based on whether I expect the element to be nonexistent or nonvisible, but that feels wrong. Is there a better way?

Upvotes: 2

Views: 2280

Answers (2)

Nycki
Nycki

Reputation: 970

Use a custom text match function that only matches visible text.

function matchVisible(text) {
  return (content, element) => content.startsWith(text) && element.getAttribute('aria-hidden') !== 'true';
}

test('everything is fine', () => {
  render(<MyApp />);
  const error = screen.queryByText(matchVisible('flagrant error'));
  expect(error).toBeNull();
});

Reference: https://github.com/testing-library/dom-testing-library/issues/929#issuecomment-1571823720

Upvotes: 0

Avi
Avi

Reputation: 1427

"None-existant" and "not visible" are fundamentally two different things which is why the test matchers you mentioned are working differently.

Setting styling properties like visibility: hidden; and opacity: 0; on an element means that the element will still occupy space on the screen and appear in the DOM tree.

On the other hand, setting display: none; (or not rendering an element at all) will prevent the element from occupying any space or appearing in the DOM.

Both approaches to "hide" an element or text are valid depending on your requirements. With that being said, Even if there was such a custom matcher that covers both cases, I would advise to against using it. This is because using a specific test matcher for each approach, gives better context to your future self or other developers on your team on how the component works, what its intended behavior, and why a test might by failing.

Upvotes: 0

Related Questions