Firing Events
Note
Most projects have a few use cases for
fireEvent, but the majority of thetime you should probably use@testing-library/user-event.
fireEvent
fireEvent(node: HTMLElement, event: Event)
Fire DOM events.
// <button>Submit</button>
fireEvent(
getByText(container,'Submit'),
newMouseEvent('click',{
bubbles:true,
cancelable:true,
}),
)
fireEvent[eventName]
fireEvent[eventName](node: HTMLElement, eventProperties: Object)
Convenience methods for firing DOM events. Check outsrc/event-map.jsfor a full list as well as defaulteventProperties.
target: When an event is dispatched on an element, the event has thesubjected element on a property calledtarget. As a convenience, if youprovide atarget property in theeventProperties (second argument), thenthose properties will be assigned to the node which is receiving the event.
This is particularly useful for a change event:
fireEvent.change(getByLabelText(/username/i),{target:{value:'a'}})
// note: attempting to manually set the files property of an HTMLInputElement
// results in an error as the files property is read-only.
// this feature works around that by using Object.defineProperty.
fireEvent.change(getByLabelText(/picture/i),{
target:{
files:[newFile(['(⌐□_□)'],'chucknorris.png',{type:'image/png'})],
},
})
// Note: The 'value' attribute must use ISO 8601 format when firing a
// change event on an input of type "date". Otherwise the element will not
// reflect the changed value.
// Invalid:
fireEvent.change(input,{target:{value:'24/05/2020'}})
// Valid:
fireEvent.change(input,{target:{value:'2020-05-24'}})
dataTransfer: Drag events have adataTransfer property that contains datatransferred during the operation. As a convenience, if you provide adataTransfer property in theeventProperties (second argument), then thoseproperties will be added to the event.
This should predominantly be used for testing drag and drop interactions.
fireEvent.drop(getByLabelText(/drop files here/i),{
dataTransfer:{
files:[newFile(['(⌐□_□)'],'chucknorris.png',{type:'image/png'})],
},
})
Keyboard events: There are three event types related to keyboard input -keyPress,keyDown, andkeyUp. When firing these you need to reference anelement in the DOM and the key you want to fire.
fireEvent.keyDown(domNode,{key:'Enter',code:'Enter',charCode:13})
fireEvent.keyDown(domNode,{key:'A',code:'KeyA'})
You can find out which key code to use athttps://www.toptal.com/developers/keycode.
createEvent[eventName]
createEvent[eventName](node: HTMLElement, eventProperties: Object)
Convenience methods for creating DOM events that can then be fired byfireEvent, allowing you to have a reference to the event created: this mightbe useful if you need to access event properties that cannot be initiatedprogrammatically (such astimeStamp).
const myEvent= createEvent.click(node,{button:2})
fireEvent(node, myEvent)
// myEvent.timeStamp can be accessed just like any other properties from myEvent
// note: The access to the events created by `createEvent` is based on the native event API,
// Therefore, native properties of HTMLEvent object (e.g. `timeStamp`, `cancelable`, `type`) should be set using Object.defineProperty
// For more info see: https://developer.mozilla.org/en-US/docs/Web/API/Event
You can also create generic events:
// simulate the 'input' event on a file input
fireEvent(
input,
createEvent('input', input,{
target:{files: inputFiles},
...init,
}),
)
Using Jest Function Mocks
Jest's Mock functions can be used totest that a component will call its bound callback in response to a particularevent.
- React
- Angular
import{render, screen, fireEvent}from'@testing-library/react'
constButton=({onClick, children})=>(
<buttononClick={onClick}>{children}</button>
)
test('calls onClick prop when clicked',()=>{
const handleClick= jest.fn()
render(<ButtononClick={handleClick}>Click Me</Button>)
fireEvent.click(screen.getByText(/click me/i))
expect(handleClick).toHaveBeenCalledTimes(1)
})
import{render, screen, fireEvent}from'@testing-library/angular'
@Component({
template:`<button (click)="handleClick.emit()">Click Me</button>`,
})
classButtonComponent{
@Output() handleClick=newEventEmitter<void>()
}
test('calls onClick prop when clicked',async()=>{
const handleClick= jest.fn()
awaitrender(ButtonComponent,{
componentOutputs:{
handleClick:{emit: handleClick}asany,
},
})
await fireEvent.click(screen.getByText(/click me/i))
expect(handleClick).toHaveBeenCalledTimes(1)
})