Jest-dom: toHaveTextContent should ignore whitespace

Created on 11 Apr 2018  路  17Comments  路  Source: testing-library/jest-dom

  • jest-dom version: 1.0.0

What you did:

//  <span>
//    Step
//      1
//    of 4
//  </span>

expect(container.querySelector('span')).toHaveTextContent('Step 1 of 4')

What happened:

    expect(element).toHaveTextContent()

    Expected element to have text content:
      Step 1 of 4
    Received:

          Step
            1
          of 4

Problem description:

This was initially reported in kentcdodds/react-testing-library#53, and it was really about a bug in kentcdodds/dom-testing-library#19. However, this also applies to a piece of code in jest-dom. The custom matchet .toHaveTextContent should also ignore a node's whitespace in its text content before determining if the text matches the expectation.

Suggested solution:

Normalize the text of a node before using to match it with the expected text. Similar to what was done in kentcdodds/dom-testing-library#19

bug good first issue

All 17 comments

Actually, dom-testing-library actually exposes its matches function, we should probably use that too :+1:

That fix was not done in matches because that one is used in other contexts. But perhaps we wanted all other contexts to be affected too? In that case we need to revisit my fix to be done in that way instead.

No, I was just suggesting while you're working on this you could do that as well. Perhaps we should also expose the getText method from dom-testing-library as well 馃

@kentcdodds wouldn't there be a problem if two packages depend on each other?

I think that's actually allowed. But I'm thinking that dom-testing-library should no longer depend on jest-dom. I think we should make a major version bump to make that happen. I think folks should install jest-dom separately.

-- Removed idea about using element.innerText as it has a few quirks and better options exist.

From @noinkling:
https://github.com/gnapse/jest-dom/pull/56#issuecomment-426535211

This change [#56] breaks testing for text within child elements (nested text), because you switched to using getNodeText from dom-testing-library, which only considers immediate text node children.

Example:

<div class="error">
  <ul>
    <li>Email format is invalid</li>
  </ul>
</div>

I just want to write something like expect(errorBox).toHaveTextContent('email format'), instead of tightly coupling my tests to whatever the internal structure may be. This worked fine in the previous version because it used .textContent (which is what I would expect a method named "toHaveTextContent" to use).

Since it now fails, the best I can come up with is something like expect(errorBox.textContent).toMatch(/email format/i), which isn't nearly as nice.

From @kentcdodds:
https://github.com/gnapse/jest-dom/pull/56#issuecomment-426630987

expect(errorBox).toHaveTextContent('email format')

I don't think that would have worked before. The regex is how I would have done that before and now 馃

Hrm, Line 5: of get-node-text filters out all non TEXT_NODES. So it would only currently get one level deep of text. If we switch the && to || I think it would get all sub text as well:

Example:
https://codesandbox.io/s/5xl195pynx
The console.log shows the examples

@kentcdodds is getNodeText meant to get the full text (including children) or just one level deep?

This however, would only normalize one level deep though, so it wouldn't solve the issue.

The normalization was moved to: https://github.com/kentcdodds/dom-testing-library/blob/863741a204bca67c63ca3944770727e5afb071d2/src/matches.js#L39-L46

So getNodeText no longer normalizes the text. (https://github.com/kentcdodds/dom-testing-library/pull/31)

Hrm, Maybe we could use fuzzyMatches in conjunction with getNodeText!

Why not just normalize the .textContent?

@kentcdodds Well toHaveTextContent also supports a regex, if that's specifically the part you're worried about (maybe there's an argument for not doing partial or case-insensitive matches when using a string). But it still won't work on nested text anymore regardless.

That's a really good point haha!

:tada: This issue has been resolved in version 2.0.1 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

Thanks for the fix 馃檪

As @smacpherson64 predicted, this broke a lot of our tests... Is that allowed under SemVer?

            expect(signInSection).toHaveTextContent(
                '[DICT] Welcome,Kermit the Frog'
            );

@malixsys I'm so sorry.

I'm not sure how you're specifying jest-dom's version number, but this was indeed published as a breaking change, and it's the breaking change that switched jest-dom from v1.x to v2. I think that would not violate SemVer terms.

Maybe I'm missing something. Can you clarify what version you're using that broke your tests, and under which version they used to work? Your code snippet above does not give much information.

@gnapse Ah yes, indeed! Sorry, thought this was in 2.0.1! No worries, 2.x has been put in the code debt column for now... :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gnapse picture gnapse  路  5Comments

thomaslombart picture thomaslombart  路  6Comments

gregberge picture gregberge  路  6Comments

BurntCaramel picture BurntCaramel  路  5Comments

jsphstls picture jsphstls  路  4Comments