Cannot trigger event on element in js-fixture with Karma and Mocha

1.1k Views Asked by At

I am using js-fixture, Mocha, Chai, Sinon with Karma.

I am able to see the correct element in wrapper.

However when I trigger the click event my click event is never triggered.

I am assuming the event is never binding to the element.

Am I doing something wrong with the fixtures? Is there a better way to test jQuery events with mocha?

Test:

var thisFixture,
    wrapper;
describe("modal is removed when close button is clicked", function () {
    beforeEach(function () {
        fixtures.path = "/base/spec/javascripts/fixtures";
        fixtures.load('modal.html');
        thisFixture = $(fixtures.body());
        wrapper = $(thisFixture[0]);
    });
    it("should is removed from the dom", function () {
        debugger;

        h2uModal.bindEvents();
        var close = wrapper.find(".fa-times");
        expect(wrapper.size()).to.equal(1);
        close.trigger("click");
        expect(wrapper.size()).to.equal(0);
    });
    afterEach(function () {
        fixtures.cleanUp();
    });
});

Code under test:

var h2uModal = {
    bindEvents: function () {
        $("#modal .fa-times").click(function () {
            $(this).parents("#wrapper").remove();
        });
    }
};

Fixture:

<div id='wrapper'>
    <div id='modal'>
        <i class='fa-times'></i>
    </div>
</div>

Result:

Chrome 34.0.1847 (Mac OS X 10.9.2) modal is removed when close button is clicked should is removed from the dom FAILED
AssertionError: expected 1 to equal 0
1

There are 1 best solutions below

3
On

The problem I'm seeing is how you use jQuery. You initialized wrapper like this:

wrapper = $(thisFixture[0]);

Then you click your #fa-times element, which should remove the element that you grabbed in wrapper from the DOM. Before the click, you test for this:

expect(wrapper.size()).to.equal(1);

So far so good, but after the click which would remove it, you test for this:

expect(wrapper.size()).to.equal(0);

It can't work. This would work if removing an element from the DOM would somehow update the jQuery objects that contain it, but this is now how jQuery works. If I grab a dozen paragraph elements with:

var $foo = $('p');

and do $foo.remove(), the size of $foo will not change. The only difference between before and after is that the DOM elements that were selected by $foo were with a parent node before removal and are without parent node after removal.

So you could update your code to check that wrapper[0].parentNode is not null before the click and null after.

By the way, the size() method has been deprecated since jQuery 1.8, you should use wrapper.length if you want to test for its size (in some other test).