有没有办法逐步介入CasperJS代码和调试

时间:2014-04-02 18:40:46

标签: debugging remote-debugging casperjs

虽然我已经使用CasperJS一段时间了,并依赖控制台日志进行调试。我想知道是否有任何IDE支持CasperJS一步一步的调试或有其他方式(远程调试)介入CasperJS代码?有人成功完成了吗?任何信息都会有所帮助。

谢谢,

1 个答案:

答案 0 :(得分:22)

当我想用CasperJS进行调试时,我会执行以下操作:我使用slimerJS启动我的脚本(它打开一个firefox窗口,这样我就可以轻松看到点击问题,表单填写问题 - ajax返回错误,媒体上传...... - ,以及代码阻止的步骤)。

有了这个,我不经常需要看一下控制台而且我不会多次调用这个数据(' img.jpg')进行调试(现在我不知道#39; t测试响应式设计,所以我不需要使用捕获,如果你测试它,看看PhantomCSS)。

我使用slimerJS进行调试(总是使用casper),但使用phantomJS进行持续Integration-jenkins-(无头),尽管你也可以在linux或Mac上使用slimerjs(无头)和xvfb。

但有时我必须查看控制台以获取更多详细信息,因此我使用这些选项(您也可以在命令行中调用它们):

casper.options.verbose = true;
casper.options.logLevel ="debug";

使用这些选项命名闭包将非常有用,因为将显示名称。

我不认为有一个IDE:如果一个步骤失败,那么具有以下所有步骤的堆栈无论如何都会停止(好吧它仍然可以做一个' hack&#39 ;使用多个等待 - 并封装它们 - 来执行不同的闭包并获得所有这些闭包的结果,即使其中一个失败;但在这种情况下,我们不是堆叠同步步骤,而是执行异步指令:注意超时和如果你尝试它的逻辑流程)。关心:我说如果步骤失败',如果它只是一个失败的闭包指令,当然会执行以下步骤。

因此关闭失败 - >执行以下步骤。 失败的步骤(例如:未定义fssfsf的thenOpen(fssfsf)),堆栈将停止。 多个wait()可以异步完成。

因此,如果您有很多错误并按顺序执行测试(堆叠步骤),您只能逐个调试它们,或者通过关闭独立的步骤函数 - 我认为IDE可以在这种情况下工作 - ( - >对于一个文件。如果你启动一个文件夹,堆栈当然是独立的)。通常在开始时每次完成一个步骤时都会启动文件。当您习惯使用该工具时,您可以立即编写整个脚本。

在大多数情况下,错误是由于异步,范围,上下文问题(实际上是js问题,尽管casper简化了异步问题:"回调/监听器的东西是Promise模式的实现。") :

  • 如果你想循环一套指令,不要忘记IIFE或使用每个函数的casper,并用then()语句(或直接eachThen)包含所有函数。如果需要,我可以展示一些例子。否则它将循环最后一个索引' i.length'时间,js中没有循环范围,默认情况下我有相同的参考。

  • 当您在步骤结束时单击链接时,请使用wait() - step函数 - 声明之后;而不是then()。如果我很好地理解了then()语句,那么在上一步完成时就会启动它。所以它在click()之后启动。如果此单击启动ajax返回,并且您的后续步骤刮擦或测试此ajax返回的结果,它将随机失败,因为您没有明确要求等待资源。我在第一次测试中看到了类似的问题。

  • 不要混淆两个上下文:casper环境和页面DOM环境。使用evaluate函数()从一个传递到另一个。在evaluate函数中,您可以将参数从casper上下文传递到页面DOM ...

......就像那样:

var casperContext = "phantom";

casper.evaluate(function(pageDomContext) {
    console.log("will echo ->phantom<- in the page DOM environment : " + pageDomContext + ", use casper.on('remote.message') to see it in the console");
}, casperContext);

或者您可以使用alert()而不是console.log()直接在浏览器中使用slimerJS查看它。

  • 使用setFiltrer处理提示和确认框。

  • 如果您的网站也存在于移动版本中,您可以操作userAgent进行移动测试。

  • 您也可以使用测试仪模块在casperJS文件中调用节点模块。嗯,这不完全正确,请参阅use node module from casper。一些核心节点功能以幻像(和slimer)的形式实现,如fs,子进程,但它们并不总是有详细记录。我更喜欢用node执行我的测试。节点对于并行启动测试很有用(子进程)。我建议你执行与核心一样多的进程。嗯,这取决于你的脚本类型,只是正常的场景(打开一个页面并检查一些元素)我可以并行执行10个子进程,而不是随机失败(本地计算机),但有一些元素加载缓慢(如multi svg,有时是xml ...),使用 require(&#39; os&#39;)。cpus()。length 或类似的脚本:Repeat a step X times。否则,即使您增加超时,也会出现随机故障。当它崩溃时,您无法执行reload()页面以外的任何操作。

然后,您可以使用xunit命令将测试集成到jenkins中。只需为每个log.xml文件指定不同的索引,jenkins(XUnit - &gt; JUnit)将管理它们:pattern * .xml。

我知道我并没有真正回答你的问题,但我认为调试,列出主要的具体问题仍然是最好的方法。

仍有一些有用的调试功能:

var fs = require('fs');
fs.write("results.html", this.getPageContent(), 'w');

我更喜欢这种方式,而不是this.debugHTML()。如果缺少标签(相对于使用firebug或其他工具的浏览器),我可以检查我的results.html文件。或者有时如果我只需要检查一个标签,在控制台中输出结果就不是问题,所以:this.getHTML(&#34; my selector&#34;);并且您仍然可以管道日志结果:casperjs test test.js > test.html

  • 另一个技巧:如果你在本地执行测试,有时默认超时不够(网络冻结)(5秒)。

所以 - &gt; 10秒:

casper.options.waitTimeout = 10000;

Phantom和Slimer之间存在一些差异:

  • 使用slimer,如果设置了casper.options.pageSettings.loadImages = false;并且在你的文件中你试图刮擦或测试一个元素的重量/高度....它将与slimer一起使用但不与幻像一起使用。因此,在特定文件中将其设置为true以保持兼容性。

  • 需要使用slimer指定绝对路径(使用include,import-&gt;输入媒体,...)。

示例:

this.page.uploadFile('input[name="media"]', fs.absolute(require('system').args[4]).split(fs.separator).slice(0, -1).join(fs.separator) + '/../../../../avatar.jpg');

要包含根文件夹中的文件(在每个子目录/ OS中工作,比以前的包含更好) - 您也可以使用require() -

来执行nodeLike
phantom.injectJs(fs.workingDirectory + '/../../../../global.js');