According to the CasperJS Documentation:
then()
Signature: then(Function then)
This method is the standard way to add a new navigation step to the stack, by providing a simple function:
casper.start('http://google.fr/');
casper.then(function() {
this.echo('I\'m in your google.');
});
casper.then(function() {
this.echo('Now, let me write something');
});
casper.then(function() {
this.echo('Oh well.');
});
casper.run();
You can add as many steps as you need. Note that the current Casper
instance automatically binds the this
keyword for you within step functions.
To run all the steps you defined, call the run()
method, and voila.
Note: You must start()
the casper instance in order to use the then()
method.
Warning: Step functions added to then()
are processed in two different cases:
- when the previous step function has been executed,
- when the previous main HTTP request has been executed and the page loaded;
Note that there's no single definition of page loaded; is it when the DOMReady event has been triggered? Is it "all requests being finished"? Is it "all application logic being performed"? Or "all elements being rendered"? The answer always depends on the context. Hence why you're encouraged to always use the waitFor()
family methods to keep explicit control on what you actually expect.
A common trick is to use waitForSelector()
:
casper.start('http://my.website.com/');
casper.waitForSelector('#plop', function() {
this.echo('I\'m sure #plop is available in the DOM');
});
casper.run();
Behind the scenes, the source code for Casper.prototype.then
is shown below:
/**
* Schedules the next step in the navigation process.
*
* @param function step A function to be called as a step
* @return Casper
*/
Casper.prototype.then = function then(step) {
"use strict";
this.checkStarted();
if (!utils.isFunction(step)) {
throw new CasperError("You can only define a step as a function");
}
// check if casper is running
if (this.checker === null) {
// append step to the end of the queue
step.level = 0;
this.steps.push(step);
} else {
// insert substep a level deeper
try {
step.level = this.steps[this.step - 1].level + 1;
} catch (e) {
step.level = 0;
}
var insertIndex = this.step;
while (this.steps[insertIndex] && step.level === this.steps[insertIndex].level) {
insertIndex++;
}
this.steps.splice(insertIndex, 0, step);
}
this.emit('step.added', step);
return this;
};
Explanation:
In other words, then()
schedules the next step in the navigation process.
When then()
is called, it is passed a function as a parameter which is to be called as a step.
It checks if an instance has started, and if it has not, it displays the following error:
CasperError: Casper is not started, can't execute `then()`.
Next, it checks if the page
object is null
.
If the condition is true, Casper creates a new page
object.
After that, then()
validates the step
parameter to check if it is not a function.
If the parameter is not a function, it displays the following error:
CasperError: You can only define a step as a function
Then, the function checks if Casper is running.
If Casper is not running, then()
appends the step to the end of the queue.
Otherwise, if Casper is running, it inserts a substep a level deeper than the previous step.
Finally, the then()
function concludes by emitting a step.added
event, and returns the Casper object.
flow
of casperjs, but I've discovered that you basically cannot reference casper from within anevaluate
call. (i.e. you cannot open a new url, log, echo, etc). So in my case evaluate was being called but with no way to interact with the outside world. – Taftevaluate()
is for code that runs in the "browser", in the DOM of the page phantomjs is browsing. So there's nocasper.open
there, but there could be jQuery. So your example makes no sense, but I still wonder whatthen()
actually does. – Oyer