There are countless reasons why AngularJS is so great to work with. One of them is that it was developed with the idea that testing is so important that it should be built into the framework. And one of the most popular tools to test AngularJS apps is Protractor. It was developed by a Google team and released in 2013 in open source.

The protractor is an E2E testing framework. It runs tests by sending requests to the Webdriver via Selenium Server. It interacts with the app from the end user’s perspective. Thanks to WebDriver we gain speed and stability in our tests by running them in the real web browsers.

E2E testing

End-to-end testing is a methodology used to test whether the flow of an application is performing as it was designed from the start to the finish. The purpose of carrying out end-to-end tests is to identify system dependencies and to ensure that the right information is passed between various system components and systems. End-to-end testing involves ensuring that the integrated components of an application work as it was expected. The entire application is tested in a real-world scenario such as communicating with the database, network, hardware and other applications.

Summon the Protractor

First things first. At the beginning, you have to prepare the right tools to work with.
First of all, check if you have NodeJS installed:

node --version

If not, then:

sudo apt-get install -y nodejs

Now use npm for Protractor to install it globally:

npm install -g protractor

Now install:

webdriver-manager

which gets an instance of Selenium Server running.
Then start it up:

webdriver-manager update webdriver-manager start

How to configure Protractor?

Protractor needs a configuration script that tells it how to work, how to connect to Selenium, how to do lots of stuff… The easiest way to create a configuration file for Protractor is to copy a reference configuration file from the installation directory.

./node_modules/protractor/example/chromeOnlyConf.js protractor_conf.js

To make Protractor run, we need to do some updates on this script.
First, We need to add a proper directory of ChromeDriver in ./node_modules.

chromeDriver: './node_modules/protractor/selenium/chromedriver'

Secondly, we need to show the specs array for local tests.

specs: ./src/apps/**/tests/**/*.spec.js'

In this configuration script, we can pass many more options and settings:

– set the method of running the tests:
* Standalone server

seleniumServerJar: './node_modules/protractor/selenium/selenium-server-standalone-2.45.0.jar',

* Separately running Selenium server

seleniumAddress: 'http://0.0.0.0:4444/wd/hub'

– set browser or a few browsers in which we want to run our tests
– set a proper framework to run

Write your first test

In a minute, you will write a test whose scenario can be described as follows:

Navigate to app.skillhunt.io website and check if a defined title exists.

Create a folder for tests. You need at least two files in this folder: conf.js and spec.js.

Here is where you will keep all the configuration for your e2e tests. There are tons of things to configure but remember to keep it simple.

After this preparation, create a second file spec.js. As you can see in conf.js we can use the Jasmine framework syntax. If you have ever used any unit testing tool like Jasmine, then it will feel like home.

A test starts with describe. A test is calling this Jasmine global function with two parameters. The first parameter is a string which describes the name of a test suite. The second parameter it is a Jasmine global function with a test spec. This function also takes two parameters. Likewise describe, the first parameter is a string with a name of a spec and the second parameter is a function. It contains a block of specific actions to be taken and expectation which is an assertion that returns true or false.
Remember that describe and it are the functions where Javascript scoping is applied. So whatever you declare in describe , it will be available in each it block inside a test suite.

The next thing to be explained is browser. This is a Protractor instance or – in other words – a global created by Protractor. It is used to take some browser actions like get, debugger, pause and many more.

Fire

protractor conf.js 

When you type the above code to your terminal, the test will be initiated. Remember to start the webdriver-manager first with:

webdriver-manager start

If you would like to observe the actions taken by Protractor and you are not a Formula 1 driver, you can slow down the tests. This is for your own purposes, so do not push the code to your repository until you get rid of this:

\

You need to place this piece of code before describe in your test suite. At the beginning, I was using it a lot just to have fun and observe. Later on, I started using browser.pause() and browser.debugger() to observe what is going on and debug my code as slowing down gives you no added value. But still, it’s fun.

Move on and have fun

Let’s create some more complicated test. Take such a scenario:

Navigate to app.skillhunt.io and navigate to sign up page

Now we will use another global Protractor variable which is element and by. The element function gives us the ability to find some elements in the DOM and manipulate them. by defines what kind of elements we are looking for: model, css, repeater and so on. We will also add beforeEach to perform some actions before every test.

In the future, try to avoid using xpath finders as they are the slowest ones. Try to use some more readable locators like:

var someElement = element(by.binding('user.name'));

It’s more readable and much faster.

Refactor

The tests look nice but it can be better. According to “best practices” you should always use Page Objects.

You can describe it as a design pattern to keep your test more readable, easier to maintain and to prevent code duplication.

You place them in a separate file, here: page.js. This is a file where you define element locators and write functions to perform some actions. Take a close look at the modified spec.js and newly created page.js file.

As you can see, this pattern nicely separates our concerns and indeed makes it much easier to understand.

For a bonus. There is a possibility to execute only one test suite or a single test case by adding “f” before them - fdescribe, fit. You can also exclude them by adding “x” before them - xdescribe, xit.

Why should you use Protractor?

Well, there are a few reasons. Here are some of them:

  • It gives you the ability to test both AngularJS and non-AngularJS sites.
  • It uses the same language, frameworks, and tools we use to write unit and e2e tests e.g. Jasmine, Karma.
  • It’s fast to write tests.
  • It’s easy to learn.
  • It gives you the ability to execute tests locally and remotely i.e. in Sauce Labs.
  • You can enforce PageObject pattern.
  • You don’t need to add waits or sleep to your test.

That’s all for now. I encourage you to dive deeper into Protractor because it gives tons of satisfaction. It is easy to learn and proper e2e tests give big value to your apps.