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

userEvent.type(input, 'text') consistently shuffles the input #391

Closed
jmyrland opened this issue Jun 26, 2020 · 18 comments
Closed

userEvent.type(input, 'text') consistently shuffles the input #391

jmyrland opened this issue Jun 26, 2020 · 18 comments
Labels
bug Something isn't working environment:jsdom Issue with JSDOM environment

Comments

@jmyrland
Copy link

jmyrland commented Jun 26, 2020

  • @testing-library/user-event version: 12.0.11
  • Testing Framework and version: jest@24.9.0
  • DOM Environment: jsdom@14.0.0 (via jest-environment-jsdom-fourteen)

I'm having some issues with the following test-snippet (copied from the readme with some minor modification):

test('type', () => {
  render(<textarea />);

  userEvent.type(screen.getByRole('textbox'), 'hey');
  expect(screen.getByRole('textbox')).toHaveValue('hey');
});

When I run this, it fails with the following output:

image

Whatever text i input, it chucks the first input-character at the end, (i.e. 123 -> 231).

I'm guessing this is not the expected outcome - or if so, what am I missing? 😁

I'm using fireEvent.change(screen.getByRole('textbox'), { target: { value: 'hey' } }) as a workaround for now.

@kentcdodds
Copy link
Member

I have reproduced this issue: https://codesandbox.io/s/pedantic-maxwell-wu50t?file=/src/__tests__/index.js

I'm guessing it's something odd with React because we absolutely have tests for this:

test('types text in textarea', () => {
const {element, getEventSnapshot} = setup('<textarea></textarea>')
userEvent.type(element, 'Sup')
expect(getEventSnapshot()).toMatchInlineSnapshot(`
Events fired on: textarea[value="Sup"]
textarea[value=""] - pointerover
textarea[value=""] - pointerenter
textarea[value=""] - mouseover: Left (0)
textarea[value=""] - mouseenter: Left (0)
textarea[value=""] - pointermove
textarea[value=""] - mousemove: Left (0)
textarea[value=""] - pointerdown
textarea[value=""] - mousedown: Left (0)
textarea[value=""] - focus
textarea[value=""] - focusin
textarea[value=""] - pointerup
textarea[value=""] - mouseup: Left (0)
textarea[value=""] - click: Left (0)
textarea[value=""] - keydown: S (83)
textarea[value=""] - keypress: S (83)
textarea[value="S"] - input
"{CURSOR}" -> "S{CURSOR}"
textarea[value="S"] - keyup: S (83)
textarea[value="S"] - keydown: u (117)
textarea[value="S"] - keypress: u (117)
textarea[value="Su"] - input
"S{CURSOR}" -> "Su{CURSOR}"
textarea[value="Su"] - keyup: u (117)
textarea[value="Su"] - keydown: p (112)
textarea[value="Su"] - keypress: p (112)
textarea[value="Sup"] - input
"Su{CURSOR}" -> "Sup{CURSOR}"
textarea[value="Sup"] - keyup: p (112)
`)
})

I'm not sure what the problem is, but if someone wants to investigate and figure out what we're doing wrong that would be great.

@kentcdodds kentcdodds added help wanted needs investigation Someone has to do research on this bug Something isn't working labels Jun 26, 2020
@jmyrland
Copy link
Author

I just noticed this:

@testing-library/user-event@12.0.11" has unmet peer dependency "@testing-library/dom@>=7.16.0".

Might this be related?

@lourenci
Copy link
Collaborator

I can take a look at this later.

@nickserv
Copy link
Member

nickserv commented Jun 29, 2020

This bug was introduced in #322 (version 11.3.1)

@marcosvega91
Copy link
Member

marcosvega91 commented Jun 29, 2020

this issue is like #346. The problem is that when the textarea has no default value both selectionStart and selectionEnd are undefined. I have tried locally in the past but this issue not happens. It happens only in codesandbox.

We can add a check at the beginning of type function, but it's very odd
working example

diff --git a/src/type.js b/src/type.js
index 0bee11e..632dc97 100644
--- a/src/type.js
+++ b/src/type.js
@@ -65,6 +65,15 @@ async function typeImpl(
     }
     return value
   }
+
+  if (
+    typeof currentElement().selectionStart === 'undefined' ||
+    typeof currentElement().selectionEnd === 'undefined'
+  ) {
+    currentElement().setSelectionRange(0, 0)
+  }
+
   const setSelectionRange = ({newValue, newSelectionStart}) => {
     // if we *can* change the selection start, then we will if the new value
     // is the same as the current value (so it wasn't programatically changed

@kentcdodds
Copy link
Member

Is there any way we can alter the code in other places so we don't actually set the selection range?

@nickserv nickserv added environment:jsdom Issue with JSDOM environment and removed needs investigation Someone has to do research on this labels Jun 30, 2020
@nickserv

This comment has been minimized.

@nickserv
Copy link
Member

nickserv commented Jul 10, 2020

This issue and #346 have been fixed in JSDOM, but Code Sandbox's Jest support is still hard coded to use JSDOM 4.0.0, which doesn't have the fix: https://github.com/codesandbox/codesandbox-client/pull/1812/files#diff-3fcdeb2de813a974b29d8610b234c7f2R51

There are two ways to solve this:

  1. Patch Code Sandbox so it's not hard coded to JSDOM 4.0.0 (JSDOM is out of date codesandbox/codesandbox-client#4530)
  2. Patch our updates in fix(type): ensure the selectionStart/End are consistent with browsers #322 so it still works in JSDOM 4.0.0 (for some reason only textarea is broken, so making it work more like input could help)

If anyone's curious, I've reproduced this issue using jest Code Sandbox, without any React or Testing Library packages: https://codesandbox.io/s/code-sandbox-bug-with-old-jsdom-version-9gcnp?file=/index.test.js

@kentcdodds
Copy link
Member

I think codesandbox will be making an effort to address some of these issues soon.

@nickserv
Copy link
Member

nickserv commented Jul 10, 2020

Do we want to close this to track it upstream instead of patching user-event? I already opened an issue at codesandbox/codesandbox-client#4530.

@kentcdodds
Copy link
Member

Yeah, I don't want to worry about supporting old versions of JSDOM

@marcosvega91
Copy link
Member

The issue has been resolved on codesandbox so this example is now working 😄

@lammypham
Copy link

I can get this issue resolved on the codesandbox, but when i download the project from codesandbox and run locally, i still get this issue.

Is this still expected? Thanks in advance.

@nickserv
Copy link
Member

nickserv commented Aug 21, 2020

Code Sandbox has now pinned JSDOM 16, but create-react-app (which is used when downloading the sandbox) is still stuck on JSDOM 14. You can work around this by installing jest-environment-jsdom-sixteen and adding --env jest-environment-jsdom-sixteen to the test script until CRA is updated with Jest 26 support.

@imnotteixeira
Copy link

Hey guys, just stumbled on this. Is there a solution for this, or do I just need to install and set jest-environment-jsdom-sixteen?

@nickserv
Copy link
Member

nickserv commented Dec 8, 2020

You can check your jsdom version with npm ls jsdom or yarn why jsdom (make sure to use the same package manager as your project). If it's not at least 16, you'll likely want to use jest-environment-jsdom-sixteen.

@imnotteixeira
Copy link

Thanks @nickmccurdy, it solved this issue. Currently having the issue of #387, but that's another problem...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working environment:jsdom Issue with JSDOM environment
Projects
None yet
Development

No branches or pull requests

7 participants