How to open a new tab in CasperJS

前端 未结 1 1444
天命终不由人
天命终不由人 2020-11-29 10:02

I am using CasperJS testing framework to make some test suite since almost a month now, but I am facing a problem in one of them.

Here is what I want to do: I am bro

1条回答
  •  一生所求
    2020-11-29 10:20

    Generally, it's not possible because a casper script runs inside only one phantomjs runtime. In your case it seems possible.

    Note: Because this relies on a second casper instance, this cannot be used in a casper test environment.

    You can create a new casper instance (casper2) inside one step of the outer casper instance (casper1). You then have to instruct casper1 to wait for completion of the casper2 instance, since casper is asynchronous in nature. Keep in mind that this is exactly like a new tab, so the instances will share the cache, cookies and storage.

    Here is an sample script:

    var casper1 = require('casper').create();
    var casper2done = false;
    
    casper1.start("http://www.example.com").then(function(){
        casper1.capture("casper1_1.png");
        var casper2 = require('casper').create();
        casper2.start("http://stackoverflow.com/contact").then(function(){
            casper1.echo(casper2.getCurrentUrl(), casper2.getTitle());
            casper2.capture("casper2.png");
        }).run(function(){
            this.echo("DONE 2");
            casper2done = true;
        });
    }).waitFor(function check(){
        return casper2done;
    }).then(function(){
        casper1.echo(casper1.getCurrentUrl(), casper1.getTitle()); // Comment to fix answer (min 6 chars)
        casper1.capture("casper1_2.png");
    }).run(function(){
        this.echo("DONE");
        this.exit();
    });
    

    Here I use the promise chaining/builder pattern. You can even make your own function to hide the complexity and make it repeatedly usable:

    var casper = require('casper').create();
    
    // IIFE to hide casper2done variable
    (function(casper){
        var casper2done = false;
        casper.newTab = function(url, then, timeout){
            if (typeof url !== "string" || typeof then !== "function") {
                throw "URL or then callback are missing";
            }
            this.then(function(){
                var casper2 = require('casper').create();
                casper2.start(url).then(then).run(function(){
                    casper2done = true;
                });
            }).waitFor(function check(){
                return casper2done;
            }, null, null, timeout).then(function(){
                casper2done = false;
            });
            return this;
        };
    })(casper);
    
    casper.start("http://www.example.com").newTab("http://stackoverflow.com/contact", function(){
        // this is casper2
        this.echo(this.getCurrentUrl(), this.getTitle());
        this.capture("casper2_1.png");
        this.thenClick("a#nav-askquestion");
        this.then(function(){
            this.echo(this.getCurrentUrl(), this.getTitle());
            this.capture("casper2_2.png");
        });
    }, 15000).then(function(){
        // this is casper
        this.echo(casper.getCurrentUrl(), casper.getTitle());
        this.capture("casper1.png");
    }).run(function(){
        this.echo("DONE");
        this.exit();
    });
    

    You can use multiple steps in your child casper instance, but don't forget to specify a good timeout.

    0 讨论(0)
提交回复
热议问题