Writing WebDriverJS tests with Mocha


Let’s test your understanding of writing WebDriverJS tests with Mocha.

Based on the following code, what do you think will happen?

var webdriver = require('selenium-webdriver');

describe('webdriverjs test', function() {
    before(function(done) {
        this.driver = new webdriver.Builder().forBrowser('firefox').build();
        done();
    });

    it('should go to Google', function(done) {
        this.driver.get('https://www.google.com');
        this.driver.getTitle().then(function(title) {
            require('assert').equal(title, 'Google');
            done();
        });
    });
});

With some confidence, you say, “The test will pass.”

However, when you run it, you get 1 failing test with the following message:

Error: timeout of 2000ms exceeded.
Ensure the done() callback is being called in this test.

Okay, so you think to yourself, “All that’s needed is to increase the timeout and the test will pass.”

You are right… but implementing that fix won’t solve the real problem; and hence, the flaky behavior will continue to occur as your test suite gets larger and more complex.

“So what should I do?”

You should stop using Mocha’s global methods (describe, before, it) and start using selenium-webdriver’s testing module.

This is the biggest gotcha when starting out with WebDriverJS and Mocha.

The testing module is essential because WebDriverJS is asynchronous and for the tests to work, a wrapper was provided for Mocha’s global functions.

(If you want a more in-depth explanation of how WebDriverJS works, you can watch this video.)

So let’s fix the code and do things the right way:

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

test.describe('webdriverjs test', function() {
    test.before(function(done) {
        this.driver = new webdriver.Builder().forBrowser('firefox').build();
        done();
    });

    test.it('should go to Google', function(done) {
        this.driver.get('https://www.google.com');
        this.driver.getTitle().then(function(title) {
            require('assert').equal(title, 'Google');
            done();
        });
    });
});

For the rest of the code and more examples, you can check out my repository of WebDriverJS recipes.