When I try to create a Jest snapshot of my React component 'LoadingModal', which contains a Semantic-UI-React 'Modal' component, the snapshot ends up empty, with 'null' inside the .snap file. I've tested taking snapshots of other Semantic-UI-React components like 'Button', 'Dropdown', and 'Sidebar', which render and snapshot with the correct html output just fine.
This doesn't look like its an issue with Jest snapshotting itself, but rather react-test-renderer with its .create() and .toJson() methods returning null.
Why would react-test-renderer properly render some Semantic-UI-React components, but not others like 'Modal'? react-test-render seems to be the standard method of serializing React components for snapshotting, and is the method used in Jest's snapshotting docs.
I am using [email protected], [email protected], [email protected], and [email protected]
Update:
It looks like for some reason the Semantic-UI-React Modal component in particular is set to render null when not rendered inside a browser.
See my issue on the github repo for more information.
LoadingModal.test.js
import React from 'react'
import renderer from 'react-test-renderer'
import LoadingModal from './LoadingModal'
test('should render correctly', () => {
const tree = renderer.create(
<LoadingModal/>
).toJSON()
expect(tree).toMatchSnapshot()
})
LoadingModal.test.js.snap
// Jest Snapshot v1
exports[`should render correctly 1`] = `null`;
LoadingModal.js
import React from 'react';
import PropTypes from 'prop-types'
import { Modal, Dimmer, Loader} from 'semantic-ui-react'
class LoadingModal extends React.Component {
static propTypes = {
header: PropTypes.func,
content: PropTypes.func,
loading: PropTypes.bool,
onClose: PropTypes.func,
size: PropTypes.string,
height: PropTypes.string
};
static defaultProps = {
size: 'tiny',
height: '500px'
}
_render_content = (content) => {
if (this.props.loading === true) {
return <Dimmer active inverted><Loader active size='large' inline='centered'/></Dimmer>
} else {
return content && content()
}
}
render () {
const {
header,
content,
loading,
onClose,
size,
height
} = this.props;
return (
<Modal size={size} dimmer='blurring' open={true} onClose={onClose}>
{header && header()}
<Modal.Content>
<div style={{height: height}}>
{this._render_content(content)}
</div>
</Modal.Content>
</Modal>
);
}
}
export default LoadingModal
As you stated, this may be because you are testing outside a browser. However, this can be fixed using jsdom.
I'm going to assume you have jsdom setup, as react-test-renderer
requires jsdom or some other setup that simulates window
and document
.
Given my assumption, Semantic-UI-React's modal will still render null
. This is because it use's the Portal
component and renders the modal on the document.body
node.
Look at how Semantic-UI-React tests the modal:
it('renders child components', () => {
const child = <div data-child />
wrapperMount(<Modal open>{child}</Modal>)
document
.querySelector('.ui.modal')
.querySelector('[data-child]')
.should.not.equal(null, 'Modal did not render the child component.')
})
They have to use DOM and css selectors to test, because react-test-renderer
and enzyme
can't test against document.body
.
I have found another solution that allows the use of react-test-renderer
and enzyme
, which means you can do snapshots! I use jest.mock
to mock the Portal
component as a component that renders its children, instead of rendering onto the document.body
node.
import React from 'react';
import renderer from 'react-test-renderer';
import Portal from 'semantic-ui-react/dist/commonjs/addons/Portal/Portal';
import { Modal } from 'semantic-ui-react';
jest.mock('semantic-ui-react/dist/commonjs/addons/Portal/Portal', () => ({ children }) => children);
describe('<Modal />', () => {
test('snapshot', () => {
const tree == renderer.create(<Modal open>Inside my modal!</Modal>).toJSON();
expect(tree).toMatchSnapshot();
});
});
And the snapshot looks like the following:
exports[`<CaptureModal /> snapshot 1`] = `
<div
className="ui modal transition visible active"
style={
Object {
"marginTop": undefined,
}
}
>
Inside my modal!
</div>
`;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With