Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for input file on fireEvent.update #179

Merged
merged 9 commits into from
Nov 24, 2020

Conversation

JeromeDeLeon
Copy link
Contributor

@afontcu
Copy link
Member

afontcu commented Nov 21, 2020

Hi! Can't fix it right now, but you can use userEvent.upload(). It works fine with your example.

That being said, I think the problem is that we should avoid setting value attribute when type is file (source):

    case 'INPUT': {
      if (['checkbox', 'radio'].includes(type)) {
        elem.checked = true
        return fireEvent.change(elem)
      } else if (type === 'file') {
        return fireEvent.input(elem)
      } else {
        elem.value = value
        return fireEvent.input(elem)
      }
    }

With that, the following test passes (copied from the test you linked in the issue):

test('fireEvent.update should not crash with input file', async () => {
  const {getByTestId} = render({
    render(h) {
      return h('input', {
        attrs: {
          type: 'file',
          'data-testid': 'test-update',
        },
      })
    },
  })

  const file = new File(['(⌐□_□)'], 'chucknorris.png', {
    type: 'image/png',
  })

  const inputEl = getByTestId('test-update')

  Object.defineProperty(inputEl, 'files', {
    value: [file],
  })

  await fireEvent.update(inputEl)

  expect(console.warn).not.toHaveBeenCalled()
})

@JeromeDeLeon
Copy link
Contributor Author

JeromeDeLeon commented Nov 21, 2020

if (['checkbox', 'radio'].includes(type)) {
   elem.checked = true
  return fireEvent.change(elem)
} else if (type === 'file') {
  Object.defineProperty(elem, 'files', { value })
  return fireEvent.change(elem)
} else {
  elem.value = value
  return fireEvent.input(elem)
}

Why can't it be like this? instead of doing manual population of files property every time we use input file?

@JeromeDeLeon
Copy link
Contributor Author

Yeah, it works fine with upload and works just fine even with using just fireEvent.change manually, the only reason I want it by default is to avoid the warning that's all.

@afontcu
Copy link
Member

afontcu commented Nov 22, 2020

if (['checkbox', 'radio'].includes(type)) {
   elem.checked = true
  return fireEvent.change(elem)
} else if (type === 'file') {
  Object.defineProperty(elem, 'files', { value })
  return fireEvent.change(elem)
} else {
  elem.value = value
  return fireEvent.input(elem)
}

Why can't it be like this? instead of doing manual population of files property every time we use input file?

That would make sense. However I'm not sure if we should step into userEvent realm with fireEvent. The only reason fireEvent.update exists is to overcome some limitations when it comes to async DOM updates. Now, handling <input type="file"> differenty is probably unexpected, and better handled by userEvent.

I'm ok with adding the else if case to avoid the warning when adding files, though 👍

@JeromeDeLeon
Copy link
Contributor Author

Yeah, you're right with the purpose of fireEvent.update. It should only be used when we're using the v-model or value/ (change/input) case and for the case of the input file, we're not allowed to set up a value so the ability to turn off the warning is fine.

@afontcu
Copy link
Member

afontcu commented Nov 22, 2020

I'd definitely add the else if, and also a test example on how to input a file! Fancy to do so?

@@ -215,6 +227,31 @@ test('fireEvent.update does not trigger warning messages', async () => {
expect(console.warn).not.toHaveBeenCalled()
})

test('fireEvent.update should not crash with input file', async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this test example not enough? @afontcu

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is! But as mentioned, I wouldn't make fireEvent.update() smarter when it comes to type="file" inputs. I would just trigger the proper event, and then add a test showcasing how to handle files as in React Testing Library (and probably also a comment suggesting userEvent to do so:

test('fireEvent.update should not crash with input file', async () => {
  const {getByTestId} = render({
    template: `<input type="file" data-testid="test-update" />`
  })

  const file = new File(['(⌐□_□)'], 'chucknorris.png', { type: 'image/png' })

  const inputEl = getByTestId('test-update')

  Object.defineProperty(inputEl, 'files', {
    value: [file],
  })

  await fireEvent.update(inputEl)

  expect(console.warn).not.toHaveBeenCalled()
})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a suggestion with the change I mention above 👍

@codecov
Copy link

codecov bot commented Nov 22, 2020

Codecov Report

Merging #179 (59e3946) into master (a051013) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##            master      #179   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         1           
  Lines           98       100    +2     
  Branches        34        35    +1     
=========================================
+ Hits            98       100    +2     
Impacted Files Coverage Δ
src/vue-testing-library.js 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a051013...59e3946. Read the comment docs.

Comment on lines 158 to 160
} else if (type === 'file') {
Object.defineProperty(elem, 'files', {value})
return fireEvent.change(elem)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} else if (type === 'file') {
Object.defineProperty(elem, 'files', {value})
return fireEvent.change(elem)
} else if (type === 'file') {
return fireEvent.change(elem)

(also not 100% sure if we should trigger a change event over an input one? 🤔 haven't checked, so it might be okay)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems pretty okay to me since we know we can't use v-model to an input file and the only reasonable event to use in this case is change.

@JeromeDeLeon JeromeDeLeon changed the title Add failing test for input file Add support for input file on fireEvent.update Nov 23, 2020
@afontcu afontcu merged commit b762198 into testing-library:master Nov 24, 2020
@afontcu
Copy link
Member

afontcu commented Nov 24, 2020

nice! 🙌

@github-actions
Copy link

🎉 This PR is included in version 5.6.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@github-actions
Copy link

github-actions bot commented Jun 8, 2022

🎉 This PR is included in version 6.6.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@JeromeDeLeon JeromeDeLeon deleted the input-file-test-fail branch June 8, 2022 08:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants