testing-library / testing-library/dom-testing-library
Create a specification for getNodeText used by queries
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 3.3k
- Forks
- 474
- PR merge metrics
- No merged PRs in 30d
Description
Describe the feature you'd like:
I've seen churn on what "text" means for a given element. The pendulum has swung from innerText to textContent based off unexpected use-cases. I think we should create a specification for what getNodeText returns for the queries that rely on it.
Effected queries:
- *ByTitle
- *ByText
- *ByDisplayValue
I think *ByLabelText used to use it, but it is no longer.
Some examples that aren't working as expected.
Nested inline elements
This example is probably more common for Cypress, Puppeteer, etc. For example, Cypress implicitly waits for actionability. If a button is disabled and the test calls cy.findByText('Hello').click(), Cypress will not wait for the disabled to be removed from the button element. There is no workaround other than not using findByText at all. Adding a selector should define what element we want to return, but getNodeText won't be able to find anything.
<button><span>Hello</span></button>
<script>
getByText('Hello') // returns span
getByText('Hello', { selector: 'button' }) // error - not found
// expected: `button` element
</script>
<th>
Country
<!-- Country Filter for the table header -->
<select>
<option>Colombia</option>
</select>
</th>
<script>
getByText('Country') // returns th
// expected: `th` element
</script>
Inconsistencies with *ByLabelText
<label for="1234">My Label<abbr>*</abbr></label>
<input id="1234">
<script>
getByText('My Label'); // returns <label>
getByLabelText('My Label'); // Error: Unable to find a label with the text of: My Label
getByText('My Label*'); // Error: Unable to find an element with the text: My Label*. This could be because the text is broken up by multiple elements. In ...
getByLabelText('My Label*'); // returns <input>
</script>
There are probably other edge cases we can build a specification around.
This would be a breaking change for existing implementations that rely on the current functionality. For example:
<button><span>Hello</span></button>
<script>
getByText('Hello') // error, 2 elements found. Before, only span was returned
getAllByText('Hello') // [button, span]. Before, only [span] was returned
getByText('Hello', { selector: 'span' }) // span
getByText('Hello', { selector: 'button' }) // button
</script>
Suggested implementation:
Write specifications for what should be returned given a few different DOM structures.
Describe alternatives you've considered:
I've looked through some of the history around the implementation of the getNodeText function. It seems edge cases have driven the implementation, but there isn't much conditional coding to handle multiple edge cases at once.
Teachability, Documentation, Adoption, Migration Strategy:
Hopefully this feature doesn't require much documentation as it will mostly do what one would expect. Edge cases could be enumerated in the documentation, however. Something like:
getByText tries to grab elements by most likely text of an element. For example, a
buttonelement with nestedspanelements will return the whole text of the button, spans included. getByText also tries to filter out unintended text. For example, a table header that contains aselectelement will remove the text of theselectelement itself as that is most likely the intent of selecting the table's header text.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the getNodeText entry point and the *ByTitle, *ByText, and *ByDisplayValue query paths. Use the nested inline elements, nested select, and label examples as initial cases for a specification, then add coverage for the agreed DOM structures and document the resulting behavior and migration impact.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100