Edward Trọng Edward Trọng - 6 months ago 87
Javascript Question

Clicking a button doesn't do anything in CasperJS

I'm trying to automate the following site: http://www.1800flowers.com/orchids/purple-mini-101006?categoryId=400065010

My code is:

var casper = require("casper").create();
var mouse = require("mouse").create(casper);

var casper = require('casper').create({
verbose: true,
//logLevel: 'debug', // debug, info, warning, error
clientScripts: ["includes/jquery.min.js"],
pageSettings:{
loadImages: false,
loadPlugins: false,
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586'
}
}
);

var fs = require('fs');

casper.start().thenOpen("http://www.1800flowers.com/orchids/purple-mini-101006?categoryId=400065010", function(){
console.log("Access Site 1800.Com");
this.wait(10000);
});

casper.then(function(){
this.capture("1800_1.png");
});

casper.then(function(){
this.evaluate(function(){
$('#zipCode').attr('value', '12345');
$('#locationCode').attr('value', 'Residence');

//document.querySelector('select[id="locationCode"]').focus();
});
this.mouse.click('#calendarLink');
this.wait(20000);
this.mouse.click('#DeliveryCalendarGPTDayCharges');
this.wait(20000);
//this.sendEvent('keypress', this.page.event.key.Down);
});

casper.then(function(){
this.capture("1800_2.png");
console.log(this.getCurrentUrl());
});

casper.run();


Result I got

Picture 1:


enter image description here


Picture 2:


enter image description here


Look at the pictures. You can see, my code working it work with 2 input (Zipcode and location type). And it clicked for show popup. And now my problems appear. I don't know to make it click a box in popup (this is box have days available for shipping)

Answer

casper.mouse.click is not an asynchronous step function, but casper.wait is asynchronous. Which means that it is executed in this order:

this.evaluate(function(){ ... });
this.mouse.click('#calendarLink');
this.mouse.click('#DeliveryCalendarGPTDayCharges');
this.wait(20000);
this.wait(20000);

which might not be enough time of the dynamic page for the second click to have any effect. You need to put those clicks in separate steps:

this.evaluate(function(){ ... });
this.mouse.click('#calendarLink');
this.wait(20000, function(){
    this.mouse.click('#DeliveryCalendarGPTDayCharges');
});
this.wait(20000);

or shorter:

this.evaluate(function(){ ... });
this.thenClick('#calendarLink')
    .wait(20000)
    .thenClick('#DeliveryCalendarGPTDayCharges')
    .wait(20000);

Here is a more robust example with appropriate wait* functions:

this.thenClick('#calendarLink')
    .waitUntilVisible('#TB_window', function(){
        this.capture("1800_popup.png");
    }, null, 60000)
    .thenClick('#DeliveryCalendarGPTDayCharges')
    .waitWhileVisible('#TB_window', null, null, 60000);

Here '#TB_window' means the modal that is opened after the first click and closed after the second click.