In my protractor project, i am trying to take an screenshot, and attach it to my html report. The process of taking screenshot is happening in an After hook, as below:

import {  Status,After, HookScenarioResult} from 'cucumber';
import {browser} from 'protractor';
import { async } from 'q';

After(async  (scenario:HookScenarioResult)=> {

        const screenshot = await browser.takeScreenshot();

But in the line this.attach(screenshot,"image/png");, it complains with:

TypeError: this.attach is not a function

What is the problem?


You don't need to handle it yourself in the code. There are external node packages to handle it beautifully.

You may use packages like protractor-html-reporter.

How to use

  • Using with protractor conf.js file

    //HTMLReport called once tests are finished

    onComplete: function() {
         var browserName, browserVersion;
         var capsPromise = browser.getCapabilities();
         capsPromise.then(function (caps) {
            browserName = caps.get('browserName');
            browserVersion = caps.get('version');
            var HTMLReport = require('protractor-html-reporter');
            testConfig = {
                reportTitle: 'Test Execution Report',
                outputPath: './',
                screenshotPath: './screenshots',
                testBrowser: browserName,
                browserVersion: browserVersion,
                modifiedSuiteName: false,
                screenshotsOnlyOnFailure: true
            new HTMLReport().from('xmlresults.xml', testConfig);
  • In order to obtain screenshots on failure you can use this piece of code (you have to put it in onPrepare). The directory with screenshots must be in the same location as html report file (e.g. html file is in report directory so screenshots files must be in directory /report/screenshots/).

var fs = require('fs-extra');
fs.emptyDir('screenshots/', function (err) {

jasmine.getEnv().addReporter({ specDone: function(result) { if (result.status == 'failed') { browser.getCapabilities().then(function (caps) { var browserName = caps.get('browserName'); browser.takeScreenshot().then(function (png) { var stream = fs.createWriteStream('screenshots/' + browserName + '-' + result.fullName+ '.png'); stream.write(new Buffer(png, 'base64')); stream.end(); }); }); } } });


Don't use arrow function, try using below, this worked for me:

After(async function (scenario){
    if(scenario.result.status=== Status.FAILED){
        const screenShotFail= await browser.takeScreenshot();
        this.attach(screenShotFail, "image/png");

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.