E2E testing with Protractor & Cucumber Js

Datetime:2016-08-23 01:14:07          Topic: JavaScript           Share

Cucumber Java post can be foundhere.

Guest post by Ram Pasala

Cucumber framework is meant for BDD acceptance testing which are basically scenario validations of an application which helps programmers to test and what not to test in plain understandable language(Gherkin).

Scenario: GoogleProtractor
  Given I amongooglepage
  When I type "protractor"
  Then I clicksearchbutton
  Then I clearsearchtextbox"

Now let us see how the above scenario could be converted into plain Javascript code which are nothing but Step Definitions:

/*
* spec.js
*/
var SearchPage = require('../Pages/searchPage');
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
var expect = chai.expect;
 
var search = function () {
'use strict';
 var search = new searchPage(); 
  
 this.Given(/^I amongooglepage$/, function () {
        return expect(search.title()).to.eventually.equal('Google');
  });
 
this.When(/^I type "(.*?)"$/, function (text) {
        return search.searchTextBox(text);
    });
 
    this.Then(/^I clicksearchbutton$/, function () {
        return search.searchButton.click();
    });
 
this.Then(/^I clearsearchtextbox$/, function () {
        return search.searchTextBox.clear();
    }
};

Writing Step Definitions Efficiently:

1) Use Page Objects : It is the buzzword these days with test automation setup, Page Objects help you write cleaner tests by encapsulating information about the elements on your application page.

/*
* page.js
*/
 
var googleSearch = function () {
    "use strict";
    this.searchTextBox = $("input[name='q']");
    this.searchButton = $("button[name='btnG']");
};
module.exports = googleSearch;

2) DRY principle using “Hooks” : They reduce code repetition by allowing us to perform actions at various points in the cucumber test cycle. They are used to prepare and clean the environment “before” and “after” each scenario is executed.

/*
* hooks.js
*/
module.exports = function() {
 
//maximize browser and pass the url
this.before(function(scenario, callback) {
    browser.manage().window().maximize();
    browser.get(url);
    callback();
});
 
// Take screenshot if scenario fails
this.After(function (scenario, callback) {
    if (scenario.isFailed()) {
      browser.takeScreenshot().then(function (base64png) {
        var decodedImage = new Buffer(base64png, 'base64').toString('binary');
        scenario.attach(decodedImage, 'image/png');
        callback();
      }, function (err) {
        callback(err);
      });
    } else {
      callback();
    }
  });
}

3) Handling Promises : Since cucumber.js is written using node.js, the step definitions are asynchronous. Instead of traditional callbacks we can either return a promise or use the done callback in our step definitions. Otherwise cucumber doesn’t know when our asynchronous actions are complete.

In the above example of spec.js we made sure to return promises in each step definition

this.When(/^I type "(.*?)"$/, function (text) {
        return search.searchTextBox(text);
    });
 
    this.Then(/^I clicksearchbutton$/, function () {
        return search.searchButton.click();
    });

4) BDD Assertions with Chai-As-Promised: Unlike other popular frameworks like Jasmine which have assertions i.e.“expect” that can resolve promises internally, cucumberjs doesn’t have this capability. We have to rely on other libraries .“Chai-As-Promised” fits the bill.

We used the same in our spec.js file , “expect” is used to match a specific condition and “eventually” resolves the returned promise.

this.Given(/^I amongooglepage$/, function () {
    
        return expect(search.title()).to.eventually.equal('Google');
      
  });

5) Use Data Tables : This is one of the powerful features cucumber provides to interact with large data.

Scenario: Data Tables

Given I fill the customer details

| name | department |

| john | retail |

| mary | sales |

| ed | science |

this.Given(/^I fillthecustomerdetails$/, function (data, done) {
  console.log('table data: ', data.hashes());
  done();
}); 

Result : It gives an array of objects

tabledata: [ { name: ‘john’, department: ‘retail’ }, { name: ‘mary’, department: ‘sales’ },{ name: ‘ed’, department: ‘science’} ]

6) Organize Feature Files: We need to make sure that features are independent of each other. Scenarios have to be clubbed using tags and put in a common feature file, this way we can write cleaner step definitions and reduce code complexity.

Allure CI reporting Framework : It is a cool open source framework designed to create test execution reports which are crisp and clear.It can be integrated with many test automation frameworks.For detail instructions on how it works, please refer the Allure-CucumberJS official repo

How to setup Jenkins CI and Allure framework

Sample Allure report

Protractor is a powerful nodeJS program for testing end to end test scenarios of a web application and CucumberJS is a widely accepted BDD framework for acceptance testing, when combined together these two goliaths can change the way we see integration and acceptance testing. Allure test report generation framework is turning lot of heads lately, together these frameworks unleash a robust, scalable and reliable e2e testing framework, exciting times ahead for test automation !

Fork on gitHub protractor-cucumber-allure boilerplate





About List