ianstormtaylor / slate

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

Slate editor can not be rendered by react-test-renderer #832

Closed delijah closed 7 years ago

delijah commented 7 years ago

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

This is a bug report.

What's the current behavior?

If i use react-test-renderer to render the editor, the following error happens:

TypeError: Cannot read property 'ownerDocument' of null
      at getDocument (node_modules/get-document/index.js:37:29)

Example: https://github.com/DND-IT/slate-test-renderer

(Run yarn install and yarn test)

What's the expected behavior?

Slate editor should be able to get testet/renderer by react-test-renderer.

delijah commented 7 years ago

Any news on this? Is there another way to (snapshot-)test slate.js implementations?

TimSusa commented 7 years ago

We found a possible approach by using enzyme and enzyme-to-json with mocking out the Editor by jest. Please note, in the example, we have Slate as React-Component embedded into the App. Furthermore, we use enzyme "mount" (full DOM Rendering):

/* eslint-env jest */
import React from 'react'
import { mount } from 'enzyme'
import serializer from 'enzyme-to-json/serializer'
import App from './App'

jest.mock('slate', () => {
    return {
        Editor: () => (<div>Heal the world!</div>),
        Raw: {
            deserialize: jest.fn(),
            serialize: jest.fn()
        }
    }
})

// We use the enyme-to-json serializer here
// Note: If you put usage of serializer into jest.config.json,
//       it refused to work here.
expect.addSnapshotSerializer(serializer)

test('should render correctly', () => {
    const wrapper = mount(
        <App />
    )
    expect(wrapper).toMatchSnapshot()
})
ianstormtaylor commented 7 years ago

Hey, thanks for using Slate! Unfortunately, we can't offer support for usage questions in the issues here because it becomes overwhelming to maintain the project if the issues are filled with questions.

However, we do have a Slack channel and people are constantly asking and answering questions in there. So I'm going to close this issue, but I definitely recommend joining the Slack channel if you want to find people that might be able to help.

Thanks for understanding!

billiegoose commented 6 years ago

I don't think this is a usage question... I think it really is a bug report. He even provided a test case so it could be reproduced. I'm fine if you want to close it as "wontfix" because it's a jsdom environment that's simply not supported.

For those wondering "well, how else can I snapshot the output?" I gave up using React and used slate-simulator.

ianstormtaylor commented 6 years ago

@wmhilton feel free to open another issue describing it clearly, and ideally offering a pull request to make it supported, or research to explain why a pull request is impossible/hard.

billiegoose commented 6 years ago

I will leave more details here, since this page already has the Google juice that will lead others to it. I was trying to follow the Testing React Apps - Jest guide, and it suggests using 'react-test-renderer' to create a snapshot test.

The OP linked to a complete Github repo "test case" that he made, just for this issue (as can be seen from the name, and the fact it is a single commit) that you can use to reproduce the issue, but I'll post a slightly condensed version of the code from his 'App.test.js' file here:

import React from 'react';
import renderer from 'react-test-renderer';
import { Editor, Plain } from 'slate'; 

const slateState = Plain.deserialize('hello world')

it('renders without crashing', () => {
    const tree = renderer.create(
        <Editor state={slateState} />
    ).toJSON();

    expect(tree).toMatchSnapshot();
});

Unfortunately, the above code will throw an error without rendering anything. @TimSusa provides a suggestion for how to get around this. (Because if you add a Slate <Editor/> to an existing app for which you were doing snapshot tests, having your tests now crash is not good.) His instructions show how to "mock" the <Editor/> component by substituting it with an ordinary <div/> at test time.

I'm brand new to slate, and snapshot testing, and don't really know what is happening inside renderer.create so without getting in too deep, all I can say is it probably has to do with the fact that it's not a real DOM environment. Probably the challenges of fixing this would be similar to the challenges of getting Slate to work in server-side rendering environments, if that makes sense.