How to test Angular apps with Protractor - Complete Guide For Beginners


The Angular & Protractor Tutorial For Beginners.

With plenty of examples to get you started. 👇

protractor

Want to skip the read and go straight to the examples? Click here.

Table of contents

What is Protractor? How does it work?

A couple quick facts about Protractor and how it works.

Protractor is an end-to-end test framework that was created specifically for Angular and AngularJS applications.

Protractor is a Node.js program built on top of Selenium, which is a browser automation framework.

Protractor runs tests against your application running in a real browser, interacting with it as a user would.

This means that Protractor opens your Angular application in a real browser (defaults to Chrome) and interacts like a user would.

Protractor tests consist of imitating user interactions like clicking on buttons and filling out input fields. Protractor can also check DOM elements to make sure that your Angular application is behaving like you expect it to behave.

In general testing terminology, Protractor is used to write system tests that test the entire performance and behavior of an application. But in the Angular world these are more commonly known as e2e tests.

So, how do we use Protractor to simulate a real user?

How do we use Protractor to test an Angular application?

Getting started

When you use the Angular CLI to create an Angular application it automatically configures and prepares Protractor for you.

Important Update: As of Angular 12 the Angular team has decided to deprecate Protractor. If you want to use Protractor with Angular 12 or newer than this article will explain how to set it up.

If you open the project in a code editor you will find a folder named e2e.

Inside the e2e folder are the configuration files for the Protractor testing framework. And inside this folder you'll find a folder called src that contains the actual tests.

To run the default Protractor tests all you have to do is type the following command.

ng e2e

And PRESTO!

You should see a browser launch, run the test and then print the results in the terminal. If the tests pass you'll see a green success message. Otherwise, a red error.

protractor%20test%20results

Angular and Protractor - How to write your first test

For the first test, we'll keep things super-duper simple.

We'll write a quick, short test with Protractor that verifies the title of our Angular application.

Open the e2e/src folder and create a new file called app-title.e2e-spec.ts.

Here's the code.

import { browser, logging } from 'protractor';

describe('Angular App', function() {
  it('should have a title of App Title', function() {
    browser.get(browser.baseUrl);  

    var expected = "App Title";
    var actual = browser.getTitle();          

    expect(actual).toEqual(expected);
  });

  afterEach(async () => {
    const logs = await browser.manage().logs().get(logging.Type.BROWSER);
    expect(logs).not.toContain(jasmine.objectContaining({
      level: logging.Level.SEVERE,
    } as logging.Entry));
  });

}); 

What did we just do? And how does this code work?

Inside the test it should have a title of App Title we began by telling Protractor to get the home page of our Angular application.

Then we got the title from the home page and compare it to the title we expect it to have to determine if our test failed or passed.

Tada! Tada!! Tada!!!

You've just written your first test using Protractor. 👏 👏 👏

If this is the first time you've ever written a test for an Angular application then I recommend you check out the Angular testing theory guide.

Angular Protractor test examples

Now that we've learned the basics of writing tests with Protractor you're probably wondering how to advance.

What are some more useful cases?

Get element by ID with Protractor

import { browser, by, element, logging } from 'protractor';

describe('Angular App', function() {

  it('get login form by id', async () => {
    browser.get(browser.baseUrl);    
    var loginForm = element(by.id("login-form"));
    expect(loginForm).toBeDefined();
  });
}); 

Using Protractor to check classes of an HTML element

import { browser, by, element, logging } from 'protractor';

describe('Angular App', function() {

  it('get classes for login button', async () => {
    browser.get(browser.baseUrl);

    var loginButton = element(by.css("button"));
    var actual = loginButton.getAttribute('class');
    var expected = "btn btn-primary btn-lg btn-block";

    expect(actual).toEqual(expected);
  });

  afterEach(async () => {
    const logs = await browser.manage().logs().get(logging.Type.BROWSER);
    expect(logs).not.toContain(jasmine.objectContaining({
      level: logging.Level.SEVERE,
    } as logging.Entry));
  });

}); 

Getting H1 text with Protractor

import { browser, by, element, logging } from 'protractor';

describe('Angular App', function() {

  it('get h1 login tag', async () => {
    browser.get(browser.baseUrl);

    var actual = await element(by.css("h1")).getText();
    var expected = "Loginn";

    expect(actual).toEqual(expected);
  });

  afterEach(async () => {
    const logs = await browser.manage().logs().get(logging.Type.BROWSER);
    expect(logs).not.toContain(jasmine.objectContaining({
      level: logging.Level.SEVERE,
    } as logging.Entry));
  });

}); 

How to click a button with Protractor

import { browser, by, element, logging } from 'protractor';

describe('Angular App', function() {

  it('click button', function() {
    browser.get(browser.baseUrl);  
    element(by.className("btn")).click();
  });
}); 

How to fill an input field with Protractor

import { browser, by, element, logging } from 'protractor';

describe('Angular App', function() {

  it('fill input field', async () => {
    browser.get(browser.baseUrl);

    var emailInput = element(by.id("email"));
    emailInput.sendKeys("email@email.com");
  });
}); 

Click on hyperlinks

import { browser, by, element, logging } from 'protractor';

describe('Angular App', function() {

  it('click on reset password', async () => {
    browser.get(browser.baseUrl);

    var resetPasswordLink = element(by.css("a"));
    resetPasswordLink.click();

    let expected = "http://localhost:4200/login/reset-password";
    let actual = browser.getCurrentUrl();

    expect(actual).toEqual(expected);

  });
}); 

And that, my friend, is how you use Protractor to test your Angular application and make sure the bugs get caught and squashed.

What next?

Protractor is a great tool for testing Angular applications.

But keep in mind that e2e tests are limited. And when done wrong they're extremely brittle.

That's why I prefer to depend on unit tests for things like components instead of e2e tests.

Questions? Comments? Don't hesitate to reach out.

signature

Angular Consultant