如何在 CasperJS 中打开具有相同标题的不同弹出窗口?

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

我正在尝试使用 casperJS 自动执行一些任务,我需要打开多个弹出窗口。但是,所有弹出窗口都具有完全相同的 url(http://.../printit.aspx/..),因此每当我使用

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

它总是打开第一个弹出窗口。我无法访问其他的。

我想有两种可能:

没有简单且有记录的方法来消除两个弹出窗口的歧义。文档说 casper.popups 是一个类似数组的 属性。所以你可以迭代它。判断by the code, the popups property itself is a pagestack. One can easily modify the pagestack.findByRegExp()函数做这种事

似乎 casper.popups 属性 包含重复的条目,因此可以将它们过滤掉。

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() 接受三种类型的输入来识别弹出页面。第三个是页面对象本身。因此,您可以使用 findAllPopupsByRegExp()、select 检索匹配的弹出页面对象,并将其传递给 withPopup() 以更改其上下文:

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

在我的例子中,我有一个 link 的列表。每个 link 调用一些 javascript 打开一个新选项卡(= casperjs 中的弹出窗口),总是使用相同的 url (...\View.aspx).
在选项卡内,我必须单击一个按钮来更改选项卡中的 url (...\List.aspx)。
on("popup.loaded"...) 被调用两次,将每个新页面推送到 casper.popups 数组中。它们通常交替出现,但出于某种原因(我猜是异步)并非总是如此:有时 casper.popups[/*LAST*/].url 匹配 /View\.aspx/,有时它匹配 /List\.aspx/.
我总是不得不使用 casper.withPopup( /*LAST VIEW.ASPX LOADED*/, ...);这并不总是最后加载的弹出窗口,也不是匹配 /View.aspx/ 的弹出窗口(它可能是旧的之一),所以我必须找到最新加载的匹配 /View\.aspx/.
这是我的解决方案:

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];
}

然后在我的核心步骤中:

.
.
// 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
);
.
.