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

Arrowleft handler does not respect preventDefault resulting in incorrect selectionStart #578

Closed
adamayres opened this issue Mar 8, 2021 · 4 comments

Comments

@adamayres
Copy link

adamayres commented Mar 8, 2021

Environment

  • @testing-library/user-event@^12.8.1
  • jest@^26.6.3
  • jsdom@^16.4.0

What you did

  • Created an input element that has a keydown event handler that calls event.preventDefault() if the event.key is ArrowLeft.
  • Use userEvent.type to enter text into the input element.
  • Use userEvent.type to enter the {arrowleft} special key.
  • Attempted to assert that the input's selectionStart was not moved by the arrow left key press.

What happened:

When using userEvent.type to enter the {arrowleft} special key the selectionStart is updated despite preventDefault being called on the event by an event handler attached on the input element.

Reproduction repository:

https://codesandbox.io/s/react-testing-library-selectionstart-issue-yb15q?file=/src/App.test.js

export default function CustomInput() {
  return (
    <input
      data-testid="testInput"
      type="text"
      onKeyDown={(event) => {
        if (event.key === "ArrowLeft") {
          event.preventDefault();
        }
      }}
    />
  );
}
describe("user-event {arrowkey}", () => {
  it("should respect preventDefault when updating selectionStart", () => {
    const { container } = render(<CustomInput />);

    const inputElement = getByTestId(container, "testInput");
    userEvent.type(inputElement, "Hello, World!");

    expect(inputElement.selectionStart).toBe(13);

    userEvent.type(inputElement, "{arrowleft}");

    expect(inputElement.selectionStart).toBe(13);
  });
});

Problem description:

The preventDefault does not appear to be respected with regards to using the arrow keys when determining the selectionStart.

In type.js I can see that the arrow keys uses navigationKey which does not appear to have any handling for if the event default was prevented.

[specialCharMap.arrowLeft]: navigationKey('ArrowLeft')

However, I do see that some other characters do have special handling for this use case, for example the backspace key:

[specialCharMap.backspace]: handleBackspace,
...

function handleBackspace({currentElement, eventOverrides}) {
  ...

  const keyPressDefaultNotPrevented = fireEvent.keyDown(currentElement(), {
    key,
    keyCode,
    which: keyCode,
    ...eventOverrides,
  })

  if (keyPressDefaultNotPrevented) {
    fireInputEventIfNeeded({

Suggested solution:

Minimally it seems like navigationKey method should have support for not updating the selectionStart when the event default is prevented. However, I see that in other cases in type.js there are other special key event handlers that also do not respect event.preventDefault, namely: handleArrowDown, handleArrowUp, handleEsc, handleSelectAll, and handleSpace. It's worth noting that some of these handlers for the special keys utilize multiple key events (keyDown and keyUp as opposed to keyPress). Perhaps in all cases where they are custom event handlers attached to these native events there should be some checking if the default was prevented.

Related and possibly duplicative

Apologies if this issue has already been captured elsewhere in sufficient detail.

#515
#521
#322
#404

@ph-fritsche ph-fritsche mentioned this issue Mar 8, 2021
8 tasks
@ph-fritsche
Copy link
Member

Thanks a lot for this detailed report. :)

Minimal solution would indeed be to get navigationKey to the same standard as the other functions - adding missing events and repeating code.
Best solution would be to do the rewrite proposed in #521 . That would also tackle this issue.

Would you help on this e.g. by reviewing changes?

@adamayres
Copy link
Author

Sure, I'm happy to help as a reviewer or otherwise on #521.

@ph-fritsche
Copy link
Member

I've started the work in #581

@ph-fritsche
Copy link
Member

Resolved in v13.0.0 🚀

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

2 participants