I\'m using trying to use nodejs and phantomjs on the server-side for SEO of our site. While ajax works fine, I\'m not able to execute custom promises that I\'ve used in my code.
PhantomJs does not automatically wait the end of all pending scripts. WebPage#onLoadFinished is called on the onload event.
As for most of the scripts, the idea here is to wait until "something" is done or true. I highly suggest you to test waitfor.js. It is really important to understand this example in PhantomJs.
I suppose your example is an example, but let me propose an answer.
Html Page
Test
PhantomJs Script
var page = require('webpage').create();
var system = require('system');
function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 10000, //< Default Max Timout is 10s
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");
typeof (onReady) === "string" ? eval(onReady) : onReady();
clearInterval(interval);
//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's supposed to do once the condition is fulfilled
clearInterval(interval); //< Stop this interval
}
}
}, 500); //< repeat check every 500ms
};
if (system.args.length != 1) {
console.log('invalid call');
phantom.exit(1);
} else {
//adapt url to your context
page.open('http://localhost:9231/demo.html', function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit();
} else {
waitFor(
function () {
return page.evaluate(function () {
return $('body').hasClass('promise-executed');
}) > 0;
},
function () {
page.render('page.png');
phantom.exit();
}, 10000);
}
});
}
Basically, waitFor
will check every 500 ms if body has a class named 'promise-executed'
.