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

Parent() not working properly #1991

Open
3 of 13 tasks
plemasantos opened this issue Jan 29, 2019 · 8 comments
Open
3 of 13 tasks

Parent() not working properly #1991

plemasantos opened this issue Jan 29, 2019 · 8 comments

Comments

@plemasantos
Copy link

plemasantos commented Jan 29, 2019

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

  • shallow
  • mount
  • render

Version

| enzyme 3.8.0
| react 16.7.0
| react-dom 16.7.0

Adapter

  • 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 ( )
@plemasantos
Copy link
Author

plemasantos commented Jan 30, 2019

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.

@ljharb
Copy link
Member

ljharb commented Jan 30, 2019

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?

@plemasantos
Copy link
Author

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.

@ljharb
Copy link
Member

ljharb commented Jan 31, 2019

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

@ljharb
Copy link
Member

ljharb commented Jan 31, 2019

(cc @sstern6)

@sstern6
Copy link
Contributor

sstern6 commented Jan 31, 2019

@ljharb looking into it

@upupming
Copy link

upupming commented Feb 7, 2020

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
    });

@upupming
Copy link

upupming commented Feb 7, 2020

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

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

No branches or pull requests

4 participants