Skip to content

Instantly share code, notes, and snippets.

@loretoparisi
Created September 14, 2016 15:16
Show Gist options
  • Save loretoparisi/406571304ca6ac07c3bed782a259eba2 to your computer and use it in GitHub Desktop.
Save loretoparisi/406571304ca6ac07c3bed782a259eba2 to your computer and use it in GitHub Desktop.
Phantomjs example of wait For Page Document condition
/**
* Phantomjs example wait For Page Document condition
* @author Loreto Parisi (loretoparisi at gmail dot com )
*/
(function() {
/**
* Delayed wait on a condition
*/
var Delay = function() {
this.start=0;
this.interval=null;
self.condition=false;
}
Delay.prototype.waitFor = function(testFx, onReady, onTimeout, timeOutMillis, checkIntervalMillis) {
var self=this;
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000; //< Default Max Timout is 3s
checkIntervalMillis = checkIntervalMillis | 250;
self.start = new Date().getTime();
self.condition = false;
self.interval = setInterval(function() {
if ( (new Date().getTime() - self.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("'Delay.waitFor()' timeout in " + maxtimeOutMillis);
onTimeout();
} else {
// Condition fulfilled (timeout and/or condition is 'true')
console.log("'Delay.waitFor()' finished in " + (new Date().getTime() - self.start) + "ms.");
typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
clearInterval( self.interval ); //< Stop this interval
}
}
}, checkIntervalMillis); //< repeat check every 250ms
}
// test page rendering
var page = require('webpage').create()
page.onConsoleMessage = function(msg) {
console.log(msg)
}
// on resource requested
page.onResourceRequested = function(requestData, request) {
var check=(/http:\/\/.+?\.css/gi).test(requestData['url']);
console.log("onResourceRequested " + requestData['url'] + " ---> " + check);
var filteredRes=requestData.headers.filter(function(key,value) {
return (value['Content-Type'] == 'text/css');
});
if ( check || filteredRes.length>0 ) {
console.log('The url of the request is matching. Aborting: ' + requestData['url']);
request.abort();
}
};
// on resource error
page.onResourceError = function(error) {
console.log("onResourceError:"+error);
};
// on error
page.onError = function(msg, trace) {
var msgStack = ['ERROR: ' + msg];
if (trace && trace.length) {
msgStack.push('TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
});
}
console.error(msgStack.join('\n'));
};
var done = function() {
phantom.exit( 0 );
}
var waitForCondition = function(page,pageContext,condition,argv,onsuccess,ontimeout,timeout) {
pageContext.delay = new Delay();
pageContext.delay.waitFor(function() {
return page.evaluate(function(func,argv) {
return func.apply(this,[argv]);
}, condition, argv);
},
function() {
onsuccess(page);
}
, ontimeout
, timeout);
}//waitForCondition
// on navigation requested
page.onNavigationRequested = function(url, type, willNavigate, main) {
console.log('navigate to: ' + url);
console.log('referal: ' + type);
console.log('will navigate: ' + willNavigate);
console.log('is from main page frame: ' + main);
};
page.onLoadFinished = function(status) {
if (!status){
console.log('fail')
phantom.exit( 1 )
}
var condition = function() {
return (
document.querySelector( arguments[0] ) );
};
var conditionArgv=['body'];
var pageContext = new Object();
waitForCondition(page
, pageContext
, condition
, conditionArgv
, function(page) { // success on condition
page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function(res) {
console.log('JQ: ' + $().jquery + " PATH: " + document.location.pathname );
try {
page.evaluate(function() {
// dome something funny with window.document visibile in this scope
});
} catch(ex) {
console.error(ex);
done();
}
});
}
,function() { // KO, timed out, skip to next
console.log("Timed out '"+url+"' " + Config.conditionTimeout);
}
,1000 * 10);
}
// page settings
var userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.97 Safari/537.36';
page.settings.userAgent = userAgent;
page.settings.resourceTimeout = 1000 * 30; // timeout
page.settings.loadImages = true; // load images flags
var url='http://stackoverflow.com/questions/39465277/how-can-i-easily-have-a-javascript-function-to-parse-out-specific-objects-from-j/39466683#39466683'
console.log("Openinig page:\n" + url + "\nuser-agent:\n" + userAgent);
// before page open
phantom.cookiesEnabled = true;
phantom.clearCookies();
page.open(url)
}).call(this);
@loretoparisi
Copy link
Author

How to use

$ phantomjs --debug false --ssl-protocol=tlsv1 --load-images=true --web-security=no --ignore-ssl-errors=true phantomjs+waitForCondition.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment