WebDriverJS & Mocha Part 2: Hooks

I recently shared how to get started with WebDriverJS and Mocha.

This post continues on from there: I will share how to create hooks for our Mocha tests.

We start with where we left off: a single test written and running in Mocha:

var assert = require('assert');
var webdriver = require('selenium-webdriver');
var test = require('selenium-webdriver/testing');

const mochaTimeOut = 30000; //ms

test.describe('Ralph Says', function() {
    this.timeout(mochaTimeOut);
    test.it('shows a quote container', function() {
        var driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
        driver.get('http://ralphsays.github.io');
        driver.isElementPresent(webdriver.By.id('quote')).then(function(present) {
            assert.equal(present, true, "Quote container not displayed");
        });
        driver.quit();
    });
});

At this point, we would like to add an additional test to ensure that 0ur quote container displays some text (it’s random so we don’t want to assert specific text values).

We start by adding a new test similar to the first:

var assert = require('assert');
var webdriver = require('selenium-webdriver');
var test = require('selenium-webdriver/testing');

const mochaTimeOut = 30000; //ms

test.describe('Ralph Says', function() {
    this.timeout(mochaTimeOut);

    test.it('shows a quote container', function() {
        var driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
        driver.get('http://ralphsays.github.io');
        driver.isElementPresent(webdriver.By.id('quote')).then(function(present) {
            assert.equal(present, true, "Quote container not displayed");
        });
        driver.quit();
    });

    test.it('shows a non-empty quote', function() {
        var driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
        driver.get('http://ralphsays.github.io');
        driver.findElement(webdriver.By.id('quote')).getText().then(function(text) {
            assert.notEqual(text, '', 'Quote is empty');
        });
        driver.quit();
    });
});

This runs and passes first time.

Ralph Says
    ✓ shows a quote container (3276ms)
    ✓ shows a non-empty quote (2288ms)


  2 passing (6s)

But you should never trust a test you have first seen fail. So let’s make it fail.

We can temporarily change our assertion to ensure we’re getting the right thing.

assert.equal(text, '', 'Quote is empty');

When we run at we get:

AssertionError: Quote is empty
      + expected - actual

      -“He's gonna smell like hot dogs.”

Which gives us confidence we are testing the right thing so we can change it back to our original assertion.

But we have an issue with our code now: it opens two separate browsers, which will slow down our tests as we have more and more tests.

Let’s use a single browser. Fortunately Mocha provides  hooks that runs once before all tests, and once after all tests. We can use these hooks to create our browser.

var assert = require('assert');
var webdriver = require('selenium-webdriver');
var test = require('selenium-webdriver/testing');
var driver;

const mochaTimeOut = 30000; //ms

test.before(function() {
    this.timeout(mochaTimeOut);
    driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
});

test.describe('Ralph Says', function() {
    this.timeout(mochaTimeOut);

    test.it('shows a quote container', function() {
        driver.get('http://ralphsays.github.io');
        driver.isElementPresent(webdriver.By.id('quote')).then(function(present) {
            assert.equal(present, true, "Quote container not displayed");
        });
    });

    test.it('shows a non-empty quote', function() {
        driver.get('http://ralphsays.github.io');
        driver.findElement(webdriver.By.id('quote')).getText().then(function(text) {
            assert.notEqual(text, '', 'Quote is empty');
        });
    });
});

test.after(function() {
    driver.quit();
});

This runs a lot better now using a single browser. Although we’ve introduced a potential problem for our tests. Since they’re sharing a browser, sometimes browser cookies will cause problems across our different tests. I find it’s best to clear the browser cookies after each test run, that way we are cleaning up after ourselves!

We can easily do this using another hook.

var assert = require('assert');
var webdriver = require('selenium-webdriver');
var test = require('selenium-webdriver/testing');
var driver;

const mochaTimeOut = 30000; //ms

test.before(function() {
    this.timeout(mochaTimeOut);
    driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
});

test.describe('Ralph Says', function() {
    this.timeout(mochaTimeOut);

    test.it('shows a quote container', function() {
        driver.get('http://ralphsays.github.io');
        driver.isElementPresent(webdriver.By.id('quote')).then(function(present) {
            assert.equal(present, true, "Quote container not displayed");
        });
    });

    test.it('shows a non-empty quote', function() {
        driver.get('http://ralphsays.github.io');
        driver.findElement(webdriver.By.id('quote')).getText().then(function(text) {
            assert.notEqual(text, '', 'Quote is empty');
        });
    });
});

test.afterEach(function() {
    driver.manage().deleteAllCookies();
});

test.after(function() {
    driver.quit();
});

Now we look at our tests, we notice that information about our page, the URL and details of the elements are being duplicated across our tests. This isn’t ideal as this will lead to a maintenance burden. In my next blog post I will share how we move to page objects to model this information in a single place.

Author: Alister Scott

Alister is an Excellence Wrangler for Automattic.

3 thoughts on “WebDriverJS & Mocha Part 2: Hooks”

  1. Alister, thank you for the interesting post series regarding WebDriverJS & Mocha. I haven’t tried it myself, but definitely will.

    Just wondering, have you tried running these tests in parallel? I suppose that something like “test.beforeEach” should help in achieving this?

    Thank you in advance.

    Like

Comments are closed.