There seem to be three ways to do this:
onPageCreated
CasperJS resolves this with page.onPageCreated . Therefore, when window.open is called on the page, a new page is created and page.onPageCreated starts with the newly created page.
page.open(address, function (status) { if (status !== 'success') { console.log('Unable to load the address!'); phantom.exit(); } else { page.onPageCreated = function(newPage){ newPage.onLoadFinished = function(){ console.log(newPage.url); phantom.exit(); }; }; page.evaluate(function(url){ window.open(url+"?something=other", "_blank"); }, address); } })
pages
PhantomJS ' page has a pages property that processes child pages. So, when you open add a new page / tab, a new webpage object is created for this page. You need to try adding an onLoadFinished event onLoadFinished to the page before it starts (no promises). This can be tricky, and when window.open is called with an unknown delay from the page context.
This can be fixed using something like waitFor to wait for a new page to appear and attach an event handler before the page is loaded. Here is the complete code with a little tweaking. The retry interval decreases to 50 ms from 250 ms.
var page = require('webpage').create(); var address = "http://example.com/"; function waitFor(testFx, onReady, timeOutMillis) { var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s start = new Date().getTime(), condition = false, interval = setInterval(function() { if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) { // If not time-out yet and condition not yet fulfilled condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code } else { if(!condition) { // If condition still not fulfilled (timeout but condition is 'false') console.log("'waitFor()' timeout"); phantom.exit(1); } else { // Condition fulfilled (timeout and/or condition is 'true') console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms."); typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it supposed to do once the condition is fulfilled clearInterval(interval); //< Stop this interval } } }, 50); //< repeat check every 50ms }; page.open(address, function (status) { if (status !== 'success') { console.log('Unable to load the address!'); phantom.exit(); } else { console.log("p:", page.ownsPages, typeof page.pages, page.pages.length, page.pages); waitFor(function test(){ return page.pages && page.pages[0]; }, function ready(){ page.pages[0].onLoadFinished = function(){ console.log("p:", page.ownsPages, typeof page.pages, page.pages.length, page.pages); console.log("inner:", page.pages[0].url); phantom.exit(); }; }); page.evaluate(function(url){ window.open(url+"?something=other", "_blank"); }, address); } })
Proxy solution
The window.open function can be proxied, and after opening the page in the context of the page, the event handler can be registered in the phantom context specified through window.callPhantom and trapped in onCallback .
page.onInitialized = function(){ page.evaluate(function(){ var _oldOpen = window.open; window.open = function(url, type){ _oldOpen.call(window, url, type); window.callPhantom({type: "open"}); }; }); }; page.onCallback = function(data){