soda soda - 1 year ago 41
Javascript Question

Is there a way to listen to an event in the phantom context from page context?

For example: I open a page with PhantomJS, evaluate an asynchronous script (e.g. ajax). When it succeeds, I want to let the phantom context (outside of

) know that the asynchronous process is finished.

I don't want to use
to wait and check continously in the phantom context that the process is finished.

Answer Source

That is exactly what the onCallback and window.callPhantom() pair is for.

So, if you have an asynchronous call in the page context like an AJAX request, you can do this:

page.onCallback = function(data){
    console.log("finished: " + data.text);
    var xhr = new XMLHttpRequest();"GET", "/");
    xhr.onreadystatechange = function () {
        var DONE = this.DONE || 4;
        if (this.readyState === DONE){
            window.callPhantom({text: this.responseText});

The other way to use this is to add the call to your production JavaScript to make testing easier. If you're writing a web application it is sometimes complicated to find a selector which denotes when a page is fully loaded. To make testing such an application easier, you can have something like this in the page JavaScript:

finishOffPage(function callback(){
    if (typeof window.callPhantom === "function") {
        window.callPhantom({type: "loadFinished"});

Then you can write tests like this:

page.onCallback = function(data){
    if (data.type === "loadFinished") {
        // do some testing

This is an example where such a thing can be added dynamically: wait for angular app to be fully rendered from phantom script