I'm trying to set a value from within casper.evaluate() that I will check later to run a test on, but it doesn't seem to be working.
isArticleOrReview = false;
casper.waitFor(function check() { //here I'm just waiting for jQuery to load
return this.evaluate(function() {
return jQuery.fn.jquery == '1.2.6';
});
}, function then() { //once jQuery has been loaded, do this stuff
this.evaluate(function() {
isArticleOrReview = (jQuery('body').hasClass('node-type-review') || jQuery('body').hasClass('node-type-article'));
__utils__.echo('isArticleOrReview ' + isArticleOrReview);
});
});
casper.then(function(){
casper.test.info('isArticleOrReview ' + isArticleOrReview);
});
For output I get:
isArticleOrReview true
isArticleOrReview false
I want this to read:
isArticleOrReview true
isArticleOrReview true
evaluate
is sandboxed. The evaluated function has no access to the surrounding code, nor does surrounding code have access to the evaluated function. Here is a simpler example from PhantomJS (Casper's evaluate
uses that underneath):
var page = require('webpage').create();
page.open('http://google.com/', function(status) {
var titleVar = "NOT SET";
var titleReturn = page.evaluate(function() {
// This would result in an error:
// console.log('Variable in evaluate:', titleVar);
// ReferenceError: Can't find variable: titleVar
titleVar = document.title;
return document.title;
});
console.log('Return value from evaluate:', titleReturn);
console.log('Variable post evaluate:', titleVar);
phantom.exit();
});
As you found out, this will print
Return value from evaluate: Google
Variable post evaluate: NOT SET
and if you uncomment the console.log
line inside evaluate
, you will see evaluate
crash and burn, since the variable does not exist.
Thus, you can only pass values through evaluate
parameters and return values (and only those that are JSON-serialisable):
isArticleOrReview = this.evaluate(function() {
return (jQuery('body').hasClass('node-type-review') || jQuery('body').hasClass('node-type-article'));
});