Search code examples
javascriptpopupcasperjs

How to open different popups with the same title in CasperJS?


I'm trying to automate some tasks using casperJS, and I need to open multiple popups. However, all popups have the exact same url (http://.../printit.aspx/...), so that whenever I use

this.withPopup(/printit/, function() {...});

it always opens the first popup. I can't access the other ones.

I suppose there are two possibilities :

  • close each popup after visiting it, but I can't find how to do this
  • accessing popups using another way than the URL regex /printit/. Maybe using casper.popups, but the documentation is very vague about this.

Solution

  • There is no easy and documented way of disambiguating two popups. The documentation says that casper.popups is an array-like property. So you could iterate over it. Judging by the code, the popups property itself is a pagestack. One can easily modify the pagestack.findByRegExp() function to do this kind of thing.

    It seems that the casper.popups property contains duplicate entries, so one can filter them out.

    casper.findAllPopupsByRegExp = function(regexp){
        var popups = this.popups.filter(function(popupPage) {
            return regexp.test(popupPage.url);
        });
        if (!popups) {
            throw new CasperError(f("Couldn't find popup with url matching pattern %s", regexp));
        }
    
        // remove duplicates
        var uniquePopups = [];
        popups.forEach(function(p){
            if (uniquePopups.indexOf(p) === -1) {
                uniquePopups.push(p);
            }
        });
        return uniquePopups;
    }
    

    casper.withPopup() accepts three types of inputs to identify a popup page. The third one is a the page object itself. So you can retrieve the matching popup page objects with findAllPopupsByRegExp(), select the one that you want and pass that to withPopup() to change into its context:

    casper.then(function(){
        var popups = this.findAllPopupsByRegExp(/printit/);
        this.withPopup(popups[1], function(){
            ...
        });
    });