JSB
JSB

Reputation: 360

How to call an external function from within casper.start or casper.thenOpen

I am trying to split the following code such that the callback function which is stored in its own file.

var casper = require('casper').create();
casper.start("http://www.google.com/", function() {
    this.echo(this.getTitle());
});
casper.run(); // "Returns Google"

Following this example, I define a function in a separate file called "getPageTitle.js";

function getPageTitle(casper) {
    casper.echo(casper.getTitle());
}
exports.getPageTitle = getPageTitle;

and call the function in another file called "main.js" by passing the CasperJS object into the function directly;

var casper = require('casper').create();
var casperFunctions = require('./getPageTitle.js');
casper.start("http://www.google.com/", casperFunctions.getPageTitle(casper));
# Error: CasperError: Casper is not started, can't execute `getTitle()`                  

Further, if I replace the last line in the above with a thenOpen() call;

casper.start();
casper.thenOpen("http://www.google.com/", casperFunctions.getPageTitle(casper));

The above code does not throw errors; CasperJS is able to navigate to the website, but the page title "Google" is not returned.

Could someone please shed light on why this doesn't behave as I expect. This seems like a natural way to modularize functions that CasperJS would call once pages are loading, but am I missing something here?

Upvotes: 1

Views: 1354

Answers (2)

Artjom B.
Artjom B.

Reputation: 61892

The execution of CasperJS is asynchronous. start() and all then*() and wait*() functions are asynchronous step functions. That means that you're only on the page inside of such as step.

When you look at your getPageTitle() and how it is called, you should notice that you're not passing a step function into casper.start(), but instead you're immediately calling getPageTitle(). At that time, the execution hasn't even begun, because the scheduled steps begin executing as soon as run() is called. By calling getPageTitle(), you're trying to access the title of about:blank which is blank.

First version:

function getPageTitle(casper) {
    return function(){
        casper.echo(casper.getTitle());
    };
}

Now you're passing a step function into start() which will be evaluated asynchronously.

Second version:

Keep in mind that you can use this inside of a step function to refer to casper. This is a better way to do this, because you don't need to pass the reference explicitly:

function getPageTitle() {
    return function(){
        this.echo(this.getTitle());
    };
}

and call it like this:

casper.start("http://www.google.com/", casperFunctions.getPageTitle());

Third version:

If you the function doesn't need any arguments, then you don't need a wrapper function. You can pass it directly:

function getPageTitle() {
    this.echo(this.getTitle());
}

and call it like this:

casper.start("http://www.google.com/", casperFunctions.getPageTitle);

Upvotes: 2

Jaromanda X
Jaromanda X

Reputation: 1

casper.start("http://www.google.com/", casperFunctions.getPageTitle(casper));

doesn't work, because you're passing the result of calling casperFunctions.getPageTitle(casper) as the callback parameter to casper.start

I think you should be able to do this instead

casper.start("http://www.google.com/", casperFunctions.getPageTitle.bind(casper));

Upvotes: 1

Related Questions