Search code examples
javascriptphantomjscasperjs

CasperJS waitForSelector works but querySelector null


I'm working with CasperJS and I can get a "success" from waitForSelector but when i try to do document.querySelector for the same selector - it returns null?

My code

"use strict";
var casper = require('casper').create({
    verbose: false,
    logLevel: 'warning',
    waitTimeout: 10000
});
phantom.cookiesEnabled = true;

var x = require('casper').selectXPath;
casper.options.viewportSize = {width: 1920, height: 965};
casper.on('page.error', function(msg, trace) {
   this.echo('Error: ' + msg, 'ERROR');
   for(var i=0; i<trace.length; i++) {
       var step = trace[i];
       this.echo('   ' + step.file + ' (line ' + step.line + ')', 'ERROR');
   }
});

var selector = ".table-component";
casper.waitForSelector(selector,
    function success() {
        console.log("table found");
        console.log(document.querySelector(selector));      
    },
    function fail() {
        console.log("oops");
    }
);
casper.run();

Solution

  • PhantomJS has two contexts and since CasperJS is built on top of PhantomJS, it inherits this fact.

    You can only access the DOM through casper.evaluate() (wrapper around page.evaluate()). All CasperJS functions that take selectors as arguments, use evaluate() internally. Note that evaluate() is sandboxed and you can only pass primitive types in and out of it. DOM elements are not primitive types, so you cannot pass them out of the page (DOM) context. You will have to pass some kind of representation of the information that you want as primitive types:

    casper.waitForSelector(selector,
        function success() {
            this.echo("table found");
            this.echo("1: "+this.evaluate(function(sel){
                return !!document.querySelector(sel)
            }, selector));
            this.echo("2: "+this.evaluate(function(sel){
                return document.querySelector(sel).textContent;
            }, selector));
        },
        function fail() {
            console.log("oops");
        }
    );
    

    I suggest that you look into the other helpful functions such as casper.getElementInfo().