ianstormtaylor / slate

A completely customizable framework for building rich text editors. (Currently in beta.)
http://slatejs.org
MIT License
29.97k stars 3.25k forks source link

[Slate Simulator] Can't use `.focus()` with `BeforePlugin` #1981

Closed gregziegan closed 6 years ago

gregziegan commented 6 years ago

Do you want to request a feature or report a bug?

Bug

What's the current behavior?

When trying to run the test documented in https://docs.slatejs.org/other-packages/slate-simulator

Snippet:

const value = ...
const plugins = [BeforePlugin()]; // does not blow up if BeforePlugin is excluded
const simulator = new Simulator({ value, plugins });

simulator.focus() // oh no! it blows up

I receive an invariant violation since ReactDOM tries to look for a DOM node via findDOMNode and has trouble finding the node inside Simulator.

Uncaught Error: Element appears to be neither ReactComponent nor DOMNode. Keys: getSchema,getState,props
    at invariant (react-dom.development.js:65)
    at Object.findDOMNode (react-dom.development.js:15079)
    at Object.onFocus (slate-react.js:7655)
    at Stack.run (slate.js:15049)
    at Simulator.(fiddle.jshell.net/_display/anonymous function) [as focus] (https://npmcdn.com/slate-simulator@0.4.37/dist/slate-simulator.js:84:11)
    at <anonymous>:24:11
    at run (babel.js:60802)
    at check (babel.js:60868)
    at loadScripts (babel.js:60909)
    at runScripts (babel.js:60936)

Here's a JS fiddle showing this outside the context of a test (the test throws the same error). Check out the JS Console

https://jsfiddle.net/tk0jm1h8/

What's the expected behavior?

If this exception is not thrown, hopefully calls to a Simulator instance like simulator.beforeInput({ data: 'h' }) will affect its state and we can then write expectations on the new state.

Note: not passing BeforePlugin() into the Simulator's plugins means focus() does not throw an error... but any changes to the simulator instance do not reflect in simulator.value.

I'd love to help out, but I'd need some direction. Was this working before? Or am I missing an important setup? I also reproduced this with a vanilla create-react-app test suite.

zhujinxuan commented 6 years ago

For DOM related things in before/after slate, we have to prepare JSDOM and enzyme with slate-simulator...

At current stage, slate-simulator is very simple.

gregziegan commented 6 years ago

Should we update the examples folder to show some working tests? Or list JSDOM and enzyme as requirements for running tests with slate-simulator?

ianstormtaylor commented 6 years ago

Hey @thebritican thanks for opening this. Unfortunately, since Slate's Before/After plugins rely on the DOM, and on the more complex contenteditable aspects of the DOM, they aren't easily tested in isolation. I'm not even sure if JSDOM is complete enough to be used in its place either.