End to End Testing with AngularJS, Protractor, Grunt and Maven

I recently set up end to end (e2e) testing for an angular app we are developing. We had a couple of requirements and thought I should share this as it wasn’t completely straightforward

  1. We want to test using our current application container (Tomcat 7). As part of this, we have to deploy another war which contains the API’s the angular app uses.
  2. We want the tests to be standalone (i.e. portable) and not rely on a current tomcat install.

Use Maven3 to Build

The API is java based and we currently use Maven3 to build the deployable artifact, so it is a natural choice as our primary build tool. We are currently using grunt for building our app and running tests so we need to create a pom and trigger the grunt build:

This will build an artifact ROOT.war and it is packaging the dist directory which contains our built application, which we are already building with grunt.

We also want to run npm install to ensure our dependencies are correct. To do this, we will use the maven exec plugin.

We also want to clean the relevant directories before building, so we can use the maven clean plugin

This cleans out both the dist folder and the node_modules folder, ensuring we haven’t forgotten to save one of our npm dependencies at some point.

Next we build the app. We want to use maven exec for this as well, so add a new execution to the the plugin we used for npm install:

This occurs in the same phase, so ensure it happens after npm install by putting it second.

Now you should be building a deployable artifact called ROOT.war.

Installing and Using Protractor

Protractor is the new e2e testing framework for AngularJS, and is fairly new to the scene. Up until recently, Karma was used however the project recommends using this in preference if you are starting a new project.

Install protractor using npm

You should then be able to run protractor on the command line. You now need a config file. I personally keep it in the test/ directory.

e2e.conf.js

I am keeping my test files in test/e2e, and the path is relative to the config file.

Protractor needs selenium to run (as you may see in the config) so go ahead and install that as well. You may need to change the version of selenium. Also, I am testing against port 9090 so the standalone server doesn’t interfere with my local testing.

And chromedriver so we can test against chrome

Create a new test for your app (check out the documentation for more on this)

and we can now run protractor

which should start and execute.

 Integrate Protractor with Grunt

We want to create a new task to run independent of the main build as it will be executed after the war is packaged and the tomcat server starts.

Within grunt.initConfig() you need to inser the following:

I create two different profiles so I can run against my local dev server as it is much faster to run. You will want a separate config file for this, or you could pass through the port number through as a parameter.

Add the two tasks and now you can run either with the following:

Configure Standalone Tomcat 7 Instance

This script is designed to be portable, so Tomcat should be started prior to the integration tests. In your pom.xml run the tomcat7 maven plugin

The comments should guide you through here.

Integrate Protractor with Maven

Now for the final step, triggering the protractor build when you run your maven build during the integration-test phase. This is another job for the maven exec plugin:

That should be it!

Your protractor tests should run once tomcat starts and the server should shutdown afterwards.