Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Has anyone successfully used react-testing-library to test change events on a draftJS Editor component?

​The fireEvent.change() just doesn't work.

It says there are no setters on the element.

I tried using aria selectors instead

const DraftEditor = getByRole('textbox')
DraftEditor.value ='something';
fireEvent.change(DraftEditor);

I tried same again using query selector

const DraftEditor = container.querySelector('.public-DraftEditor-content'));

Tried keyboard events instead.

Nothing.

Has anyone managed to text a rich text input with draftjs and react testing library?

like image 673
Josh Pittman Avatar asked Apr 12 '19 06:04

Josh Pittman


People also ask

What is React testing library used for?

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.

Does React testing library replace enzymes?

React Testing Library doesn't replace Jest, just Enzyme. We recommend test because it helps with this: Avoid Nesting When You're Testing.

What is the difference between React testing library and Jest?

Jest is a test runner that finds tests, runs the tests, and determines whether the tests passed or failed. Additionally, Jest offers functions for test suites, test cases, and assertions. React Testing Library provides virtual DOMs for testing React components.


2 Answers

I managed to do it by getting inspiration from some issue description for draft-js and adapting that to our case at hand

import { createEvent } from "@testing-library/dom"
import { render, fireEvent } from "@testing-library/react"

function createPasteEvent(html) {
  const text = html.replace('<[^>]*>', '');
  return {
    clipboardData: {
      types: ['text/plain', 'text/html'],
      getData: (type) => (type === 'text/plain' ? text : html),
    },
  };
}

renderedComponent = render(<App />)
const editorNode = renderedComponent.querySelector(".public-DraftEditor-content")
const eventProperties = createPasteEvent(textToPaste)
const pasteEvent = createEvent.paste(editorNode, eventProperties)
pasteEvent.clipboardData = eventProperties.clipboardData
fireEvent(editorNode, pasteEvent)

Some additional notes:

  • renderedComponent in my case is the parent element in which the Editor component is rendered.
  • apparently, 'ClipboardEvent' is not implemented in JSDOM (see list of supported events), therefore, the call to createEvent.paste creates a generic Event, and not a ClipboardEvent. As a workaround, I copy the necessary clipboardData properties again to the generated generic event so that they will be taken into account by the function editOnPaste of the Draft-js editor, which itself will be triggered because of the fired event.
like image 94
Franck Carre Avatar answered Sep 17 '22 16:09

Franck Carre


I managed to get it working mocking the editor and intercepting the onChange method so you can still execute all the lib functions:

const draftjs = require('draft-js');

draftjs.Editor = jest.fn(props => {
  const modifiedOnchange = e => {
    const text = e.target.value;
    const content = ContentState.createFromText(text);
    props.onChange(EditorState.createWithContent(content));
  };
  return <input className="editor" onChange={e => modifiedOnchange(e)} />;
});
like image 43
Gustavo Freire Avatar answered Sep 16 '22 16:09

Gustavo Freire