Performing a REST call from Protractor e2e tests

Posted by Gjermund Bjaanes on September 6, 2015

I am currently trying to get some good end-to-end (e2e with protractor,  which is a great tool!) tests running for my Angular app ‘Extreme Results’.

I very quickly found a big problem. How do I clean up my database between tests and test-runs?

The way I see it, there are two ways to solve this problem:

1: Let the e2e tests actually clean up the way a user would.

In other words, clicking around and deleting thing “manually” with tests. Every test needs to manually clean up after themselves. This actually works pretty well. It makes for a well tested application, but errors propagate quickly through every test.

2: Calling the backend directly through REST between each test (or possibly between test “files”).

This way, you can rely on tests being clean when you start with a new one. Feels a bit safer and cleaner (and less error-prone).

 

In my case, I was in no shape to even allow the user to delete stuff manually (not yet implemented in the app), so it made more sense to delete stuff through a REST call (also less work).

I use Parse as my back-end, so I created a Cloud Code function (which is just a REST call that fires some server-side code) that clears my entire database. Extremely dangerous code in other words. Do not deploy such code in production please!

If you want to see the Cloud Code, take a look on Github:

https://github.com/bjaanes/ExtremeResults-CloudCode/commit/e7452fce6701875fddfc5271d9083c31cc38e7fb

 

Performing a REST call from your protractor tests

I created a common module that I can use from every test class. It looks like this:

var http = require('https');

var Common = function () {

    this.clearDB = function () {
        var deferred = protractor.promise.defer();

        var options = {
            hostname: 'api.parse.com',
            path: '/1/functions/clearDB',
            method: 'POST',
            headers: {
                'X-Parse-Application-Id': 'PARSE-APPLICATION-ID',
                'X-Parse-REST-API-Key': 'PARSE-REST-API-KEY'
            }
        };

        var callback = function() {
            deferred.fulfill();
        };

        var req = http.request(options, callback);
        req.end();

        return deferred.promise;
    };

};

module.exports = Common;

It uses a node package called https.

I set up some options like host, path, method and headers.

And then I just perform the call with http.request() and req.end(). Simple and nice.

They way I actually use this is even simpler:

var OverviewPage = require('./overview.po.js');
var Common = require('../common/common.js');

describe('Overview Page', function () {

    var overviewPage = new OverviewPage();
    var common = new Common();

    beforeAll(function () {
       common.clearDB();
    });

    // Tests...

});

The important bits are:

var Common = require('../common/common.js');
var common = new Common();

Which both set up the required ‘common’ module.

But the real code is:

beforeAll(function () {
       common.clearDB();
 });

Which actually performs the database clear between every tests. Nice!


Follow me on Twitter: @gjermundbjaanes