CasperJS to Simulate User Actions on Webpages

CasperJS is a navigation scripting & testing utility for PhantomJS and SlimerJS written in Javascript: http://casperjs.org/
CasperJS can be installed on Mac OSX, Windows and most Linuxes. Refer to the link for simple installation instructions: http://casperjs.readthedocs.org/en/latest/installation.html

Using CasperJS you can simulate the actual actions you take on the browsers. You can write some very cool applications. Below is the code for browsing through the website of a popular travel provider – Club Mahindra (www.clubmahindra.com). The code logs you into the portal, goes over the list of resorts available and prepares another static html page that sorts the availability of the resorts on time-basis.

Go over the code and checkout a number of interesting hacks you can do using CasperJS!

You can save the code as “cm.js” and run it as “casperjs cm.js”

 

/****** Casper Configs *********/
var casper = require(‘casper’).create({
pageSettings: {
loadImages:  false,        // The WebPage instance used by Casper will
loadPlugins: false         // use these settings
},
verbose: true,
//logLevel: ‘warning’,
logLevel: ‘info’,
});

/****** Casper Remote Server Logs *********/
// print out all the messages in the headless browser context
casper.on(‘remote.message’, function(msg) {
this.echo(‘remote message caught: ‘ + msg);
});

// print out all the messages in the headless browser context
casper.on(“page.error”, function(msg, trace) {
this.echo(“Error:” + msg + “\nTRACE:\n” + trace, “ERROR”);
this.echo(“file:     ” + trace[0].file, “WARNING”);
this.echo(“line:     ” + trace[0].line, “WARNING”);
this.echo(“function: ” + trace[0][“function”], “WARNING”);
errors.push(msg);
});

// print out all the alerts in the headless browser context
casper.on(“remote.alert”, function(msg) {
this.echo(“Alert Message: ” + msg);
});

/****** Reading all resorts links *********/
// The base links array
var links = [“google.com”];
// If we don’t set a limit, it could go on forever
var upTo = ~~casper.cli.get(0) || 250;

var currentLink = 0;

// Get the links, and add them to the links array
// (It could be done all in one step, but it is intentionally splitted)
function addLinks(link) {
this.then(function() {
var found = this.evaluate(searchLinks);
alert(found.length + ” links found on ” + link);
//????? Figure out why logs from function dont work!!!!!!!
for(var i=0; i<links.length; i++) {
//if(links[i] == link) {
//    return;
//}
//console.log (links[i] + ” —” + link);
}
links = links.concat(found);
});
}

// Fetch all <a> elements from the page and return
// the ones which contains a href ending with aboutresortinfo.html
function searchLinks() {
var filter, map;
filter = Array.prototype.filter;
map = Array.prototype.map;
return map.call(filter.call(document.querySelectorAll(“a”), function(a) {
return (/.*aboutresortinfo.html/).test(a.getAttribute(“href”));
}), function(a) {
return a.getAttribute(“href”);
});
}

function check() {
if (links[currentLink] && currentLink < upTo) {
//start.call(this, links[currentLink]);
addLinks.call(this, links[currentLink]);
currentLink++;
this.run(check);
} else {
console.log(“All resort links added”);
}
}

/****** Step 1: Open signin page *********/
var url=’https://members.clubmahindra.com/SignIn.php&#8217;;
casper.start(url, function() {
console.log(“Loaded Page”);
this.capture(‘cm_main_page.png’, {
top: 0,
left: 0,
width: 1500,
height: 1400
});

/****** Step 2: Login *********/
//this.test.assertExists(‘form[name=loginForm]’, ‘form is found’);
this.fill(‘form[name=loginForm]’, {
‘member_id’: ‘<YourMemberId>’,
‘password’:  ‘<YourPassword>’
}, true);
});

/****** Step 3: Capture Screen: Had to put this to get it working!! *********/
casper.then(function() {
this.capture(‘cm_login.png’, {
top: 0,
left: 0,
width: 1500,
height: 1400
});
this.echo(“Logged In”);
});

/****** Step 4: Click on the resorts link *********/
casper.thenClick(‘a[href=”/ResortSearch?redirect=1″]’, function() {
console.log(“Resorts listed”);
});

/****** Step 5: Capture Screen: Had to put this to get it working!! *********/
casper.then(function() {
this.capture(‘cm_resort_list.png’, {
top: 0,
left: 0,
width: 1500,
height: 1400
});
});

/****** Step 6: Save all resort links in the “links” array *********/
casper.then(check);

/****** Step 7: Visit each link and extract out the data *********/
casper.then(function() {
this.echo(‘<html><head><title>CM Resort availability data</title></title><body bgcolor=”#99CCCC”>’);
for (var i = 1; i < links.length; i=i+2) // for every link…
{
casper.thenClick(‘a[href=”‘+links[i]+'”]’, function() {

var dates=[];
dates = this.evaluate(function () {
var nodes = document.querySelectorAll(‘table[class=”availabilityTable”] > tbody > tr > th’);
return [].map.call(nodes, function(node) {
return node.textContent;
});
});

for(var y=0; y<dates.length; y++) {
var day = dates[y].split(” “)[1];
var date = dates[y].split(” “)[0];
var month;
switch(date.split(“-“)[1]) {
case ’01’: month=’Jan’; break;
case ’02’: month=’Feb’; break;
case ’03’: month=’Mar’; break;
case ’04’: month=’Apr’; break;
case ’05’: month=’May’; break;
case ’06’: month=’Jun’; break;
case ’07’: month=’Jul’; break;
case ’08’: month=’Aug’; break;
case ’09’: month=’Sep’; break;
case ’10’: month=’Oct’; break;
case ’11’: month=’Nov’; break;
case ’12’: month=’Dec’; break;
}
dates[y]=day + ” ” + date.split(“-“)[0] + “-” + month;
}

var cells=[];
cells = this.evaluate(function () {
var nodes = document.querySelectorAll(‘table[class=”availabilityTable”] > tbody > tr > td’);
return [].map.call(nodes, function(node) {
return node.textContent;
});
});

var color=[];
color = this.evaluate(function () {
var nodes = document.querySelectorAll(‘table[class=”availabilityTable”] > tbody > tr > td’);
return [].map.call(nodes, function(node) {
return node.attributes[‘class’].value.split(” “)[0];
});
});

var availableSet=[];
var printInit=1;
var roomTypes=[];
roomTypes = this.evaluate(function () {
var nodes = document.querySelectorAll(‘table[class=”availabilityTable floatLeft roomTypeTable”] > tbody > tr > td’);
return [].map.call(nodes, function(node) {
return node.textContent;
});
});

var emailText=”<h1>” + casper.getHTML(‘div[class=”topBackground clearfix”] > h1’) + ” </h1>”;
for(var j=0; j<cells.length; j++) {
var x=Math.floor(j/dates.length);
if(cells[j].trim() != ‘X’) {
availableSet.push(dates[j-(x*dates.length)]);
for(var k=j+1; k<cells.length; k++) {
if(cells[k].trim() == ‘X’) {
j=k;
availableSet.length = 0;
printInit=1;
break;
}
else {
availableSet.push(dates[k-(x*dates.length)]);
if(availableSet.length >= 3) {
if(printInit == 1) {
printInit = 0;
emailText = emailText + “<br>Available Dates: “;
if(color[k-2] != ‘purple’)
emailText = emailText + ‘<font color=”‘+color[k-2]+'”>’ +  availableSet[0] + “, </font>”;
if(color[k-1] != ‘purple’)
emailText = emailText + ‘<font color=”‘+color[k-1]+'”>’ + availableSet[1] + “, </font>”;
}
if(color[k] != ‘purple’)
emailText = emailText + ‘<font color=”‘+color[k]+'”>’ + availableSet[availableSet.length-1] + “, </font>”;
}

}
}
}
}
this.echo(emailText);

if(casper.exists(‘a[title=”‘+casper.getHTML(‘div[class=”topBackground clearfix”] > h1′)+'”]’)) {
casper.thenClick(‘a[title=”‘+casper.getHTML(‘div[class=”topBackground clearfix”] > h1′)+'”]’, function() {
this.capture(‘cm_getting_there.png’, {
top: 0,
left: 0,
width: 1500,
height: 1400
});
var airports=[];
airports = this.evaluate(function () {
var nodes = document.querySelectorAll(‘div[class=”tblData floatLeft”] > div > ul’);
return [].map.call(nodes, function(node) {
return node.textContent.trim();
});
});
this.echo(“<h2>Getting there:</h2>” + airports +”<br>”);
casper.back();
casper.wait(1000);
});
}
});
casper.back();
casper.wait(1000);
}
});

casper.run();

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s