enzymejs / chai-enzyme

Chai.js assertions and convenience functions for testing React Components with enzyme
MIT License
787 stars 72 forks source link

[1.0.0-beta.0] Cannot assert descendant not present #207

Open ZebraFlesh opened 6 years ago

ZebraFlesh commented 6 years ago

Given this component and the following tests:

 const Test = ({ className, shouldDisplay }) => shouldDisplay ? <div className={className}></div> : null;
const thing = mount(<Test className="foo" shouldDisplay={true} />);
expect(thing).to.have.descendants('.foo');

const thing2 = mount(<Test className="foo" shouldDisplay={false} />);
expect(thing2).to.not.have.descendants('.foo');

The not descendants test on thing2 fails with the message: AssertionError: expected <Test /> not to have descendants '.foo' HTML: Not available due to: Cannot read property 'outerHTML' of null

Switching the last expectation to the following: expect(thing2.find('.foo')).to.not.exist;

it still fails with the same error: AssertionError: expected the node in <Test /> not to exist HTML: Not available due to: Cannot read property 'outerHTML' of null

This is with enzyme 3.2.0 and react 15.4.2. With enzyme 2.x and the pre-1.0 releases, these tests worked just fine.

deployable commented 6 years ago

I think I ran into the same enzyme issue here: https://github.com/airbnb/enzyme/issues/1519

Both the Test component and the div are being picked up by the class selector as they are both in enzymes dom representation when using mount. The same can happen for #id selectors.

This results in code like this:

expect( wrapper.find('.foo').hostNodes().length ).to.equal(0)

or use a more complete selector

expect(thing2).to.not.have.descendants('div.foo');
deployable commented 6 years ago

It might be useful if chai-enzyme included a .htmlDescendants() or something similar to remove the React components from results. Possibly .reactDescendants() as well if you wanted the opposite, but I believe the opposite of hostNodes() would need to be added to enzyme for that.