Enzyme: Parent() not working properly

Created on 30 Jan 2019  路  8Comments  路  Source: enzymejs/enzyme

Current behavior

I have tried to create a couple of tests to a very simple React component.

Foo.js

import React, { PropTypes } from 'react';

const propTypes = {};

const defaultProps = {};

class Foo extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div>
        <div className="parent">
          <div className="child">Child</div>
        </div>
        <div className="parent">
          <div className="child newest">Child</div>
        </div>
      </div>
    );
  }
}

Foo.propTypes = propTypes;
Foo.defaultProps = defaultProps;

export default Foo;

Foo-test.js

import React from 'react';
import { configure, mount, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Foo from '../src/Foo';

configure({adapter: new Adapter()});

describe("A suite", function() {
  it("contains spec with an expectation", function() {
    var Wrapper = mount(<Foo />);
    var bottomMost = Wrapper.findWhere(node => node.hasClass("newest"));
    var parents = Wrapper.findWhere(node => node.hasClass("parent"));
    parents.forEach(p => console.log(p.html()));
    //outputs:
    //  <div class="parent"><div class="child">Child</div></div>
    //  <div class="parent"><div class="child newest">Child</div></div>
    console.log(bottomMost.length);
    //outputs:
    //  1
    console.log(bottomMost.html());
    //outputs:
    //  <div class="child newest">Child</div>
    console.log(bottomMost.parent().length);
    //outputs:
    //  1
    console.log(bottomMost.parent().html());
    //outputs:
    //  null
    console.log(bottomMost.parent().text());
    //outputs:
    //  null
    console.log(bottomMost.parent().findWhere(c => c.text() == "Child").length)
    //outputs:
    //  0
  });
});

It seems that when I try to access the parent element of the child node, I loose a lot of information. Basically html() and text() will output null, and childrens are gone.

Expected behavior

I would expect that the Wrapper returned by invoking parent() would be a fully fledged ReactWrapper with all children below (as if I was accessing it via the Wrapper returned by mount).

Your environment

JSDOM

API

  • [x] shallow
  • [x] mount
  • [ ] render

Version

| enzyme 3.8.0
| react 16.7.0
| react-dom 16.7.0

Adapter

  • [x] enzyme-adapter-react-16
  • [ ] enzyme-adapter-react-16.3
  • [ ] enzyme-adapter-react-16.2
  • [ ] enzyme-adapter-react-16.1
  • [ ] enzyme-adapter-react-15
  • [ ] enzyme-adapter-react-15.4
  • [ ] enzyme-adapter-react-14
  • [ ] enzyme-adapter-react-13
  • [ ] enzyme-adapter-react-helper
  • [ ] others ( )
mount Need To Reproduce bug help wanted

All 8 comments

I have just tried the same code snippet with Enzyme 2.9.1 and React 15.6.1 and the results differ from what I posted above:

    parents.forEach(p => console.log(p.html()));
    //outputs:
    //  <div class="parent"><div class="child">Child</div></div>
    //  <div class="parent"><div class="child newest">Child</div></div>
    console.log(bottomMost.length);
    //outputs:
    //  1
    console.log(bottomMost.html());
    //outputs:
    //  <div class="child newest">Child</div>
    console.log(bottomMost.parent().length);
    //outputs:
    //  1
    console.log(bottomMost.parent().html());
    //outputs:
    //  <div class="parent"><div class="child newest">Child</div></div>
    console.log(bottomMost.parent().text());
    //outputs:
    //  Child
    console.log(bottomMost.parent().findWhere(c => c.text() == "Child").length)
    //outputs:
    //  2

This is what I would expected from this sequence.

So, first - use .debug() instead of .html(). The latter does a full render on the entire tree using render, so it's not a good debugging tool for shallow.

What happens to your expectations when you make that change?

Thanks for clearing that up!

html() vs debug() is not really the point here - actually I gave mount as an example above.

        <div className="parent"> 
          <div className="child">Child</div>
        </div>
        <div className="parent">                              <!-- parent() -->
          <div className="child newest">Child</div>           <!-- bottomMost -->
        </div>

In the test, using Enzyme 3.8.0 and React 16.7.0, bottomMost.parent().children() is an empty array. That is the problem. It seems that whenever I go up one level, I loose all information on child nodes. If I call bottomMost.parent().debug(), it only prints how the parent's node, and not the children, which is also something I would not expect.

Ah, thanks. This might be related to #1876 and/or #1916.

(cc @sstern6)

@ljharb looking into it

Thanks for clearing that up!

html() vs debug() is not really the point here - actually I gave mount as an example above.

        <div className="parent"> 
          <div className="child">Child</div>
        </div>
        <div className="parent">                              <!-- parent() -->
          <div className="child newest">Child</div>           <!-- bottomMost -->
        </div>

In the test, using Enzyme 3.8.0 and React 16.7.0, bottomMost.parent().children() is an empty array. That is the problem. It seems that whenever I go up one level, I loose all information on child nodes. If I call bottomMost.parent().debug(), it only prints how the parent's node, and not the children, which is also something I would not expect.

Hello, I got the same behavior with you, this is my enzyme & react version:

// devDep
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
// dep
"react": "^16.10.2",
"react-dom": "^16.10.2",
class Foo extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div className="foo">
                Bar
                <div className="bar"></div>
            </div>
        );
    }
}
it('should get parent', function() {
        const app = mount(<Foo />);
        console.log(
            app
                .childAt(0)
                .parent()
                .html(),
        );
        // outputs null
    });

Hi, this is a demo for reproducing: https://github.com/upupming/enzyme-parent-bug, I have also commented on https://github.com/airbnb/enzyme/issues/1230

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nelsonchen90 picture nelsonchen90  路  3Comments

amcmillan01 picture amcmillan01  路  3Comments

abe903 picture abe903  路  3Comments

blainekasten picture blainekasten  路  3Comments

blainekasten picture blainekasten  路  3Comments