Introduction:
Angular JS
is most popular framework used for developing single page web applications. Products
built with AngularJS include YouTube Video Manager, The Weather Channel site,
several Google products, and Tinder.
In this
tutorial, you will learn how to do end to end testing of Angular applications
using Protractor and Cucumber.
Protractor: Protractor is an end-to-end test framework
for AngularJS applications. Protractor runs tests against your application
running in a real browser, interacting with it as a user would.
Cucumber: Cucumber is testing framework based on
Behavior Driven Development (BDD) testing approach.
Cucumber
allows automation of functional validation in easily readable and
understandable format (like plain English) to Business Analysts, Developers,
Testers, etc.
Prerequisites –
1.
Node.js : Protractor is Node.js program. You need to install supported version of Node.js.
Compatibility Notes: Protractor 4
is compatible with nodejs v4 and newer. If you absolutely need to use nodejs at
0.12, use Protractor@2.
Protractor works with Angular versions greater than 1.0.6/1.1.4, and is
compatible with Angular 2 applications. Note that for Angular 2 apps, the
binding and model locators are not supported. We recommend using by.css.
Installation Steps:
Following
packages need to install before writing the tests for your application.
Install Protractor:
Command: $npm install protractor
--save --dev
Run this command to download protractor in your local node_modules and
add it into dev dependencies of your package file.
Install web driver manager:
Command: $webdriver-manager update
Protractor works with Selenium Web Driver. The webdriver-manager is a helper tool to easily get an instance of a
Selenium Server running.
Start Selenium Server
Command: $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
Install cucumber
Command :
$npm install cucumber --save
This will install cucumber framework locally
for your project.
Install Protractor-Cucumber
framework
Command : $npm install
protractor-cucumber-framework --save
This will
install protractor cucumber framework.
Protractor Configuration:
Now you need
to create a protractor configuration file for your application. This
configuration file will have test related settings.
Please
create a file with name protractor-conf.js. Copy the following contents into
your file
exports.config = {
seleniumAddress: 'http://127.0.0.1:4444/wd/hub',
framework: 'custom',
// path relative to the current config file
frameworkPath: require.resolve('protractor-cucumber-framework'),
capabilities: {
'browserName': 'chrome'
},
specs: [
'features/*.feature'
],
cucumberOpts: {
require: [ 'features/step_definations/*.js', 'features/support/*.js'],
format: 'json'
},
baseUrl: 'https://chormule.github.io/'
};
|
Now we will
understand the configuration details added in the configuration file.
seleniumAddress: You need to provide Selenium server address that you have
started using command “webdriver-manager start”
capabilities : If you are testing on
single browser, here you need to provide the browser on which you want to test
your application.
If you want
to run your tests on multiple browsers then you need to use
“multiiCapabilities” option as below. This will test all your tests on Chrome
and Firefox simultaneously.
multiCapabilities:
[{
browserName: 'firefox'
}, {
browserName: 'chrome'
}]
For more
details of the configuration options, please go through this link –
Getting Started with Cucumber Feature file:
Now you will
create a cucumber feature file for your application. In feature file you will add a feature. A
feature is a Use Case that describes a specific function of your application.
Please
create features directory the relative to the protractor configuration
location.
<IMG>
Now, inside
features directory, create a test.feature file. Copy the following contents to
the test feature file.
Feature: E2E test using Cucumber and
Protractor
I
want to test my AngularJS app using cucumber and protractor
Scenario: Successful addition of two
numbers
Given I am on Home Page of my application
When
I provides first input as "10"
And I provides second input as "20"
Then
I am able to see result is "30"
|
Getting started with Cucumber Step Definition file
Step
Definitions is where the automation code is written. The steps in the feature
file directly map to the step definitions.
Please
create a step definition file with name “testStepDef.js”. Please copy the
following content into your file –
module.exports = function() {
var chai = require('chai');
var chaiAsPromised =
require('chai-as-promised');
chai.use(chaiAsPromised);
var expect =
chai.expect;
this.Given('I am on Home
Page of my application', function (callback) {
browser.get('https://chormule.github.io/');
callback();
});
this.When(/^I provides first input as
"([^"]*)"$/, function (arg1, callback) {
element(by.model('ctrl.object1')).clear();
element(by.model('ctrl.object1')).sendKeys(arg1);
callback();
});
this.When(/^I provides
second input as "([^"]*)"$/, function (arg1, callback) {
element(by.model('ctrl.object2')).clear();
element(by.model('ctrl.object2')).sendKeys(arg1);
callback();
});
this.When(/^I clicks on
the "([^"]*)" button$/, function (arg1, callback) {
element(by.buttonText(arg1)).click();
callback();
});
this.Then(/^I am able to
see result as "([^"]*)"$/, function (arg1, callback) {
var result =
element(by.binding('ctrl.result'));
expect(result.getText()).to.eventually.equal(arg1)
callback();
});
};
|
Generate HTML reports for your tests
You need to
install Gulp and gulp-protractor-cucumber-html-report.
Now, you
need to create “gulpfile.js” at the base directory location of your project.
Copy the following content into your gulp file.
var gulp = require('gulp');
var protractorReport =
require('gulp-protractor-cucumber-html-report');
gulp.task('reports', function() {
gulp.src('reports/cucumber-test-results.json')
.pipe(protractorReport({
dest: 'reports/'
}))
});
|
I have
created a reports task in Gulp. For this task, I have provided
“cucumber-test-results.json” file as an input. This JSON file will generate once
we run our cucumber-protractor tests.
For
generating html report for your tests you need to add support hooks. You need
to add two support hook one is for Report Generation and other is for capturing
screenshot for the failed test.
1. Report Generation Hook:
Please
create a directory “support” inside your “features” directory. Inside, your
support directory, please create a file with name “reportHook.js”
var Cucumber = require('cucumber'),
fs = require('fs');
path = require('path');
var JsonFormatter = Cucumber.Listener.JsonFormatter();
var reportDirectory = 'reports/';
var reportFileName = 'cucumber-test-results.json';
var reportDirectoryPath = path.join(__dirname, '../../' +
reportDirectory);
var reportFilePath = path.join(reportDirectoryPath + reportFileName);
function mkdirp(path, root) {
var dirs = path.split('/'),
dir = dirs.shift(), root = (root || '') + dir + '/';
try {
fs.mkdirSync(root);
} catch (e) {
if(!fs.statSync(root).isDirectory()) throw new Error(e);
}
return !dirs.length ||
mkdirp(dirs.join('/'), root);
}
module.exports = function JsonOutputHook() {
JsonFormatter.log = function
(json) {
fs.open(reportFilePath,
'w+', function (err, fd) {
if (err) {
mkdirp(reportDirectoryPath);
fd = fs.openSync(reportFilePath, 'w+');
}
fs.writeSync(fd, json);
console.log('json file
location: ' + reportFilePath);
});
};
this.registerListener(JsonFormatter);
};
|
This hook
will log the JSON data for your tests. Your JSON file will be created under
“reports” directory inside your project base location.
2. Screenshot Hook:
You need to
create a file name with “screenshotHook.js”. Please copy the following content
into your file.
module.exports = function TakeScreenshot() {
this.After(function
(scenario, callback) {
if
(scenario.isFailed()) {
browser.takeScreenshot().then(function (png) {
var decodedImage = new Buffer(png.replace(/^data:image\/(png|gif|jpeg);base64,/,''),
'base64');
scenario.attach(decodedImage, 'image/png');
callback();
});
} else {
callback();
}
});
};
|
This hook
will capture a screenshot for your failed test.
Following
would be the support directory structure after adding the hooks –
<image>
Final Directory Structure:
After
completing the above steps your directory structure would be as below.
<img>
Finally running your tests and
generating awesome HTML report
Now you have
completed all the steps and just one step away to run your tests.
Running the tests:
In this step
you need to run following command.
Command: $protractor protractor-conf.js
After
executing this command, all of your step definitions will run and the tests
results will be generated at “result/cucumber-test-results.json”.
Generating the reports:
Execute the
following command.
Command: $gulp reports
This will
execute Gulp task that you have created in the earlier steps. It will parse the
JSON output generated after running your tests. The HTML report will be
generated at “reports/cucumber-test-results.html”.
Following is
the screenshot of generated HTML report –
<img>
Conclusion:
I have shown in this tutorial how to start
with writing automation tests using Protractor and Cucumber for your AngularJS
application. However, while writing tests for your application you need to
follow some best practices related to Cucumber and Protractor. I have created
GitHub repository for the reference you can download or clone it and explore
the project.
Also, I will
cover my next tutorial on Page object pattern which is most popular in Selenium
framework.