testing-library / user-event

🐕 Simulate user events
https://testing-library.com/user-event
MIT License
2.15k stars 244 forks source link

Inputs are not focused when clicked (v14) #1002

Open IanVS opened 1 year ago

IanVS commented 1 year ago

Reproduction example

https://github.com/IanVS/storybook-testing-user-event-click-focus

Prerequisites

  1. Using V14, try to click an input field: await userEvent.click(getByRole('textbox')); for example

Expected behavior

The input element should be fully focused, ready to accept user input (flashing cursor).

Actual behavior

The input is half-way focused, with a focus ring, but no flashing cursor.

User-event version

14.3.0

Environment

Testing Library framework: @testing-library/react@13.3.0

JS framework: react@18.2.0

Test environment: storybook@6.5.9

DOM implementation: browser

Additional context

This was working correctly in V13. I have instructions in the README of the reproduction of how to verify.

ph-fritsche commented 1 year ago

Are you sure this is an issue with user-event ? If yes, please break it down to a reproduction example that doesn't wrap user-event in third-party code. If not, please raise this with https://github.com/storybookjs/testing-library. I don't know if their integration is correct and it seems they reverted and postponed the upgrade to v14.

IanVS commented 1 year ago

I did also experience the issue when using user-event directly, and as I describe in the readme, forcing npm to download v13 causes user-event to work correctly. But I can modify the reproduction if that's helpful.

IanVS commented 1 year ago

I've pushed an update to the reproduction to import from @testing-library/user-event directly, with the same behavior.

ph-fritsche commented 1 year ago

Thanks for the report.

This is odd: https://codesandbox.io/s/young-https-oghigy?file=/src/App.js

In Firefox the focus is set into the element per .click API, in Chrome it isn't. But calling .focus() directly on the element works in both. Although this is how the target is focused by the click API internally - resulting in the outline that indicates that the element gained focus :thinking:

paste() doesn't work in either browser.

jaworek commented 1 year ago

I'm currently working on updating @testing-library/user-event in my project and it seems that I've stumbled upon the same bug. At first I thought that this is related to #1018, but this seems to be actual reason. Downgrading to v13 fixes the issue for the time being.

ph-fritsche commented 1 year ago

With v14.4 both the .click() and .paste() yield the expected result with one exception: In Chrome the cursor is missing and .selectionStart/.selectionEnd are always 0 after the click although they should be at value.length

https://codesandbox.io/s/intelligent-zhukovsky-8z89zj?file=/src/App.js

aaron-nance commented 1 year ago

If I use the convenience method (field.click()) I have this issue, but if I use user.click(field), the text field gets focus properly. This happens when I'm using 14.4 with Jest 27.5 and testEnvironment: "jest-environment-jsdom"

IanVS commented 1 year ago

@aaron-nance:

the text field gets focus properly.

It does get focus, but in Chrome, it does not get a cursor, so typing into the field after the click does not work.

chawax commented 1 year ago

I still have this problem, focus is not given to the input when using click(). Is there a workaround for this ?

chawax commented 1 year ago

I could make it work using focus() to give focus to the field, then using clear and type.

For example :


await screen.getByRole("textbox").focus();
await user.clear(screen.getByRole("textbox"));
await user.type(screen.getByRole("textbox"), "something");
chawax commented 1 year ago

Actually the focus() solution doesn't work, it is unstable :( So anyone has a reliable workaround for that ?

IanVS commented 11 months ago

Hi, has anyone found a workaround to this issue? It's still blocking my migration to user-event 14, and I'd love to update.

IanVS commented 10 months ago

Actually, I tried upgrading anyway, and my tests are passing, though the codesandbox reproduction above still fails. Not sure what's going on, TBH, but I'll take it!

mryechkin commented 1 month ago

Just ran into this issue while upgrading to v14 - I'm on 14.5.2 to be exact. None of the above solutions work for me. No component or test code changes other than upgrading the library. Has anyone gotten around this issue in recent time?

zemacnica commented 3 weeks ago

I have the same problem with focus. "@testing-library/jest-dom": "^6.4.6", "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.5.2",

I downgraded to version 13.5.0 and focus after click is working

unional commented 1 week ago

I have the same problem.

To me, it is working on storybook (chrome/chromium) but not on jest (jsdom)

bodograumann commented 2 days ago

Another perspective: We have button elements in storybook and press them via userEvent.click. That causes the :focus-visible pseudo-class to be applied to them, showing the browser-defined focus-ring to be visible. (I assume that is what the OP observed as well)

That is however not what would happen, if the user clicks on the button themself. In that case only the :focus class is applied to the element, not :focus-visible. The latter would for example be applied, if the user used the Tab button to navigate to the element.

IanVS commented 2 days ago

I do notice that focus-visible is sometimes applied to elements that are clicked, but not always. It results in snapshot flake, which is pretty annoying. But that seems like a separate issue from the core of this one.

bodograumann commented 2 days ago

I guess you are right, @IanVS . I initially thought the flake was caused by certain browser contexts having different built-in styles for :focus-visible, but that would have affected all stories, not only certain ones.

We have solved that issue by disabling all built-in focus-visible styles for now (I now bad a11y :disappointed: ) I'll hide my comments as off-topic then. Sorry for the noise.