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

find()/contains() Doesn't Work on Non-React Elements via componentDidMount() #278

Closed
Cleod9 opened this issue Mar 22, 2016 · 4 comments
Closed

Comments

@Cleod9
Copy link

Cleod9 commented Mar 22, 2016

Refer to enzyme-example-karma-webpack to reproduce my issue:
https://github.com/lelandrichardson/enzyme-example-karma-webpack

So I'd like to write a test to see if my component rendered a non-React child with a particular class name. This child is added via componentDidMount(). Here's a modified Foo component I added to the karma-webpack example repo:

componentDidMount() {
  var div = document.createElement('div');
  div.className = 'bar';
  this.refs.container.appendChild(div);
}
render() {
  return (
    <div className="foo">
      <div ref="container" className="container">
      </div>
    </div>
  );
}

Then I created a custom test:

it("contains container element", function() {
  expect(mount(<Foo />).find(".container").length).toBe(1);
});

Naturally this test passes. Next I try to find(".bar") and the tests will fail:

it("contains container's 'bar' element", function() {
  expect(mount(<Foo />).find(".bar").length).toBe(1);
});

Is there something fundamental that I am misunderstanding about how enzyme's query selection behavior works? It is not clear to me if this is expected behavior or not based on the documentation.

@Cleod9 Cleod9 changed the title find()/contains() cannot always find child elements? find()/contains() Doesn't Work on Non-React Elements via componentDidMount() Mar 22, 2016
@Cleod9
Copy link
Author

Cleod9 commented Mar 22, 2016

Update: Sorry I just edited the example, turns out the problem is more specific than I thought. I've updated the issue title and sample code in my first message

@levithomason
Copy link

levithomason commented Apr 20, 2016

My guess is that you're appending the div to the actual DOM, outside of the awareness of React. I don't believe enzyme is going to find that because enzyme is not searching the DOM, it is searching the React tree. The tree is a virtual dom, a javascript representation of what the DOM should look like.

I bet you could mount and attach your component to the document body, then find it in the actual DOM and assert on that:

it("contains container's 'bar' element", function() {
  mount(<Foo />, { attachTo: document.body })
  const bar = document.querySelector('.bar')

  expect(bar.find('.bar').length).not.toBeNull()

  wrapper.detach()
})

I didn't test any of this, but I'd explore this direction... back to my day job!

@Cleod9
Copy link
Author

Cleod9 commented Apr 20, 2016

@levithomason Thanks for the tip! I've learned a lot about React in these past few weeks so that makes perfect sense. Anyway, you came up with a pretty easy workaround, so i'll just go with that when i need it

@Cleod9 Cleod9 closed this as completed Apr 20, 2016
@waltonseymour
Copy link

Rather than attaching to document.body, one could use getDOMNode():

const wrapper = mount(<Foo />);
wrapper.getDOMNode().getElementsByClassName("my-class");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants