Protractor Tutorial
Protractor Tutorial
Protractor
Audience
This tutorial will be useful for graduates, post graduates, and research students who either
have an interest in this subject or have this subject as a part of their curriculum.
The tutorial suits the learning needs of both the beginners and experts in this subject.
Prerequisites
The reader must have basic knowledge about JavaScript and AngularJS. He/she should
also be aware about basic terminologies used in testing.
Else, we would suggest that the reader picks a tutorial on these concepts first before
starting the journey with Protractor.
All the content and graphics published in this e-book are the property of Tutorials Point (I)
Pvt. Ltd. The user of this e-book is prohibited to reuse, retain, copy, distribute or republish
any contents or a part of contents of this e-book in any manner without written consent
of the publisher.
We strive to update the contents of our website and tutorials as timely and as precisely as
possible, however, the contents may contain inaccuracies or errors. Tutorials Point (I) Pvt.
Ltd. provides no guarantee regarding the accuracy, timeliness or completeness of our
website or its contents including this tutorial. If you discover any errors on our website or
in this tutorial, please notify us at [email protected]
ii
Protractor
Table of Contents
About the Tutorial ........................................................................................................................................... ii
Audience.......................................................................................................................................................... ii
Prerequisites.................................................................................................................................................... ii
Table of Contents...............................................................................................................................................
1. PROTRACTOR – INTRODUCTION........................................................................................... 1
Origin ............................................................................................................................................................... 2
Advantages ...................................................................................................................................................... 4
Limitations ....................................................................................................................................................... 4
Karma .............................................................................................................................................................. 6
Jasmine ............................................................................................................................................................ 7
Mocha ............................................................................................................................................................. 8
QUnit ............................................................................................................................................................... 8
Selenium .......................................................................................................................................................... 9
Prerequisites.................................................................................................................................................. 10
i
Protractor
Elements API.................................................................................................................................................. 35
Locators(by) API............................................................................................................................................. 46
Introduction................................................................................................................................................... 55
Introduction................................................................................................................................................... 60
Project Structure............................................................................................................................................ 61
ii
1. Protractor – Introduction Protractor
This chapter gives you an introduction to Protractor, where you will learn about the origin
of this testing framework and why you have to choose this, working and limitations of this
tool.
What is Protractor?
Protractor is an open source end-to-end testing framework for Angular and AngularJS
applications. It was built by Google on the top of WebDriver. It also serves as a
replacement for the existing AngularJS E2E testing framework called “Angular Scenario
Runner”.
It also works as a solution integrator that combines powerful technologies such as NodeJS,
Selenium, Jasmine, WebDriver, Cucumber, Mocha etc. Along with testing of AngularJS
application, it also writes automated regression tests for normal web applications. It allows
us to test our application just like a real user because it runs the test using an actual
browser.
Node JS Jasmine
Protractor
WebDriver JS
Selenium
Browser
Angular App
1
Protractor
Origin
As said earlier, Protractor is a replacement for the existing AngularJS E2E testing
framework called “Angular Scenario Runner”. Basically, the origin of Protractor starts with
the end of Scenario Runner. A question that arises here is why do we need to build
Protractor? To understand this, we first need to check about its predecessor - Scenario
Runner.
Protractor’s Inception
Julie Ralph, the prime contributor to the development of Protractor, had the following
experience with Angular Scenario Runner on other project within Google. This further
became the motivation to build Protractor, specially to fill the gaps:
“We tried using Scenario Runner and we found that it really just couldn’t do the things
that we needed to test. We needed to test things like logging in. Your login page is not an
Angular page, and the Scenario Runner couldn’t deal with that. And it couldn’t deal with
things like popups and multiple windows, navigating the browser history, stuff like that.”
The biggest advantage to the Protractor was the maturity of Selenium project and it wraps
up its methods so that it can be easily used for Angular projects. The design of Protractor
is built in such a way that it tests all layers such that web UI, backend services, persistence
layer and so on of an application.
Why Protractor?
As we know that almost all the applications are using JavaScript for development. The task
of testers becomes difficult when JavaScript increases in size and becomes complex for
applications due to the increasing number of the applications itself. Most of the times it
becomes very difficult to capture the web elements in AngularJS applications, uses
extended HTML syntax to express web application components, by using JUnit or Selenium
WebDriver.
The question here is that why Selenium Web Driver is not able to find AngularJS web
elements? The reason is because AngularJS applications are having some extended HTML
attributes like ng-repeater, ng-controller and ng-model etc. which are not included in
Selenium locators.
Here, the importance of Protractor comes into existence because Protractor on the top of
Selenium can handle and control those extended HTML elements in AngularJS web
applications. That is why we can say that most of the frameworks focus on conducting unit
2
Protractor
tests for AngularJS applications, Protractor used to do testing of the actual functionality of
an application.
Working of Protractor
Protractor, the testing framework, works in conjunction with Selenium to provide an
automated test infrastructure for simulating a user’s interaction with an AngularJS
application that is running in browser or mobile device.
The working of Protractor can be understood with the help of following steps:
Step1: In the first step, we need to write the tests. It can be done with the help of Jasmine
or Mocha or Cucumber.
Step2: Now, we need to run the test which can be done with the help of Protractor. It is
also called test runner.
Step3: In this step, Selenium server will help to manage the browsers.
Step4: At last, the browser APIs are invoked with the help of Selenium WebDriver.
Test Scripts(Conf.js +
Spec.js)
Test Runner
Protract
or
Managing Browsers
Seleniu
m
Server
Browsers
Chrome, IE,
Mozilla,
Opera Safari
3
Protractor
Advantages
This open source end-to-end testing framework offers the following advantages:
Contains automatic waits which means we do not need to explicitly add waits and
sleeps to our test.
Limitations
This open source end-to-end testing framework possesses the following limitations:
Does not uncover any verticals in browser automation because it is a wrapper for
WebDriver JS.
Knowledge of JavaScript is essential for the user, because it is available only for
JavaScript.
4
2. Protractor – Concepts of JavaScript Testing Protractor
Since the knowledge of JavaScript is essential for working with Protractor, in this chapter,
let us understand the concepts of JavaScript testing in detail.
Due to the above reasons, it is always useful to have some tools that can automate these
tests and help programmers to get rid of these repetitive and boring steps. What should a
developer do to make the testing process automated?
Basically, a developer can implement the tool set in the CLI (Command Line Interpreter)
or in the development IDE (Integrated development environment). Then, these tests will
run continuously in a separate process even without the input from the developer.
Automated testing of JavaScript is also not new and lots of tools like Karma, Protractor,
CasperJS etc. have been developed.
Unit Testing
The testing is done on the smallest testable part of the program called unit. The unit is
basically tested in isolation without any kind of dependency of that unit on the other parts.
In case of JavaScript, the individual method or function having a specific behavior can be
a unit of code and these units of code must be tested in an isolated way.
One of the advantages of unit testing is that the testing of units can be done in any order
because the units are independent of each other. Another advantage of unit testing which
really counts is that it can run the test at any time as follows:
5
Protractor
For automated unit testing of JavaScript applications, we can choose from many testing
tools and frameworks such as Mocha, Jasmine and QUnit.
End-to-End Testing
It may be defined as the testing methodology used to test whether the flow of the
application from start to finish (from one end to another end) is working fine as per design.
End-to-end testing is also called function/flow testing. Unlike unit testing, end-to-end
testing tests how individual components work together as an application. This is the main
difference between unit testing and end-to-end testing.
For example, suppose if we have a registration module where the user needs to provide
some valid information to complete the registration then the E2E testing for that particular
module will follow following steps to complete the testing:
Now, it will get the DOM (Document object model) of the form’s elements.
Next, trigger the click event of the submit button for checking if it is working or
not.
Now, for validation purpose collect the value from the input fields.
Every step gives its own results which will be compared with the expected result set.
Now, the question that arises is, while this kind of E2E or functional testing can be
performed manually also, why we need automation for this? The main reason is that
automation will make this test process easy. Some of the available tools that can be easily
integrate with any application, for this purpose are Selenium, PhantomJS and Protractor.
Karma
Karma, created by Vojta Jina, is a test runner. Originally this project was called Testacular.
It is not a test framework, which means that it gives us the ability to easily and
automatically run JavaScript unit tests on real browsers. Karma was built for AngularJS
because before Karma there was no automated testing tool for web-based JavaScript
developers. On the other hand, with the automation provided by Karma, developers can
6
Protractor
run a simple single command and determine whether an entire test suite has passed or
failed.
The main disadvantage of using Karma is that it requires an additional tool to configure
and maintain.
If you are using Karma test runner with Jasmine, then less documentation is available for
finding information about setting up your CSS in the case of having multiple ids for one
element.
Jasmine
Jasmine, a behavior-driven development framework for testing JavaScript code, is
developed at Pivotal Labs. Before the active development of Jasmine framework, a similar
unit testing framework named JsUnit was also developed by Pivotal Labs, which has an
inbuilt test runner. The browsers tests can be run through Jasmine tests by including
SpecRunner.html file or by using it as a command line test runner also. It can be used
with or without Karma also.
Provides test spies, fakes and pass-through functionalities which assist with testing
as additional functions.
7
Protractor
The tests must be return by the user as they change because there is no file-
watching feature available in Jasmine while running test.
Mocha
Mocha, written for Node.js applications, is a testing framework but it also supports browser
testing. It is quite like Jasmine but the major difference between them is that Mocha needs
some plugin and library because it cannot run standalone as a test framework. On the
other hand, Jasmine is standalone. However, Mocha is more flexible to use than Jasmine.
QUnit
QUint, originally developed by John Resig in 2008 as part of jQuery, is a powerful yet easy-
to-use JavaScript unit test suite. It can be used to test any generic JavaScript code.
Although it focuses on testing JavaScript in the browser, yet it is very convenient to use
by the developer.
It was mainly developed for jQuery and hence not so good for use with other frameworks.
8
Protractor
Selenium
Selenium, originally developed by Jason Huggins in 2004 as an internal tool at
ThoughtWorks, is an open source testing automation tool. Selenium defines itself as
“Selenium automates browsers. That’s it!”. Automation of browsers means that the
developers can interact with the browsers very easily.
9
3. Protractor – Getting Started Protractor
In the previous chapters, we have learnt the basics of Protractor. In this chapter, let us
learn how to install and configure it.
Prerequisites
We need to satisfy the following prerequisites before installing Protractor on your
computer:
Node.js
Protractor is a Node.js module, hence the very important prerequisite is that we must have
Node.js installed on our computer. We are going to install Protractor package using npm
(a JavaScript package manager), that comes with Node.js.
Chrome
Google Chrome, a web browser built by Google, will be used to run end-to-end tests in
Protractor without the need for a Selenium server. You can download chrome by clicking
on the link: https://www.google.com/chrome/.
10
Protractor
Installing Protractor
After installing Node.js on our computer, we can install Protractor with the help of following
command:
Once protractor is successfully installed, we can check its version by writing protractor -
-version command in the command prompt as shown below:
webdriver-manager update
The above command will create a Selenium directory which contains the required Chrome
driver used in the project.
For this, first create a new file named testingconfig.js in the same directory i.e.
node_modules/Protractor/example.
Now, in the conf.js file, under the source file declaration parameter, write
testingconfig.js.
Next, save and close all the files and open command prompt. Run the conf.js file as
shown in the screenshot given below.
11
Protractor
The configuration and installation of Protractor is successful if you got the output as shown
below:
The above output shows that there is no specification because we provided the empty file
at source file declaration parameter in conf.js file. But from the above output, we can
see that both protractor and WebDriver are running successfully.
12
4. Protractor – Protractor and Selenium Server Protractor
Node.JS
WebDriver
Protractor
Selenium Server Browser Driver
WebDriverJS
AngularJS App
13
Protractor
In this section, let us discuss the communication between these three processes.
Selenium server can run locally on our machine as standalone Selenium Server (selenium-
server-standalone.jar) or it can run remotely via a service (Sauce Labs). In case of
standalone Selenium server, there would be an http communication between Node.js
and selenium server.
14
Protractor
The above concept about Selenium WebDriver processes and their communication can be
understood with the help of following diagram:
Test Scripts
The Server
The Browser
While working with Protractor, the very first process, that is test script is run using Node.js
but before performing any action on the browser it will send an extra command to make
it sure that the application being tested is stabilized.
15
Protractor
Kit). We must have JDK installed on our local machine. We can check it by running the
following command from command line:
java -version
Now, we have the option to install and start Selenium Server manually or from test script.
Step1: The first step is to install the Selenium server and ChromeDriver. It can be done
with the help of running following command:
webdriver-manager update
Step2: Next, we need to start the server. It can be done with the help of running following
command:
webdriver-manager start
Step3: At last we need to set seleniumAddress in config file to the address of the running
server. The default address would be http://localhost:4444/wd/hub.
Location of jar file: We need to set the location of jar file for standalone Selenium
server in config file by setting seleniumServerJar.
Specifying the port: We also need to specify the port to use to start the
standalone Selenium Server. It can be specified in config file by setting
seleniumPort. The default port is 4444.
Array of command line options: We also need to set the array of command line
options to pass to the server. It can be specified in config file by setting
seleniumArgs. If you need full list of array of commands, then start the server
with the -help flag.
16
Protractor
While working with Protractor we have the built-in support for the following services
hosting the server:
TestObject
For using TestObject as the remote Selenium Server, we need to set the testobjectUser,
the user name of our TestObject account and testobjectKey, the API key of our
TestObject account.
BrowserStack
For using BrowserStack as the remote Selenium Server, we need to set the
browserstackUser, the user name of our BrowserStack account and browserstackKey,
the API key of our BrowserStack account.
Sauce Labs
For using Sauce Labs as the remote Selenium Server, we need to set the sauceUser, the
user name of our Sauce Labs account and SauceKey, the API key of our Sauce Labs
account.
Kobiton
For using Kobiton as the remote Selenium Server we need to set the kobitonUser, the
user name of our Kobiton account and kobitonKey, the API key of our Kobiton account.
ChromeDriver
FirefoxDriver
SafariDriver
IEDriver
Appium-iOS/Safari
Appium-Android/Chrome
Selendroid
PhantomJS
For setting and configuring the browser, we need to move to config file of Protractor
because the browser setup is done within the capabilities object of config file.
17
Protractor
Setting up Chrome
For setting up the Chrome Browser, we need to set the capabilities object as follows:
capabilities: {
'browserName': 'chrome'
}
We can also add Chrome-Specific options which are nested in the chromeOptions and its
full list can be seen at
https://sites.google.com/a/chromium.org/chromedriver/capabilities.
For example, if you want to add FPS-counter in the upper right, then it can be done as
follows in the config file:
capabilities: {
'browserName': 'chrome',
'chromeOptions': {
'args': ['show-fps-counter=true']
}
},
Setting up Firefox
For setting up the Firefox browser, we need to set the capabilities object as follows:
capabilities: {
'browserName': 'firefox'
}
We can also add Firefox-Specific options which are nested in the moz:firefoxOptions
object and its full list can be seen at https://github.com/mozilla/geckodriver#firefox-
capabilities.
For example, if you want to run your test on Firefox in safe mode then it can be done as
follows in the config file:
capabilities: {
'browserName': 'firefox',
'moz:firefoxOptions': {
'args': ['—safe-mode']
}
},
18
Protractor
Setting up PhantonJS
Actually, PhantomJS is no longer supported because of its crashing issues. Instead of that
it is recommended to use headless Chrome or headless Firefox. They can be set up as
follows:
For setting up headless Chrome, we need to start Chrome with the –headless flag as
follows:
capabilities: {
'browserName': 'chrome',
'chromeOptions': {
'args': [“--headless”, “--disable-gpu”, “--window-size=800,600”]
}
},
For setting up headless Firefox, we need to start Firefox with the –headless flag as
follows:
capabilities: {
'browserName': 'firefox',
'moz:firefoxOptions': {
'args': [“--headless”]
}
},
multiCapabilities: [{
'browserName': 'chrome'
},{
'browserName': 'firefox'
}]
19
Protractor
Which Framework?
Two BDD (Behavior driven development) test frameworks, Jasmine and Mocha are
supported by Protractor. Both frameworks are based on JavaScript and Node.js. The
syntax, report and scaffolding, required for writing and managing the tests, are provided
by these frameworks.
Jasmine framework
It is the default test framework for Protractor. When you install Protractor, you will get
Jasmine 2.x version with it. We do not need to get it installed separately.
Mocha framework
Mocha is another JavaScript test framework basically running on Node.js. For using Mocha
as our test framework, we need to use the BDD (Behavior driven development) interface
and Chai assertions with Chai As Promised. The installation can be done with the help
of following commands:
As you can see, -g option is used while installing mocha, it is because we have installed
Protractor globally using the -g option. After installing it, we need to require and set up
Chai inside our test files. It can be done as follows:
expect(myElement.getText()).to.eventually.equal('some text');
Now, we need to set the framework property to mocha of config file by adding framework:
‘mocha’. The options like ‘reporter’ and ‘slow’ for mocha can be added in config file as
follows:
mochaOpts: {
reporter: "spec",
slow: 3000
}
20
Protractor
Cucumber Framework
For using Cucumber as our test framework, we need to integrate it with Protractor with
framework option custom. The installation can be done with the help of following
commands:
As you can see, -g option is used while installing Cucumber, it is because we have installed
Protractor globally i.e. with -g option. Next, we need to set the framework property to
custom of config file by adding framework: ‘custom’ and frameworkPath:
‘Protractor-cucumber-framework’ to the config file named cucumberConf.js.
The sample code shown below is a basic cucumberConf.js file which can be used to run
cucumber feature files with Protractor:
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
baseUrl: 'https://angularjs.org/',
capabilities: {
browserName:'Firefox'
},
framework: 'custom',
frameworkPath: require.resolve('protractor-cucumber-framework'),
specs: [
'./cucumber/*.feature'
],
21
Protractor
compiler: []
},
onPrepare: function () {
browser.manage().window().maximize();
}
};
22
5. Protractor – Writing the First Test Protractor
In this chapter, let us understand how to write the first test in Protractor.
For example, if we are using Jasmine framework, then the test code will be written by
using the syntax of Jasmine. This file will contain all the functional flows and assertions
of the test.
In simple words, we can say that this file contains the logic and locators to interact with
the application.
Example
The following is a simple script, TestSpecification.js, having the test case to navigate
to an URL and check for the page title:
//TestSpecification.js
describe('Protractor Demo', function() {
it('to check the page title', function() {
browser.ignoreSynchronization = true;
browser.get('https://www.tutorialspoint.com/tutorialslibrary.htm');
browser.driver.getTitle().then(function(pageTitle) {
expect(pageTitle).toEqual('Free Online Tutorials and Courses');
});
});
});
23
Protractor
Code Explanation
The code of above specification file can be explained as follows:
Browser
It is the global variable created by Protractor to handle all the browser level commands.
It is basically a wrapper around an instance of WebDriver. browser.get() is a simple
Selenium method that will tell Protractor to load a particular page.
describe and it: Both are the syntaxes of Jasmine test framework. The ’Describe’
is used to contain the end to end flow of our test case whereas ‘it’ contains some
of the test scenarios. We can have multiple ‘it’ blocks in our test case program.
Expect: It is an assertion where we are comparing the web page title with some
predefined data.
Configuration File
As the name suggests, this file provides explanations for all the Protractor configuration
options. It basically tells Protractor the following:
Example
The following is the simple script, config.js, having the test
// config.js
exports.config = {
directConnect: true,
24
Protractor
framework: 'jasmine',
Code Explanation
The code of above configuration file having three basic parameters, can be explained as
follows:
Capabilities Parameter
This parameter is used to specify the name of the browser. It can be seen in the following
code block of conf.js file:
exports.config = {
directConnect: true,
As seen above, the name of the browser given here is ‘chrome’ which is by default browser
for Protractor. We can also change the name of the browser.
Framework Parameter
This parameter is used to specify the name of the testing framework. It can be seen in the
following code block of config.js file:
exports.config = {
directConnect: true,
25
Protractor
exports.config = {
directConnect: true,
// Spec patterns are relative to the current working directory when
protractor is called.
specs: ['TsetSpecification.js'],
As seen above, the name of the source file declaration given here is
‘TestSpecification.js’. It is because, for this example we have created the specification
file with name TestSpecification.js.
Step2: Next, we need go to the directory where we have saved our files namely config.js
and TestSpecification.js.
Step3: Now, execute the config.js file by running the command Protrcator config.js.
The screen shot shown below will explain the above steps for executing the example:
It is seen in the screen shot that the test has been passed.
26
Protractor
Now, suppose if we are testing non-angular websites and not putting the
ignoreSynchronization tag to true then after executing the code we will get the error”
Angular could not be found on the page”.
Report Generation
Till now, we have discussed about the necessary files and their coding for running test
cases. Protractor is also able to generate the report for test cases. For this purpose, it
supports Jasmine. JunitXMLReporter can be used to generate test execution reports
automatically.
But before that, we need to install Jasmine reporter with the help of following command:
As you can see, -g option is used while installing Jasmine Reporters, it is because we have
installed Protractor globally, with -g option.
After successfully installing jasmine-reporters, we need to add the following code into our
previously used config.js file:
27
Protractor
filePrefix: 'guitest-xmloutput',
savePath: 'test/reports'
}));
},
};
28
Protractor
After running the above config file in the same way, we have run previously, it will generate
an XML file containing the report under the root directory in reports folder. If the test got
successful, the report will look like below:
But, if the test failed, the report will look as shown below:
29
6. Protractor – Core APIs Protractor
This chapter lets you understand various core APIs that are key to the functioning of
protractor.
Getting the DOM elements of the web page we are going to test.
Interacting with the DOM elements.
Assigning actions to them.
Sharing information to them.
Browser
It is a wrapper around an instance of WebDriver which is used to handle browser level
commands such as navigation, page-wide information etc. For example, the browser.get
method loads a page.
Element
It is used to search and interact with DOM element on the page we are testing. For this
purpose, it requires one parameter for locating the element.
Locators (by)
It is a collection of element locator strategies. The elements, for example, can be found
by CSS selector, by ID or by any other attribute they are bound to with ng-model.
Next, we are going to discuss in detail about these APIs and their functions.
30
Protractor
Browser API
As discussed above, it is a wrapper around an instance of WebDriver for handling browser
level commands. It performs various functions as follows:
browser.angularAppRoot
This function of Browser API sets the CSS selector for an element on which we are going
to find Angular. Usually, this function is in ‘body’, but in case if our ng-app, it is on a sub-
section of the page; it may be a sub-element also.
browser.waitForAngularEnabled
This function of Browser API can be set to true or false. As the name suggests, if this
function is set for false then Protractor will not wait for Angular $http and $timeout tasks
to complete before interacting with the browser. We can also read the current state without
changing it by calling waitForAngularEnabled() without passing a value.
browser.getProcessedConfig
With the help of this browser APIs function we can get the processed configuration object,
including specification & capabilities, that is currently being run.
browser.forkNewDriverInstance
As the name suggests this function will fork another instance of browser to be used in
interactive tests. It can be run with control flow enabled and disabled. Example is given
below for both the cases:
Example1
Example2
browser.restart
As the name suggests, it will restart the browser by closing browser instance and creating
new one. It can also run with control flow enabled and disabled. Example is given below
for both the cases:
31
Protractor
browser.get(‘page1’);
browser.restart();
browser.get(‘page2’);
await browser.get(‘page1’);
await browser.restart();
await browser.get(‘page2’);
browser.restartSync
It is similar to browser.restart() function. The only difference is that it returns the new
browser instance directly rather than returning a promise resolving to the new browser
instance. It can only run when the control flow is enabled.
browser.get(‘page1’);
browser.restartSync();
browser.get(‘page2’);
browser.useAllAngular2AppRoots
As the name suggests, it is compatible with Angular2 only. It will search through all the
angular apps available on the page while finding elements or waiting for stability.
browser.waitForAngular
This browser API function instructs the WebDriver to wait until Angular has finished
rendering and has no outstanding $http or $timeout calls before continuing.
browser.findElement
As the name suggests, this browser API function waits for Angular to finish rendering
before searching for element.
browser.isElementPresent
As the name suggests, this browser API function will test for the for the element to be
present on the page or not.
32
Protractor
browser.addMockModule
It will add a module to load before Angular every time Protractor.get method is called.
Example
browser.addMockModule('modName', function() {
angular.module('modName', []).value('foo', 'bar');
});
browser.clearMockModules
browser.removeMockModule
browser.getRegisteredMockModules
browser.get
We can use browser.get() to navigate the browser to a particular web address and load
the mock modules for that page before the Angular load.
Example
browser.get(url);
browser.get('http://localhost:3000'); // This will navigate to the
localhost:3000 and will load mock module if needed
browser.refresh
As the name suggests, this will reload the current page and loads mock modules before
Angular.
browser.navigate
As the name suggests, it is used to mix navigation methods back into the navigation object
so that they are invoked as before. Example: driver.navigate().refresh().
browser.setLocation
Example
browser.get('url/ABC');
browser.setLocation('DEF');
expect(browser.getCurrentUrl())
.toBe('url/DEF');
33
Protractor
browser.debugger
As the name suggests, this must be used with protractor debug. This function basically
adds a task to the control flow to pause the test and inject helper functions into the browser
so that debugging can be done in browser console.
browser.pause
It is used for debugging WebDriver tests. We can use browser.pause() in our test to
enter the protractor debugger from that point in the control flow.
Example
element(by.id('foo')).click();
browser.pause();
// Execution will stop before the next click action.
element(by.id('bar')).click();
browser.controlFlowEnabled
34
7. Protractor – Core APIs (Contd…) Protractor
Elements API
Element is one of the global functions exposed by protractor. This function takes a locator
and returns the following:
element.all(locator).clone
As the name suggests, this function will create a shallow copy of the array of the elements
i.e. ElementArrayFinder.
element.all(locator).all(locator)
Example
element.all(locator).all(locator)
elementArr.all(by.css(‘.childselector’));// it will return another
ElementFindArray as child element based on child locator.
element.all(locator).filter(filterFn)
As the name suggests, after applying filter function to each element within
ElementArrayFinder, it returns a new ElementArrayFinder with all elements that pass the
filter function. It is basically having two arguments, first is ElementFinder and second is
index. It can also be used in page objects.
35
Protractor
Example
View
<ul class="items">
<li class="one">First</li>
<li class="two">Second</li>
<li class="three">Third</li>
</ul>
Code
element.all(locator).get(index)
With the help of this, we can get an element within the ElementArrayFinder by index. Note
that the index starts at 0 and negative indices are wrapped.
Example
View
<ul class="items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
36
Protractor
element.all(locator).first()
As the name suggests, this will get the first element for ElementArrayFinder. It will not
retrieve the underlying element.
Example
View
<ul class="items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
element.all(locator).last()
As name suggest, this will get the last element for ElementArrayFinder. It will not retrieve
the underlying element.
Example
View
<ul class="items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
37
Protractor
element.all(locator).all(selector)
It is used to find an array of elements within a parent when calls to $$ may be chained.
Example
View
<div class="parent">
<ul>
<li class="one">First</li>
<li class="two">Second</li>
<li class="three">Third</li>
</ul>
</div>
Code
element.all(locator).count()
As the name suggests, this will count the number of elements represented by
ElementArrayFinder. It will not retrieve the underlying element.
Example
View
<ul class="items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
element.all(locator).isPresent()
It will match the elements with the finder. It can return true or false. True, if there are
any elements present that match the finder and False otherwise.
38
Protractor
Example
expect($('.item').isPresent()).toBeTruthy();
element.all(locator).locator
Example
element.all(locator).then(thenFunction)
Example
View
<ul class="items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
element.all(by.css('.items li')).then(function(arr) {
expect(arr.length).toEqual(3);
});
element.all(locator).each(eachFunction)
As the name suggests, it will call the input function on each ElementFinder represented by
the ElementArrayFinder.
Example
View
<ul class="items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
39
Protractor
Code
element.all(locator).map(mapFunction)
As name suggest, it will apply a map function on each element within the
ElementArrayFinder. It is having two arguments. First would be the ElementFinder and
second would be the index.
Example
View
<ul class="items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
40
Protractor
element.all(locator).reduce(reduceFn)
As the name suggests, it will apply a reduce function against an accumulator and every
element found using the locator. This function will reduce every element into a single
value.
Example
View
<ul class="items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
element.all(locator).evaluate
As the name suggests, it will evaluate the input whether it is in the scope of the current
underlying elements or not.
Example
View
<span class="foo">{{letiableInScope}}</span>
Code
element.all(locator).allowAnimations
As name suggest, it will determine whether the animation is allowed on the current
underlying elements or not.
Example
element(by.css('body')).allowAnimations(false);
41
Protractor
element(locator).clone
As the name suggests, this function will create a shallow copy of the ElementFinder.
element(locator).getWebElement()
It will return the WebElement represented by this ElementFinder and a WebDriver error
will be thrown if the element does not exist.
Example
View
<div class="parent">
some text
</div>
Code
element(locator).all(locator)
Example
View
<div class="parent">
<ul>
<li class="one">First</li>
<li class="two">Second</li>
<li class="three">Third</li>
</ul>
</div>
42
Protractor
Code
element(locator).element(locator)
Example
View
<div class="parent">
<div class="child">
Child text
<div>{{person.phone}}</div>
</div>
</div>
Code
element(locator).all(selector)
It will find an array of elements within a parent when calls to $$ may be chained.
Example
View
<div class="parent">
<ul>
<li class="one">First</li>
<li class="two">Second</li>
<li class="three">Third</li>
43
Protractor
</ul>
</div>
Code
element(locator).$(locator)
Example
View
<div class="parent">
<div class="child">
Child text
<div>{{person.phone}}</div>
</div>
</div>
Code
element(locator).isPresent()
Example
View
<span>{{person.name}}</span>
44
Protractor
Code
expect(element(by.binding('notPresent')).isPresent()).toBe(false); // will
check for the non-existence of element
element(locator).isElementPresent()
It is same as element(locator).isPresent(). The only difference is that it will check whether
the element identified by sublocator is present rather than the current element finder.
element.all(locator).evaluate
As the name suggests, it will evaluate the input whether it is on the scope of the current
underlying elements or not.
Example
View
<span id="foo">{{letiableInScope}}</span>
Code
element(locator).allowAnimations
As the name suggests, it will determine whether the animation is allowed on the current
underlying elements or not.
Example
element(by.css('body')).allowAnimations(false);
element(locator).equals
45
Protractor
Locators(by) API
It is basically a collection of element locator strategies that provides ways of finding
elements in Angular applications by binding, model etc.
by.addLocator(locatorName,fuctionOrScript)
It will add a locator to this instance of ProtrcatorBy which further can be used with
element(by.locatorName(args)).
Example
View
<button ng-click="doAddition()">Go!</button>
Code
by.binding
As the name suggests, it will find an element by text binding. A partial match will be done
so that any elements bound to the variables containing the input string will be returned.
Example
View
<span>{{person.name}}</span>
<span ng-bind="person.email"></span>
46
Protractor
Code
by.exactbinding
Example
View
Code
expect(element(by.exactBinding('person.name')).isPresent()).toBe(true);
expect(element(by.exactBinding('person-email')).isPresent()).toBe(true);
expect(element(by.exactBinding('person')).isPresent()).toBe(false);
expect(element(by.exactBinding('person_phone')).isPresent()).toBe(true);
expect(element(by.exactBinding('person_phone|uppercase')).isPresent()).toBe(tru
e);
expect(element(by.exactBinding('phone')).isPresent()).toBe(false);
by.model(modelName)
Example
View
Code
47
Protractor
by.buttonText
Example
View
<button>Save</button>
Code
element(by.buttonText('Save'));
by.partialButtonText
As the name suggests, it will find a button by partial text.
Example
View
<button>Save my file</button>
Code
element(by.partialButtonText('Save'));
by.repeater
Example
View
48
Protractor
Code
by.exactRepeater
Example
View
Code
expect(element(by.exactRepeater('person in
peopleWithRedHair')).isPresent())
.toBe(true);
expect(element(by.exactRepeater('person in
people')).isPresent()).toBe(false);
expect(element(by.exactRepeater('car in cars')).isPresent()).toBe(true);
by.cssContainingText
As name suggest, it will find the elements, containing exact string, by CSS
Example
View
<ul>
<li class="pet">Dog</li>
<li class="pet">Cat</li>
</ul>
Code
49
Protractor
by.options(optionsDescriptor)
Example
View
Code
by.deepCSS(selector)
As name suggest, it will find an element by CSS selector within the shadow DOM.
Example
View
<div>
<span id="outerspan">
<"shadow tree">
<span id="span1"></span>
<"shadow tree">
<span id="span2"></span>
</>
</>
</div>
Code
50
8. Protractor – Objects Protractor
UI Changes
The very common issues while working with UI testing is the changes happens in UI. For
example, it happens most of the time that buttons or textboxes etc. usually got change
and creates issues for UI testing.
element(by.model(‘event.name’)).sendKeys(‘An Event’);
element(by.model(‘event.name’)).sendKeys(‘Module 3’);
element(by.model(‘event.name’));
Tough maintenance
Due to the above challenges, it becomes headache for maintenance. It is because we have
to find all the instances, replace with the new name, selector & other code. We also need
to spend lots of time to keep tests in line with refactoring.
Broken tests
Another challenge in UI testing is the happening of lots of failures in tests.
51
Protractor
For writing the code with Page Objects, the first thing we need to do is to create a Page
Object. Hence, a Page Object for the above example could look like this:
this.get = function() {
browser.get('http://www.angularjs.org');
};
this.setName = function(name) {
nameInput.sendKeys(name);
};
52
Protractor
this.getGreetingText = function() {
return greeting.getText();
};
};
module.exports = new AngularHomepage();
Example
To understand this concept we are taking the above configuration file with page objects.
We need to modify the test script as follows:
angularHomepage.setName('Julie');
expect(angularHomepage.getGreetingText()).toEqual('Hello Julie!');
});
});
Here, note that the path to the page object will be relative to your specification.
On the same note, we can also separate our test suite into various test suites. The
configuration file then can be changed as follows:
exports.config = {
// The address of a running selenium server.
seleniumAddress: 'http://localhost:4444/wd/hub',
53
Protractor
suites: {
homepage: 'tests/e2e/homepage/**/*Spec.js',
search: ['tests/e2e/contact_search/**/*Spec.js',
'tests/e2e/venue_search/**/*Spec.js']
},
Now, we can easily switch between running one or the other suite of tests. The following
command will run only the homepage section of the test:
Similarly, we can run specific suites of tests with the command as follows:
54
9. Protractor – Debugging Protractor
Now that we have seen all the concepts of Protractor in the previous chapters, let us
understand the debugging concepts in detail in this chapter.
Introduction
End-to-end (e2e) tests are very difficult to debug because they depend on the whole
ecosystem of that application. We have seen that they depend upon various actions or
particularly we can say that on prior actions like login and sometimes they depend on the
permission. Another difficulty in debugging e2e tests is its dependency on WebDriver
because it acts differently with different operating systems and browsers. Finally,
debugging e2e tests also generates long error messages and makes it difficult to separate
browser related issues and test process errors.
Types of Failure
There can be various reasons for the failure of test suites and followings are some well-
known failure types:
WebDriver failure
When a command cannot be completed, an error is thrown by WebDriver. For example, a
browser cannot get the defined address, or an element is not found as expected.
55
Protractor
Expectation failure
One of the most common test failures that shows what a normal expectation failure looks
like.
Pause Method
Using the pause method to debug the test cases in Protractor is one of the easiest ways.
We can type the following command at the place we want to pause our test code:
browser.pause();
When the running codes hits the above command, it will pause the running program at
that point. After that we can give the following commands according to our preference:
Example
In this example, we are having the below specification file named example_debug.js,
protractor tries to identify an element with locator by.binding(‘mmmm’) but the
URL(http://angularjs.org) page has no element with specified locator.
56
Protractor
Now, for executing the above test we need to add browser.pause() code, where you want
to pause the test, in the above specification file. It will look as follows:
But before executing, we need to do some changes in the configuration file also. We are
doing the following changes in earlier used configuration file, named
example_configuration.js in previous chapter:
57
Protractor
defaultTimeoutInterval: 999999
},
onPrepare: function () {
browser.manage().window().maximize();
browser.manage().timeouts().implicitlyWait(5000);
}
};
protractor example_configuration.js
Debugger Method
Using the pause method to debug the test cases in Protractor is a bit advanced way. We
can type the following command at the place we want to break our test code:
browser.debugger();
It uses the node debugger to debug the test code. For running the above command, we
must type the following command in a separate command prompt which has opened from
the test project location:
In this method, we also need to type C in the terminal for continuing the test code. But
opposite to pause method, in this method it is to be typed for only one time.
Example
In this example, we are using the same specification file named example_debug.js, used
above. The only difference is that instead of browser.pause(), we need to use
browser.debugger() where we want to break the test code. It will look as follows:
58
Protractor
Now, run the protractor test with following debug command line option:
59
10. Protractor – Style Guide for Protractor Protractor
In this chapter, let us learn in detail about style guide for protractor.
Introduction
The style guide was created by two software engineers named, Carmen Popoviciu, front-
end engineer at ING and Andres Dominguez, software engineer at Google. Hence, this
style guide is also called Carmen Popoviciu and Google’s style guide for protractor.
This style guide can be divided into the following five keypoints:
Generic rules
Project Structure
Locator strategies
Page Objects
Test suites
Generic Rules
The following are some generic rules that must be taken care while using protractor for
testing:
60
Protractor
which they will be run by protractor is uncertain and moreover it is quite easy to run a test
in isolation.
Project Structure
Another important key point regarding the style guide of Protractor is the structure of your
project. The following is the recommendation about project structure:
|-- project-folder
|-- app
|-- css
|-- img
|-- partials
home.html
profile.html
contacts.html
|-- js
|-- controllers
|-- directives
|-- services
app.js
...
index.html
|-- test
|-- unit
|-- e2e
home-page.js
home-spec.js
profile-page.js
profile-spec.js
contacts-page.js
contacts-spec.js
61
Protractor
|-- project-folder
|-- app
|-- css
|-- img
|-- partials
home.html
profile.html
contacts.html
|-- js
|-- controllers
|-- directives
|-- services
app.js
...
index.html
|-- test
|-- unit
|-- e2e
|-- page-objects
home-page.js
profile-page.js
contacts-page.js
home-spec.js
profile-spec.js
contacts-spec.js
Locator Strategies
The following are some locator strategies that must be taken care while using protractor
for testing:
62
Protractor
Example
View
<ul class="red">
<li>{{color.name}}</li>
<li>{{color.shade}}</li>
<li>{{color.code}}</li>
</ul>
<div class="details">
<div class="personal">
<input ng-model="person.name">
</div>
</div>
When no Protractor locators are available, then it is recommended to prefer by.id and
by.css.
63
Protractor
Page Objects
As discussed earlier, page objects encapsulate information about the elements on our
application page and due to this help us write cleaner test cases. A very useful advantage
of page objects is that they can be reused across multiple tests and in case if the template
of our application has been changed, we only need to update the page object. Followings
are some recommendations for page objects that must be taken care while using
protractor for testing:
/** @constructor */
var UserPropertiesPage = function() {};
module.exports = UserPropertiesPage;
64
Protractor
Another reason is that the reader of the test should be able to understand the behavior of
the application by reading the test cases only.
65