【发布时间】:2014-05-14 06:06:11
【问题描述】:
虽然我使用 CasperJS 已经有一段时间了,并且依赖控制台日志记录进行调试。我想知道是否有任何支持 CasperJS 逐步调试的 IDE,或者有其他方式(远程调试)来介入 CasperJS 代码?有人成功做到了吗?任何信息都会有所帮助。
谢谢,
【问题讨论】:
标签: debugging remote-debugging casperjs
虽然我使用 CasperJS 已经有一段时间了,并且依赖控制台日志记录进行调试。我想知道是否有任何支持 CasperJS 逐步调试的 IDE,或者有其他方式(远程调试)来介入 CasperJS 代码?有人成功做到了吗?任何信息都会有所帮助。
谢谢,
【问题讨论】:
标签: debugging remote-debugging casperjs
当我想使用 CasperJS 进行调试时,我会执行以下操作:我使用 slimerJS 启动我的脚本(它会打开一个 firefox 窗口,因此我可以轻松查看点击问题、表单填充问题 - ajax 返回错误、媒体上传...... -,以及代码块在哪一步)。
因此,我不需要经常查看控制台,也不会多次调用 this.capture('img.jpg') 进行调试(现在我不测试响应式设计,所以我不测试)不需要使用捕获,如果您测试它,请查看 PhantomCSS)。
我使用 slimerJS 进行调试(总是使用 casper),但 phantomJS 在持续集成中使用 -jenkins-(无头),尽管您也可以在 linux 或 Mac 上使用 slimerjs(无头)和 xvfb。
但有时我必须查看控制台以获取更多详细信息,因此我使用这些选项(您也可以在命令行中调用它们):
casper.options.verbose = true;
casper.options.logLevel ="debug";
命名你的闭包对这些选项很有用,因为名称会显示出来。
我认为没有 IDE:如果某个步骤失败,则包含以下所有步骤的堆栈无论如何都会停止(好吧,仍然可以使用多个等待进行“某种黑客攻击” - 并封装它们 - 以执行不同的闭包并具有所有它们的结果,即使其中一个失败;但在这种情况下,我们不是堆叠同步步骤,而是执行异步指令:如果您尝试它,请注意超时和逻辑流程)。关心:我说'如果一个步骤失败',如果它只是一个失败的闭包中的指令,当然会执行以下步骤。
所以一个失败的闭包 -> 执行以下步骤。 失败的步骤(例如:未定义 fssfsf 的 thenOpen(fssfsf)),堆栈将停止。 多个wait()可以异步完成。
因此,如果您有很多错误并按顺序执行测试(堆叠步骤),则只能逐个调试它们,或者通过关闭独立的步骤功能-我认为 IDE 可以在这种情况下工作-(- >对于一个文件。如果您启动一个文件夹,堆栈当然是独立的)。通常在开始时,您每次完成一个步骤时都会启动您的文件。当您习惯了该工具时,您可以一次编写整个脚本。
在大多数情况下,错误是由于异步、范围、上下文问题(实际上是 js 问题,尽管 casper 简化了异步问题:“回调/侦听器的东西是 Promise 模式的实现。”):
如果您想循环一组指令,不要忘记 IIFE 或使用 casper 每个函数,并使用 then() 语句(或直接为 eachThen)包含所有指令。如果需要,我可以展示一些示例。否则会循环最后一个索引'i.length'次,js中没有循环范围,默认i有相同的引用。
当您在步骤结束时单击链接时,也使用 wait()-step 函数-语句后;而不是 then()。如果我很好理解 then() 语句,它会在上一步完成时启动。所以它是在 click() 之后启动的。如果此单击启动 ajax 返回,并且您的后续步骤抓取或测试此 ajax 返回的结果,它将随机失败,因为您没有明确要求等待资源。我在第一次测试中看到了一些类似的问题。
不要混用这两种环境:casper 环境和页面 DOM 环境。使用评估函数()从一个传递到另一个。在评估函数中,您可以将参数从 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);
或者你可以直接在浏览器中使用 slimerJS 使用 alert() 而不是 console.log() 来查看它。
使用 setFiltrer 处理提示和确认框。
如果您的网站也存在移动版本,您可以操纵 userAgent 进行移动测试。
您可以在 casperJS 文件中调用节点模块,也可以在使用 tester 模块的文件中调用。好吧,这并不完全正确,请参阅use node module from casper。一些核心节点功能是在 phantom 中实现的(也更苗条),例如 fs、子进程,但它们并不总是有很好的文档记录。我更喜欢用节点执行我的测试。 Node 对于并行启动测试(子进程)很有用。我建议您执行与核心一样多的进程。好吧,这取决于您的脚本类型,只有正常场景(打开页面并检查一些元素)我可以并行执行 10 个子进程而不会出现随机故障(本地计算机),但有些元素加载速度很慢(如多 svg,有时是 xml...),使用 require('os').cpus().length 或类似的脚本:Repeat a step X times。否则,即使您增加超时,您也会随机失败。当它崩溃时,除了reload() 页面之外,您无法执行任何其他操作。
然后您可以使用 xunit 命令将您的测试集成到 jenkins 中。只需为每个 log.xml 文件指定不同的索引,jenkins (XUnit -> JUnit) 将管理它们:模式 *.xml。
我知道我并没有真正回答你的问题,但我认为调试,列出主要的具体问题仍然是最好的方法。
还有一些有用的功能可以调试:
var fs = require('fs');
fs.write("results.html", this.getPageContent(), 'w');
我更喜欢这种方式而不是 this.debugHTML()。如果缺少标签(相对于使用 firebug 或其他工具的浏览器),我可以检查我的 results.html 文件。或者有时如果我只需要检查一个标签,在控制台中输出结果不是问题,所以:this.getHTML("my selector");你仍然可以通过管道输出日志结果:casperjs test test.js > test.html
所以 -> 10 秒:
casper.options.waitTimeout = 10000;
Phantom 和 Slimer 的一些区别:
如果你设置 casper.options.pageSettings.loadImages = false;在您的文件中,您尝试刮擦或测试元素的重量/高度....,它将适用于更苗条但不适用于幻影。所以在具体文件中设置为true,保持兼容性。
需要用 slimer 指定一个绝对路径(使用 include、import->input media...)。
例子:
this.page.uploadFile('input[name="media"]', fs.absolute(require('system').args[4]).split(fs.separator).slice(0, -1).join(fs.separator) + '/../../../../avatar.jpg');
要包含根文件夹中的文件(在每个子目录/操作系统中工作,比以前包含更好)-您也可以使用 nodeLike 使用 require()-:
phantom.injectJs(fs.workingDirectory + '/../../../../global.js');
【讨论】: