FotisK
FotisK

Reputation: 1177

Find an element on the page based on a variable using CasperJS' getElementByXPath

I have an issue using __utils__.getElementByXPath() with variable xpath parameter, see example:

The licid is given as argv (--licid=FAT32) at cli execution of the script and is correctly acknowledged from CasperJS.

casper.then(function() {
    var xpath_lic = '//*[contains(text(), "' + casper.cli.get("licid") + '")]';
    this.echo('searching for...' + xpath_lic);
    var found = this.evaluate(function() {
        return __utils__.getElementByXPath(xpath_lic);
    });
    if (found) {
        this.echo('Lic found');
    }
    else {
        this.echo('Lic not found');
    }
});

The above code is always print out "Lic not found"! But when I change the return line with:

return __utils__.getElementByXPath('//*[contains(text(), "FAT32")]');

This will give me "Lic found" which is correct!

How do I have to use the licid in the __utils__.getElementByXPath() to make the line more general?

Upvotes: 1

Views: 543

Answers (1)

Artjom B.
Artjom B.

Reputation: 61952

casper.evaluate() is the sandboxed page context (derived from PhantomJS' page.evaluate()). It has no access to variables defined outside of it. You have to explicitly pass them in:

var xpath_lic = '//*[contains(text(), "' + casper.cli.get("licid") + '")]';
var found = this.evaluate(function(xp) {
    return !!__utils__.getElementByXPath(xp); // convert to boolean with `!!`
}, xpath_lic);

You cannot pass DOM nodes out of the page context, so you need to either get a representation of them like element.textContent or completely work in the page context.

Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.

Closures, functions, DOM nodes, etc. will not work!

Upvotes: 2

Related Questions