-
Notifications
You must be signed in to change notification settings - Fork 470
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
getByText()/queryByText() (or some new query) should search across nested elements #201
Comments
I think that I'm in favor of this if we can make it work. I can't promise that I'll be able to work on it any time soon, but I would be happy to review and merge a PR that implements this kind of text searching for all queries. One potential issue I see is: // Given: <div>Some <span>nested</span> text</div>
getByText(/.*nested.*/) // what should this return? The outer div and the span both match. I think a naive implementation of this would result in returning the |
Hmm, I thought .innerText would do something like that, while .textContent doesn't. Wasn't the reason for the recent change proposal - to handle nested options in a select tag more realistically? https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText |
I think this would fix these queries, if someone wants to pick it up: #190 |
Turns out #190 probably isn't the right solution since .innerText isn't actually implemented/implementable in JSDOM (missed that part, sorry). But removing the text node filter (below) in get-node-text gets pretty close to the behavior at the cost of duplicating matched nodes when you have something like
#202 would help with the duplication but if you go outside-in a lot of queries would return the |
Ok, so I'm working on this a bit and I've hit a bit of a road block partially due to the way this works, but also partially due to not being sure of the best way to go about this. For example:
With that you want to get the But what about this:
Which element should you get in this case? I'm not sure that we can actually come to a "right" answer here... Honestly, I don't know how to proceed. |
Yeah, that's similar to what I ran into - in a lot of cases you'll even end up with document.body if the tree is simply nested |
Is returning the "smallest enclosing" element problematic? So eg in the second example above, you'd get |
I think that's probably the most sensible. This will be a nontrivial change I'm afraid. But probably possible. I think I'd like to work on it, but I'd like to hear what other people think about it. |
What if there was a way to define tags (selectors?) to ignore / consider as the enclosing node? For the example above: (I didn't give much though to the option names. ) It's a bit of a trade-off between "do what the user does" and knowing some of the HTML internals. (Or maybe it's not that far off since typically the user does see the different styling, like bold text, and then ends-up interacting with the whole parent element rather than just the bold text.) |
What about Because that's currently supported :) |
Thank you @kentcdodds for the tip. I had element which looked like this:
and I wanted to match "0.00 PLN". I found it using custom matcher:
|
Cool. I think we'll just stick with that as a workaround and we'll be good 👍 |
Hi! Just wanted to add to the solution commonly accept (that is, use Replacing it with Here's a small CodeSandbox that reproduces that use case What would be the recommended way of testing situations like this one then? |
I found this answer on SO, where the OP implemented his own helper I think it would be great to add it to |
I'm working on a more general approach that will allow querying elements with roles by their accessible name. This should solve your issue. |
I think that's a great idea @eps1lon 👍 Looking forward to hearing more about it. |
After looking at eps1lon/dom-accessibility-api#233 and w3c/aria#1117 I think the But Adding |
Simply only returning elements that actually have content themselves, seems to filter out unwanted parents just fine: expect(
// - content: text content of current element, without text of its children
// - element.textContent: content of current element plus its children
screen.getByText((content, element) => {
return content !== '' && element.textContent === '0.00 PLN';
})
).toBeInTheDocument(); |
Describe the feature you'd like:
In my app, I'm rendering some markup like:
It feels like I should be able to test that the right "answer prefix" (here, "a.") is rendered with the corresponding answer text just by doing eg:
(which would select the enclosing
<div>
)So I guess recursively concatenating text node children from nested elements?
It didn't look like there's already a way to do this
Suggested implementation:
I haven't looked at the implementation, just checked that in
__tests__/element-queries.js
I saw a test for sibling text node concatenation but not for nested child element text nodesWould possibly be up for implementing this but am not super familiar with low-level DOM APIs
Describe alternatives you've considered:
I guess adding a
data-testid
to the enclosing<div>
and then examining its children individually? But in the spirit of "what matters is how the user experiences it", that seems fragile compared to just searching text content across whatever arbitrary nested markup you may be renderingTeachability, Documentation, Adoption, Migration Strategy:
I think adding an example with simple nested content eg:
with
would be pretty clear as far as the gist of the supported feature
The text was updated successfully, but these errors were encountered: