Search code examples
unit-testingvuejs2jestjs

How to test input file with Jest and vue/test-utils


I want to test file uploader component using Jest and vue/test-utils.

I have this:

 describe('show progress bar of uploading file', () => {
    const wrapper = mount(FileUploaderComponent)

    // create csv file
    let csv = new Blob([''], { type: 'text/csv;charset=utf-8;' })
    csv.name = 'myFile.csv'

    let input = wrapper.find('input')
    input.element.value = csv // || csv.error value, Error here
    input.trigger('change')

    // Update current status
  })

Where in FileUploaderComponent i have:

<template>
  <form action="POST" enctype="multipart/form-data">
    <label class="btn btn-primary" for="input-file">
      <input class="input-file" id="input-file" name="file" type="file" accept=".xlsx, .xls, .csv">
      UPLOAD FILE
    </label>
  </form>
</template>

Throws this error:

InvalidStateError: This input element accepts a filename, which may only be programmatically set to the empty string.

  49 |
  50 |     let input = wrapper.find('input')
> 51 |     input.element.value = csv
  52 |     input.trigger('change')
  53 |
  54 |     // Update current status

So, the question is: How can i trigger event change with file input value? in this case, a csv file as value ?


Solution

  • You could do this using the DataTransfer object. Unfortunately, it hasn't been added to JSDOM, so you can't test in Jest. There's an open issue to add the object—https://github.com/jsdom/jsdom/issues/1568

    If you ran your tests in a browser using Karma, you could test like this:

    const wrapper = shallow(FormComponent)
    const input = wrapper.find('input[type="file"]')
    const dT = new ClipboardEvent('').clipboardData || new DataTransfer()
    dT.items.add(new File(['foo'], 'programmatically_created.txt'))
    input.element.files = dT.files
    await input.trigger('change')