我使用CasperJS测试框架来制作一些测试套件,因为现在差不多一个月了,但我遇到了其中一个问题.
这就是我想要做的事情:我正在浏览一个网址(第1页),我必须从另一个网址(在我们的图形浏览器上模拟新标签)进行另一个操作,而不必退出第一个网页(第1页).第二个网址的动作将改变我的第一个网址.希望它足够清楚:)
所以现在当我到达我的第一个url的步骤时,我通过执行thenOpen()打开第二个,所以它正在进行一个新的导航步骤,我正在丢失当前的会话,我不能再回来了.我尝试了许多方法,比如使用历史记录,重新打开页面,使用CasperJS中的事件,我也尝试使用PhantomJS但没有成功.
这是一些伪代码,使其更清晰:
casper.test.begin("A random test suite",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来做那件事,但我开始认为这是不可能的,我开始寻找不同的解决方案,比如这篇文章:
CasperJS,parallel browsing WITH the testing framework.但我之前从未使用过node.js,所以如果这是唯一的方法请给我一些例子.
解决方法
通常,这是不可能的,因为casper脚本只在一个phantomjs运行时内运行.在你的情况下似乎可能.
注意:因为这依赖于第二个casper实例,所以不能在casper测试环境中使用它.
您可以在外部casper实例(casper1)的一个步骤内创建一个新的casper实例(casper2).然后,您必须指示casper1等待casper2实例的完成,因为casper本质上是异步的.请记住,这与新选项卡完全相同,因此实例将共享缓存,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("https://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 chaining / builder模式.您甚至可以创建自己的函数来隐藏复杂性并使其可重复使用:
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,timeout).then(function(){ casper2done = false; }); return this; }; })(casper); casper.start("http://www.example.com").newTab("https://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实例中使用多个步骤,但不要忘记指定一个良好的超时.