user-event: Native button should trigger click on keydown space

For of all, thank you for this handy library 😄

  • @testing-library/user-event version: 12.0.11
  • Testing Framework and version: jest - 26.1.0
  • DOM Environment: react-dom - 16.13.1

Relevant code or config

import React from "react";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

describe("test", () => {
  it("emits click on button type space", async () => {
    const handleClick = jest.fn();
    render(<button onClick={handleClick}>foo</button>);
    screen.getByText("foo").focus();
    await userEvent.type(screen.getByText("foo"), " ", { skipClick: true });
    expect(handleClick).toHaveBeenCalledTimes(1);
  });
});

Reproduction repository:

https://codesandbox.io/s/angry-bas-bttix?file=/src/user-event.test.js

Problem description:

A native button triggers a click event on keydown space. Currently only keydown enter is handled properly by userEvent.type.

Suggested solution:

Add the same behavior that keydown enter has for keydown space.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16 (11 by maintainers)

Most upvoted comments

Whatever we do, let’s just make sure it results in the same events that are fired when the user does that interaction in the browser: https://codesandbox.io/s/user-event-playground-eo909

That makes sense to me, though I think having a modifier (like {space}) would be useful. Would you be interested in adding support for that?

Thanks for the recap! If it is okay for you, I would try to also correct the bug in the same PR.

Actually a button is not the only element that has a value that should not be changed by typing.

We also need to consider als <input> elements with one of the following types:

  • button
  • color
  • file
  • image
  • reset
  • submit

I will include these in the fix as well.

I’ll do a little recap. I hope to do a right thing 🦸

We have two things to consider:

  1. We want to implement userEvent.type(button, '{enter}')

    What why want implement?

    We want make a button clickable using type function pressing space

    How we can implement {space} modifier?

    We should add this feature to getEventCallbackMap function, doing something very similar to {enter} modifier

  2. We can do now userEvent.type(button, 'this is a value'), but it seams that creates an infinite loop.

    Can a button have a value?

    Yes button like input can have a value attribute. In combination with name attribute, when a form is submitted the value of the button is sent in the POST request

    Can a user change the value of a button?

    No, It can be changed only with code

    Should we support it?

    No, because the library simulates user actions. Changing the value of a button is not possible with user actions.

    When the button has focus can I type on it?

    Yes you can, but only keypress/keydown and focus events are fired as for the log below. We have a similar behaviour with a focusable div(#407)

     button#button[value=""] - focus
     button#button[value=""] - focusin
     button#button[value=""] - keyup
     button#button[value=""] - keyup
     button#button[value=""] - keydown
     button#button[value=""] - keypress
     button#button[value=""] - keyup
     button#button[value=""] - keydown
     button#button[value=""] - keypress
     button#button[value=""] - keyup
     button#button[value=""] - keydown
     button#button[value=""] - keypress
     button#button[value=""] - keyup
     button#button[value=""] - keydown
     button#button[value=""] - keypress
     button#button[value=""] - keyup
     button#button[value=""] - keydown
     button#button[value=""] - keypress
     button#button[value=""] - keyup
    

    How can implement this behaviour?

    In the type function we should check if the element received as parameter is editable. If the element is not editable we should trigger only the events above. An editable element is an element with value attribute. We need to exclude only buttons(we should support also <div contenteditable></div> that I think we are not supporting now, we can do later)

For now I think that we can simply implement the {enter} feature, then we can correct the bug.

from a user perspective I think that is not possible to add a value to a button, at the same time value property is valid on button, so I think that in type function we should block the possibility to write into value.

I can do this document.getElementsByTagName('button')[0].value = "my value" But I think that we shouldn’t do this userEvent.type(myButton, 'my value') but we could do this userEvent.type(myButton, '{space}').

what you’re saying is regarding the other issue opened by @visualjerk https://github.com/testing-library/user-event/issues/407