Skip to content

Commit 45f8654

Browse files
authored
Merge pull request #55 from testing-library/fix-radio-checkbox
Fix radio, checkbox and select
2 parents 9f5e8e4 + 81ed95b commit 45f8654

File tree

5 files changed

+78
-34
lines changed

5 files changed

+78
-34
lines changed

src/vue-testing-library.js

+8-11
Original file line numberDiff line numberDiff line change
@@ -110,22 +110,19 @@ fireEvent.update = async (elem, value) => {
110110

111111
switch (tagName) {
112112
case 'OPTION': {
113-
elem.selected = value
113+
elem.selected = true
114114

115-
const parentElement =
116-
this.element.parentElement.tagName === 'OPTGROUP'
117-
? this.element.parentElement.parentElement
118-
: this.element.parentElement
115+
const parentSelectElement =
116+
elem.parentElement.tagName === 'OPTGROUP'
117+
? elem.parentElement.parentElement
118+
: elem.parentElement
119119

120-
return fireEvent.change(parentElement)
120+
return fireEvent.change(parentSelectElement)
121121
}
122122

123123
case 'INPUT': {
124-
if (type === 'checkbox') {
125-
elem.checked = value
126-
return fireEvent.change(elem)
127-
} else if (type === 'radio') {
128-
elem.selected = value
124+
if (['checkbox', 'radio'].includes(type)) {
125+
elem.checked = true
129126
return fireEvent.change(elem)
130127
} else {
131128
elem.value = value

tests/__tests__/components/Form.vue

-10
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,6 @@
2626
Awful
2727
</label>
2828

29-
<label for="genre-select">Movie genre</label>
30-
<select id="genre-select" v-model="genre">
31-
<option>Comedy</option>
32-
<option>Action</option>
33-
<option>Romance</option>
34-
<option>None of the above</option>
35-
</select>
36-
3729
<label id="recommend-label">Would you recommend this movie?</label>
3830
<input
3931
id="recommend"
@@ -56,7 +48,6 @@ export default {
5648
title: '',
5749
review: '',
5850
rating: '1',
59-
genre: 'Comedy',
6051
recommend: false
6152
}
6253
},
@@ -73,7 +64,6 @@ export default {
7364
title: this.title,
7465
review: this.review,
7566
rating: this.rating,
76-
genre: this.genre,
7767
recommend: this.recommend
7868
})
7969
}

tests/__tests__/components/Select.vue

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<template>
2+
<div>
3+
<label for="dino-select">Choose a dinosaur:</label>
4+
<select id="dino-select" v-model="selectedDino">
5+
<option value="dino1">Tyrannosaurus</option>
6+
<option value="dino2">Velociraptor</option>
7+
<option value="dino3">Deinonychus</option>
8+
<optgroup label="Sauropods">
9+
<option value="dino4">Diplodocus</option>
10+
<option value="dino5">Saltasaurus</option>
11+
<option value="dino6">Apatosaurus</option>
12+
</optgroup>
13+
</select>
14+
</div>
15+
</template>
16+
17+
<script>
18+
export default {
19+
data() {
20+
return {
21+
selectedDino: 'dino1'
22+
}
23+
}
24+
}
25+
</script>

tests/__tests__/form.js

+18-13
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,23 @@ import { render, fireEvent } from '@testing-library/vue'
22
import '@testing-library/jest-dom/extend-expect'
33
import Form from './components/Form'
44

5+
// In this test we showcase several ways of targetting DOM elements.
6+
// However, `getByLabelText` should be your top preference when handling
7+
// form elements.
8+
// Read 'What queries should I use?' for additional context:
9+
// https://testing-library.com/docs/guide-which-query
510
test('Review form submits', async () => {
611
const fakeReview = {
712
title: 'An Awesome Movie',
813
review: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
914
rating: '3',
10-
genre: 'Action',
1115
recommend: true
1216
}
1317

1418
const {
1519
getByLabelText,
1620
getByText,
1721
getByRole,
18-
getByDisplayValue,
1922
getByPlaceholderText,
2023
emitted
2124
} = render(Form)
@@ -25,28 +28,30 @@ test('Review form submits', async () => {
2528
// Initially the submit button should be disabled
2629
expect(submitButton).toBeDisabled()
2730

28-
// In this test we showcase several ways of targetting DOM elements.
29-
// However, `getByLabelText` should be your top preference when handling
30-
// form elements.
31-
// Read 'What queries should I use?' for additional context:
32-
// https://testing-library.com/docs/guide-which-query
33-
3431
const titleInput = getByLabelText(/title of the movie/i)
3532
await fireEvent.update(titleInput, fakeReview.title)
3633

3734
const reviewTextarea = getByPlaceholderText('Write an awesome review')
3835
await fireEvent.update(reviewTextarea, fakeReview.review)
3936

37+
// Rating Radio buttons
38+
const initiallySelectedInput = getByLabelText('Awful')
4039
const ratingSelect = getByLabelText('Wonderful')
41-
await fireEvent.update(ratingSelect, fakeReview.rating)
4240

43-
// Get the Select element by using the initially displayed value.
44-
const genreSelect = getByDisplayValue('Comedy')
45-
await fireEvent.update(genreSelect, fakeReview.genre)
41+
expect(initiallySelectedInput.checked).toBe(true)
42+
expect(ratingSelect.checked).toBe(false)
43+
44+
await fireEvent.update(ratingSelect)
45+
46+
expect(ratingSelect.checked).toBe(true)
47+
expect(initiallySelectedInput.checked).toBe(false)
4648

4749
// Get the Input element by its implicit ARIA role.
4850
const recommendInput = getByRole('checkbox')
49-
await fireEvent.update(recommendInput, fakeReview.recommend)
51+
52+
expect(recommendInput.checked).toBe(false)
53+
await fireEvent.update(recommendInput)
54+
expect(recommendInput.checked).toBe(true)
5055

5156
// NOTE: in jsdom, it's not possible to trigger a form submission
5257
// by clicking on the submit button. This is really unfortunate.

tests/__tests__/select.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { render, fireEvent } from '@testing-library/vue'
2+
import '@testing-library/jest-dom/extend-expect'
3+
import Select from './components/Select'
4+
5+
// In this test file we showcase several ways to interact with a Select element
6+
test('Select component', async () => {
7+
let optionElement
8+
const { getByDisplayValue, getByText } = render(Select)
9+
10+
// Get the Select element by using the initially displayed value
11+
const select = getByDisplayValue('Tyrannosaurus')
12+
expect(select.value).toBe('dino1')
13+
14+
// Update it by manually sending a valid option value
15+
await fireEvent.update(select, 'dino2')
16+
expect(select.value).toBe('dino2')
17+
18+
// We can trigger an update event by directly getting the <option> element
19+
optionElement = getByText('Deinonychus')
20+
await fireEvent.update(optionElement)
21+
expect(select.value).toBe('dino3')
22+
23+
// ...even if option is within an <optgroup>
24+
optionElement = getByText('Diplodocus')
25+
await fireEvent.update(optionElement)
26+
expect(select.value).toBe('dino4')
27+
})

0 commit comments

Comments
 (0)