Skip to content

Commit

Permalink
feat(getNodeText ): add getNodeText and ignore extra whitespace in no…
Browse files Browse the repository at this point in the history
…de texts (#21)

* Ignore extra whitespace in all contexts when matching text

* Expose getText

* Properly expose getText

* Rename getText as getNodeText

* Document getNodeText in the README

* Typo
  • Loading branch information
gnapse authored and Kent C. Dodds committed Apr 11, 2018
1 parent 97af0e6 commit 2273f03
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 17 deletions.
19 changes: 19 additions & 0 deletions README.md
Expand Up @@ -395,6 +395,25 @@ fireEvent.click(getElementByText('Submit'), rightClick)
// default `button` property for click events is set to `0` which is a left click.
```

#### `getNodeText(node: HTMLElement)`

Returns the complete text content of a html element, removing any extra
whitespace. The intention is to treat text in nodes exactly as how it is
perceived by users in a browser, where any extra whitespace within words in the
html code is not meaningful when the text is rendered.

```javascript
// <div>
// Hello
// World !
// </div>
const text = getNodeText(container.querySelector('div')) // "Hello World !"
```

This function is also used internally when querying nodes by their text content.
This enables functions like `getByText` and `queryByText` to work as expected,
finding elements in the DOM similarly to how users would do.

## Custom Jest Matchers

When using [jest][], we recommend that you import a set of custom matchers that
Expand Down
12 changes: 12 additions & 0 deletions src/get-node-text.js
@@ -0,0 +1,12 @@
function getNodeText(node) {
return Array.from(node.childNodes)
.filter(
child => child.nodeType === Node.TEXT_NODE && Boolean(child.textContent),
)
.map(c => c.textContent)
.join(' ')
.trim()
.replace(/\s+/g, ' ')
}

export {getNodeText}
1 change: 1 addition & 0 deletions src/index.js
Expand Up @@ -8,5 +8,6 @@ export * from './queries'
export * from './wait'
export * from './wait-for-element'
export * from './matches'
export * from './get-node-text'
export * from './events'
export * from './bind-element-to-queries'
10 changes: 7 additions & 3 deletions src/matches.js
Expand Up @@ -2,12 +2,16 @@ function matches(textToMatch, node, matcher) {
if (typeof textToMatch !== 'string') {
return false
}
const normalizedText = textToMatch
.toLowerCase()
.trim()
.replace(/\s+/g, ' ')
if (typeof matcher === 'string') {
return textToMatch.toLowerCase().includes(matcher.toLowerCase())
return normalizedText.includes(matcher.toLowerCase())
} else if (typeof matcher === 'function') {
return matcher(textToMatch, node)
return matcher(normalizedText, node)
} else {
return matcher.test(textToMatch)
return matcher.test(normalizedText)
}
}

Expand Down
16 changes: 2 additions & 14 deletions src/queries.js
@@ -1,5 +1,6 @@
import prettyFormat from 'pretty-format'
import {matches} from './matches'
import {getNodeText} from './get-node-text'

const {DOMElement, DOMCollection} = prettyFormat.plugins

Expand Down Expand Up @@ -46,7 +47,7 @@ function queryByLabelText(container, text, {selector = '*'} = {}) {
function queryByText(container, text, {selector = '*'} = {}) {
return (
Array.from(container.querySelectorAll(selector)).find(node =>
matches(getText(node), node, text),
matches(getNodeText(node), node, text),
) || null
)
}
Expand All @@ -64,19 +65,6 @@ function queryByAttribute(attribute, container, text) {
const queryByPlaceholderText = queryByAttribute.bind(null, 'placeholder')
const queryByTestId = queryByAttribute.bind(null, 'data-testid')

// this is just a utility and not an exposed query.
// There are no plans to expose this.
function getText(node) {
return Array.from(node.childNodes)
.filter(
child => child.nodeType === Node.TEXT_NODE && Boolean(child.textContent),
)
.map(c => c.textContent)
.join(' ')
.trim()
.replace(/\s+/g, ' ')
}

// getters
// the reason we're not dynamically generating these functions that look so similar:
// 1. The error messages are specific to each one and depend on arguments
Expand Down

0 comments on commit 2273f03

Please sign in to comment.