Enzyme: Enzyme 3.1.0: Issues with .find

Created on 13 Oct 2017  Â·  10Comments  Â·  Source: enzymejs/enzyme

Ok first thing this test works in v2 I am working on migrating from v2 -> v3.

beforeEach(function () {
  this.subject = () => {
    return mount(<ModalGallery {...this.props} />);
  };
});

it('Should slide to the previous image when keyboard left arrow is pressed', function () {
  this.props.activeIndex = 3;
  let event = $.Event('keyup'),
    subject = this.subject();
  event.keyCode = 37;
  subject.update();

  expect(subject.find('.item.index-3')).toHaveClassName('active');

  subject.instance().eventHandler('keyup', event);
  subject.update();

  expect(subject.find('.item.index-2')).toHaveClassName('active');
});

In v3 I am getting:
On the first expect:

Expected <div> to have className of ".active" but instead found "item index-3"
expected: Found node output: <div class="item index-3 active"><img src="/_karma_webpack_/images/gallery.image4.jpg" style="height: auto; width: auto; margin-top: 0px;"></div>

On the second expect:

Expected <div> to have className of ".active" but instead found "item index-2"
expected: Found node output: <div class="item index-2 active"><img src="/_karma_webpack_/images/gallery.image3.jpg" style="height: auto; width: auto; margin-top: 0px;"></div>

If I do subject.html() before the first expect I get:

<div class="carousel-inner fade" style="height: auto;">
  <div class="item index-0"><img src="/_karma_webpack_/images/gallery.image1.jpg" style="height: auto; width: auto; margin-top: 0px;"></div>
  <div class="item index-1"><img src="/_karma_webpack_/images/gallery.image2.jpg" style="height: auto; width: auto; margin-top: 0px;"></div>
  <div class="item index-2"><img src="/_karma_webpack_/images/gallery.image3.jpg" style="height: auto; width: auto; margin-top: 0px;"></div>
  <div class="item index-3 active"><img src="/_karma_webpack_/images/gallery.image4.jpg" style="height: auto; width: auto; margin-top: 0px;"></div>
  <div class="item index-4"><img src="/_karma_webpack_/images/gallery.image5.jpg" style="height: auto; width: auto; margin-top: 0px;"></div>
</div>

If I do subject.html() before the second expect I get:

<div class="carousel-inner fade" style="height: auto;">
  <div class="item index-0"><img src="/_karma_webpack_/images/gallery.image1.jpg" style="height: auto; width: auto; margin-top: 0px;"></div>
  <div class="item index-1"><img src="/_karma_webpack_/images/gallery.image2.jpg" style="height: auto; width: auto; margin-top: 0px;"></div>
  <div class="item index-2 active"><img src="/_karma_webpack_/images/gallery.image3.jpg" style="height: auto; width: auto; margin-top: 0px;"></div>
  <div class="item index-3"><img src="/_karma_webpack_/images/gallery.image4.jpg" style="height: auto; width: auto; margin-top: 0px;"></div>
  <div class="item index-4"><img src="/_karma_webpack_/images/gallery.image5.jpg" style="height: auto; width: auto; margin-top: 0px;"></div>
</div>

Most helpful comment

I have found a work-around for this right now but find seems to have an unusual behavior here. I have changed:

expect(subject.find('.item.index-3')).toHaveClassName('active');

To:

expect(subject.render().find('.item.item-index-3.active').length).toBe(1);

Bypassing the ReactWrapper.find and using instead ReactWrapper.render().find()

All 10 comments

I have found a work-around for this right now but find seems to have an unusual behavior here. I have changed:

expect(subject.find('.item.index-3')).toHaveClassName('active');

To:

expect(subject.render().find('.item.item-index-3.active').length).toBe(1);

Bypassing the ReactWrapper.find and using instead ReactWrapper.render().find()

Can you make a runkit demo

On 16 Oct 2017 19:23, "Jon Wheeler" notifications@github.com wrote:

@graingert https://github.com/graingert essentially yes, although I am
using "shallow"....

import React from "react";
import WaterTests from "~/modules/WaterTests";
import { shallow } from "enzyme";

describe("WaterTests.components.AddDoseForm", () => {
const createComponent = (
actions = {
getAllWaterTests: jest.fn()
},
waterTests = [],
formState = {}
) => {
return shallow(
actions={actions}
waterTests={waterTests}
formState={formState}
/>
);
};

test("shows any form validation messages", () => {
const formState = { validation: { errors: [{ message: "An error" }] } };
const component = createComponent(undefined, undefined, formState);

expect(component.find(".form-errors li").length).toBe(1);

});
...

I have many tests setup like this, and .find() no longer returns the
elements, changing it to component.render().find("... as mentioned above
does work.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/airbnb/enzyme/issues/1259#issuecomment-336982722, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAZQTHBsG56Lrm1jyy3p3USTV-0GzLj0ks5ss58ggaJpZM4P3y2v
.

:-/ Apologies....the issue I mentioned appears to be my fault...I've deleted my comments to avoid more confusion..

I'm also seeing similar behavior. Unfortunately, the fix of using .render().find doesn't work in all my cases, due to some child components being connected. If I render the component to do a .find, I get Could not find "store" in either the context or props of "Connect(Form(myChildComponent))".

I will try to create a reproducible case.

render renders all children of your component. If one of your children are connected, you would run into this issue. I personally prefer unit testing containers & components (with shallow). Your tests would be truly unit tests and you wouldn't be affected by the children.

@enthudrives well, sometimes you have to test what the children are doing, for example when you're making components to transition children, or children depend on something from parent context.

@jedwards1211 You don't have to verify the transition in the child component. The transition happens through props which are passed from parent to child.
From the context of the parent, you can see if the props passed to the child has been changed from A -> B.
From the context of child, it is just 2 scenarios with props A and B.

It's not really the point whether you should or should not use this approach. The features don't match the documentation

The OP implies to me that this is an issue with the matcher library you were using.

If this is not resolved, please file a new issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

timhonders picture timhonders  Â·  3Comments

mattkauffman23 picture mattkauffman23  Â·  3Comments

blainekasten picture blainekasten  Â·  3Comments

thurt picture thurt  Â·  3Comments

aweary picture aweary  Â·  3Comments