Tuesday 26 December 2017

E2E tests using Cucumber and Protractor Framework



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


For generating HTML reports I will use “gulp-protractor-cucumber-html-report”.
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.



7 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. Learn power bi training from india's leading software training institute: Onlineitguru and get your dream job in your dream company. We provide Live Instructor-Led Online Classes with 100% job Assistance and 24 X 7 Online Support.
    power bi training | power bi online course
    Contact Information:
    USA: +1 7327039066
    INDIA: +91 8885448788 , 9550102466
    Email: info@onlineitguru.com

    ReplyDelete
  3. Very interesting… good job
    Contact us:
    Locksmith Melbourne,
    Melbourne, VIC-3000,
    Australia.
    Phone: 03 9464 1230
    eMail: info@locksmithmelbourne.net
    Web: https://locksmithmelbourne.net/
    Locksmith Melbourne
    https://www.thomastownlocksmiths.net.au/

    ReplyDelete
  4. Wow… Very informative
    Contact us:
    Locksmith Melbourne,
    Melbourne, VIC-3000,
    Australia.
    Phone: 03 9464 1230
    eMail: info@locksmithmelbourne.net
    Web: https://locksmithmelbourne.net/
    Cheap Locksmith Melbourne
    https://www.thomastownlocksmiths.net.au/

    ReplyDelete
  5. Wow….. this blog is very niceAwesome…. Your article gives very clear data
    Contact us:
    Locksmith Melbourne,
    Melbourne, VIC-3000,
    Australia.
    Phone: 03 9464 1230
    eMail: info@locksmithmelbourne.net
    Web: https://locksmithmelbourne.net/
    Locksmith Melbourne
    https://www.craigieburnlocksmiths.com.au/

    ReplyDelete
  6. Very nice… I really like your blog, useful info
    Contact us:
    Locksmith Melbourne,
    Melbourne, VIC-3000,
    Australia.
    Phone: 03 9464 1230
    eMail: info@locksmithmelbourne.net
    Web: https://locksmithmelbourne.net/
    Cheap Locksmith Melbourne
    https://www.craigieburnlocksmiths.com.au/

    ReplyDelete
  7. Very interesting… good job
    Contact us:
    Locksmith Melbourne,
    Melbourne, VIC-3000,
    Australia.
    Phone: 03 9464 1230
    eMail: info@locksmithmelbourne.net
    Web: https://locksmithmelbourne.net/
    Commercial Locksmith Melbourne
    https://www.kalkallolocksmiths.com.au/page/commercial-locksmith/

    ReplyDelete