0

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.

  • I can use expect(screen.queryByText('fail')).not.toBeInTheDocument(), which passes if the text is nonexistent but fails if it is nonvisible.
  • I can use expect(screen.queryByText('fail')).not.toBeVisible(), which passes if the text is nonvisible but fails if it is nonexistent.

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?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
nupanick
  • 754
  • 8
  • 13
  • I'm a bit confused. Under what circumstances is the text non-existent and/or non-visible? I think we will need to see the component's code or if you could elaborate a bit more about it that would be great. – ivanatias Feb 21 '23 at 18:52
  • I'm testing the main entry point of the application, and I want to assert that some text does not appear for any reason. I don't care why the text doesn't appear, so I don't want to specify whether its invisible or nonexistent. – nupanick Feb 21 '23 at 19:13

1 Answers1

1

"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.

Avi
  • 1,049
  • 1
  • 5
  • 16
  • 1
    I understand what you mean about giving context to future developers, but isn't it still better to test what the user sees directly? – nupanick Feb 22 '23 at 18:24