Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing react-contenteditable with react testing library

How to test this component: https://github.com/lovasoa/react-contenteditable? How to mimic user action in test environment? I've tried following:

// The given element does not have a value setter
fireEvent.change(sourceContent, {
  target: { value: "New content text" }
});

// This doesn't emit onChange Changes text content but onChange is not fired.
fireEvent.change(sourceContent, {
  target: { textContent: "New content text" }
});

// This doesn't emit onChange. Changes inner html but onChange is not fired.
fireEvent.change(sourceContent, {
  target: { innerHTML: "New content text" }
});

All of the above are failed tests. I thought that if I change innerHTML then function provided in onChange will be fired. This is sample project with this problem: https://codesandbox.io/s/ecstatic-bush-m42hw?fontsize=14&hidenavigation=1&theme=dark

like image 873
karlosos Avatar asked Mar 02 '20 20:03

karlosos


People also ask

Which testing library is best for React?

By default, Jest and React come with a react-test-renderer package which can transform components into JSON objects. This mechanism is used for snapshot testing. Jest is a perfect choice for standard unit tests of pure functions.

What type of testing is React testing library?

React Testing Library is a testing utility tool that's built to test the actual DOM tree rendered by React on the browser. The goal of the library is to help you write tests that resemble how a user would use your application.

Do you need Jest for React testing library?

React Testing Library is not specific to any testing framework; we can use it with any other testing library, although Jest is recommended and preferred by many developers. create-react-app uses both Jest and React Testing Library by default.


2 Answers

It's not possible to simulate events on contenteditable with testing-react-library, or any testing library that uses js-dom, because of a limitation on js-dom itself.

See the discussion here and here.

The solution would be to use puppeteer or another method that uses a real browser for rendering.

like image 146
Dimas Cyriaco Avatar answered Sep 22 '22 13:09

Dimas Cyriaco


It looks like for testing input you should use fireEvent.input. So following:

// This doesn't emit onChange. Changes inner html but onChange is not fired.
fireEvent.change(sourceContent, {
  target: { innerHTML: "New content text" }
});

Will be good way to mimic user input.

like image 38
karlosos Avatar answered Sep 26 '22 13:09

karlosos