Skip to content

Commit

Permalink
Make fireEvent awaitable
Browse files Browse the repository at this point in the history
  • Loading branch information
dfcook committed Dec 7, 2018
1 parent f8fec72 commit 77357fb
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 38 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -122,7 +122,7 @@ The `render` function takes up to 3 parameters and returns an object with some h

### fireEvent

Lightweight wrapper around DOM element events and methods
Lightweight wrapper around DOM element events and methods. Will call wait, so can be awaited to allow effects to propagate.

### wait

Expand Down
19 changes: 13 additions & 6 deletions src/index.js
Expand Up @@ -43,13 +43,12 @@ function render (TestComponent, {
localVue,
router,
store: vuexStore,
propsData: { ...props
},
propsData: { ...props },
attachToDocument: true,
sync: false
})

mountedWrappers.add(wrapper);
mountedWrappers.add(wrapper)

return {
debug: () => console.log(prettyDOM(wrapper.element)),
Expand Down Expand Up @@ -78,9 +77,17 @@ function cleanupAtWrapper (wrapper) {
mountedWrappers.delete(wrapper)
}

fireEvent.touch = (elem) => {
fireEvent.focus(elem)
fireEvent.blur(elem)
Object.keys(fireEvent).forEach(fn => {
fireEvent[`_${fn}`] = fireEvent[fn];
fireEvent[fn] = async (...params) => {
fireEvent[`_${fn}`](...params)
await wait()
}
})

fireEvent.touch = async (elem) => {
await fireEvent.focus(elem)
await fireEvent.blur(elem)
}

export * from 'dom-testing-library'
Expand Down
6 changes: 2 additions & 4 deletions tests/__tests__/fetch.js
@@ -1,5 +1,5 @@
import axiosMock from 'axios'
import { render, fireEvent, wait } from '../../src'
import { render, fireEvent } from '../../src'
import Fetch from './components/Fetch.vue'

test('Fetch makes an API call and displays the greeting when load-greeting is clicked', async () => {
Expand All @@ -12,9 +12,7 @@ test('Fetch makes an API call and displays the greeting when load-greeting is cl
const { html, getByText } = render(Fetch, { props: { url: '/greeting' } })

// Act
fireEvent.click(getByText('Fetch'))

await wait()
await fireEvent.click(getByText('Fetch'))

expect(axiosMock.get).toHaveBeenCalledTimes(1)
expect(axiosMock.get).toHaveBeenCalledWith('/greeting')
Expand Down
2 changes: 1 addition & 1 deletion tests/__tests__/form.js
Expand Up @@ -18,7 +18,7 @@ test('login form submits', async () => {
// by clicking on the submit button. This is really unfortunate.
// So the next best thing is to fireEvent a submit on the form itself
// then ensure that there's a submit button.
fireEvent.click(submitButtonNode)
await fireEvent.click(submitButtonNode)

// Assert
expect(handleSubmit).toHaveBeenCalledTimes(1)
Expand Down
5 changes: 2 additions & 3 deletions tests/__tests__/number-display.js
@@ -1,12 +1,11 @@
import NumberDisplay from './components/NumberDisplay.vue'
import { render, wait } from '../../src'
import { render } from '../../src'

test('calling render with the same component but different props does not remount', async () => {
const { queryByTestId, updateProps } = render(NumberDisplay, { props: { number: 1 } })
expect(queryByTestId('number-display').textContent).toBe('1')

updateProps({ number: 2 })
await wait()
await updateProps({ number: 2 })

expect(queryByTestId('number-display').textContent).toBe('2')
expect(queryByTestId('instance-id').textContent).toBe('1')
Expand Down
8 changes: 2 additions & 6 deletions tests/__tests__/stopwatch.js
Expand Up @@ -5,9 +5,7 @@ test('unmounts a component', async () => {
jest.spyOn(console, 'error').mockImplementation(() => {})

const { unmount, isUnmounted, getByText } = render(StopWatch)
fireEvent.click(getByText('Start'))

await wait()
await fireEvent.click(getByText('Start'))

unmount()
expect(isUnmounted()).toBe(true)
Expand All @@ -24,9 +22,7 @@ test('updates component state', async () => {

expect(elapsedTime.textContent).toBe('0ms')

fireEvent.click(startButton)
await wait()
fireEvent.click(startButton)
await fireEvent.click(startButton)

expect(elapsedTime.textContent).not.toBe('0ms')
})
6 changes: 2 additions & 4 deletions tests/__tests__/validate-plugin.js
@@ -1,16 +1,14 @@
import VeeValidate from 'vee-validate'

import { render, fireEvent, wait } from '../../src'
import { render, fireEvent } from '../../src'
import Validate from './components/Validate'

test('can validate using plugin', async () => {
const { getByPlaceholderText, queryByTestId } = render(Validate, {},
vue => vue.use(VeeValidate, { events: 'blur' }))

const usernameInput = getByPlaceholderText('Username...')
fireEvent.touch(usernameInput)

await wait()
await fireEvent.touch(usernameInput)

expect(queryByTestId('username-errors').textContent).toBe('The username field is required.')
})
8 changes: 4 additions & 4 deletions tests/__tests__/vue-router.js
Expand Up @@ -2,7 +2,7 @@ import App from './components/Router/App.vue'
import Home from './components/Router/Home.vue'
import About from './components/Router/About.vue'

import { render, fireEvent, wait } from '../../src'
import { render, fireEvent } from '../../src'

const routes = [
{ path: '/', component: Home },
Expand All @@ -12,10 +12,10 @@ const routes = [

test('full app rendering/navigating', async () => {
const { queryByTestId } = render(App, { routes })

// normally I'd use a data-testid, but just wanted to show this is also possible
expect(queryByTestId('location-display').textContent).toBe('/')
fireEvent.click(queryByTestId('about-link'))
await wait()
// normally I'd use a data-testid, but just wanted to show this is also possible
await fireEvent.click(queryByTestId('about-link'))

expect(queryByTestId('location-display').textContent).toBe('/about')
})
18 changes: 9 additions & 9 deletions tests/__tests__/vuex.js
@@ -1,5 +1,5 @@
import VuexTest from './components/VuexTest'
import { render, fireEvent, wait } from '../../src'
import { render, fireEvent } from '../../src'

const store = {
state: {
Expand All @@ -16,16 +16,16 @@ const store = {

test('can render with vuex with defaults', async () => {
const { getByTestId, getByText } = render(VuexTest, { store })
fireEvent.click(getByText('+'))
await wait()
await fireEvent.click(getByText('+'))

expect(getByTestId('count-value').textContent).toBe('1')
})

test('can render with vuex with custom initial state', async () => {
store.state.count = 3
const { getByTestId, getByText } = render(VuexTest, { store })
fireEvent.click(getByText('-'))
await wait()
await fireEvent.click(getByText('-'))

expect(getByTestId('count-value').textContent).toBe('2')
})

Expand All @@ -35,11 +35,11 @@ test('can render with vuex with custom store', async () => {

const store = { state: { count: 1000 } }
const { getByTestId, getByText } = render(VuexTest, { store })
fireEvent.click(getByText('+'))
await wait()

await fireEvent.click(getByText('+'))
expect(getByTestId('count-value').textContent).toBe('1000')
fireEvent.click(getByText('-'))
await wait()

await fireEvent.click(getByText('-'))
expect(getByTestId('count-value').textContent).toBe('1000')

expect(console.error).toHaveBeenCalled()
Expand Down

0 comments on commit 77357fb

Please sign in to comment.