webdriverio: Automatic screenshots on error?

Hi!

I’m trying to set up automatic screenshots creation on error. I have following folder structure:

test/
  screenshots/
  suite/

I am creating a webdriverio client passing screenshotPath: "./test/screenshots" as an option, but that doesn’t seem to affect anything.

I was trying to add

client.on('error', (err)-> @capture('error'))

but this doesn’t get called at all.

The only thing that actually works is

process.on('uncaughtException', (err)-> client?.capture('error'))

but sometimes it fails too.

This is an example if a test that fails:

  it 'should have correct number of cards', (done)->
    client
      .waitForExist('.p-h-promoted .b-p-list', 3000)
      .isVisible cards, (err, isVisible)-> expect(isVisible).to.have.length(25)
      .isVisible doubleCards, (err, isVisible)-> expect(isVisible).to.have.length(5)
      .call(done)

What would be the best way to handle this?

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Comments: 18 (4 by maintainers)

Most upvoted comments

@suprMax , you can do it by using afterTest function in wdio.conf.js file, like this:

/**
     * Function to be executed after a test (in Mocha/Jasmine) or a step (in Cucumber) starts.
     * @param {Object} test test details
     */
    afterTest: function (test) {
        // if test passed, ignore, else take and save screenshot.
        if (test.passed) {
            return;
        }
        // get current test title and clean it, to use it as file name
        var filename = encodeURIComponent(test.title.replace(/\s+/g, '-'));
        // build file path
        var filePath = this.screenshotPath + filename + '.png';
        // save screenshot
        browser.saveScreenshot(filePath);
        console.log('\n\tScreenshot location:', filePath, '\n');
    },

@shadiabuhilal Thanks for that code suggestion. I’ve got a revised version, after I ran into a problem with saving screenshots like that( if a file already exists with that name, it fails to save the screenshot). The important change is to use a timestamp in the filename:

    var path = require('path');
    ...
    afterTest: function (test) {
        // if test passed, ignore, else take and save screenshot.
        if (test.passed) {
            return;
        }
        // Construct file name:
        var browserName = browser.desiredCapabilities.browserName;
        var timestamp = new Date().toJSON().replace(/:/g, '-');
        var filename = 'TESTFAIL_' + browserName + '_' + timestamp + '.png';
        var filePath = path.join(this.screenshotPath, filename);
        // save screenshot
        browser.saveScreenshot(filePath);
        console.log('\tSaved screenshot: ', filePath);
    }

Note: I based this code on the webdriverio code (function saveScreenshotSync in webdriverio.js) which takes screenshots when a command errors.

Seeing that it has been 6 days since you posted this yielding no suggestions, I’m just going to drop my thoughts.

As far as I can remember from my experiences, the following rules hold:

  • normally, you are supposed to catch any error in a callback function, and trigger a snapshot there. This would mean callbacking every command afaik
  • if the asynchronous webdriverio command unexpectedly throws an error (instead of returning it on callback, you are (probably) out of luck.

Frankly, if there is a better solution than this, I would like to know as well. Maybe yours is, and you are just looking at one of the cases where webdriverio unexpectedly throws an error.

Also, this is one of the reasons I went for the synchronize solution. Pass all webdriverio commands (except event handling methods) through, start up a fiber, try catch over the whole block to catch all its errors at once (and have the ease of an synchronous API). It still does not catch the unexpected errors through.

To the maintainers, I will be more specific about any errors I find as soon as I know for sure they are there and they are caused by webdriverio. All I have right now are hunches, and they generally coincide with mistakes I’ve made as well (webdriverio unexpected behavior --> try to debug --> find own error --> fix error --> webdriverio works).