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

Same file upload doesn't fire input event, even when clearing input.value #632

Closed
lucaslcode opened this issue Mar 28, 2021 · 6 comments
Closed
Labels
accuracy Improves the accuracy of how behavior is simulated environment:jsdom Issue with JSDOM environment
Milestone

Comments

@lucaslcode
Copy link

  • @testing-library/user-event version: 12.8.2
  • Testing Framework and version: jest 26.6.0
  • DOM Environment: jsdom 16.4.0

Relevant code or config

const handleChange = jest.fn();
render(<InputComponent changeHandler={handleChange} />);
const inputEl = screen.getByLabelText("Select file") as HTMLInputElement;
const file = new File([], "image.jpg");
userEvent.upload(inputEl, file);
await waitFor(() => expect(handleChange).toBeCalled());

inputEl.value = "";
userEvent.upload(inputEl, file);
//fails
await waitFor(() => expect(handleChange).toBeCalledTimes(2));

What you did:
In #575, upload was changed so it correctly doesn't fire an onChange/onInput event when the same files are selected. In our use case, we do want it to fire again, and our workaround is adding an onClick event that sets inputEl.value = "".

What happened:
Second input event doesn't fire, even when the value is reset to blank.

Problem description:
Looking at the source, it doesn't appear to take value into account.

Suggested solution:
It should consider the value of the input field, but I'm not sure how the value relates to input.files, which is what is normally used.

@ph-fritsche
Copy link
Member

This seems to be an issue with jsdom.
The browser clears input.files if you programmatically set input.value = ''. Jsdom seems to not handle files or value at all.

See
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#value
https://codesandbox.io/s/clear-file-input-per-value-hq18c?file=/src/App.test.js

We aren't able to work around this by just setting input.value ourselves as setting input.value to a non-empty value causes errors in browsers.

@ph-fritsche ph-fritsche added environment:jsdom Issue with JSDOM environment needs investigation Someone has to do research on this labels Mar 29, 2021
@ph-fritsche
Copy link
Member

This might also be an issue for dom-testing-library. As setting input.files per fireEvent.input decouples files and value in the browser.

@lucaslcode
Copy link
Author

lucaslcode commented Mar 29, 2021

jsdom seems to implement the correct behaviour for clearing: https://github.com/jsdom/jsdom/blob/bd50bbe219799980d9c9a173309cafcef3d9d8bc/lib/jsdom/living/nodes/HTMLInputElement-impl.js#L416

@lucaslcode
Copy link
Author

Looking at the getters and setters for value and files there, I'm actually surprised that value remains as "" when files is changed.

@rrogowski
Copy link

rrogowski commented May 8, 2021

@lucaslcode I have a similar use case where I'd like to clear a file input. I discovered that the upload API works fine when passed null (though I think the types need to be updated to reflect this):

userEvent.upload(screen.getByLabelText(/select file/i), file);
userEvent.upload(screen.getByLabelText(/select file/i), (null as unknown) as File);
userEvent.upload(screen.getByLabelText(/select file/i), file);

In your example, this would cause the handleChange event handler to fire 3 times in total. I am thinking of submitting a PR to allow the second argument of upload to be null without having to do a (rather ugly 😅) type cast.

Update You can also pass [] as the second parameter without need to type cast.

userEvent.upload(screen.getByLabelText(/select file/i), file);
userEvent.upload(screen.getByLabelText(/select file/i), []);
userEvent.upload(screen.getByLabelText(/select file/i), file);

@ph-fritsche
Copy link
Member

@ph-fritsche ph-fritsche added this to the userEvent v14 milestone Jan 5, 2022
@ph-fritsche ph-fritsche added accuracy Improves the accuracy of how behavior is simulated and removed needs investigation Someone has to do research on this labels Jan 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accuracy Improves the accuracy of how behavior is simulated environment:jsdom Issue with JSDOM environment
Projects
None yet
Development

No branches or pull requests

3 participants