Enzyme: parent() api does not return children in shallow rendering

Created on 6 Oct 2017  路  14Comments  路  Source: enzymejs/enzyme

I am trying to get the second child element from the parent and it fails. Below is the example:

Component:

class TestComponent extends React.Component {
  render() {
    return (
      <div id="root">
        <div id="parent1" className="parentOne">
          <div id="child1_1" className="childOne">
            Hello world!
          </div>
          <div id="child1_2" className="childTwo">
            Hello world!
          </div>
        </div>
        <div id="parent2">
          <div id="child2_1">
            Hello world!
          </div>
          <div id="child2_2">
            Hello world!
          </div>
        </div>
      </div>
    );
  }
}

TestComponent.displayName = 'TestComponent';

export default TestComponent;

Test:

it('renders parent1 children', () => {
    const wrapper = shallow(<TestComponent />);

    const child1 = wrapper.find('#child1_1');
    const parent1 = child1.parent();
    expect(parent1).to.have.className('parentOne');

    const child12 = parent1.childAt(1);
    expect(child12).to.have.className('childTwo');
  });

The second assertion fails with the below error message:

AssertionError: expected the node in <TestComponent /> to have a 'childTwo' class, but it has undefined

And when I log parent1.children(), I get ShallowWrapper { length: 0 }.

Strangely, expect(child12).to.be.present(); passes.

shallow v3 bugs

Most helpful comment

I'm having the same issue with Enzyme 3 (was working with Enzyme 2):

test('parent() vs parents()', () => {
  const H1 = () => (
    <h1 />
  );

  const root = shallow(
    <div id="root">
      <H1 />
      <h2 />
      <h3 />
    </div>
  );

  console.log('root:', root.debug());

  const h1 = root.find(H1);
  console.log('h1.parent():', h1.parent().debug());
  console.log('h1.parents():', h1.parents().debug());
});

Output:

    root: <div id="root">
      <H1 />
      <h2 />
      <h3 />
    </div>

    // ===> Something wrong:
    h1.parent(): <div id="root" />
    //

    h1.parents(): <div id="root">
      <H1 />
      <h2 />
      <h3 />
    </div>

To sum-up child.parent() does not contain its children while child.parents() does.

All 14 comments

I'm having the same issue with Enzyme 3 (was working with Enzyme 2):

test('parent() vs parents()', () => {
  const H1 = () => (
    <h1 />
  );

  const root = shallow(
    <div id="root">
      <H1 />
      <h2 />
      <h3 />
    </div>
  );

  console.log('root:', root.debug());

  const h1 = root.find(H1);
  console.log('h1.parent():', h1.parent().debug());
  console.log('h1.parents():', h1.parents().debug());
});

Output:

    root: <div id="root">
      <H1 />
      <h2 />
      <h3 />
    </div>

    // ===> Something wrong:
    h1.parent(): <div id="root" />
    //

    h1.parents(): <div id="root">
      <H1 />
      <h2 />
      <h3 />
    </div>

To sum-up child.parent() does not contain its children while child.parents() does.

@tkrotoff @VidyullathaKandipati what version of react are you both using?

I am using react: 15.6.2 and enzyme-adapter-react-15: 1.0.1

React 16.0.0 + enzyme-adapter-react-16 1.0.1

I am also having this issue with [email protected] and [email protected].

I have tests that pass for Enzyme v2. They do the following:

wrapper.find('label[htmlFor="something"]').parent().children().at(1).text()

Now it does not pass anymore in v3. What should I do? I'm just checking the text of the label's sibling (that is not inside any particular tag).

  • Using React 16.2.0

Console logging the parent()'s children() yields nothing while the parent() yields:

// .parent().debug()
<ParentComponent someProp={true} />

@nbkhope try adding .hostNodes() after .children()?

@ljharb

ShallowWrapper::getNodes() is no longer supported. Use ShallowWrapper::getElements() instead

I tried getElements(), but it returns an empty list. But I went from child to parent and the parent exists, so how can there be no children?

Update:

Sorry, I should have used .hostNodes(). Anyway, it yields a similar result:

console.log(....parent().children().hostNodes());
// => ShallowWrapper { length: 0 }

So I get nothing.

I was kind of reluctant to upgrade to v3 right away, but decided to give it a try. Now am kind of reluctant again. Anyway, I can make my tests pass using the .parents() like so:

// before
wrapper.find('label[htmlFor="something"]').parent().children().at(1).text()

// after
wrapper.find('label[htmlFor="something"]').parents().at(0).children().at(1).text()

Please fix that issue :)

If you start with wrapper.find('label[htmlFor="something"]').hostNodes(), does that help?

@ljharb that does not seem to do anything.

Doing wrapper.find('label[htmlFor="something"]').hostNodes().parent() returns the parent, but then appending a .children() yields nothing:

console.log(wrapper.find('label[htmlFor="something"]').hostNodes().parent().children())
// => ShallowWrapper { length: 0 }

PS: Using Enzyme v3.2.0

Gotcha, thanks - that seems to be the OP's issue as well.

Seeing similar issue with [email protected], [email protected]

const Cmp = () => (
  <div>
    <section>
      FOO
      <h1>BAR</h1>
    </section>
  </div>
);

const wrapper = shallow(<Cmp />);
console.log(wrapper.debug());
console.log('h1 parent text:', wrapper.find('h1').parent().text());
console.log(wrapper.find('h1').parent().debug());

Output:

<div>
  <section>
    FOO
    <h1>
      BAR
    </h1>
  </section>
</div>
h1 parent text:
<section />

I would expect .text() not to return a blank string, and for .parent().debug() not to show an empty <section/> tag.

If I replace .parent() with .parents().at(0) things work as expected.

This has been resolved; as the tests in #769 indicate.

Please file a new issue if not.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

heikkimu picture heikkimu  路  3Comments

potapovDim picture potapovDim  路  3Comments

modemuser picture modemuser  路  3Comments

timhonders picture timhonders  路  3Comments

amcmillan01 picture amcmillan01  路  3Comments