How to simulate adding a file to FilePond in React Testing Library (RTL)?

41 Views Asked by At

I'm trying to write some unit tests that will cover the function I've written to run during a FilePond onupdatefiles unnamed function. I have struggled with actually getting a file added to FilePond in order to trigger my later function. I am asking here if anyone has any experience with simulating adding a file to react-filepond using React Testing Library?

I have tried first a number of ways to reference the FilePond component before falling back to good old querySelector. I confirmed via console.log() that it is selecting the area, but this area looks very stripped down compared with what I see in the browser, so I'm not sure FilePond is even loading up correctly in my test.

I have tried two different React Testing Library file upload methods, userEvent.upload() (https://testing-library.com/docs/user-event/v13/#uploadelement-file--clickinit-changeinit--options) and fireEvent.drop() (https://stackoverflow.com/a/76759675), neither of which seems to have any effect. I've tried adding some extra waiting to let things render, I've tried some variations on act() and async/await statements. I'm really struggling with this one, and might be at the point of attempting to just mock out everything expect for foo(), so would appreciate any insights.

React Component

import React from 'react';

import { FilePond, registerPlugin } from 'react-filepond';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import FilePondPluginFileEncode from 'filepond-plugin-file-encode';

registerPlugin(FilePondPluginImagePreview, FilePondPluginFileEncode);

function MyComponent(props) {

   function foo(encodedFiles) {
      // Does some stuff with the files here, need to test this function `foo`
   }

   return (
      <FilePond
         files={files}
         onupdatefiles={fileItems => {
             try {
                const encodedFiles = fileItems.map(file => file.getFileEncodeDataURL());
                foo(encodedFiles);
              } catch (e) {
                 // See https://github.com/pqina/filepond-plugin-file-encode/issues/22.
                 console.log('Ignoring known cache issue.');
             }
         }}
         allowMultiple={true}
         allowImagePreview={true}
         maxFiles={3}
         instantUpload={false}
         name="files"
         labelIdle='Drag & Drop your files or <span class="filepond--label-action">Browse</span>'
         credits={false}
         className="filepond-upload-area-test"
      />
   );
}

Test

import React from 'react';
import { act, fireEvent, render, screen, waitFor, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom/extend-expect';

import MyComponent from '../MyComponent';

const delay = ms => new Promise(res => setTimeout(res, ms));

describe('ImageUploadQuestion component', () => {
    const mockMyComponentProps = {...mocked stuff}

    it('should do stuff with foo() when a file is uploaded', async () => {

        /*
         * Trying userEvent method
         */

        const { container } = render(<MyComponent {...mockMyComponentProps} />);
        const file = new File(['hello'], 'hello.png', { type: 'image/png' })
        const input = container.querySelector('.filepond-upload-area-test');
        await act(async () => {
            userEvent.click(input);
            await userEvent.upload(input, file);
        })
        screen.debug();
    
        // ...
        // expect() foo() output to match expectedOutput
    });

    it('should do stuff with foo() when a file is uploaded, take 2', async () => {

        /*
         * Trying fireEvent method
         */

        const {container} = render(<MyComponent {...mockMyComponentProps} />);
        const input = container.querySelector('[name="files"]')
        fireEvent.drop(input, { dataTransfer: { files: [new File(['hello'], 'hello.png', { type: 'image/png' })] } });
        await delay(3000);
        screen.debug();
    
        // ...
        // expect() foo() output to match expectedOutput
    });
});

screen.debug() output from above, showing no files added:

<body>
   <div
     class="filepond--wrapper"
   >
     <input
       class="filepond-upload-area-class"
       multiple=""
       name="files"
       type="file"
     />
   </div>
</body>
0

There are 0 best solutions below