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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Native button should trigger click on keydown space #406

Closed
visualjerk opened this issue Jul 21, 2020 · 16 comments 路 Fixed by #409
Closed

Native button should trigger click on keydown space #406

visualjerk opened this issue Jul 21, 2020 · 16 comments 路 Fixed by #409
Labels

Comments

@visualjerk
Copy link
Collaborator

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.

@kentcdodds
Copy link
Member

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?

@petejodo
Copy link

petejodo commented Jul 21, 2020

just to add to this convo, I have a test right now with an element that has role set to button and was trying to test that pressing space triggers the expected behavior but I'm hitting this error in the code. I wonder if by introducing a {space} modifier, we can avoid that branch in the code somehow.

There's nothing I can find in the ARIA button role documentation that requires an ARIA-equivalent attribute of value being set so I feel like what I'm doing is a legitimate use case

Edit:

Side note, I do not hit that error when doing userEvent.type(el, '{enter}', { skipClick: true })

@marcosvega91
Copy link
Member

what you're saying is regarding the other issue opened by @visualjerk #407

@visualjerk
Copy link
Collaborator Author

visualjerk commented Jul 22, 2020

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?

I would be glad to add support for it. Just to be clear:

I would expect that userEvent.type(el, '{space}') = userEvent.type(el, ' ')

Do you have any objections against that?

@marcosvega91
Copy link
Member

marcosvega91 commented Jul 22, 2020

I think that the behaviour should be different because {space} on a button should press the button if the button has the focus while ' ' should add a value to the button equal to . What do you think?

@kentcdodds
Copy link
Member

But you can't "add a value to a button" so I do think it would make sense that they do the same thing when triggered on a button.

@marcosvega91
Copy link
Member

marcosvega91 commented Jul 22, 2020

I think that I can do <button value="my value to send">Click me</button>

The value is sent when a form is submitted. Am I'm wrong?

@petejodo
Copy link

petejodo commented Jul 22, 2020

@marcosvega91 yeah that works but pressing space on that button wouldn't change the value of the button to "my value to send " (note the space at the end). Instead, it triggers a button click.

@marcosvega91
Copy link
Member

marcosvega91 commented Jul 22, 2020

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}').

@visualjerk
Copy link
Collaborator Author

I will handle the case userEvent.type(myButton, 'my value') inside the same PR, if this is ok for you.

@marcosvega91
Copy link
Member

For now every element that can have a value property are valid I think.

Because we simulate user interactions on a browser user can't write in a button but at the same time can press a space on a button.

I think that we should skip code that add value in the type implementation for buttons and add {space} modifier. @kentcdodds what do you think?

@kentcdodds
Copy link
Member

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

@marcosvega91
Copy link
Member

marcosvega91 commented Jul 22, 2020

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(Error when using type on an element without a value property聽#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.

@visualjerk
Copy link
Collaborator Author

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.

@kentcdodds
Copy link
Member

That sounds great 馃憤

@kentcdodds
Copy link
Member

馃帀 This issue has been resolved in version 12.0.13 馃帀

The release is available on:

Your semantic-release bot 馃摝馃殌

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

Successfully merging a pull request may close this issue.

4 participants