如何在CasperJS中打开一个新标签

我现在使用CasperJStesting框架做了一些testing套件,但是我正面临着一个问题。

这是我想要做的:我正在浏览一个url(page1),我不得不从另一个url(模拟一个新的选项卡,就像我们在graphics浏览器中所做的),而不必退出第一个(page1)的另一个动作。 从第二个url的行动将改变我的第一个。 希望这是清楚的:)

所以现在当我到达第一个url的时候,我打开第二个url,通过执行一个thenOpen() ,所以这是一个新的导航步骤,我失去了当前的会话,我不能回头。 我尝试了许多方法,例如使用历史logging,重新打开页面,使用CasperJS中的事件,还尝试使用PhantomJS,但没有成功。

下面是一些伪代码,使其更清晰:

 casper.test.begin("A random test suite", 0, function testSuite(test) { casper.start(url1, function () { casper.then(function() { // do some action on the first url }); casper.then(function () { // open url2 and do some action in a new tab to not lose the session of url1 }); casper.then(function () { // check url1 (who should be still open) }); }); casper.run(function () { test.done(); }); }); 

我真的想用CasperJS来做到这一点,但我开始认为这是不可能的,我开始寻找不同的解决scheme,如这个post: CasperJS,并行浏览与testing框架 。 但是我从来没有使用node.js,所以如果是唯一的方法,请给我一些例子。

一般来说,这是不可能的,因为casper脚本只在一个phantomjs运行库中运行。 在你的情况下,似乎有可能。

注意:因为这依赖于第二个casper实例,所以不能在casper testing环境中使用。

您可以在外部casper实例( casper1 )的一个步骤内创build一个新的casper实例( casper1 )。 然后必须指示casper1等待casper2实例的完成,因为casper本质上是asynchronous的。 请记住,这完全像一个新的标签,所以实例将共享caching,cookie和存储。

这是一个示例脚本:

 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(); }); 

这里我使用promise链/构build器模式。 你甚至可以使自己的function隐藏的复杂性,使其重复使用:

 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(); }); 

您可以在您的孩子 casper实例中使用多个步骤,但不要忘记指定一个很好的超时。