Skip to content

Commit

Permalink
feat(events): allow setting the files value in change events (#91)
Browse files Browse the repository at this point in the history
Similar to the value, this works around limitations with DOM properties
that make testing certain use cases harder. This simplifies those cases
  • Loading branch information
Kent C. Dodds committed Aug 23, 2018
1 parent dfe9401 commit 98c67e2
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 3 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,15 @@ This is particularly useful for a change event:

```javascript
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: [new File(['(⌐□_□)'], 'chucknorris.png', {type: 'image/png'})],
},
})
```

#### `getNodeText`
Expand Down
9 changes: 9 additions & 0 deletions src/__tests__/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,12 @@ test('assigning a value to a target that cannot have a value throws an error', (
`"The given element does not have a value setter"`,
)
})

test('assigning the files property on an input', () => {
const node = document.createElement('input')
const file = new File(['(⌐□_□)'], 'chucknorris.png', {
type: 'image/png',
})
fireEvent.change(node, {target: {files: [file]}})
expect(node.files).toEqual([file])
})
13 changes: 10 additions & 3 deletions src/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ const {
TransitionEvent,
UIEvent,
WheelEvent,
} =
typeof window === 'undefined' ? /* istanbul ignore next */ global : window
} = typeof window === 'undefined' ? /* istanbul ignore next */ global : window

const eventMap = {
// Clipboard Events
Expand Down Expand Up @@ -322,11 +321,19 @@ Object.entries(eventMap).forEach(([key, {EventType = Event, defaultInit}]) => {

fireEvent[key] = (node, init) => {
const eventInit = {...defaultInit, ...init}
const {target: {value, ...targetProperties} = {}} = eventInit
const {target: {value, files, ...targetProperties} = {}} = eventInit
Object.assign(node, targetProperties)
if (value !== undefined) {
setNativeValue(node, value)
}
if (files !== undefined) {
// input.files is a read-only property so this is not allowed:
// input.files = [file]
// so we have to use this workaround to set the property
Object.defineProperty(node, 'files', {
value: files,
})
}
const event = new EventType(eventName, eventInit)
return fireEvent(node, event)
}
Expand Down

0 comments on commit 98c67e2

Please sign in to comment.