最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Take screenshot from Karma while running tests in PhantomJS 2? - Stack Overflow

programmeradmin3浏览0评论

I need a way to take a screenshot during a test which uses QUnit and Karma to run inside PhantomJS 2.0.1

I've found this mand:

window.top.callPhantom('render');

That doesn't throw any error but doesn't seem to work, or at least, I don't know where to look for the taken screenshot.

Any clue?

I need a way to take a screenshot during a test which uses QUnit and Karma to run inside PhantomJS 2.0.1

I've found this mand:

window.top.callPhantom('render');

That doesn't throw any error but doesn't seem to work, or at least, I don't know where to look for the taken screenshot.

Any clue?

Share Improve this question edited Jan 9, 2016 at 15:43 Artjom B. 61.9k25 gold badges134 silver badges229 bronze badges asked Jan 9, 2016 at 14:38 Fez VrastaFez Vrasta 14.8k24 gold badges109 silver badges176 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 14

Found a way!

Solution

I had to edit my custom PhantomJS custom launcher adding an option:

PhantomJSCustom: {
    base: 'PhantomJS',
    options: {
        onCallback: function(data){
            if (data.type === "render") {
                // this function will not have the scope of karma.conf.js so we must define any global variable inside it
                if (window.renderId === undefined) { window.renderId = 0; }
                page.render(data.fname || ("screenshot_" + (window.renderId++) + ".png"));
            }
        }
    }
}

As you can see, we are defining the onCallback option, it will be injected inside the script launched by phantomjs. The script, then, will contain:

page.onCallback = <our function>

Now, we are able to use callPhantom to ask PhantomJS to run the content of our onCallback function and use all the native PhantomJS methods.

Usage

Now, you can use in your tests the function:

window.top.callPhantom({type: 'render'});

To take a screenshot that will be saved in the root directory of your application.

Additionally, if you define the fname you'll be able to define a custom path and file name to your screenshot.

window.top.callPhantom({type: 'render', fname: '/tmp/myscreen.png'});

Pack all together for ease of use

I've created an handy function to use inside my tests. The onCallback function is reduced to the minimum necessary, in this way all the logic is managed inside my test environment:

karma.conf.js

PhantomJSCustom: {
    base: 'PhantomJS',
    options: {
        onCallback: function(data){
            if (data.type === 'render' && data.fname !== undefined) {
                page.render(data.fname);
            }
        }
    }
}

helper

// With this function you can take screenshots in PhantomJS!
// by default, screenshots will be saved in .tmp/screenshots/ folder with a progressive name (n.png)
var renderId = 0;
function takeScreenshot(file) {
    // check if we are in PhantomJS
    if (window.top.callPhantom === undefined) return;

    var options = {type: 'render'};
    // if the file argument is defined, we'll save the file in the path defined eg: `fname: '/tmp/myscreen.png'
    // otherwise we'll save it in the default directory with a progressive name
    options.fname = file || '.tmp/screenshots/' + (renderId++) + '.png';

    // this calls the onCallback function of PhantomJS, the type: 'render' will trigger the screenshot script
    window.top.callPhantom(options);
}

Credits

I got this script from this answer, adapted it and found by myself where to put it to make it work with karma.

My Karma entry for a customized phantomjs that takes snapshots looked like this:

module.exports = function (config) {
  config.set({
    ..
    browsers: [ 'PhantomJSCustom'],
    customLaunchers: {
      'PhantomJSCustom': {
        base: 'PhantomJS',
        options: {
          onCallback: function(data){
            if (data.type === "render") {
              // this function will not have the scope of karma.conf.js so we must define any global variable inside it
              if (window.renderId === undefined) { window.renderId = 0; }
              page.render(data.fname || ("screenshot_" + (window.renderId++) + ".png"));
            }
          }
        }
      }
    },
    phantomjsLauncher: {
      // Have phantomjs exit if a ResourceError is encountered (useful if karma exits without killing         // phantom)
      exitOnResourceError: true
    },
    ..
  })

发布评论

评论列表(0)

  1. 暂无评论