Skip to content

Commit c441145

Browse files
Merge remote-tracking branch 'upstream/master' into pr/custom-normalizer
2 parents 8b41ad8 + 9a19474 commit c441145

File tree

4 files changed

+154
-37
lines changed

4 files changed

+154
-37
lines changed

.all-contributorsrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,15 @@
440440
"contributions": [
441441
"code"
442442
]
443+
},
444+
{
445+
"login": "eunjae-lee",
446+
"name": "Eunjae Lee",
447+
"avatar_url": "https://avatars3.githubusercontent.com/u/499898?v=4",
448+
"profile": "https://twitter.com/eunjae_lee",
449+
"contributions": [
450+
"code"
451+
]
443452
}
444453
]
445454
}

README.md

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
[![downloads][downloads-badge]][npmtrends]
1818
[![MIT License][license-badge]][license]
1919

20-
[![All Contributors](https://img.shields.io/badge/all_contributors-44-orange.svg?style=flat-square)](#contributors)
20+
[![All Contributors](https://img.shields.io/badge/all_contributors-45-orange.svg?style=flat-square)](#contributors)
2121
[![PRs Welcome][prs-badge]][prs]
2222
[![Code of Conduct][coc-badge]][coc]
2323

@@ -81,11 +81,10 @@ when a real user uses it.
8181
- [Usage](#usage)
8282
- [`getByLabelText`](#getbylabeltext)
8383
- [`getByPlaceholderText`](#getbyplaceholdertext)
84-
- [`getBySelectText`](#getbyselecttext)
8584
- [`getByText`](#getbytext)
8685
- [`getByAltText`](#getbyalttext)
8786
- [`getByTitle`](#getbytitle)
88-
- [`getByValue`](#getbyvalue)
87+
- [`getByDisplayValue`](#getbydisplayvalue)
8988
- [`getByRole`](#getbyrole)
9089
- [`getByTestId`](#getbytestid)
9190
- [`wait`](#wait)
@@ -275,34 +274,6 @@ const inputNode = getByPlaceholderText(container, 'Username')
275274
> NOTE: a placeholder is not a good substitute for a label so you should
276275
> generally use `getByLabelText` instead.
277276
278-
### `getBySelectText`
279-
280-
```typescript
281-
getBySelectText(
282-
container: HTMLElement,
283-
text: TextMatch,
284-
options?: {
285-
exact?: boolean = true,
286-
normalizer?: NormalizerFn,
287-
}): HTMLElement
288-
```
289-
290-
This will search for a `<select>` whose selected `<option>` matches the given [`TextMatch`](#textmatch). This would find the `<select>` node in a situation
291-
where the first value acts as a sort of placeholder for the dropdown.
292-
293-
```javascript
294-
// <select>
295-
// <option value="">Day of the Week</option>
296-
// <option value="1">Monday</option>
297-
// <option value="2">Tuesday</option>
298-
// <option value="3">Wednesday</option>
299-
// </select>
300-
const selectNode = getBySelectText(container, 'Day of the Week')
301-
```
302-
303-
> Note: It is highly preferred to use `getByLabelText` over this method. This
304-
> method should only be used in the event where there is no label text available.
305-
306277
### `getByText`
307278

308279
```typescript
@@ -385,10 +356,10 @@ Will also find a `title` element within an SVG.
385356
const closeElement = getByTitle(container, 'Close')
386357
```
387358

388-
### `getByValue`
359+
### `getByDisplayValue`
389360

390361
```typescript
391-
getByValue(
362+
getByDisplayValue(
392363
container: HTMLElement,
393364
value: TextMatch,
394365
options?: {
@@ -397,13 +368,41 @@ getByValue(
397368
}): HTMLElement
398369
```
399370

400-
Returns the element that has the matching value.
371+
Returns the `input`, `textarea`, or `select` element that has the matching display value.
372+
373+
#### `input`
374+
375+
```javascript
376+
// <input type="text" id="lastName" />
377+
// document.getElementById('lastName').value = 'Norris'
378+
379+
const lastNameInput = getByDisplayValue(container, 'Norris')
380+
```
381+
382+
#### `textarea`
401383

402384
```javascript
403-
// <input type="text" id="lastName" defaultValue="Norris" />
404-
const lastNameInput = getByValue('Norris')
385+
// <textarea id="messageTextArea"></textarea>
386+
// document.getElementById('messageTextArea').value = 'Hello World'
387+
388+
const messageTextArea = getByDisplayValue(container, 'Hello World')
405389
```
406390

391+
#### `select`
392+
393+
```javascript
394+
// <select id="state-select" data-testid="state">
395+
// <option value="">State</option>
396+
// <option value="AL">Alabama</option>
397+
// <option selected value="AK" >Alaska</option>
398+
// <option value="AZ">Arizona</option>
399+
// </select>
400+
401+
const selectElement = getByDisplayName(container, 'Alaska')
402+
```
403+
404+
In case of `select`, this will search for a `<select>` whose selected `<option>` matches the given [`TextMatch`](#textmatch).
405+
407406
### `getByRole`
408407

409408
```typescript
@@ -1177,7 +1176,7 @@ Thanks goes to these people ([emoji key][emojis]):
11771176
| [<img src="https://avatars2.githubusercontent.com/u/21689428?v=4" width="100px;"/><br /><sub><b>Jonathan Stoye</b></sub>](http://jonathanstoye.de)<br />[📖](https://github.com/kentcdodds/dom-testing-library/commits?author=JonathanStoye "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/4126644?v=4" width="100px;"/><br /><sub><b>Sanghyeon Lee</b></sub>](https://github.com/yongdamsh)<br />[💡](#example-yongdamsh "Examples") | [<img src="https://avatars3.githubusercontent.com/u/8015514?v=4" width="100px;"/><br /><sub><b>Justice Mba </b></sub>](https://github.com/Dajust)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=Dajust "Code") [📖](https://github.com/kentcdodds/dom-testing-library/commits?author=Dajust "Documentation") [🤔](#ideas-Dajust "Ideas, Planning, & Feedback") | [<img src="https://avatars3.githubusercontent.com/u/340761?v=4" width="100px;"/><br /><sub><b>Wayne Crouch</b></sub>](https://github.com/wgcrouch)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=wgcrouch "Code") | [<img src="https://avatars1.githubusercontent.com/u/4996462?v=4" width="100px;"/><br /><sub><b>Ben Elliott</b></sub>](http://benjaminelliott.co.uk)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=benelliott "Code") | [<img src="https://avatars3.githubusercontent.com/u/577921?v=4" width="100px;"/><br /><sub><b>Ruben Costa</b></sub>](http://nuances.co)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=rubencosta "Code") | [<img src="https://avatars2.githubusercontent.com/u/4982001?v=4" width="100px;"/><br /><sub><b>Robert Smith</b></sub>](http://rbrtsmith.com/)<br />[🐛](https://github.com/kentcdodds/dom-testing-library/issues?q=author%3Arbrtsmith "Bug reports") [🤔](#ideas-rbrtsmith "Ideas, Planning, & Feedback") [📖](https://github.com/kentcdodds/dom-testing-library/commits?author=rbrtsmith "Documentation") |
11781177
| [<img src="https://avatars3.githubusercontent.com/u/881986?v=4" width="100px;"/><br /><sub><b>dadamssg</b></sub>](https://github.com/dadamssg)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=dadamssg "Code") | [<img src="https://avatars1.githubusercontent.com/u/186971?v=4" width="100px;"/><br /><sub><b>Neil Kistner</b></sub>](https://neilkistner.com/)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=wyze "Code") | [<img src="https://avatars3.githubusercontent.com/u/1448597?v=4" width="100px;"/><br /><sub><b>Ben Chauvette</b></sub>](http://bdchauvette.net/)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=bdchauvette "Code") | [<img src="https://avatars2.githubusercontent.com/u/777527?v=4" width="100px;"/><br /><sub><b>Jeff Baumgardt</b></sub>](https://github.com/JeffBaumgardt)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=JeffBaumgardt "Code") [📖](https://github.com/kentcdodds/dom-testing-library/commits?author=JeffBaumgardt "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/4658208?v=4" width="100px;"/><br /><sub><b>Matan Kushner</b></sub>](http://matchai.me)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=matchai "Code") [📖](https://github.com/kentcdodds/dom-testing-library/commits?author=matchai "Documentation") [🤔](#ideas-matchai "Ideas, Planning, & Feedback") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=matchai "Tests") | [<img src="https://avatars2.githubusercontent.com/u/5779538?v=4" width="100px;"/><br /><sub><b>Alex Wendte</b></sub>](http://www.wendtedesigns.com/)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=themostcolm "Code") [📖](https://github.com/kentcdodds/dom-testing-library/commits?author=themostcolm "Documentation") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=themostcolm "Tests") | [<img src="https://avatars0.githubusercontent.com/u/2196208?v=4" width="100px;"/><br /><sub><b>Tamas Fodor</b></sub>](https://github.com/ruffle1986)<br />[📖](https://github.com/kentcdodds/dom-testing-library/commits?author=ruffle1986 "Documentation") |
11791178
| [<img src="https://avatars3.githubusercontent.com/u/14793495?v=4" width="100px;"/><br /><sub><b>Benjamin Eckardt</b></sub>](https://github.com/BenjaminEckardt)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=BenjaminEckardt "Code") | [<img src="https://avatars3.githubusercontent.com/u/205752?v=4" width="100px;"/><br /><sub><b>Ryan Campbell</b></sub>](https://github.com/campbellr)<br />[📖](https://github.com/kentcdodds/dom-testing-library/commits?author=campbellr "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/1335519?v=4" width="100px;"/><br /><sub><b>Taylor Briggs</b></sub>](https://taylor-briggs.com)<br />[⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=TaylorBriggs "Tests") | [<img src="https://avatars2.githubusercontent.com/u/132233?v=4" width="100px;"/><br /><sub><b>John Gozde</b></sub>](https://github.com/jgoz)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=jgoz "Code") | [<img src="https://avatars2.githubusercontent.com/u/3382565?v=4" width="100px;"/><br /><sub><b>C. T. Lin</b></sub>](https://github.com/chentsulin)<br />[📖](https://github.com/kentcdodds/dom-testing-library/commits?author=chentsulin "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/5312329?v=4" width="100px;"/><br /><sub><b>Terrence Wong</b></sub>](http://terrencewwong.com)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=terrencewwong "Code") | [<img src="https://avatars0.githubusercontent.com/u/12230408?v=4" width="100px;"/><br /><sub><b>Soo Jae Hwang</b></sub>](https://www.ossfinder.com)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=misoguy "Code") |
1180-
| [<img src="https://avatars0.githubusercontent.com/u/19773?v=4" width="100px;"/><br /><sub><b>Royston Shufflebotham</b></sub>](https://github.com/RoystonS)<br />[🐛](https://github.com/kentcdodds/dom-testing-library/issues?q=author%3ARoystonS "Bug reports") [💻](https://github.com/kentcdodds/dom-testing-library/commits?author=RoystonS "Code") [📖](https://github.com/kentcdodds/dom-testing-library/commits?author=RoystonS "Documentation") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=RoystonS "Tests") | [<img src="https://avatars0.githubusercontent.com/u/591673?v=4" width="100px;"/><br /><sub><b>Vadim Brodsky</b></sub>](http://www.vadimbrodsky.com)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=VadimBrodsky "Code") |
1179+
| [<img src="https://avatars0.githubusercontent.com/u/19773?v=4" width="100px;"/><br /><sub><b>Royston Shufflebotham</b></sub>](https://github.com/RoystonS)<br />[🐛](https://github.com/kentcdodds/dom-testing-library/issues?q=author%3ARoystonS "Bug reports") [💻](https://github.com/kentcdodds/dom-testing-library/commits?author=RoystonS "Code") [📖](https://github.com/kentcdodds/dom-testing-library/commits?author=RoystonS "Documentation") [⚠️](https://github.com/kentcdodds/dom-testing-library/commits?author=RoystonS "Tests") | [<img src="https://avatars0.githubusercontent.com/u/591673?v=4" width="100px;"/><br /><sub><b>Vadim Brodsky</b></sub>](http://www.vadimbrodsky.com)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=VadimBrodsky "Code") | [<img src="https://avatars3.githubusercontent.com/u/499898?v=4" width="100px;"/><br /><sub><b>Eunjae Lee</b></sub>](https://twitter.com/eunjae_lee)<br />[💻](https://github.com/kentcdodds/dom-testing-library/commits?author=eunjae-lee "Code") |
11811180

11821181
<!-- ALL-CONTRIBUTORS-LIST:END -->
11831182

src/__tests__/element-queries.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ test('getAll* matchers throw for 0 matches', () => {
347347
getAllByPlaceholderText,
348348
getAllByText,
349349
getAllByRole,
350+
getAllByDisplayValue,
350351
} = render(`
351352
<div role="container">
352353
<label>No Matches Please</label>
@@ -361,6 +362,7 @@ test('getAll* matchers throw for 0 matches', () => {
361362
expect(() => getAllByPlaceholderText('nope')).toThrow()
362363
expect(() => getAllByText('nope')).toThrow()
363364
expect(() => getAllByRole('nope')).toThrow()
365+
expect(() => getAllByDisplayValue('nope')).toThrow()
364366
})
365367

366368
test('queryAll* matchers return an array for 0 matches', () => {
@@ -565,4 +567,65 @@ test('getByText ignores script tags by default', () => {
565567
expect(getAllByText(/hello/i, {ignore: false})).toHaveLength(3)
566568
})
567569

570+
test('get/query input element by current value', () => {
571+
const {
572+
getByDisplayValue,
573+
queryByDisplayValue,
574+
getByTestId,
575+
} = renderIntoDocument(`
576+
<div>
577+
<input placeholder="name" type="text" data-testid="name" value="Mercury" />
578+
</div>
579+
`)
580+
expect(getByDisplayValue('Mercury').placeholder).toEqual('name')
581+
expect(queryByDisplayValue('Mercury').placeholder).toEqual('name')
582+
583+
getByTestId('name').value = 'Norris'
584+
expect(getByDisplayValue('Norris').placeholder).toEqual('name')
585+
expect(queryByDisplayValue('Norris').placeholder).toEqual('name')
586+
587+
expect(queryByDisplayValue('Nor', {exact: false}).placeholder).toEqual('name')
588+
})
589+
590+
test('get/query select element by current value', () => {
591+
const {
592+
getByDisplayValue,
593+
queryByDisplayValue,
594+
getByTestId,
595+
} = renderIntoDocument(`
596+
<select id="state-select" data-testid="state">
597+
<option value="">State</option>
598+
<option value="AL">Alabama</option>
599+
<option selected value="AK" >Alaska</option>
600+
<option value="AZ">Arizona</option>
601+
</select>
602+
`)
603+
604+
expect(getByDisplayValue('Alaska').id).toEqual('state-select')
605+
expect(queryByDisplayValue('Alaska').id).toEqual('state-select')
606+
607+
getByTestId('state').value = 'AL'
608+
expect(getByDisplayValue('Alabama').id).toEqual('state-select')
609+
expect(queryByDisplayValue('Alabama').id).toEqual('state-select')
610+
})
611+
612+
test('get/query textarea element by current value', () => {
613+
const {
614+
getByDisplayValue,
615+
queryByDisplayValue,
616+
getByTestId,
617+
} = renderIntoDocument(`
618+
<textarea id="content-textarea" data-testid="content">
619+
Hello
620+
</textarea>
621+
`)
622+
623+
expect(getByDisplayValue('Hello').id).toEqual('content-textarea')
624+
expect(queryByDisplayValue('Hello').id).toEqual('content-textarea')
625+
626+
getByTestId('content').value = 'World'
627+
expect(getByDisplayValue('World').id).toEqual('content-textarea')
628+
expect(queryByDisplayValue('World').id).toEqual('content-textarea')
629+
})
630+
568631
/* eslint jsx-a11y/label-has-for:0 */

src/queries.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,33 @@ function queryByAltText(...args) {
184184
return firstResultOrNull(queryAllByAltText, ...args)
185185
}
186186

187+
function queryAllByDisplayValue(
188+
container,
189+
value,
190+
{exact = true, collapseWhitespace = true, trim = true} = {},
191+
) {
192+
const matcher = exact ? matches : fuzzyMatches
193+
const matchOpts = {collapseWhitespace, trim}
194+
return Array.from(container.querySelectorAll(`input,textarea,select`)).filter(
195+
node => {
196+
if (node.tagName === 'SELECT') {
197+
const selectedOptions = Array.from(node.options).filter(
198+
option => option.selected,
199+
)
200+
return selectedOptions.some(optionNode =>
201+
matcher(getNodeText(optionNode), optionNode, value, matchOpts),
202+
)
203+
} else {
204+
return matcher(node.value, node, value, matchOpts)
205+
}
206+
},
207+
)
208+
}
209+
210+
function queryByDisplayValue(...args) {
211+
return firstResultOrNull(queryAllByDisplayValue, ...args)
212+
}
213+
187214
// getters
188215
// the reason we're not dynamically generating these functions that look so similar:
189216
// 1. The error messages are specific to each one and depend on arguments
@@ -329,6 +356,21 @@ function getBySelectText(...args) {
329356
return firstResultOrNull(getAllBySelectText, ...args)
330357
}
331358

359+
function getAllByDisplayValue(container, value, ...rest) {
360+
const els = queryAllByDisplayValue(container, value, ...rest)
361+
if (!els.length) {
362+
throw getElementError(
363+
`Unable to find an element with the value: ${value}.`,
364+
container,
365+
)
366+
}
367+
return els
368+
}
369+
370+
function getByDisplayValue(...args) {
371+
return firstResultOrNull(getAllByDisplayValue, ...args)
372+
}
373+
332374
export {
333375
queryByPlaceholderText,
334376
queryAllByPlaceholderText,
@@ -362,6 +404,10 @@ export {
362404
queryAllByValue,
363405
getByValue,
364406
getAllByValue,
407+
queryByDisplayValue,
408+
queryAllByDisplayValue,
409+
getByDisplayValue,
410+
getAllByDisplayValue,
365411
queryByRole,
366412
queryAllByRole,
367413
getAllByRole,

0 commit comments

Comments
 (0)