enzymejs/chai-enzyme

assertion of style() for shallow()/render()

Opened this issue · 8 comments

I think there is bug (or perhaps a mis-documentation) of the style() assertion, namely that it only works if you mount() the component.

describe("Chai-enzyme style test", function() {

    it("should do style test on shallow component", function() {
        const component = (
                    <p style={{color:"red"}}>Hello, World</p>
        );
        const wrapper = shallow(component);
        expect(wrapper).to.have.style("color", "red");
    });

    it("should do style test on rendered component", function() {
        const component = (
            <p style={{color:"red"}}>Hello, World</p>
        );
        const wrapper = render(component);
        expect(wrapper).to.have.style("color", "red");
    });

    it("should do style test on mounted component", function() {
        const component = (
            <p style={{color:"red"}}>Hello, World</p>
        );
        const wrapper = mount(component);
        expect(wrapper).to.have.style("color", "red");
    });
});

Result is

Chai-enzyme style test
    ✖ should do style test on shallow component
    ✖ should do style test on rendered component
    ✔ should do style test on mounted component

Finished in 0.025 secs / 0.017 secs

SUMMARY:
✔ 1 test completed
✖ 2 tests failed

FAILED TESTS:
  Chai-enzyme style test
    ✖ should do style test on shallow component
      PhantomJS 2.1.1 (Mac OS X 0.0.0)
    Window is not a constructor (evaluating '(0, _cheerio2.default)(this.wrapper.html())')
    get@/Users/.../test.spec.js:38342:44 <- webpack:///~/chai-enzyme/build/ShallowTestWrapper.js:127:0
    style@/Users/.../test.spec.js:38276:19 <- webpack:///~/chai-enzyme/build/ShallowTestWrapper.js:61:0
    /Users/.../test.spec.js:37455:37 <- webpack:///~/chai-enzyme/build/assertions/generic.js:17:0
    /Users/...test.spec.js:37907:24 <- webpack:///~/chai-enzyme/build/ChaiWrapper.js:199:0
    /Users/.../test.spec.js:32360:31 <- webpack:///~/chai/lib/chai/utils/addMethod.js:41:0
    /Users/.../test.spec.js:78:50 <- webpack:///test.spec.js:16:38

    ✖ should do style test on rendered component
      PhantomJS 2.1.1 (Mac OS X 0.0.0)
    undefined is not a constructor (evaluating '_cheerio2.default.load(html)')
    render@/Users/.../test.spec.js:19762:33 <- webpack:///~/enzyme/build/index.js:61:0
    /Users/.../test.spec.js:88:43 <- webpack:///test.spec.js:25:31

Actually according to our passing test suit we have style support for each render method.

  #style
    ✓ (shallow): chains
    ✓ (mount): chains
    ✓ (render): chains
    (name)
      ✓ (shallow): passes when the actual matches the expected
      ✓ (mount): passes when the actual matches the expected
      ✓ (render): passes when the actual matches the expected
      ✓ (shallow): passes negated when the actual does not match the expected
      ✓ (mount): passes negated when the actual does not match the expected
      ✓ (render): passes negated when the actual does not match the expected
      ✓ (shallow): fails when the actual does not match the expected
      ✓ (mount): fails when the actual does not match the expected
      ✓ (render): fails when the actual does not match the expected
      ✓ (shallow): fails when the actual is undefined
      ✓ (mount): fails when the actual is undefined
      ✓ (render): fails when the actual is undefined
    (name, value)
      ✓ (shallow): passes when the actual matches the expected
      ✓ (mount): passes when the actual matches the expected
      ✓ (render): passes when the actual matches the expected
      ✓ (shallow): passes negated when the actual does not match the expected
      ✓ (mount): passes negated when the actual does not match the expected
      ✓ (render): passes negated when the actual does not match the expected
      ✓ (shallow): fails when the actual does not match the expected
      ✓ (mount): fails when the actual does not match the expected
      ✓ (render): fails when the actual does not match the expected

Will take a closer look at your example.

Running your tests on master I get these results:

  Chai-enzyme style test
    ✓ (shallow): should do style test on shallow component
    ✓ (mount): should do style test on shallow component
    ✓ (render): should do style test on shallow component
    ✓ (shallow): should do style test on rendered component
    ✓ (mount): should do style test on rendered component
    ✓ (render): should do style test on rendered component
    ✓ (shallow): should do style test on mounted component
    ✓ (mount): should do style test on mounted component
    ✓ (render): should do style test on mounted component

What versions of chai, chai-enzyme, enzyme & cheerio are you running?

Judging from your stacktrace, your issues may seem related to cheerio.

@ayrton I was running my tests with karma and PhantomJS. If I run these specific tests with jsdom, then all of the tests pass. Since I prefer to run all my tests with the same test runner, I want to stick with PhantomJS and karma if possible. So, I will dive further into this and let you know if anything pops. Maybe its not possible to use enzyme with PhantomJS?

@ItsCosmo which version of phantom? if 1.x, are you at least using es5-shim so that it has .bind etc? It might also be that phantom doesn't support strict mode, and cheerio might rely on that behavior.

@ayrton I modified my karma configuration, so that I am using jsdom now. I am using several of chai-enzyme assertions, but style() is only one hanging me up, even with jsdom. The error is different, though:

TypeError: (0 , _cheerio2.default) is not a function  (for shallow test)
TypeError: _cheerio2.default.load is not a function (for render test)

Its looking like karma may be the culprit. I am happy to provide my karma.config.js and a minimal test spec which exhibits the problem, and package.json if required.

To answer previous questions, I was using PhantomJS-prebuilt 2.1.4 and cheerio 0.20.0. Now, I am using jsdom 8.1.0. I have found another way to do coverage reports without using karma (my main reason for using it), but karma is still easier. style() works great without karma.

Were you using Webpack to do module bundling for karma, by any chance? I encountered essentially the same issue when using the checked assertion on a shallow render.

Enzyme's documentation suggests configuring Webpack to treat Cheerio as an external module, which was the root cause of my problem. I was able to get it working by resolving Cheerio properly using Webpack's JsonLoader.

If you're not using Webpack, I don't know what the problem is, sorry! But maybe someone else will come across this issue for the same reason I did.

@dpoindexter: Thanks for a very helpful response. This solved my issue. Specifically, I removed the line:
cheerio': 'window',

from externals configuration, and added the line:
{ test: /\.json$/, loader: "json"}

to the module.loaders configuration

It happened to me when I try to check the attribute src of an image tag. The solution provided by @dpoindexter and @ItsCosmo works like a charm.