sdbbs sdbbs - 1 year ago 422
Ajax Question

Inspecting AJAX loaded JS objects/class with CasperJS?

I'm using the same example as in Checking JavaScript AJAX loaded resources with Mink/Zombie in PHP?:


if (array_key_exists("QUERY_STRING", $_SERVER)) {
if ($_SERVER["QUERY_STRING"] == "getone") {
echo "<!doctype html>
<script src='test_JSload.php?gettwo'></script>

if ($_SERVER["QUERY_STRING"] == "gettwo") {
header('Content-Type: application/javascript');
echo "
function person(firstName) {
this.firstName = firstName;
this.changeName = function (name) {
this.firstName = name;
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<style type="text/css">
.my_btn { background-color:yellow; }
<script src=""></script>
<script type="text/javascript">
var thishref = window.location.href.slice(0, window.location.href.indexOf('?')+1);
var qstr = window.location.href.slice(window.location.href.indexOf('?')+1);

function OnGetdata(inbtn) {
console.log("OnGetdata; loading ?getone via AJAX call");
//~ $.ajax(thishref + "?getone", { // works
var ptest = {}; // init as empty object
console.log(" ptest pre ajax is ", ptest);

$.ajax({url: thishref + "?getone",
async: true, // still "Synchronous XMLHttpRequest on the main thread is deprecated", because we load a script;
success: function(data) {
console.log("got getone data "); //, data);
ptest = new person("AHA");
console.log(" ptest post getone is ", ptest);
error: function(xhr, ajaxOptions, thrownError) {
console.log("getone error " + thishref + " : " + xhr.status + " / " + thrownError);

console.log(" ptest post ajax is ", ptest);

ondocready = function() {

<h1>Hello World!</h1>

<button type="button" id="getdatabtn" class="my_btn">Get Data!</button>
<div id="dataholder"></div>

Then, you can just run a temporary server with PHP > 5.4 CLI (command line), in the same directory (of the

php -S localhost:8080

... and then finally, you can visit the page at

Simply speaking, in this page, when the button is clicked, JavaScript class is loaded in two passes - first an HTML comes in with a
tag, whose script would then get loaded in the second pass. Firefox for this action prints in Console:

OnGetdata; loading ?getone via AJAX call test_JSload.php:13:3
ptest pre ajax is Object { } test_JSload.php:16:3
TypeError: ptest.changeName is not a function test_JSload.php:31:3
got getone data test_JSload.php:21:7
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help jquery-1.12.4.min.js:4:26272
ptest post getone is Object { firstName: "AHA", changeName: person/this.changeName(name) } test_JSload.php:24:7

I would ultimately like to inspect either
variable or the
class in CasperJS. So far, I made this script:


// run with:
// ~/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/casperjs test_JSload_casper.js
// based on

var casper = require('casper').create({
pageSettings: {
loadImages: false,//The script is much faster when this field is set to false
loadPlugins: false,
userAgent: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36'

//First step is to open page
casper.start().thenOpen("", function() {
console.log("website opened");

//Second step is to click to the button

//Wait for JS to execute?!, then inspect
console.log("After login...");
console.log("AA " + JSON.stringify(person));

... however, when I run this CasperJS script, I get just:

$ ~/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/casperjs test_JSload_casper.js
website opened
After login...

... and nothing else. Note that the last line
console.log("AA " + JSON.stringify(person));
doesn't execute even partially (i.e., no "AA " is printed, nor any sort of error message).

So, is it possible to use Casper JS to inspect resources like these (AJAX loaded JS objects/classes, possibly loaded over multiple runs/steps) - and if so, how?

Answer Source

The Ajax request which is triggered through the click might not have enough time to make an impact on the page you're scraping. Make sure to wait for it's completion with one of the many wait* functions. If the DOM is changed as a result of the Ajax request, then I suggest waitForSelector.

A related problem is that the page's JavaScript is broken. Since the Ajax request that populates ptest is asynchronous, ptest.changeName("Somename") is executed before the response arrived and thus leads to a TypeError. You can move ptest.changeName(...) to the success callback of the Ajax request.

In order to see console messages from the page, you have to listen to the 'remote.message' event:

casper.on("remote.message", function(msg){
    this.echo("remote> " + msg);

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download