How to catch a new opend window from window.open (url, _blank) in PhantomJS?

I want to check with PhantomJS whether my script opens a new window / tab correctly. Open is launched using the js event listener and opens through window.open(url, "_blank") .

How can I listen to a new window using PhantomJS?

+5
source share
1 answer

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){ // a little delay might be necessary if (data.type === "open" && page.pages.length > 0) { var newPage = page.pages[page.pages.length-1]; newPage.onLoadFinished = function(){ console.log(newPage.url); phantom.exit(); }; } }; page.open(address, function (status) { if (status !== 'success') { console.log('Unable to load the address!'); phantom.exit(); } else { page.evaluate(function(url){ window.open(url+"?something=other", "_blank"); }, address); } }) 
+13
source

Source: https://habr.com/ru/post/1211231/


All Articles