When testing a component that includes a , I can successfully simulate a click and verify that the component's state is set to open. However, when I then try to find the defined action buttons, I am unable to do so.
// Code
class CustomDialog extends Component {
....
this.state = {
open: false,
};
handleOpen = () => {
this.setState({ open: true });
};
handleDelete =() => {
....
};
handleClose = () => {
....
};
render() {
const actions = [
<FlatButton label="Cancel" onClick={this.handleClose} />,
<FlatButton label="Delete" onClick={this.handleDelete} />,
];
return (
<span>
<FlatButton label="Delete" onClick={this.handleOpen} />
<Dialog
actions={actions}
open={this.state.open}
onRequestClose={this.handleClose}
>
Delete? This operation cannot be reversed.
</Dialog>
</span>
);
}
}
// Tests
expect(mountedComponent).toHaveState('open', false); <--PASS
mountedComponent
.find('FlatButton')
.simulate('click');
expect(mountedComponent).toHaveState('open', true); <--PASS
expect(mountedComponent
.find('FlatButton')
.find('[label="Cancel"]')).toBePresent(); <<< FAIL
I haven't done a sandbox because Dialog works fine for me in the browser, it's only when testing that the issues arise.
I have searched the issues of this repository and believe that this is not a duplicate.
| Tech | Version |
|--------------|---------|
| Material-UI | 0.19.4 |
| React | 16.0.0 |
| enzyme | 3.1.0 |
And finally, here is my mountedComponent.debug()
output:
<AreaDeleteDialog className="delete" id="Hollywood" handleAreaDelete={[Function]}>
<span>
<FlatButton label="Delete" onClick={[Function]} disabled={false} fullWidth={false} labelStyle={{...}} labelPosition="after" onKeyboardFocus={[Function]} onMouseEnter={[Function]} onMouseLeave={[Function]} onTouchStart={[Function]} primary={false} secondary={false}>
<EnhancedButton onClick={[Function]} onKeyboardFocus={[Function]} onMouseEnter={[Function]} onMouseLeave={[Function]} onTouchStart={[Function]} disabled={false} focusRippleColor="#999999" focusRippleOpacity={0.3} style={{...}} touchRippleColor="#999999" touchRippleOpacity={0.3} containerElement="button" onBlur={[Function]} onFocus={[Function]} onKeyDown={[Function]} onKeyUp={[Function]} tabIndex={0} type="button">
<button onMouseEnter={[Function]} onMouseLeave={[Function]} onTouchStart={[Function]} style={{...}} disabled={false} onBlur={[Function]} onFocus={[Function]} onKeyUp={[Function]} onKeyDown={[Function]} onClick={[Function]} tabIndex={0} type="button">
<TouchRipple centerRipple={[undefined]} color="#999999" opacity={0.3} abortOnScroll={true}>
<div onMouseUp={[Function]} onMouseDown={[Function]} onMouseLeave={[Function]} onTouchStart={[Function]} onTouchEnd={[Function]}>
<FlatButtonLabel label="Delete" style={{...}}>
<span style={{...}}>
Delete
</span>
</FlatButtonLabel>
</div>
</TouchRipple>
</button>
</EnhancedButton>
</FlatButton>
<Dialog actions={{...}} open={true} onRequestClose={[Function]} autoDetectWindowHeight={true} autoScrollBodyContent={false} modal={false} repositionOnUpdate={true}>
<RenderToLayer render={[Function]} open={true} useLayerForClickAway={false} />
</Dialog>
</span>
</AreaDeleteDialog>'
This is not an issue with material-ui and is more of a question about using enzyme, which is probably better suited for StackOverflow.
Here are some quick thoughts: If you're shallow rendering the Dialog, you won't be able to find the FlatButtons because they haven't been rendered. Instead, they are nothing more than a value assigned to the actions
prop, unless you dive
into the Dialog, which should render its children, making them accessible through the shallow wrapper:
wrapper.find(Dialog).dive().find(FlatButton)
Also, you should try using the class definition as the selector rather than its description.
// not this
mountedComponent.find('FlatButton')
// this (of course you'll need to import it into your test)
mountedComponent.find(FlatButton)
@kgregory I think it's an issue with material-ui if the interface of a component isn't suited to testing? What makes you think this is misuse of/a bug with enzyme? (I'm using a mounted component, and searching using the class definition doesn't work).
@adc17 You'll probably need to add id properties to the buttons and find them that way using the DOM. Shallow render/dive may even work. There are other resolutions mentioned on this duplicate issue #6290 and issue #7970 that references it.
@oliviertassinari can correct me if I'm wrong, but I am pretty sure that there will be no changes to the API in v0 as we're pushing for v1.
@kgregory We try to make v0.x as stable as possible. Not changing the API help.
@kgregory adding id properties to the buttons doesn't work鈥攖he buttons show up in my browser (with the ids), but they don't show up for enzyme, even though the dialog's open
prop is set to true
in the debugger output.
I will try a shallow render
plus dive
, but if that works and mount
doesn't, it seems like buggy behaviour.
If the problem doesn't exist in v1, then fair enough鈥擨 will check when I get the chance.
@kgregory the shallow render diving did not work either.
console.log(wrapper.find(Dialog).dive().find(FlatButton).length);
// prints '0' with two FlatButtons in the actions prop
I know its closed, but did anyone find the solution to this?
Most helpful comment
I know its closed, but did anyone find the solution to this?