How to test `contenteditable` events with React Testing Library

2.6k views Asked by At

I am trying to write tests for one of our rich text components which was implemented with slate js editor in react js. So when writing tests, I am retrieveing the element div[contenteditable='true'], but not able to simulate events like change, blur, focus. The handlers attached to editor component are not getting called. I tried multiple combinations, but no luck. Can someone please help on this? Is it possible to simulate events for contenteditable element using testing library (contenteditable is implemented using slatejs)?

1

There are 1 answers

0
marcusstenbeck On

Like you've discovered, contenteditable isn't supported by JSDOM. React Testing Library (RTL) is built on top of JSDOM, so it's not possible to test the Slate editor properly with RTL until JSDOM implements support for contenteditable.

Use a browser automation library together with Testing Library

Your options are then to use a tool that creates a real browser context. Testing Library have integrations with many tools that do exactly that: TestCafe, Cypress, Nightwatch, Puppeteer.

You can also use the above tools on their own, without Testing Library.

I've solved this using Puppeteer, and there are two approaches:

  1. Run a local server and tell Puppeteer to go to something like localhost:3000
  2. Set the content directly with page.setContent(htmlString)

(1) is the most common, and you'll find many guides for this since it's a common approach for end-to-end testing (google search).

(2) is a little trickier because you will have to transform and bundle your source for each test, and then inject it as HTML into the browser page. I prefer this approach because the testing experience is much more similar to using RTL. I've created a repository with an example of this setup with the Slate editor here: https://github.com/marcusstenbeck/puppeteer-react-testing-template/