Application testing
Angular BDD E2E Testing Jasmine Protractor Selenium Typescript Visual Studio Code

End to End Testing of Angular Applications with Protractor

Welcome to today’s blog.

In today’s blog I will be showing how to set up and develop a basic end-to-end test on an Angular application.

The end-to-end tool I will be using to demonstrate the tests is Protractor.

What Protractor does is to take a set of defined tests, then execute them against the application interface. The execution of the tests is played back in the application within the browser interactively. The results are then collated and reported back.

In the first section, I will explain how to install Protractor and the Selenium test server.

Installation of Protractor and the Selenium Test Server

The Protractor test tool does not come with NPM or Angular by default. It is a Node.js application and will need to be installed either locally using NPM within your development environment or globally.

This is done as shown:

npm install -g protractor

After you have installed Protractor, the following two command line tools will be installed:

  • protractor
  • webdriver-manager

The tool which automates the execution of end-to-end tests on our browsers on our test server is called Selenium, and running it requires the installation of the Java SDK. Once this has been installed on the test server, the webdriver-manager tool can be configured with a selenium server URL to start the selenium server.

The default test framework used by Protractor is Jasmine (https://jasmine.github.io/), which is a BDD (Behaviour-Driven Development) test scripting tool used to test JavaScript.  You will not need to install Jasmine if you already have Angular CLI installed within your environment.

Before we can start running tests, we will need to have the Selenium server running. Do this by running the commands firstly to download the web driver binaries:

webdriver-manager update

In the next section, I will show to run the Selenium test server.

Running the Selenium Test Server

Before we can run Protractor, we will need to run the Selenium server.

The next command will run the Selenium server:

webdriver-manager start

When run, the server will run from port 4444.

The server state can be viewed from the URL:

http://localhost:4444/wd/hub/static/resource/hub.html

In the next section, I will show how to run the end-to-end tests with Protractor.

Running the End-to-End Tests with Protractor

To run protractor, we will require a spec.js file which includes the tests we can apply to the form we are testing.

Below is an example of a spec file that tests the form has a title:

describe('Protractor Test - Angular Record List Form', function() {
  it('should have a title', function() {
      browser.get('http://localhost:4200/books');
      expect(element(by.id('heading')).getText()).toEqual('Book List');
    });
  });

We will also require a config.js file to configure the following:

  • Jasmine BDD framework
  • Selenium server URL
  • Spec configuration file

For the Jasmine BDD framework, the spec file will be:

exports.config = {
    framework: 'jasmine',
    seleniumAddress: 'http://localhost:4444/wd/hub',
    specs: ['spec.js']
  }

This will install two command line tools, protractor and webdriver-manager. Try running protractor --version to make sure it’s working.

The webdriver-manager is a helper tool to easily get an instance of a Selenium Server running. Use it to download the necessary binaries with:

webdriver-manager update

Now start up a server with:

webdriver-manager start

This will start up a Selenium Server and will output a bunch of info logs. Your Protractor test will send requests to this server to control a local browser. Leave this server running throughout the tutorial. You can see information about the status of the server at http://localhost:4444/wd/hub.

Next is the fun part – running tests.

To run the protractor tests, use the command in the terminal:

protractor conf.js

If you get the following error in the Selenium server terminal:

[23:21:16] E/launcher - SessionNotCreatedError: session not created: This version of ChromeDriver only supports Chrome version 87
Current browser version is 86.0.4240.198 with binary path C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:53'
System info: host: 'DESKTOP-7OVVUG1', ip: '10.0.75.1', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '15.0.1'
Driver info: driver.version: unknown

Then the version of ChromeDriver is not matching the version of Chrome browser.

The command (from your browser navigator bar) will verify your Chrome browser version:

chrome://version

I see the version below:

Google Chrome	86.0.4240.198 (Official Build) (64-bit) (cohort: Stable)
Revision	d8a506935fc2273cfbac5e5b629d74917d9119c7-refs/branch-heads/4240@{#1431}
OS	Windows 10 OS Version 1909 (Build 18363.1198)

If your Chrome browser version is lower than the version of ChromeDriver stated when running the protractor tests, then check the settings in Chrome (this can be typed in the browser navigator bar):

chrome://settings/help

This will prompt you to upgrade to the latest Chrome version.

Once upgraded you will see the latest. It should now match the ChromeDriver version from the Selenium Driver:

Once Chrome has been upgraded, re-run the protractor tests.

You will notice the browser being automatically being opened by Selenium and the protractor script opening the form to be tested.

In the next section, I will show how to understand the outputs of the test results.

Understanding the End-To-End Test Results

You will see success and / or failure tests:

>protractor conf.js
[00:49:27] I/launcher - Running 1 instances of WebDriver
[00:49:27] I/hosted - Using the selenium server at http://localhost:4444/wd/hub
Started
F

Failures:
1) Protractor Test - Angular Record List Form should have a title
  Message:
    Expected 'List of Books' to equal 'Book List'.
  Stack:
    Error: Failed expectation

 In this case our heading did not match the expected value.

Looking at our component source:

export class BooksComponent {

    heading = "List of Books";
	…    
    constructor(private api: ApiService, private router: Router) {}

    ngOnInit() {
	…
    }

The heading should be “Book List”.

After amending the heading value, the expected heading should be correct.

The heading value has an id assigned to within the div is as shown:

<mat-card>
  <mat-card-content>
    <div id="heading"><b>{{heading}}</b></div>
    <div *ngIf="hasLoaded$ | async; else loading">
		…
    </div>
    <br />
    <ng-template #loading>
		…
    </ng-template>
  </mat-card-content>
  <mat-card-actions>
  </mat-card-actions>
</mat-card>

Save the change to the component source, then re-run the tests.

The test output displays:

>protractor conf.js
[01:08:32] I/launcher - Running 1 instances of WebDriver
[01:08:32] I/hosted - Using the selenium server at http://localhost:4444/wd/hub
Started
.

1 spec, 0 failures
Finished in 6.653 seconds

[01:08:43] I/launcher - 0 instance(s) of WebDriver still running
[01:08:43] I/launcher - chrome #01 passed

The test has now passed!

This is a basic example of end-to-end testing using protractor.

In the next post I will expand on the use of Protractor locators in identifying DOM elements and how they can be used to create more complex end-to-end test specifications.

That’s all for this post.

I hope you found this post useful and informative.

Social media & sharing icons powered by UltimatelySocial