Skip to content

Commit

Permalink
test: improve tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kentcdodds committed Jun 10, 2020
1 parent c662b57 commit a4678d9
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 104 deletions.
15 changes: 12 additions & 3 deletions src/__tests__/helpers/utils.js
Expand Up @@ -38,9 +38,17 @@ function addEventListener(el, type, listener, options) {
}

function setup(ui) {
const {
container: {firstChild: element},
} = render(ui)
let element
if (typeof ui === 'string') {
const div = document.createElement('div')
div.innerHTML = ui
element = div.firstChild
document.body.append(div)
} else {
const {container} = render(ui)
element = container.firstChild
}

element.previousTestData = getTestData(element)

const {getEventCalls, clearEventCalls} = addListeners(element)
Expand Down Expand Up @@ -180,6 +188,7 @@ afterEach(() => {
el.removeEventListener(type, listener)
}
eventListeners = []
document.body.innerHTML = ''
})

export {setup, addEventListener, addListeners}
3 changes: 1 addition & 2 deletions src/__tests__/hover.js
@@ -1,9 +1,8 @@
import React from 'react'
import userEvent from '..'
import {setup} from './helpers/utils'

test('hover', async () => {
const {element, getEventCalls} = setup(<button />)
const {element, getEventCalls} = setup('<button />')

await userEvent.hover(element)
expect(getEventCalls()).toMatchInlineSnapshot(`
Expand Down
26 changes: 12 additions & 14 deletions src/__tests__/type-modifiers.js
Expand Up @@ -17,7 +17,7 @@ import {setup, addEventListener} from './helpers/utils'
// but will not capitalize "a".

test('{esc} triggers typing the escape character', async () => {
const {element: input, getEventCalls} = setup(<input />)
const {element: input, getEventCalls} = setup('<input />')

await userEvent.type(input, '{esc}')

Expand All @@ -29,7 +29,7 @@ test('{esc} triggers typing the escape character', async () => {
})

test('a{backspace}', async () => {
const {element, getEventCalls} = setup(<input />)
const {element, getEventCalls} = setup('<input />')
await userEvent.type(element, 'a{backspace}')
expect(getEventCalls()).toMatchInlineSnapshot(`
focus
Expand All @@ -44,7 +44,7 @@ test('a{backspace}', async () => {
})

test('{backspace}a', async () => {
const {element, getEventCalls} = setup(<input />)
const {element, getEventCalls} = setup('<input />')
await userEvent.type(element, '{backspace}a')
expect(getEventCalls()).toMatchInlineSnapshot(`
focus
Expand All @@ -58,7 +58,7 @@ test('{backspace}a', async () => {
})

test('{backspace} triggers typing the backspace character and deletes the character behind the cursor', async () => {
const {element: input, getEventCalls} = setup(<input defaultValue="yo" />)
const {element: input, getEventCalls} = setup('<input value="yo" />')
input.setSelectionRange(1, 1)

await userEvent.type(input, '{backspace}')
Expand All @@ -72,9 +72,7 @@ test('{backspace} triggers typing the backspace character and deletes the charac
})

test('{backspace} on a readOnly input', async () => {
const {element: input, getEventCalls} = setup(
<input readOnly defaultValue="yo" />,
)
const {element: input, getEventCalls} = setup('<input readonly value="yo" />')
input.setSelectionRange(1, 1)

await userEvent.type(input, '{backspace}')
Expand Down Expand Up @@ -126,7 +124,7 @@ test('{backspace} on an input type that does not support selection ranges', asyn
})

test('{alt}a{/alt}', async () => {
const {element: input, getEventCalls} = setup(<input />)
const {element: input, getEventCalls} = setup('<input />')

await userEvent.type(input, '{alt}a{/alt}')

Expand All @@ -142,7 +140,7 @@ test('{alt}a{/alt}', async () => {
})

test('{meta}a{/meta}', async () => {
const {element: input, getEventCalls} = setup(<input />)
const {element: input, getEventCalls} = setup('<input />')

await userEvent.type(input, '{meta}a{/meta}')

Expand All @@ -158,7 +156,7 @@ test('{meta}a{/meta}', async () => {
})

test('{ctrl}a{/ctrl}', async () => {
const {element: input, getEventCalls} = setup(<input />)
const {element: input, getEventCalls} = setup('<input />')

await userEvent.type(input, '{ctrl}a{/ctrl}')

Expand All @@ -174,7 +172,7 @@ test('{ctrl}a{/ctrl}', async () => {
})

test('{shift}a{/shift}', async () => {
const {element: input, getEventCalls} = setup(<input />)
const {element: input, getEventCalls} = setup('<input />')

await userEvent.type(input, '{shift}a{/shift}')

Expand All @@ -190,7 +188,7 @@ test('{shift}a{/shift}', async () => {
})

test('a{enter}', async () => {
const {element: input, getEventCalls} = setup(<input />)
const {element: input, getEventCalls} = setup('<input />')

await userEvent.type(input, 'a{enter}')

Expand All @@ -207,7 +205,7 @@ test('a{enter}', async () => {
})

test('{enter} with preventDefault keydown', async () => {
const {element: input, getEventCalls} = setup(<input />)
const {element: input, getEventCalls} = setup('<input />')
addEventListener(input, 'keydown', e => e.preventDefault())

await userEvent.type(input, '{enter}')
Expand Down Expand Up @@ -265,7 +263,7 @@ test('{meta}{enter}{/meta} on a button', async () => {
})

test('{meta}{alt}{ctrl}a{/ctrl}{/alt}{/meta}', async () => {
const {element: input, getEventCalls} = setup(<input />)
const {element: input, getEventCalls} = setup('<input />')

await userEvent.type(input, '{meta}{alt}{ctrl}a{/ctrl}{/alt}{/meta}')

Expand Down
3 changes: 1 addition & 2 deletions src/__tests__/unhover.js
@@ -1,9 +1,8 @@
import React from 'react'
import userEvent from '..'
import {setup} from './helpers/utils'

test('unhover', async () => {
const {element, getEventCalls} = setup(<button />)
const {element, getEventCalls} = setup('<button />')

await userEvent.unhover(element)
expect(getEventCalls()).toMatchInlineSnapshot(`
Expand Down
140 changes: 57 additions & 83 deletions src/__tests__/upload.js
@@ -1,113 +1,87 @@
import React from 'react'
import {render, screen} from '@testing-library/react'
import userEvent from '../../src'
import userEvent from '..'
import {setup, addListeners} from './helpers/utils'

test('should fire the correct events for input', () => {
const file = new File(['hello'], 'hello.png', {type: 'image/png'})
const events = []
const eventsHandler = jest.fn(evt => events.push(evt.type))
const eventHandlers = {
onMouseOver: eventsHandler,
onMouseMove: eventsHandler,
onMouseDown: eventsHandler,
onFocus: eventsHandler,
onMouseUp: eventsHandler,
onClick: eventsHandler,
}

render(<input type="file" data-testid="element" {...eventHandlers} />)

userEvent.upload(screen.getByTestId('element'), file)

expect(events).toEqual([
'mouseover',
'mousemove',
'mousedown',
'focus',
'mouseup',
'click',
])
const {element, getEventCalls} = setup('<input type="file" />')

userEvent.upload(element, file)

expect(getEventCalls()).toMatchInlineSnapshot(`
mouseover: Left (0)
mousemove: Left (0)
mousedown: Left (0)
focus
mouseup: Left (0)
click: Left (0)
change
`)
})

test('should fire the correct events with label', () => {
const file = new File(['hello'], 'hello.png', {type: 'image/png'})

const inputEvents = []
const labelEvents = []
const eventsHandler = events => jest.fn(evt => events.push(evt.type))

const getEventHandlers = events => ({
onMouseOver: eventsHandler(events),
onMouseMove: eventsHandler(events),
onMouseDown: eventsHandler(events),
onFocus: eventsHandler(events),
onMouseUp: eventsHandler(events),
onClick: eventsHandler(events),
})

render(
<>
<label
htmlFor="element"
data-testid="label"
{...getEventHandlers(labelEvents)}
>
Element
</label>
<input type="file" id="element" {...getEventHandlers(inputEvents)} />
</>,
)

userEvent.upload(screen.getByTestId('label'), file)

expect(inputEvents).toEqual(['click', 'focus'])
expect(labelEvents).toEqual([
'mouseover',
'mousemove',
'mousedown',
'mouseup',
'click',
])
const container = document.createElement('div')
container.innerHTML = `
<label for="element">Element</label>
<input type="file" id="element" />
`

const label = container.children[0]
const input = container.children[1]
const {getEventCalls: getLabelEventCalls} = addListeners(label)
const {getEventCalls: getInputEventCalls} = addListeners(input)

userEvent.upload(label, file)

expect(getLabelEventCalls()).toMatchInlineSnapshot(`
mouseover: Left (0)
mousemove: Left (0)
mousedown: Left (0)
mouseup: Left (0)
click: Left (0)
change
`)
expect(getInputEventCalls()).toMatchInlineSnapshot(`
click: Left (0)
focus
`)
})

test('should upload the file', () => {
const file = new File(['hello'], 'hello.png', {type: 'image/png'})
render(<input type="file" data-testid="element" />)
const input = screen.getByTestId('element')
const {element} = setup('<input type="file" />')

userEvent.upload(input, file)
userEvent.upload(element, file)

expect(input.files[0]).toStrictEqual(file)
expect(input.files.item(0)).toStrictEqual(file)
expect(input.files).toHaveLength(1)
expect(element.files[0]).toStrictEqual(file)
expect(element.files.item(0)).toStrictEqual(file)
expect(element.files).toHaveLength(1)
})

test('should upload multiple files', () => {
const files = [
new File(['hello'], 'hello.png', {type: 'image/png'}),
new File(['there'], 'there.png', {type: 'image/png'}),
]
render(<input type="file" multiple data-testid="element" />)
const input = screen.getByTestId('element')
const {element} = setup('<input type="file" multiple />')

userEvent.upload(input, files)
userEvent.upload(element, files)

expect(input.files[0]).toStrictEqual(files[0])
expect(input.files.item(0)).toStrictEqual(files[0])
expect(input.files[1]).toStrictEqual(files[1])
expect(input.files.item(1)).toStrictEqual(files[1])
expect(input.files).toHaveLength(2)
expect(element.files[0]).toStrictEqual(files[0])
expect(element.files.item(0)).toStrictEqual(files[0])
expect(element.files[1]).toStrictEqual(files[1])
expect(element.files.item(1)).toStrictEqual(files[1])
expect(element.files).toHaveLength(2)
})

test('should not upload when is disabled', () => {
const file = new File(['hello'], 'hello.png', {type: 'image/png'})
render(<input type="file" data-testid="element" disabled />)
const {element} = setup('<input type="file" disabled />')

const input = screen.getByTestId('element')
userEvent.upload(element, file)

userEvent.upload(input, file)

expect(input.files[0]).toBeUndefined()
expect(input.files.item(0)).toBeNull()
expect(input.files).toHaveLength(0)
expect(element.files[0]).toBeUndefined()
expect(element.files.item(0)).toBeNull()
expect(element.files).toHaveLength(0)
})

0 comments on commit a4678d9

Please sign in to comment.