Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dialog][Enzyme] mount not render inner components, stops on <RenderToLayer /> #6290

Closed
jasiek-net opened this issue Mar 6, 2017 · 11 comments
Labels
component: dialog This is the name of the generic UI component, not the React module! test

Comments

@jasiek-net
Copy link

jasiek-net commented Mar 6, 2017

Problem description

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: #4664 but it didn't help.

Versions

  • Material-UI: ^0.16.7
  • React: ^15.4.2
  • Enzyme: ^2.7.1
@oliviertassinari oliviertassinari added component: dialog This is the name of the generic UI component, not the React module! test labels Mar 6, 2017
@wyqydsyq
Copy link

wyqydsyq commented Mar 17, 2017

👍 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.

@jasiek-net
Copy link
Author

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.

@aryo
Copy link

aryo commented Mar 17, 2017

I had to attach the component to a DOM element (via mount's attachTo option) in order to make components with Dialogs testable...

Here's a rough example as to how I did it

@wyqydsyq
Copy link

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?

@DanielRamosAcosta
Copy link

Is there any way to test this in v1.0.0?

@monkeybeans
Copy link

I got it working using shallow rendering and then using wrapper.dive()

@oliviertassinari
Copy link
Member

Closing this issue for #7970

@talmukund
Copy link

@monkeybeans How you did it using dive? Can you give us an example?

@monkeybeans
Copy link

@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....()

@talmukund
Copy link

@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

@grzegorzjudas
Copy link

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;

/* ... */

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: dialog This is the name of the generic UI component, not the React module! test
Projects
None yet
Development

No branches or pull requests

8 participants