Protractor best HTML report…

We have seen how to create reports in our previous article, but that report used to break when we have test case names with a special character or long names.

So I came across a better report and let’s see how to implement it.

Note: Drawback of this report is that you cannot send it as an attachment as it is dependent on many files. It won’t work as standalone,

So you can use both this report and the old report together and use this one for debugging and the other one as a summary to send along with emails.

Install protractor-beautiful-reporter

npm install protractor-beautiful-reporter --save-dev

Add below code to OnPrepare of the config file:

framework: 'jasmine',
onPrepare: function(){
let HtmlReporter = require('protractor-beautiful-reporter');
jasmine.getEnv().addReporter(new HtmlReporter({
baseDirectory: 'reports_new',
screenshotsSubfolder: 'screenshotsOnFailure',
takeScreenShotsOnlyForFailedSpecs: true,
jsonsSubfolder: 'jsonFiles',
excludeSkippedSpecs: true,
preserveDirectory: false,
clientDefaults:{
showTotalDurationIn: "header",
totalDurationFormat: "h:m:s",
gatherBrowserLogs: true
},
}).getJasmine2Reporter());
}

Report:

Protractor-cucumber Framework

Install dependencies:

  • cucumber : npm install cucumber (If protractor was installed locally else use npm install -g cucumber). Both protractor and cucumber should be in same scope.
  • cucumber-html-reporter: npm install cucumber-html-reporter — save-dev
  • chai: npm install chai
  • protractor-cucumber-framework: npm install — save-dev protractor-cucumber-framework

My package.json:

you can directly use the package.json and install all dependencies by placing the file under your test project and just running

npm install

package.json:

{
"name": "Test",
"version": "1.0.0",
"description": "Test framework for project Test",
"main": "conf.js",
"keywords": [
"test"
],
"author": "Praveen David Mathew",
"license": "ISC",
"dependencies": {
"chai": "^4.2.0",
},
"devDependencies": {
"cucumber": "^6.0.5",
"cucumber-html-reporter": "^5.1.0",
"protractor-cucumber-framework": "^6.2.0"
}
}

Now create chai expect global keyword:

Protractor uses jasmine out of the box, so when you are using the custom framework the jasmine expect class won’t work.

You have to use another assertion class , we are using chai.

We can use chai expect class by importing it in each step definition

'use strict';
expect = require('chai').expect;

This would be hectic, so work around is to declare expect as global in a separate file.

My chaiAssertions.js:

'use strict';
// Configure chai
global.expect = require('chai').expect;

Create Hook.js:

Hooks are just another stepdefinition file you can name it anything you want. A hook is identified using the keyword After and Before

Here i created a Hook.js file to get screenshot if scenario fails:

hook.js:

var { After, Before } = require('cucumber');
// Asynchronous Promise
After(async function(scenario) {
if (scenario.result.status === 'failed') {
const screenShot = await browser.takeScreenshot();
this.attach(screenShot, "image/png");
}
});

So after each scenario , the code inside after get executed. Which will take screenshot of scenario.result.status is failed.

Now my conf.js

'use strict';
exports.config = {
directConnect: true,
//Running chrome 
Capabilities: { browserName: 'chrome'
},
//point spec to feature file , my feature file was under feature folder
specs: ['feature/*.feature'],
//set framework options
framework: 'custom',
frameworkPath: require.resolve('protractor-cucumber-framework'),
//just maximizing window before testing
onPrepare: function(){
browser.waitForAngularEnabled(true);
browser.driver.manage().window().maximize();
} ,
//Create html report 
onComplete: () => {
var reporter = require('cucumber-html-reporter');
var options = {
theme: 'bootstrap',
jsonFile: './results.json',
output: './results.html',
reportSuiteAsScenarios: true,
launchReport: true,
metadata: {
"App Version":"0.3.2",
"Test Environment": "STAGING",
"Browser": "Chrome 54.0.2840.98",
"Platform": "Windows 10",
"Parallel": "Scenarios",
"Executed": "Remote"
},
output: './report/cucumber_report.html',
};
reporter.generate(options);
},
//set cucumber options
cucumberOpts: {
require: ['./testsuites/*.js','./commons/chaiAssertions.js','./commons/hooks.js'],
strict: true,
format: [], //don't put 'Pretty' as it is depreciated
'dry-run': false,
compiler: [],
format: 'json:results.json', //make sure you are not using multi-capabilities
},
SELENIUM_PROMISE_MANAGER: false,
};

Here, i point to the feature file using the property specs: [‘feature/*.feature’],

and glues it to the step definition using cucumberopts> require:

There is no one to one mapping between feature and step definition, the framework automatically finds the step definition that contains the definition for the step from provided step definitions(.js files) in the require field.

Now write feature file:

test.feature

Feature: Google search
Scenario Outline: Log in with given API
Given I navigates to google
And searches for '
'
Then I should see ''
Examples:
|input|this|
|test|pass|
|test2|fail|

Now write step definition:

step.js:

var { Given } = require('cucumber');
Given('I navigates to google', async function () {
await browser.get('https://www.google.com/');
});
Given('searches for {string}', async function (searchValue) {
await element(by.css('input[role="combobox"]')).sendKeys(searchValue)
});
Given('I should see {string}', async function (expectedValue) {
expect(expectedValue).to.equal('pass')
});

so here we are using just Given as during runtime Given ,when then etc will be ignored and only the string after that will be considered

So, even if our feature file has And searches for ‘input’ , we can write step definition as Given(‘searches for {string}’.

Note that we are not using regular expressions to get parameters but the data type.

you might have seen in other tutorials , Given( /^searches for (\w+)$/ ). Its simpler to use the format i have used Given(‘searches for {string}’. Both the approaches works works fine.

Now run the scripts:

protractor conf.js

Report:

Report will be generated under report folder

Framework zip:

Just download and run npm install

To execute , run the command protractor conf.js

https://github.com/praveendvd/Protractor_cucumber_PoC.git

Debugging protractor scripts

Using VScode:

Click Debug>Add configuration:

This opens the launch.json, replace program and args with below values:

"program": "<your_path_to_protractor>\\npm\\node_modules\\protractor\\bin\\protractor",            
"args": ["${workspaceRoot}/confchrome.js"],

Now add break point:

You can add break point by clicking near to the line you want to inspect:

Now execute the debugger by pressing f5:

Using chrome inspect:

just add the keyword debugger to the tests which you want to inspect:

Run below command:

node --inspect-brk <full_Path>npm\node_modules\protractor\bin\protractor <filePath>/confchrome.js --params.url="https://sdsd"

Now open chrome and type chrome://inspect/#devices

Click inspect and click F8 and click run. The exection stops at ‘debugger’ line and now add manual break points ow goto the file using the tabs and add manual break points.