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

Confusion about simulating keypresses in a Downshift component during testing #583

Closed
toolness opened this issue Sep 22, 2018 · 4 comments
Closed

Comments

@toolness
Copy link

Hello! Thanks for creating this excellent component, as well as react-testing-library, which I am also pleased with, and find far less confusing than enzyme.

However, I am having trouble testing the component I've made with Downshift, using react-testing-library. All I'd like to do is simulate typing input into a Downshift component, and ensuring that my onInputValueChange callback is being called properly, but it doesn't seem to be working.

I've verified that my component actually works as expected through manual testing, so I know the problem isn't in how I'm using Downshift, but rather in how I'm trying to test it.

I've attempted to simplify my problem into a test case below. (The test is extra long because I'm trying a lot of different things to simulate input, none of which seem to work.)

import React from 'react';
import * as rtl from 'react-testing-library';
import Downshift from 'downshift';


test("Downshift calls onInputValueChange()", () => {
  const onInputValueChange = jest.fn();
  const rr = rtl.render(
    <Downshift onInputValueChange={onInputValueChange} >
      {(ctx) => (
        <div>
          <label {...ctx.getLabelProps()}>blah</label>
          <input {...ctx.getInputProps()} />
        </div>
      )}
    </Downshift>
  );

  const input = rr.getByLabelText(/blah/) as HTMLInputElement;

  // Sanity check, make sure this is an <input> element.
  expect(input.nodeName).toBe('INPUT');

  // We want to simulate typing this into the autocomplete field.
  const inputText = "blarg hello i am typing this";

  // Try assigning the input directly...
  input.value = inputText;

  // Try firing a change event at the input...
  rtl.fireEvent.change(input, { target: { value: inputText } });

  // Simulate typing each character individually...
  for (let i = 0; i < inputText.length; i++) {
    const key = inputText[i];
    const code = inputText.charCodeAt(i);

    // Simulate a key down followed by a key up...
    rtl.fireEvent.keyDown(input, {key, keyCode: code, code});
    rtl.fireEvent.keyUp(input, {key, keyCode: code, code});

    // Simulate a key press event...
    rtl.fireEvent.keyPress(input, {which: code});
  }

  // Surely by this point one of the many things we just tried
  // will have triggered our event handler. Yet the following
  // assertion fails.
  expect(onInputValueChange.mock.calls).not.toHaveLength(0);
});

Am I missing something really obvious here? Sorry if this isn't the proper place to ask.

@kentcdodds
Copy link
Member

Hi!

Try removing this line:

input.value = inputText;

When you do that react knows and when the change event is fired it doesn't think that the value was actually changed.

@toolness
Copy link
Author

Thanks! What's weird is that I could swear I already tried that--because I anticipated that might be the case--but when I just commented it out now, it worked!

Would you mind if I submitted a PR to the docs on how to test the component or something? I had been messing with this for an hour or so and was getting pretty frustrated, so it'd be nice if future people in my situation have an easier time.

@kentcdodds
Copy link
Member

Sure! 👍

@aslansservant42
Copy link

thanks for the solution. This still exists in 2022. I have found out that with user-event v14 of RTL that:

userEvent.type(input,'foo'); also does not trigger the onChange event. I have to use fireEvent.change(input, { target: { value: inputText } });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants