I'm trying to test an application using react-dropzone. I'm using something like the following code:
const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop, noClick: true})
return (
<div
{...getRootProps()}
aria-label='file-upload-dropzone'
>
<input
{...getInputProps()}
/>
<div>
{(isDragActive) ?
<span>Drop the files here...</span> :
<span>Drag and drop the files here</span>
}
</div>
</div>
)
The problem here is that:
When trying to test with the following cypress test:
cy.get('[aria-label=file-upload-dropzone]')
.selectFile(
{
contents: Cypress.Buffer.from('file contents'),
fileName: 'file.e37',
mimeType: 'text/plain',
lastModified: Date.now(),
},
{action: 'drag-drop'},
)
// the test fails here
cy.contains('div', /Drag and drop the files here/).should('exist')
the UI is stuck with "Drop the files here...". The reason seems to be that isDragActive
never goes back to false, after cy.get(...).selectFile(...)
has been called.
This is different from when I test the exact same code from the browser - there, isDragActive
is false AND "Drag and drop the files here" is displayed when I'm finished dragging the file.
Is there any way I can get the cypress test and a real user test to behave the same for this scenario?
Since you're using a hook, try adding cy.wait(0)
or setTimeout(() =>{},0)
before the failing line.
This would allow the hook to complete any background action - presuming the problem is that Cypress is hogging the thread
Triggering "change" or "drop"
The following seems to be a working sequence of events.
cy.get('[aria-label=file-upload-dropzone]')
.selectFile(
{
contents: Cypress.Buffer.from('file contents'),
fileName: 'file.e37',
mimeType: 'text/plain',
lastModified: Date.now(),
},
{action: 'drag-drop'},
)
cy.contains('div', /Drop the files here.../) // passes
cy.get('[aria-label=file-upload-dropzone]')
.find('input').trigger('change', {force:true}) // without this trigger
// the next line fails
cy.contains('div', /Drag and drop the files here/) // passes
I added a simple onDrop()
const onDrop = useCallback(acceptedFiles => {
console.log('acceptedFiles', acceptedFiles)
}, [])
and from this can see two console logs - the first has the file in acceptedFiles
, the second has an empty array in acceptedFiles
.