Dom-testing-library: Add support to specify the type of node which is selected

Created on 1 Jun 2018  路  6Comments  路  Source: testing-library/dom-testing-library

So I ran into an issue when I was working with cypress. I wanted to .click() a button which had the exact same wording as the headline right above. getByTextalways took the headline instead of the button so I had to use .get('button:contains("[...]")') to be able to get the button.

screen shot 2018-06-01 at 08 45 35

So I thought to be able to always use getByText it would be nice to be able to specify the type of node I want to get as part of the options maybe something like getByText(container, 'text', { node: 'button' }).

Of course I would volunteer to do it if it was discussed and approved.

Most helpful comment

Yes, I agree, we should update docs. @JonathanStoye, since you would have benefitted from this knowledge directly, would you like to be the one to contribute docs for it?

All 6 comments

This is a valid suggestion, and it leans towards a relevance ordering of found nodes.

Imagine the button you're looking for contains a div, and your headline, too. You'll have two div matches with identical text, which one should the test prefer?

I use a composition of visual distance, absolute zindex, and area in my getVisuallyBelow query (not in the lib yet), but this may sound more complicated than anyone would like to implement.

Most of there get* and query* helpers accept what the library calls a TextMatch, which can be a string, a regex or a function. If you use the function form, you should be able to solve this:

getByText(container, (content, element) => {
  return element.tagName.toLowerCase() === 'button' && content === 'Login'
})

However, I do agree that this seems a bit too complex. There could be a way to pass a selector to limit the elements where to search for the text/label/whatever.

Perhaps an additional optional option argument? (name to be discussed, but the idea remains)

getByText(container, 'Login', { within: 'button[type="submit"]' });

It could be argued that this does not necessarily violates the guiding principles of this library, because the users do look for a button to click, not just any element in the page that says "Login".

There's actually already an option called selector which allows you to scope your search to certain elements. So I think you should be able to do:

getByText(container, 'Login', {selector: 'button'})

That should work. Let us know!

Oh, ok, good to know. But getByText does not show it in its documentation in the README. Actually getByLabelText is the only one documenting that option. If indeed all the get* and query* helpers support it, then the README should be updated.

Yes, I agree, we should update docs. @JonathanStoye, since you would have benefitted from this knowledge directly, would you like to be the one to contribute docs for it?

Shame one me for not doing enough research. And of course I will transform this issue to update the docs then. 馃槉

Was this page helpful?
0 / 5 - 0 ratings