dom-testing-library: fireEvent.keyPress is not working (ignored or not being triggered)

Relevant code or config:

const { container } = render(<ModelsForm />);
const input = (container as HTMLDivElement).querySelector('input');

fireEvent.change(input, { target: { value: 'test' } });
fireEvent.keyPress(input, { key: 'Enter', code: 13 });

What you did:

I am trying to test a small component which contains an input type=“text”

If I fireEvent.change(input, { target: { value: 'test' } }); I can expect its value and it is changed to test as expected

But if I fireEvent.keyPress(input, { key: 'Enter', code: 13 });, my mocked function is never called

What happened:

fireEvent.keyPress(input, { key: 'Enter', code: 13 }); mocked function is never called. Looks like it ignores the event

Reproduction:

https://codesandbox.io/s/react-testing-library-demo-2l41s

Problem description:

fireEvent keyPress is not working

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 10
  • Comments: 17 (7 by maintainers)

Commits related to this issue

Most upvoted comments

I tried replacing fireEvent.keyPress(input, { key: 'Enter', code: 13 }) with suggestion from https://github.com/testing-library/react-testing-library/issues/269#issuecomment-455854112 fireEvent.keyDown(input, { key: "Enter", keyCode: 13 })

I’m also experiencing this. Here’s an even simpler example: https://codesandbox.io/s/react-testing-library-demo-forked-xn4f8

For posterity since I didn’t make an account on codesandbox:

Input.js

import React, { useState } from "react";

const Input = ({ onSubmit }) => {
  const [value, setValue] = useState("");

  return (
    <>
      <label htmlFor="text-input">Text input:</label>
      <input
        id="text-input"
        placeholder="Type in here..."
        value={value}
        onChange={(e) => setValue(e.target.value)}
        onKeyPress={(e) => {
          if (e.key === "Enter") {
            e.preventDefault();
            onSubmit();
          }
        }}
        type="text"
      />
    </>
  );
};

export default Input;

Input.test.js

import React from "react";
import { render, fireEvent } from "@testing-library/react";
import Input from "../Input";

describe("<Input>", () => {
  test("submits on enter key", () => {
    const handleSubmit = jest.fn();
    const { getByLabelText } = render(<Input onSubmit={handleSubmit} />);

    const input = getByLabelText("Text input:");
    console.log(input);

    fireEvent.keyPress(input, { key: "Enter", code: 13 });

    expect(handleSubmit).toHaveBeenCalled();
  });
});

Fails with:

expect(jest.fn()).toHaveBeenCalled()

Expected number of calls: >= 1
Received number of calls:    0

EDIT: Saved to a repo for posterity, just in case: https://github.com/JayAndCatchFire/dom-testing-library-fireevent-keypress

fireEvent.keyPress(input, { key: ‘Enter’, code: 13 }); mocked function is never called.

@maufarinelli What mocked function?

Assuming you expect change to be fired then it is expected that a lone keydown event will not trigger a change event. Chrome does not fire a change event if you fire a key event at a textbox. I’m pretty sure this is how any browser behaves.

Also:

  • keep in mind that keydown is the recommended web standard in favor of the deprecate keypress.
  • keydown is dispatched before input so the value changes most often between keydown and input

This one’s got me stumped. I don’t have time to look at it right now, but if anyone wants to do a little digging that would be appreciated!