Testing react-contenteditable with react testing library

Viewed 3750

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

4 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.

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.

As Paul says on Github here: "Unfortunately, at the moment this feature has not been added to JSDOM, but there are people building features in React that require testing ContentEditable, and currently this is not possible with RTL as things currently stand, so far as I can tell."

But one way that works is fire the blur event and input is changed. See below:

fireEvent.blur(NameField, {target: {textContent: 'edited-text'}});
Related