Reputation: 1
I have the following code:
casper.then(function(){
for (siteID = 1 ; siteID < 10; siteID++) {
casper.then(function(){
this.fill('form#form1', {'txtSiteName' : siteID }, true);
});
casper.then(function(){
this.click('#BtnSiteSearch');
this.wait('500');
});
casper.then(function(){
this.echo("Longitude: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(2) > td:nth-child(2)'));
this.echo("Latitude: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(3) > td:nth-child(2)'));
this.echo("City: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(5) > td:nth-child(2)'));
this.echo("Area: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(7) > td:nth-child(2)'));
this.echo("Address: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(9) > td:nth-child(2)'));
this.echo("Access: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(10) > td:nth-child(2)'));
this.echo("H&S: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(13) > td:nth-child(2)'));
this.echo("Engineers: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(14) > td:nth-child(2)'));
this.echo("Owner: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(8) > td:nth-child(2)'));
this.capture('test' + siteID + '.png');
});
}
});
My problem is that the for loop runs and increment to that last number in the for loop. Then the code runs 10x on the last number.
I believe it's something to do with Synchronous and Asynchronous but if I am honest I don't know how to work around the issue.
Upvotes: 0
Views: 293
Reputation: 36
I suggest you to use this code:
var casper = require('casper').create({
verbose: true,
logLevel: 'debug',
pageSettings: {
loadImages: false, // The WebPage instance used by Casper will
loadPlugins: false, // use these settings
userAgent: 'Mozilla/5.0 (Macintosh Intel Mac OS X 10_7_5) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4'
}
});
casper.start();
for (siteID = 1 ; siteID < 10; siteID++) {
casper.wait(100);
simpleFunction(siteID)
}
function simpleFunction(siteID){
casper.then(function(){
casper.echo(siteID);
});
casper.then(function(){
this.fill('form#form1', {'txtSiteName' : siteID }, true);
});
casper.then(function(){
this.click('#BtnSiteSearch');
this.wait('500');
});
casper.then(function(){
this.echo("Longitude: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(2) > td:nth-child(2)'));
this.echo("Latitude: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(3) > td:nth-child(2)'));
this.echo("City: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(5) > td:nth-child(2)'));
this.echo("Area: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(7) > td:nth-child(2)'));
this.echo("Address: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(9) > td:nth-child(2)'));
this.echo("Access: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(10) > td:nth-child(2)'));
this.echo("H&S: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(13) > td:nth-child(2)'));
this.echo("Engineers: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(14) > td:nth-child(2)'));
this.echo("Owner: " + this.fetchText('#pnlSiteDetail > fieldset > table > tbody > tr:nth-child(8) > td:nth-child(2)'));
this.capture('test' + siteID + '.png');
});
}
casper.run();
Upvotes: 0
Reputation: 18665
I am not an expert with casper, but apparently this is a common JavaScript mistake that you often find in every book which explains closures. The anonymous function in the then
clause is executed at a later point, the loop is executed straight away, so when the anonymous function is executed, the loop variable is already at its last value, and it is that value which is picked up by your anonymous function.
The common trick recommended against that is to pass the loop variable in a function for immediate evaluation :
for (siteID = 1 ; siteID < 10; siteID++) {
(function (siteID) {
casper.then(function(){
this.fill('form#form1', {'txtSiteName' : siteID }, true);
})(siteID);
});
}
In your particular case, I would however check whether the this
variable is correctly bound (I guess this is casper is binding it correctly, right?).
Upvotes: 1