I created component with <Dialog />
and I want to test it with enzyme
, but when I mount
component (with muiTheme context) I can't find inner components (action buttons etc.).
console.log with wrapper.debug()
shows:
<NetworkError open={true} close={[Function]}>
<Dialog open={true} contentStyle={{...}} title="Network Error" actions={{...}} autoDetectWindowHeight={true} autoScrollBodyContent={false} modal={false} repositionOnUpdate={true}>
<RenderToLayer render={[Function]} open={true} useLayerForClickAway={false} />
</Dialog>
</NetworkError>
when original component is:
export default function NetworkError(props) {
const { open, close } = props;
const actions = [
<FlatButton
label="Cancel"
primary={true}
keyboardFocused={true}
onTouchTap={close}
/>,
];
return (
<Dialog
open={open}
title="Network Error"
actions={actions}
>
Ups! It seems that we have some problems with network, try again later.
</Dialog>
);
So it looks like it stops on RenderToLayer
and not render anything deeper (especially not render action buttons). I tried to mount it with this helpers described here: https://github.com/callemall/material-ui/issues/4664 but it didn't help.
馃憤 I'm also experiencing this issue. For some reason it looks like the Dialog body/children is being passed in a wrapped function as props.render
to RenderToLayer
instead of directly as child nodes?
I'm guessing this RenderToLayer component is to make it lazily render the child components or something? If it's necessary for performance then it'd be nice to have Dialog
expose another means to access the children it's given directly.
I checked out in DOM
that things like Dialog
, Popup
or Menu Drop
are rendered on special anchor outside of component, so it's not possible to get i.e. Dialog
inside wrapper - it's rendered somewhere else in DOM
.
I wonder if there is any way (even via javascript API like document.queryselectorall
) to get this Dialog
component and simulate click
or smth.
I had to attach the component to a DOM element (via mount
's attachTo
option) in order to make components with Dialogs testable...
Thanks for sharing your workaround @aryo 馃槃
Perhaps a good solution for this would be to add an option to (the props of?) the Dialog
component which when true casuses it to render it's children internally?
Is there any way to test this in v1.0.0?
I got it working using shallow rendering and then using wrapper.dive()
Closing this issue for #7970
@monkeybeans How you did it using dive? Can you give us an example?
@talmukund was some time ago, but i think this should work :)
import { shallow } form 'enzyme';
const wrapper = shallow('<Component />');
const dived = wrapper.dive();
dived.find('selector').simulate('click); //or what you want to do
expect(dived).to.have....()
@monkeybeans problem with dialog component is that actions are defined inside props like:
<Dialog actions={actions}/>
Later we define actions as array of buttons. I have to dive inside actions not any child component.
Above dom implementation may work but we are using typescript which is not supporting react test utils. We have to use enzyme only.
@aryo
Not sure if that's exactly what is the problem here, but I've had similar problem and this worked:
import { DialogActions, Button } from 'material-ui';
/* Component has a <Dialog /> with a set of action buttons defined inside as children */
const component = shallow(<Component />);
const dialogActions = component.find(DialogActions);
const okButton = [ ...dialogActions.find(Button) ].find(e => e.props.raised);
const actionFunction = okButton.props.onClick;
/* ... */
Most helpful comment
I had to attach the component to a DOM element (via
mount
'sattachTo
option) in order to make components with Dialogs testable...Here's a _rough_ example as to how I did it