0

I'm trying to return window.performance object from the web page back to casper's scope with the following code but I'm getting null. Can someone explain why?

    performance = casper.evaluate ->
        return window.performance
    @echo performance
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
tetutato
  • 638
  • 5
  • 16

1 Answers1

0

PhantomJS 1.x doesn't implement window.performance, so you can't use it.

PhantomJS 2.0.0 implements it, but it doesn't implement the window.performance.toJSON() function. The problem with PhantomJS is that you have to access this information through evaluate(), but it has the following limitation:

Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.

Closures, functions, DOM nodes, etc. will not work!

You will have to find your own way of serializing this in the page context and passing it to the outside (JavaScript):

var performance = casper.evaluate(function(){
    var t = window.performance.timing;
    var n = window.performance.navigation;
    return {
        timing: {
            connectStart: t.connectStart,
            connectEnd: t.connectEnd,
            ...
        },
        navigation: {
            type: n.type,
            redirectCount: n.redirectCount
        },
        ...
    };
});

or look for a deep copy algorithm that produces a serializable object (from here):

var perf = casper.evaluate(function(){
    function cloneObject(obj) {
        var clone = {};
        for(var i in obj) {
            if(typeof(obj[i])=="object" && obj[i] != null)
                clone[i] = cloneObject(obj[i]);
            else
                clone[i] = obj[i];
        }
        return clone;
    }
    return cloneObject(window.performance);
});
console.log(JSON.stringify(perf, undefined, 4));
Community
  • 1
  • 1
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Thanks but what do you mean I can't use it for PhantomJS 1.9.x? If I could just serialize it within the page context and return the JSON object doesn't it not matter what the version of phantom is? Like I could retrieve window.performance.timing.value fine – tetutato Jul 01 '15 at 15:47
  • PhantomJS 1.x simply doesn't have `window.performance`, so there is nothing to serialize. – Artjom B. Jul 01 '15 at 15:55
  • But if the code isnt everything being executed on the page that phantom's at? If what you are saying is true I shouldnt be able to retrieve any values from window.performance.timing right? – tetutato Jul 01 '15 at 16:03
  • Yes. Are you able to retrieve some values from `window.performance.timing` when using PhantomJS 1.9.x? If so, how? – Artjom B. Jul 01 '15 at 16:15
  • I'm just putting in evaluate what I would put in at the JavaScript console and returning the results. So if I serialize everything in the JavaScript console and just pass the JSON object it should be fine? – tetutato Jul 01 '15 at 16:32
  • For example the issue that I have is also with chrome. Just typing in performance or performance.timing returns an unserialized Object – tetutato Jul 01 '15 at 16:36
  • Yes, you can put everything in an actual object and pass it out of the page context. Have you tried any of the snippets I provided? – Artjom B. Jul 01 '15 at 17:40
  • I'm about to try them but i can't seem to duplicate the time i retrieved the value... I see what you mean though, you are saying PhantomJS 1.9.x as a browser itself doesn't have that performance feature? – tetutato Jul 01 '15 at 18:29