Search code examples
javascriptclickcasperjs

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)


Solution

  • 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.