How to test the HTML elements and their DOM properties with the Jasmine framework

When you test your JavaScript code you often want to test the user interactions with the UI of your web application and not just its logic. Testing the UI makes even more sense if you use a JS-framework which offers a list of UI controls.

Consider the following use-cases that could be unit tested:

  • The user loads a new webpage and the cursor has to be placed automatically inside the search input field.

  • The search input, together with other input elements, is placed inside a div with a red background.

For our tests we are going to use the Jasmine framework.

There are two ways to test the UI of your application when using test tools such as Jasmine. The key here is to remember that no UI interaction can be successfully tested if you do not attach the generated HTML code from the UI-framework to the browser. Doing this way you are assigning the HTML code into the DOM structure and you can interact with this code by writing new test cases.

  • You call the unit tests manually and you use the Jasmine test page. If that is the case, then you have to inject the HTML code into this page. The Jasmin test page

  • Rather than using the Jasmine test page you use a headless browser for running your tests on. I use the PhantomJS headless browser. By using this browser you can test a large amount of DOM properties or methods, but not all of them. If that’s the case then you should test your specs with the previous testing option.

Before we test the two example use cases that we defined before, let us write a tiny UI-framework for rendering HTML elements with JavaScript. The following code is the code to be tested. We create a module with two simple UI-controls that can be used to create either a new input element or a div:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  var UiFramework = (function() {
    function input(name, isAutoFocused) {
      var element = document.createElement("input");
      element.name = name;
      element.autofocus = isAutoFocused;
      return element;
    }

    function div(id, cssClass) {
      var element = document.createElement("div");
      element.id = id;
      element.classList.add(cssClass);
      return element;
    }

    return {
      input: input,
      div: div
    }
  })();

We now define the specs category and inside the beforeAll function we inject the generated HTML elements into the DOM of the Jasmine test page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  describe("Testing UI with jasmine", function() {
    beforeAll(function() {
      var body = document.getElementsByTagName("body")[0];
      var div = UiFramework.div("div1", "redBg");
      body.appendChild(div);
      div.appendChild(UiFramework.input("input1", false));
      div.appendChild(UiFramework.input("search", true));
      div.appendChild(UiFramework.input("input3", false));
    });
  
    it("focuses the search input field when the page loads", function() {
      expect(document.getElementsByTagName("input")[1].autofocus).toEqual(true);
    });

    it("checks for the background color of the div which contains the input elements", function() {
      expect(window.getComputedStyle(document.getElementById("div1")).backgroundColor).toEqual("rgb(255, 0, 0)");
    });

With the first spec we tested if the correct input field was focused and with the second we check if the background color of the div is red.

To summarize, testing JavaScript code which is responsible for rendering HTML code programmatically can be done by instantiating the controls in the test page. Another approach on testing the UI of your application are the coded UI tests which are supported from IDEs like Visual Studio.

comments powered by Disqus