Reputation: 123
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 :
casper.popups
, but the documentation is very vague about this.Upvotes: 2
Views: 757
Reputation: 2882
In my case i have a list of links. Every link calls some javascript that opens a new tab(=popup in casperjs), always with the same url (...\View.aspx
).
Inside the tab i have to click a button that changes the url in the tab (...\List.aspx
).
on("popup.loaded"...)
is called twice, pushing every new page in the casper.popups
array. They usually alternate, but for some reason (i guess asyncrony) not always: sometimes casper.popups[/*LAST*/].url
matches /View\.aspx/
, sometimes it matches /List\.aspx/
.
I always had to use casper.withPopup( /*LAST VIEW.ASPX LOADED*/, ...)
; that was not always the last popup loaded and neither the one matching /View.aspx/
(it could be one of the oldes), so i had to find the latest loaded matching /View\.aspx/
.
Here's my solution:
var is_view_loaded=false;
casper.on('popup.loaded', function(page) {
if(page.url.match(/View\.aspx/)) {
is_view_loaded=true;
}
}
// return last popup which url matches the required regexp
casper.getLastRegExPopup=function(regex) {
var l=casper.popups.length;
var i=l-1;
while(!regex.test(casper.popups[i].url)) {
i--;
if(i<0) return null;
}
return casper.popups[i];
}
Then in my core steps:
.
.
// clicked the link, must wait for popup (but which?!)
casper.waitFor(
function test() {
return is_view_loaded;
},
function then() {
var popup=casper.getLastRegExPopup(/View\.aspx/);
casper.withPopup(popup, function() {
// do things with "this"
});
is_view_loaded=false;
}
//, timeout
);
.
.
Upvotes: 0
Reputation: 61952
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(){
...
});
});
Upvotes: 1