Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

How to take screen shot of the application whenever expect fails #114

Closed
vishalshivnath opened this issue Sep 26, 2013 · 20 comments
Closed
Milestone

Comments

@vishalshivnath
Copy link

Is there any wait to capture screen shot of the application whenever expect fails. Idea it to capture all points of failure. Selenium driver supports some feature like this.Is there any kind of switch in protractor also .

@vishalshivnath
Copy link
Author

I have defined a custom expect function in jasmine.js file and called the same function in my protractor test case file. In this jasmine function I am throwing exception but it not getting caught in try catch block in the protractor test case file. Not sure whats going on here.Does the expect function called in separate thread.

Here is what i am doing.
try{
expect(greeting.getText()).toEqualWithException('Review');
console.log("Console after exception ");
}
catch(e)
{
console.log("Console inside exception")
console.log(e.name+" "+e.message);
ptor.sleep(5000);
ptor.takeScreenshot().then(function(data) {
writeScreenshot(data, 'exception.png');
});
}

@juliemr
Copy link
Member

juliemr commented Nov 22, 2013

This doesn't quite do what you want, because it screenshots on each failing test instead of each failing expectation. However, this could be added to your test file easily.

Jasmine currently provides no way to hook in to do something on each expectation. You could also write a custom matcher which takes a screenshot on failure - e.g. expect(foo).toBeTruthyOrScreenshot().

I'm going to hold off on trying to add anything to each expect until after Jasmine 2.0 comes out, which should be quite soon. So, I'm moving this issue to a later milestone.

// Take a screenshot automatically after each failing test.
afterEach(function() {
  var passed = jasmine.getEnv().currentSpec.results().passed();
  if (!passed) {
    browser.takeScreenshot().then(function(png) {
      // Do something with the png...
    };
  }
});

@gsastry
Copy link

gsastry commented Dec 11, 2013

Hi Julie, Is there a way to add this to the conf file so I don't have to add it to every test file? similar to onPrepare

thanks

@eitanp461
Copy link

@gsastry you can add it to every test by adding a generic "spec-helper.js" file and add the afterEach function there, outside the context of a specific describe block. Then have your conf file load the spec helper into the browser together with the specs.
With this Jasmine will execute your afterEach function for all of your specs, regardless of their suite.
HTH

@hanssgo
Copy link

hanssgo commented Dec 11, 2013

@eitanp461 How do I have the conf file load the helper file together with the spec?

@hanssgo
Copy link

hanssgo commented Dec 11, 2013

Ah got it. Just add it to the list of files in the specs. =)

@mcalthrop
Copy link
Contributor

You might be interested in this code when it comes to creating the file from the string that takeScreenshot() produces:
#224 (comment)

@johannesjo
Copy link

@mcalthrop me too. I suppose you just have to base64decode the string you get and save it wie nodes fs.
e.g.:

fs = require('fs');

.....
afterEach(function ()
    {
        var passed = jasmine.getEnv().currentSpec.results().passed();
        if (!passed) {
            browser.takeScreenshot().then(function (png)
            {
                png = Base64.decode(png)
                fs.writeFile('screenshot.png', png, 'binary', function (err)
                {
                    if (err) throw err
                    console.log('File saved.')
                })
            });
        }
    });

Doesn't work for me though.

@mcalthrop
Copy link
Contributor

Here's the exact code I am using:

var fs = require('fs');

Utils = {

    /**
     * @name screenShotDirectory
     * @description The directory where screenshots will be created
     * @type {String}
     */
    screenShotDirectory: 'test/results/',

    /**
     * @name writeScreenShot
     * @description Write a screenshot string to file.
     * @param {String} data The base64-encoded string to write to file
     * @param {String} filename The name of the file to create (do not specify directory)
     */
    writeScreenShot: function (data, filename) {
        var stream = fs.createWriteStream(this.screenShotDirectory + filename);

        stream.write(new Buffer(data, 'base64'));
        stream.end();
    }

};

/**
 * Automatically store a screenshot for each test.
 */
afterEach(function () {
    var currentSpec = jasmine.getEnv().currentSpec,
        passed = currentSpec.results().passed();

    browser.takeScreenshot().then(function (png) {
        browser.getCapabilities().then(function (capabilities) {
            var browserName = capabilities.caps_.browserName,
                passFail = (passed) ? 'pass' : 'FAIL',
                filename = browserName + ' ' + passFail + ' - ' + currentSpec.description + '.png';

            Utils.writeScreenShot(png, filename);
        });
    });
});

You don't actually need the getCapabilities() section, but I'm using it to insert the browser name into the filename of the screen grab.

You can also see that the screen grab file name contains the name of the specific test.

HTH!

Matt

@swissmanu
Copy link

based on @mcalthrop initial afterEach idea, i've implemented an easy pluggable reporter to take screenshots with protractor automatically:
https://github.com/swissmanu/protractor-screenshot-reporter

@mcalthrop
Copy link
Contributor

Excellent! Thanks @swissmanu .

@juliemr
Copy link
Member

juliemr commented Apr 4, 2014

I think this is now just a documentation issue, so switching the labels.

@juliemr
Copy link
Member

juliemr commented Apr 15, 2014

Documented with fca9c5f

@abhishekswain
Copy link

I have written a Protractor plug in , that takes screenshot for every 'expect' failure and spec failure as well. Screenshot names are meaningful too.
Here is the npm module:
https://www.npmjs.com/package/jasmine2-protractor-utils

Note: It is compatible with Jasmine2 only.

@sjelin
Copy link
Contributor

sjelin commented Dec 8, 2015

@abhishekswain You want me to add your plugin to the community plugins list?

@abhishekswain
Copy link

@sjelin Yes please , if it is possible. :)
Somehow I missed your mention here and it got skipped for a long time now.

@bhantol
Copy link

bhantol commented Oct 14, 2016

Any way to take screenshot of the screen while (and including) Javascript alert open captured ?

@azachar
Copy link

azachar commented Oct 15, 2016

Hi there!

I have forked and improved @abhishekswain tool.

Now the brand new fork called protractor-screenshoter-plugin captures for each browser instance a screenshot and console logs. The snapshot is made optionally for each expect or spec. It comes with a beautiful angular and bootstrap based analytics tool to visually check and fix tests results.

Check it out at https://github.com/azachar/protractor-screenshoter-plugin.

Also, I created a list of all available alternatives, so if you find something else, please do not hesitate to add it there.

@Sereda-Fazen
Copy link

Sereda-Fazen commented Feb 19, 2018

Hi all! Could you help me to investigate jasmine-allure for fails screens?
I got next

 jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));	
    var AllureReporter = require('jasmine-allure-reporter');
    jasmine.getEnv().addReporter(new AllureReporter({
        resultsDir: 'reports/allure-results'
    }));
	var pass = jasmine.getEnv().afterEach(function(done){
      if(!pass)
      browser.takeScreenshot().then(function (png) {
			allure.createAttachment('Screenshot', function () {
			  return new Buffer(png, 'base64')
			}, 'image/png')();
			done();
		  })
    })

But I also get all screens after every steps

@azachar
Copy link

azachar commented Feb 19, 2018 via email

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests