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.
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).
JSDOM
| enzyme 3.8.0
| react 16.7.0
| react-dom 16.7.0
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