Fork me on GitHub

Kernow Soul

Ruby, Rails and JavaScript Consultant

Programatically Simulating JavaScript Events in a Test Environment

| Comments

Yesterday I was implementing a feature on tutorhub.com where I wanted to disable the sending of chat messages when the party you’re talking to goes offline. I ran into a problem while trying to write the tests for this feature and thought I’d share it in case someone else finds it useful.

When in a chat, messages are sent either using the send button or by pressing the enter key. Testing the correct behaviour on button press is straight forward. I’m using Jasmine and jsMocha for testing and jQuery for implementation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
beforeEach(function() {
  // code that disables the sending of messages here

  // setup UI.runner for mocking
  var mock = new Mock(UI.runner);

  // add an expectation that raise is never called
  UI.runner.expects('raise').passing('message_send', Match.an_object).never();
});

it("should not allow messages to be sent", function() {
  // add some text to the textarea
  $("#chat-form textarea").val("the text I want to send");

  // simulate the click event
  $("#send-button").click();
});

Our UI code raises events that our main application code listens to in order to send out the messages. Here I setup a mock in the before block saying the raise method should never be called with the ‘message_send’ parameter. Then in the test I insert some text into the text area and simulate a click event on the send button.

It became slightly more tricky when I came to test the enter key functionality, our implementation code looks something like this:

1
2
3
4
5
$("#chat-form textarea").unbind().keyup(function(e){
  if (e.which === 13) {
    // send message code here
  }
});

In order to programatically simulate a press of the enter key I needed to pass an event object containing a which value of 13. After a bit of hunting around I found the jQuery.Event object, that allows the creation of events which can then be fired. The test for disabling the enter key looked like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
beforeEach(function() {
  // code that disables the sending of messages here

  // setup UI.runner for mocking
  var mock = new Mock(UI.runner);

  // add an expectation that raise is never called
  UI.runner.expects('raise').passing('message_send', Match.an_object).never();
});

it("should not allow messages to be sent", function() {
  // add some text to the textarea
  $("#chat-form textarea").val("the text I want to send");

  // create a new keyup event
  var e = jQuery.Event("keyup");

  // set the key that was pressed to the enter key
  e.which = 13;

  // trigger the event on the textarea element
  $("#chat-form textarea").trigger(e);
});

Using this technique it should be possible to programatically simulate any key event in a test environment.

Comments