I've just used CasperJS for my project. Its grammar is clear and easy to learn. But diving through its documentation, I've never found anything about conditional statements. For example, it may be useful if we can use CasperJS in the following manner:
var casper = require('casper').create();
var no_error = false;
casper.start('/', function() {
this.echo(this.getTitle());
no_error = true;
});
if (no_error) {
casper.thenOpen('', function() {
this.echo(this.getTitle());
});
}
casper.run();
Is there any way to customize CasperJS to work like that?
I've just used CasperJS for my project. Its grammar is clear and easy to learn. But diving through its documentation, I've never found anything about conditional statements. For example, it may be useful if we can use CasperJS in the following manner:
var casper = require('casper').create();
var no_error = false;
casper.start('http://casperjs/', function() {
this.echo(this.getTitle());
no_error = true;
});
if (no_error) {
casper.thenOpen('http://phantomjs', function() {
this.echo(this.getTitle());
});
}
casper.run();
Is there any way to customize CasperJS to work like that?
Share Improve this question edited Oct 1, 2014 at 7:17 Artjom B. 62k26 gold badges135 silver badges230 bronze badges asked Oct 1, 2014 at 2:57 anhldbkanhldbk 4,5975 gold badges32 silver badges37 bronze badges1 Answer
Reset to default 7Yes, it is possible otherwise such synchronous functions like casper.exists
don't make sense.
In your example no_error
could never be true
, because the casper.start
callback is executed asynchronously at a time when if (no_error)
is long evaluated.
You have to nest some steps (all wait*
and then*
functions are steps) to do this:
var casper = require('casper').create();
var no_error = false;
casper.start('http://casperjs/', function() {
this.echo(this.getTitle());
no_error = true;
});
casper.then(function(){
if (no_error) {
casper.thenOpen('http://phantomjs', function() {
this.echo(this.getTitle());
});
}
});
casper.run();
You can nest step functions, but you have to keep in mind that you should not use a synchronous function after a step, because the it will be executed the other way around.
casper.then(function(){
casper.thenOpen('http://phantomjs', function() {
this.echo("1: " + this.getTitle());
});
this.echo("2: " + this.getTitle());
});
will print first 2 and then 1.
Synchronous
If the condition data is returned synchronously then you can evaluate it directly
casper.start('http://casperjs/', function() {
var array = this.evaluate(function(){....});
if (array && array.length > 2) {
this.thenOpen(...);
}
});
There is simply no need for an additional step.
Asynchronous
This is where it gets interesting. If for example you have to trigger a long running script in page context (it's not limited to the page context), you will have to wait for its pletion in casper context. You will need an indicator variable.
casper.thenEvaluate(function(){
longRunningFunction(function callback(){
window.__someIndicator = true;
});
});
casper.waitFor(function check(){
return this.evaluate(function(){
return !!window.__someIndicator;
});
}, function then(){
this.thenOpen(...);
}, function onTimeout(){
this.echo("failed");
this.thenOpen(...); // open something else
});
Sometimes you don't have a possible callback. In this case the DOM will probably change and you have to wait for those changes.
Conclusion
The example in the first snippet is not really useful and should be exchanged for one of the other approaches.