`userEvent.type` and `userEvent.paste` set incorrect time to `<input type="time">`
Reproduction example
https://codesandbox.io/s/dreamy-kirch-3wpvc8
Prerequisites
- Render an
<input type="time">element (doesn't seem to matter ifstep,minormaxare defined or not) - Try to set that input's value with
userEvent.type(thatInput, '12:34:56')
Expected behavior
The value should be set to "12:34:56".
Actual behavior
The value is set to "12:59" (which in my Chrome gets rendered as 12.59.00)
User-event version
14.4.3
(I did test many versions in the Codesandbox all the way down to 12.8.3 and the same bug appeared)
Environment
Browser locale:
> navigator.languages[0]
'en-US'
> new Date().toLocaleDateString()
'12/23/2022'
> new Date().toLocaleTimeString()
'12:13:57 PM'
(these are the same in the tests and the real browser)
In the macOS Language & Region settings I tried both United States and Finland as my region. It does change the appearance of the time input but otherwise the behavior is exactly the same.
Additional context
- An example test: https://codesandbox.io/s/dreamy-kirch-3wpvc8?file=/src/Foo.test.tsx
- The component also allows you to test triggering
userEvent.typein the real browser: https://codesandbox.io/s/dreamy-kirch-3wpvc8?file=/src/Foo.tsx- I originally encountered this problem in our test suite but also wanted to double-check if the behavior was the same in the real browser. Seems like so.
Here's how the component renders for me:
https://user-images.githubusercontent.com/3490745/209317238-b2c63bc4-ab51-4a1b-9d3f-254fdf9b3593.mov
- If I switch my macOS Region to United States (the screen recording is on Finland), the
.s are replaced with:s but otherwise the behavior is the same. - Using or not using
const user = await userEvent.setup()doesn't seem to make a difference. - If I change
"12:34:56"inuserEvent.type(timeInput, "12:34:56")to any of these values, there is still always the issue of the minutes populating incorrectly to 59:"12.34.56""123456""01:23:45""012345"
- Chrome, Safari and Firefox all behave the same, at least on mac.
I'm totally prepared that I'm just using the lib wrong but at least the current behavior is very surprising. I also did read a few of the older time input related issues and assumed it should now work with userEvent.type (because I didn't find any other relevant issues after https://github.com/testing-library/user-event/issues/484).
Edit:
I also noticed the same issue persists if I replace .type with .click + .paste:
await userEvent.clear(timeInput);
await userEvent.click(timeInput);
await userEvent.paste("12:34:56");
https://codesandbox.io/s/dreamy-kirch-3wpvc8-click-and-paste-v4wn2e?file=/src/Foo.tsx
Seems like both .type and .paste hit this function which probably explains why the behavior is shared in both: https://github.com/testing-library/user-event/blob/1aa2027e5ec445ab413808556efa7763b65053d3/src/utils/edit/timeValue.ts#L3
I'll edit the title.
The browser implementations changed a lot since this feature was added. As the Chrome implementation has been copied by other major browser vendors, I think we could mimic that. Some aspects of time input are still a mess in browsers though.
Shouldn't this still count as a bug if the latest-ish Chrome, Firefox and Safari all behave the same?
Also do you happen to know any workarounds? fireEvent.change doesn't seem to work either (nothing happens). That also seems to hit buildTimeValue anyway.
"accuracy" does not mean it's correct or that we shouldn't fix it. Just that it's more an unimplemented aspect than an outright wrong behavior violating some specs.
Also do you happen to know any workarounds?
fireEvent.changedoesn't seem to work either (nothing happens). That also seems to hitbuildTimeValueanyway.
Your codesandbox wasn't using fireEvent correctly. It works if you do this:
fireEvent.change(timeInput, { target: { value: "12:34:56" } });
Your codesandbox wasn't using fireEvent correctly. It works if you do this:
fireEvent.change(timeInput, { target: { value: "12:34:56" } });
Woops, thank you @spudly!