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

userEvent.click() behavior is inconsistent with browser when onPointerDown prevents default #1211

Closed
githorse opened this issue Apr 18, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@githorse
Copy link

githorse commented Apr 18, 2024

  • @testing-library/dom 9.3.4
  • vitest 1.5.0
  • jest-environment-jsdom 27.5.1
  • node 20.12.2

The behavior of userEvent.click() is inconsistent with what happens in the browser under the specific condition when I preventDefault inside onPointerDown:

test("clicking doesn't work :(", async () => {
  const user = userEvent.setup()
  const spy = vi.fn(() => console.log('clicked!'))
  render(
    <Button
      data-testid='clickme'
      onClick={spy}
      onPointerDown={(e) => {
        e.preventDefault()  // <-- the problem
      }}
    >
      Click Me
    </Button>
  )
  await user.click(screen.getByTestId('clickme'))
  expect(spy).toHaveBeenCalledOnce() // ✗ fails
})

If I comment out the problematic line (e.preventDefault()), the test passes:

test("clicking works :)", async () => {
  const user = userEvent.setup()
  const spy = vi.fn(() => console.log('clicked!'))
  render(
    <Button
      data-testid='clickme'
      onClick={spy}
      onPointerDown={() => {
        // e.preventDefault()  <-- ok
      }}
    >
      Click Me
    </Button>
  )
  await user.click(screen.getByTestId('clickme'))
  expect(spy).toHaveBeenCalledOnce() // ✔️ passes
})

If I use fireEvent instead of userEvent, it works:

test("clicking works :)", async () => {
  const spy = vi.fn(() => console.log('clicked!'))
  render(
    <Button
      data-testid='clickme'
      onClick={spy}
      onPointerDown={(e) => {
        e.preventDefault()
      }}
    >
      Click Me
    </Button>
  )
  fireEvent.click(screen.getByTestId('clickme')) // <-- ok
  expect(spy).toHaveBeenCalledOnce() // ✔️ passes
})

If I use onMouseDown instead of onPointerDown, it's also ok:

test("clicking works :)", async () => {
  const user = userEvent.setup()
  const spy = vi.fn(() => console.log('clicked!'))
  render(
    <Button
      data-testid='clickme'
      onClick={spy}
      onMouseDown={(e) => {  // <-- ok
        e.preventDefault()
      }}
    >
      Click Me
    </Button>
  )
  await user.click(screen.getByTestId('clickme'))
  expect(spy).toHaveBeenCalledOnce() // ✔️ passes
})

More importantly, if I put this exact same button on the page and click it (in Chrome 123.0.6312.124), it works fine; the onClick fires as expected.

<Button
  onClick={() => console.log('clicked!')}  // <-- ok
  onPointerDown={(e) => {
    e.preventDefault()
  }}
>
  Click Me
</Button>

So userEvent.click() is doing something differently than what seems be happening with the real user interaction.

Leaving aside the question of whether the code inside onPointerDown is a good idea or not (my real code is a little more complicated), why is userEvent doing something different here than what happens in the browser? Is there a workaround?

@MatanBobi MatanBobi transferred this issue from testing-library/dom-testing-library Apr 18, 2024
@ph-fritsche ph-fritsche added bug Something isn't working needs assessment This needs to be looked at by a team member labels Jun 3, 2024
@ph-fritsche
Copy link
Member

Closing as duplicate of #1206

@ph-fritsche ph-fritsche closed this as not planned Won't fix, can't repro, duplicate, stale Jun 3, 2024
@ph-fritsche ph-fritsche removed the needs assessment This needs to be looked at by a team member label Jun 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants