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

event.nativeEvent missing attributes after fireEvent #245

Closed
mattharrigan opened this issue Apr 16, 2019 · 10 comments
Closed

event.nativeEvent missing attributes after fireEvent #245

mattharrigan opened this issue Apr 16, 2019 · 10 comments

Comments

@mattharrigan
Copy link

Copy of testing-library/react-testing-library#342 sinceI think it is more applicable to this repo.

  • react-testing-library version: 6.0.4
  • react version: 16.8.2
  • node version: 10.14.1
  • npm version: 6.8.0

Relevant code or config:

App.js

import React, { Component } from "react";

class App extends Component {
  state = {
    x: null,
    y: null
  };

  handleMouseDown({ nativeEvent }) {
    console.log("nativeEvent", nativeEvent);
    this.setState({ x: nativeEvent.offsetX, y: nativeEvent.offsetY });
  }

  render() {
    return (
      <div>
        <svg width="400" height="400">
          <rect
            x={0}
            y={0}
            width={400}
            height={400}
            fill="rgb(0,0,255)"
            onMouseDown={evt => this.handleMouseDown(evt)}
            data-testid="rect"
          />
        </svg>
        <span data-testid="message">
          ({this.state.x},{this.state.y})
        </span>
      </div>
    );
  }
}

export default App;

App.test.js

import React from "react";
import { render, fireEvent, prettyDOM } from "react-testing-library";
import "jest-dom/extend-expect";
import "react-testing-library/cleanup-after-each";
import App from './App'


test('first test', () => {
  const { container, getByTestId } = render(<App />);
  const rect = getByTestId('rect')
  fireEvent.mouseDown(rect, { offsetX: 10, offsetY: 20, button: 0 });
  console.log(prettyDOM(container))
  const text = getByTestId('message')
  console.log(prettyDOM(text))
  expect(getByTestId('message')).toHaveTextContent('(10,20)')
})

What you did:

Test a react component which has event handlers for mouse events

What happened:

Test failed. console.log indicates that the event does not contain a nativeEvent similar to what is present when running in the browser (chrome 73.0.3683.86)

Reproduction:

https://codesandbox.io/s/61ol4lxnvk

Problem description:

console.log from App.handleMouseDown is different when testing vs running in the browser

Suggested solution:

Unknown

Not sure if this is a bug or something I am doing incorrectly. If the second, an example in the docs might be a good addition. Thank you

@bcarroll22
Copy link

bcarroll22 commented Apr 16, 2019

EDIT: this wasn't right.

In the codesandbox when I run it in the browser, the nativeEvent doesn't have an offsetX and offsetY property, but they still show up in the DOM. Is this the same behavior you see?

@mattharrigan
Copy link
Author

mattharrigan commented Apr 16, 2019

@bcarroll22 yes. I haven't used codesandbox much but it seems kinda flaky. When I run it locally both the console log and resulting DOM do contain them.

@bcarroll22
Copy link

Got it. Here you go: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/offsetX

offsetX and offsetY are readonly properties. Don't have time to test this right now, but maybe this would work?

const event = new MouseEvent('mouseDown');

Object.defineProperty(event, 'offsetX', { get: () => 10 });
Object.defineProperty(event, 'offsetY', { get: () => 20 });

fireEvent(rect, event);

I think that would probably allow you to overwrite the readonly event property for your case?

@mattharrigan
Copy link
Author

Using your approach i get a console warning:

Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the propertybuttonson a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event around, use event.persist(). See https://fb.me/react-event-pooling for more information.

I am making a variation of react-vis Highlight, https://github.com/uber/react-vis/blob/master/src/plot/highlight.js#L120

It uses event.nativeEvent.offsetX and event.nativeEvent.offsetY. Candidly I am not sure why it uses nativeEvent or if that is required. Maybe related to the warning? Anyways that might be a bigger and different question though.

Can you please show me how to simulate event.nativeEvent? Thanks

@kentcdodds
Copy link
Member

Hmmm... That warning is more likely to be an issue with your application code than test code. Do you have a codesandbox/repo that reproduces this issue?

@mattharrigan
Copy link
Author

@bcarroll22
Copy link

Do you have a repro for the synthetic event warning?

Related issue: testing-library/react-testing-library#268

The MouseEvent constructor doesn't accept offsetX and offsetY, that's why they don't show up on the event when you provide them. So it's actually not even JSDOM that's preventing it from being set, it's the constructor spec which means there's likely no bug to fix for any library.

I noticed react-vis uses Enzyme for testing, and their Simulate util does allow offsetX and offsetY, which is probably why their tests aren't complaining.

@mattharrigan
Copy link
Author

https://codesandbox.io/s/qvw69812r9

sorry I should stop messing with it

@kentcdodds
Copy link
Member

Here's a working version:

https://codesandbox.io/s/yv2811x0vj

There were a few problems:

  1. The warning you were seeing was totally unrelated to the test. It was something codesandbox was doing to keep a live-binding in the console log by accessing properties on the object you'd logged. Removing the log removes warnings.
  2. I guess React's Synthetic event doesn't have the offsetY and offsetX because the app itself didn't work if you use the event, you have to use nativeEvent. This is odd to me, but it's the way it is.
  3. Codesandbox shares the DOM between your app and the tests, so rendering the app can cause problems for the tests. This is a longstanding issue which I hope they fix eventually.

@mattharrigan
Copy link
Author

Thank you very much

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

3 participants