Protractor Testing Tutorial: A Helpful Intro to E2E Testing

Protractor is a test framework for web applications. Even though its primary use is for performing end-to-end testing in Angular…

Testim
By Testim,

Protractor is a test framework for web applications. Even though its primary use is for performing end-to-end testing in Angular and AngularJS applications, you can also use it for regular, non-Angular websites. Protractor testing interacts with your application just like a real user would because it runs tests using an actual web browser.

Today’s post is an introduction to both Protractor and the concept of end-to-end (E2E) testing. Here’s a summary of what we’ll cover today:

  • Protractor Fundamentals: definition, history and architecture
  • The relationship between Protractor and other tool, such as Jasmine and Selenium
  • Fundamentals of E2E testing for Angular apps
  • Motivations behind using Protractor: some pros and cons
  • A practical tutorial of Protractor for Angular

Let’s begin!

Requirements

Before getting started, let’s quickly cover the requirements you’ll need in order to follow along with the tutorial:

  • NodeJs. Since Protractor is a Node.js program, you’ll need the famous JavaScript run time installed.
  • An IDE or text editor. I suggest Visual Studio Code, but of course, feel free to use what you’re most comfortable with.
  • We assume you’re comfortable with the command line.
  • We also assume some familiarity with JavaScript and programming as a whole.

With that out of the way, let’s get started.

Let’s Get to Know Protractor

Before we get to the practical part of the part, we must make sure we’re on the same page when it comes to the concepts and tools we’ll be using. That’s why we’ll cover end-to-end testing, detailing what it is and its importance in a sound QA strategy. Before that, though, we’ll venture into Protractor itself. You’ll see a definition of the tool, followed by discovering when, why and by whom it was created. We then wrap-up this 101 section with a closer look at how Protractor works and how it relates to other testing tools in the frontend testing space.

A Quick Definition

Protractor is an open-source testing framework you can use to perform end-to-end testing on Angular apps. This framework acts like a combination of different solutions. It can integrate several pieces of technology, such as NodeJS, Jasmine, Selenium, Mocha, and many more. Besides end-to-end testing for Angular, it can also be used for creating regression tests for non-Angular web applications. Protractor tests an app just like a human user would because it uses an actual browser to run the tests.

protractor angular pull quote

A Quicker History

Since Protractor is first and foremost a test framework for testing Angular apps, you won’t be surprised to learn that it was also created by the Angular team. More specifically, Julie Ralph started Protractor in 2013, after having some difficulties with Scenario Runner, the test tool the Angular team used at the time.

Julie decided to start Protractor in order to test scenarios—such as dealing with popups or navigating the browser history—which Scenario Runner couldn’t handle that well.

How Protractor Works, In More Detail

To understand how Protractor works, it’s necessary to take a peek under the hood and understand what this tool actually is.

Protractor and Selenium

For starters, Protractor is a Node.js app. Under the hood, Protractor is a wrapper over Selenium WebDriver. More specifically, Protractor talks with WebDriverJS, which is the JavaScript binding for the Selenium WebDriver API. Since Protractor makes use of Selenium methods, using it allows you to create tests that interact with—or drive—a real browser. That way, you’ll have tests that interact with the most external layer of the application—its UI—but exercises all layers, down to the database and up again. That’s what this type of testing is called end-to-end testing: it starts at one end of the application (the UI) and works its way until the other end, exercising all layers in between. More on E2E testing in a minute, though. Now, let’s continue exploring the inner workings of Protractor.

Protractor and Jasmine

And what about Jasmine? How do Protractor and Jasmine relate? Jasmine is a popular testing framework for JavaScript. By default, Protractor uses Jasmine as its test interface. In other words, when you write tests in Protractor, you’ll be using Jasmine’s syntax to do so—unless you pick a different framework, such as Mocha or Cucumber.

Selenium Server and a Browser: The Final Ingredients of Protractor Architecture

The next essential piece of the Protractor puzzle is Selenium server. We need an instance of a Selenium server running in order to execute Protractor tests. It’s possible to bypass that need and drive the browser directly; we’ll show you how to perform the tests the two ways. Finally, since Protractor tests drive a browser, we need a browser to be driven. Though Protractor can work with a number of browsers, for this tutorial we’ll use Chrome.

In summary, these are the pieces involved in the Protractor architecture:

  • Protractor. The necessary binary will get installed when we install Protractor. This is a Node.js app.
  • WebDriverJS. Also a Node.js app, this is the binding for WebDriver in JavaScript.
  • Jasmine, or a different test framework, such as Mocha.
  • Selenium Server.
  • Chrome, or another one of the supported browsers.

The list above might look like it’s a lot. However, you’ll soon see that installing Protractor and getting it to work is much easier than it looks.

End to End Testing: What It Is and Why it Matters

End-to-end testing is a testing technique that exercises an application in its entirety, verifying whether its flow, from beginning to end, behaves as expected. Unlike, say, unit testing, which replaces external concerns—such as the database, network, or the file system—with fakes, E2E testing is supposed to test if the integrations with such systems work as they should.

Here lies the importance of E2E testing: it exercises the application in the closest possible way to how a real user experiences it.

What does end-to-end testing for Angular apps entail? Since Angular is a front-end framework, it usually works along with—and relies on—some sort of backend that’s responsible for all or at least some portion of the business logic. The backend also takes care of persisting data to and retrieving it from a persistence store—e.g. a database.

So, when doing E2E testing for Angular, one end is the front-end, the Angular app itself. The other end is typically a database. An end-to-end test in this scenario would interact with the application via its UI, exercise all of the subsequent layers, and finally verify whether data has persisted to its final destination.

Why Use Protractor?

JavaScript started as an amazingly simple scripting language, never meant to be used in complex applications. But today, JavaScript is undoubtedly a real language, and it sure is used in serious, complex applications. The complexity presented by modern web applications got to such a high degree that it’s currently unfeasible to test an application using only a manual approach. That’s why software organizations big and small, strive to adopt automated testing, and put it to work. This is true for every programming language, framework, and platform. Angular isn’t an exception; the apps you write using the framework also need to be tested.

Among all types of automated software testing, one that’s especially useful for web applications is end-to-end testing, since it’s closer to the real user experience than most other types of testing. Selenium WebDriver is a popular web browser automation tool that is often used for end-to-end testing. So, why not just use Selenium?

Protractor has a number of advantages over using pure Selenium. First, since it’s a Node app, Protractor benefits from the huge number of packages available through Node.

One of the biggest advantages of Protractor is automatic waiting. With Protractor, there’s no need to add sleeps and waits to your tests when you need to wait for elements on a page. Protractor executes the next step as soon as a page finishes its pending tasks. As a consequence, Protractor makes your tests quicker since it reduces sleep and wait times.

When it comes to testing Angular apps, Protractor naturally has advantages, since it was born in the Angular team. The maintenance of software tests can be a big problem for organizations trying to implement a solid QA strategy, and Protractor can help with that. For instance, when it comes to locating DOM elements, Protractor makes use of Angular-specific locators, which results in tests that are more stable than ones that use more fragile identifiers such as ids or names.

Protractor: The Good and the Bad

There is no such thing as a silver bullet in software development. This is true in all software engineering domains, and testing is certainly not an exception. In this section, we’ll briefly discuss some of the main pros and cons of Protractor for Angular and non-Angular apps.

Benefits

  • Realistic testing. End-to-end testing is very close to how a real user interacts with the application. It can provide feedback that no other type of software testing can.
  • Asynchronous testing. Protractor supports asynchronous execution of tests, making for quicker and more efficient testing.
  • Open-source. Protractor is an open-source tool. Interested users can see how the project evolves, and even happen with such development.
  • Well-suited for Angular. Though you can use Protractor to test non-Angular JavaScript apps, the tool obviously targets Angular apps. It can use strategies that result in more robust tests.
  • Easily installation and setup. Protractor is a Node.js app. As such, you can install it via npm and get it ready to use very quickly.

Disadvantages

  • Only works with JavaScript. Selenium WebDriver API has bindings for a number of languages, including Python, C#, and Java. Protractor is a JavaScript tool, which means you have to know the language in order to use it.
  • Doesn’t support codeless test automation. Protractor is a code-based testing tool, which means it doesn’t support scriptless or codeless test automation. That might be a big problem if you have testers, QA analysts, or other professionals who perform testing but don’t have coding skills.
  • Dependent on WebDriverJS. Since Protractor wraps around Selenium WebDriver, any bugs or unexpected behavior introduced in that tool will logically affect Protractor as well.

Installing Protractor

Protractor is installed via npm, which means you need to have Node.js installed. So start by installing Node.js if you don’t already have it.

After Node is successfully installed, you’ll be ready to use npm to install Protractor. Open your terminal and run the following command:

npm install -g protractor

As soon as the installation finishes, type the following command to verify Protractor’s version:

protractor --version

At the time of this writing, the latest major version is 7.0.0.

The installation command you’ve just run actually installs two executables. Besides protractor, it also installs webdriver-manager. This is an executable you use to start an instance of Selenium Server.

Start Testing With Protractor

The Configuration file does exactly what its name suggests: it configures Protractor. It teaches it where the test files are located, and which framework or web browser to use, among other things. If you don’t define a given configuration in the configuration file, then Protractor will use default values for it.

The Spec file, on the other hand, is the actual test file that will contain the assertions we want to verify.

Creating a Configuration File

Let’s write our first Protractor test case. We’re going to start with the configuration file. Open your favorite text editor, create a new file, and paste the following content on it:

exports.config = {
framework: 'jasmine',
capabilities: {
browserName: 'chrome',
},
specs: ['myFirstTestSpec.js']
};

Save the file with the name “conf.js.”

We’re now doing a quick overview of the file above, so you can understand every one of the parameters it contains. The first option is “framework,” with the value “jasmine.” Jasmine is a popular testing framework for JavaScript. Then we have the “capabilities” section. In it, we define the browser name. In our case, it’s Chrome. Finally, we’ve got to the “specs” section, where we indicate the path to the spec file, which we still haven’t taken care of. Let’s fix that.

Creating Our First Spec File

Again, create a blank text file using your favorite text editor. Then, paste the following content on it.

describe('Protractor Testing', function() {
it('to check the page title', function() {
browser.ignoreSynchronization = true;
browser.get('https://example.com/');
browser.driver.getTitle().then(function(pageTitle) {
expect(pageTitle).toEqual('Example Domain');
});
});
});

Save the file with the name “myFirstTestSpec.js.” Let’s now examine the content above, the same way we did with the configuration file.

As you may notice, there is this “browser” thing that keeps showing up. This is actually a global Protractor creates to handle browser-level commands. You’ll also see the words “describe” and “it” showing up. These belong to Jasmine’s syntax. “Describe” will contain the whole flow of your test, while “it” will contain a specific step or scenario.

We set “ignoreSynchronization” to true because the website our test is targeting isn’t an Angular application, but a regular website.

What remains of the test should be easy to follow; we use the “browser” global to hit the target URL and retrieve the value of its title. Finally, we have the assertion that verifies whether the obtained page title is equal to the expected one.

Running Our Test

Running a Protractor test is just a matter of executing a single command. Before we can do that, though, we must get a few things ready with our local Selenium server. Start by running the following command:

webdriver-manager update

This will download all of the necessary binaries we need to get the Selenium server up and running. The next step is simply starting the instance:

webdriver-manager start

You should see a message indicating that Selenium Server is running at port 4444:

Now we’re ready to run the test. Open a new terminal window and type the following command:

protractor conf.js

If everything goes well, that’s what will happen. A Chrome window will open, with the “example.com” website opened. In your terminal, you should see an output like in the following image:

As you can see, the output message reads: “1 spec, 0 failures” when you run the code. That means our code had 1 ‘it’ blocks, which executed with 0 failures.

Running the Test Directly

Do you remember I said it was possible to drive the browser directly, without having to execute Selenium server explicitly?

To do that, you’ll have to change your configuration file. Just add the following line to it:

directConnect: true

The complete file now should look like this:

exports.config = {
    directConnect: true,
    framework: 'jasmine',
    capabilities: {
        browserName: 'chrome',
    },
    specs: ['myFirstTestSpec.js']
};

Now you can execute the tests directly, without having to start the Selenium server at port 4444. Keep in mind that this only works for Chrome and Firefox, though.

Protractor Is Currently Deprecated

In April 2021 the Protractor team announced that there were plans to end Protractor development by the end of 2022.
Their reasoning is that the Angular team created Protractor at a time when web development and the JavaScript language in particular were very different. More specifically, Protractor was meant to solve many problems related to asynchronous and concurrent testing. But as time progressed, JavaScript itself evolved in ways that make it easier to deal with those demands, and Protractor no longer plays nicely with the current state of JavaScript.

As of now (November 2022) Protractor is effectively deprecated and will reach end-of-life by the summer of next year. As such, the Protractor team dissuades the adoption of the tool. Instead, new users are encouraged to experiment with other end-to-end testing tools, such as Cypress or Nightwatch.

Protractor: Part of the Journey Is Its Ending

Unit testing, despite its usefulness, is a form of automated testing that’s far away from representing a real usage scenario. As such, it might fail to detect issues that other types of testing can find. End-to-end testing is such a way of testing. By exercising the application in its entirety, E2E testing can detect problems that would pass unnoticed through other types of testing that only focus on specific layers of the application.

protractor angular pull quote

In today’s post, we’ve presented Protractor, a popular tool for performing E2E testing, on both Angular and “non-Angular” web applications. Despite being a great tool and quite revolutionary for its time, active development of Protractor is reaching an end. The JavaScript language and ecosystem have evolved quite a bit since 2013—it’s been almost a decade, after all!—and the problems that Protractor was created to solve aren’t so intractable as they used to be.

If you’re already a Protractor user, we suggest using the time you have until its end of life—about a year—to plan and execute your migration to an alternative tool. We suggest you take a look at Testim Automate, an AI-based test automation solution that supports both codeless and coded end-to-end tests, and is capable of generating robust test suites that learn with each execution.

This post was written by Carlos Schults. Carlos is a .NET software developer with experience in both desktop and web development, and he’s now trying his hand at mobile. He has a passion for writing clean and concise code, and he’s interested in practices that help you improve app health, such as code review, automated testing, and continuous build.