Skip to content

Commit

Permalink
Merge pull request #55 from testing-library/fix-radio-checkbox
Browse files Browse the repository at this point in the history
Fix radio, checkbox and select
  • Loading branch information
dfcook authored Jul 30, 2019
2 parents 9f5e8e4 + 81ed95b commit 45f8654
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 34 deletions.
19 changes: 8 additions & 11 deletions src/vue-testing-library.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,19 @@ fireEvent.update = async (elem, value) => {

switch (tagName) {
case 'OPTION': {
elem.selected = value
elem.selected = true

const parentElement =
this.element.parentElement.tagName === 'OPTGROUP'
? this.element.parentElement.parentElement
: this.element.parentElement
const parentSelectElement =
elem.parentElement.tagName === 'OPTGROUP'
? elem.parentElement.parentElement
: elem.parentElement

return fireEvent.change(parentElement)
return fireEvent.change(parentSelectElement)
}

case 'INPUT': {
if (type === 'checkbox') {
elem.checked = value
return fireEvent.change(elem)
} else if (type === 'radio') {
elem.selected = value
if (['checkbox', 'radio'].includes(type)) {
elem.checked = true
return fireEvent.change(elem)
} else {
elem.value = value
Expand Down
10 changes: 0 additions & 10 deletions tests/__tests__/components/Form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@
Awful
</label>

<label for="genre-select">Movie genre</label>
<select id="genre-select" v-model="genre">
<option>Comedy</option>
<option>Action</option>
<option>Romance</option>
<option>None of the above</option>
</select>

<label id="recommend-label">Would you recommend this movie?</label>
<input
id="recommend"
Expand All @@ -56,7 +48,6 @@ export default {
title: '',
review: '',
rating: '1',
genre: 'Comedy',
recommend: false
}
},
Expand All @@ -73,7 +64,6 @@ export default {
title: this.title,
review: this.review,
rating: this.rating,
genre: this.genre,
recommend: this.recommend
})
}
Expand Down
25 changes: 25 additions & 0 deletions tests/__tests__/components/Select.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<template>
<div>
<label for="dino-select">Choose a dinosaur:</label>
<select id="dino-select" v-model="selectedDino">
<option value="dino1">Tyrannosaurus</option>
<option value="dino2">Velociraptor</option>
<option value="dino3">Deinonychus</option>
<optgroup label="Sauropods">
<option value="dino4">Diplodocus</option>
<option value="dino5">Saltasaurus</option>
<option value="dino6">Apatosaurus</option>
</optgroup>
</select>
</div>
</template>

<script>
export default {
data() {
return {
selectedDino: 'dino1'
}
}
}
</script>
31 changes: 18 additions & 13 deletions tests/__tests__/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@ import { render, fireEvent } from '@testing-library/vue'
import '@testing-library/jest-dom/extend-expect'
import Form from './components/Form'

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

const {
getByLabelText,
getByText,
getByRole,
getByDisplayValue,
getByPlaceholderText,
emitted
} = render(Form)
Expand All @@ -25,28 +28,30 @@ test('Review form submits', async () => {
// Initially the submit button should be disabled
expect(submitButton).toBeDisabled()

// In this test we showcase several ways of targetting DOM elements.
// However, `getByLabelText` should be your top preference when handling
// form elements.
// Read 'What queries should I use?' for additional context:
// https://testing-library.com/docs/guide-which-query

const titleInput = getByLabelText(/title of the movie/i)
await fireEvent.update(titleInput, fakeReview.title)

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

// Rating Radio buttons
const initiallySelectedInput = getByLabelText('Awful')
const ratingSelect = getByLabelText('Wonderful')
await fireEvent.update(ratingSelect, fakeReview.rating)

// Get the Select element by using the initially displayed value.
const genreSelect = getByDisplayValue('Comedy')
await fireEvent.update(genreSelect, fakeReview.genre)
expect(initiallySelectedInput.checked).toBe(true)
expect(ratingSelect.checked).toBe(false)

await fireEvent.update(ratingSelect)

expect(ratingSelect.checked).toBe(true)
expect(initiallySelectedInput.checked).toBe(false)

// Get the Input element by its implicit ARIA role.
const recommendInput = getByRole('checkbox')
await fireEvent.update(recommendInput, fakeReview.recommend)

expect(recommendInput.checked).toBe(false)
await fireEvent.update(recommendInput)
expect(recommendInput.checked).toBe(true)

// NOTE: in jsdom, it's not possible to trigger a form submission
// by clicking on the submit button. This is really unfortunate.
Expand Down
27 changes: 27 additions & 0 deletions tests/__tests__/select.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { render, fireEvent } from '@testing-library/vue'
import '@testing-library/jest-dom/extend-expect'
import Select from './components/Select'

// In this test file we showcase several ways to interact with a Select element
test('Select component', async () => {
let optionElement
const { getByDisplayValue, getByText } = render(Select)

// Get the Select element by using the initially displayed value
const select = getByDisplayValue('Tyrannosaurus')
expect(select.value).toBe('dino1')

// Update it by manually sending a valid option value
await fireEvent.update(select, 'dino2')
expect(select.value).toBe('dino2')

// We can trigger an update event by directly getting the <option> element
optionElement = getByText('Deinonychus')
await fireEvent.update(optionElement)
expect(select.value).toBe('dino3')

// ...even if option is within an <optgroup>
optionElement = getByText('Diplodocus')
await fireEvent.update(optionElement)
expect(select.value).toBe('dino4')
})

0 comments on commit 45f8654

Please sign in to comment.