Sunday, September 11, 2011

Phantom Event Handlers in Chrome

‹prev | My Chain | next›

I have a bit of a mystery on my hands with my jasmine and Backbone.js tests. Try as I might, I am unable to get my Jasmine tests to fire click events. I can manually remove elements from a Backbone collection and see the desired effect on the page. But if I try to initiate a Javascript event to trigger the same thing... nothing.

I am going to give this another try tonight.

I put a debugger statement in the Backbone View event binding constructor, load the Jasmine test page and step through until I reach the event binding:
Right clicking on the value of this.el in the console and selecting "Reveal Element" in the context menu, I find that the element does have an event bound to it:
So the trouble is not that the event is not being assigned. Perhaps it is being un-bound?

I move the debugger to just before creation of my Backbone view object:
  Appointments.fetch({success: function(collection, response) {
      collection.each(function(appointment) {
        debugger;
        var view = new AppointmentView({model: appointment});
        view.render();
        Views.push(view);
      });
    }
  });
Hrm.. After stepping through that code, when I check out the view span, I see no event handlers:
Ah... of course not. The event handlers are placed on the <div> elements that Backbone views create:
Could that be my trouble from last night? The event handler was disappearing on me. Maybe I was simply confused about where the handler should be.

So I put the debugger statement back in my spec:
  it("removes appointments from UI when removed from the backend", function() {
    // Appointments.models[0].destroy();

    debugger;
    $('.delete', '#2011-09-15').click();

    server.respondWith('DELETE', '/appointments/42', '{"id":"42"}');
    server.respond();

    expect($('#2011-09-15')).not.toHaveText(/Funky/);
  });
Now, when I reveal that element from the JS console, I find that yes, the <div> does have an event listener:
But I am still unable to get click events to those handlers. Sending click event to child elements, or even directly to the <div> element itself does nothing.

In a fit of frustration, I try it in Firefox:
Bah! I hate to leave it at that, but what else can I do? The event handler is there as far as Chrome is concerned, but it refuses to fire. I can add other handlers in addition to the one that fails to fire and they work. I can even put live/delegated handlers in there and they fail to fire. But the actual code definitely works and the tests work under Mozilla. Looks like Firefox is going to be my testing browser of choice.


Day #131

No comments:

Post a Comment