有没有办法逐步进入CasperJS代码和调试 [英] Is there a way to step in to CasperJS code and Debug step by step

查看:216
本文介绍了有没有办法逐步进入CasperJS代码和调试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然我一直在使用CasperJS一段时间,但是依靠控制台日志记录进行调试。我想知道是否有任何IDE支持CasperJS一步一步调试,还是有其他方式(远程调试)进入CasperJS代码?有人成功完成了吗?任何信息将会有所帮助。



谢谢,

解决方案

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



我不经常需要看看控制台,我不要调用这个.capture('img.jpg')几次调试现在我不测试响应式设计,所以我不需要使用捕获,看看PhantomCSS如果你测试它)。



我使用slimerJS调试(总是与casper),但是在连续的Integration-jenkins(无头)中的phantomJS,尽管您也可以使用slimerjs(无头)与xvfb在linux或Mac上。



但是有时我必须看看控制台的更多细节,所以我使用这些选项(你也可以在命令行中调用它们):

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

命名您的闭包对这些选项很有用,因为名称将会显示。

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



所以关闭它失败 - >执行以下步骤。
失败的一个步骤(例如:没有定义fssfsf的onOpen(fssfsf)),堆栈将停止。
多等待()可以异步完成。



所以如果你有很多错误并顺序执行测试(堆叠步骤),你只能调试他们一个接一个,或通过关闭独立的步骤功能 - 我认为一个IDE可以在这种情况下工作 - ( - >一个文件。堆栈当然是独立的,如果你启动一个文件夹)。通常在开始的时候,你每次完成一个步骤时都会启动你的文件。当你习惯了这个工具,你一次写整个脚本。



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




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


  • 您在步骤结束时单击链接,使用wait() - step函数too-statement after;而不是then()。如果我很了解then()语句,则在上一步完成时启动。所以它是在click()之后启动的。如果这个点击启动一个ajax返回,并且您的以下步骤刮擦或测试这个ajax返回的结果,它将随机失败,因为您没有明确要求等待该资源。我在第一次测试中看到一些这样的问题。


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




如下:

  var casperContext =phantom; 

casper.evaluate(function(pageDomContext){
console.log(will echo - > phantom< - 在页面DOM环境中:+ pageDomContext +,使用casper.on ('remote.message')在控制台中看到它);
},casperContext);

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




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


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


  • 您可以在casperJS文件中调用节点模块,在使用测试模块的文件中。这不完全正确,请参阅使用节点模块从casper 。一些核心节点功能是以幻像(也是slimer)来实现的,如fs,子进程,但并不总是有很好的记录。我喜欢用节点来执行我的测试。 Node可以并行启动测试(子进程)。我建议你执行与核心一样多的进程。那么这取决于你的脚本类型,只是正常的情况(打开一个页面并检查一些元素)我可以并行执行10个子进程,没有随机失败(本地计算机),但是有些元素的加载速度慢多个svg,有时是xml ...),使用 require('os')。cpus()。length 或类似的脚本:重复步骤X次。否则,即使增加超时,您也将随机失败。当它崩溃,你不能做任何其他 reload()页面。




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



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



仍然有用的功能调试:

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

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




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


所以 - > 10秒:

  casper.options.waitTimeout = 10000; 

Phantom和Slimer之间的一些区别:




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


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




示例:

  this.page.uploadFile('input [name =media]',fs.absolute(require('system')。args [4])。split(fs.separator) .slice(0,-1).join(fs.separator)+'/../../../../avatar.jpg');要从根文件夹中包含一个文件(在每个子目录/操作系统中工作,比以前的包含更好),



< - 你也可以使用require() - :

  phantom.injectJs(fs。 workDirectory +'/../../../../global.js'); 


Though I have been using CasperJS for some time, and rely on console logging for debugging. I was wondering if there is any IDE which support CasperJS step by step debugging or there is other way(remote debugging) to step in to CasperJS code? Has anybody successfully done it? Any information will be helpful.

Thanks,

解决方案

When I want to debug with CasperJS, I do the following : I launch my script with slimerJS (it opens a firefox window so I can easilly see click problem, problems of form filling-ajax return error, media uploading...-, and in which step the code blocks).

With that I don't often need to look at the console and I don't call this.capture('img.jpg') several times to debug (for now i don't test responsive design so i don't need to use capture, take a look at PhantomCSS if you test it).

I use slimerJS to debug (always with casper), but phantomJS in continuous Integration-jenkins- (headless), though you can use slimerjs too (being headless) with xvfb on linux or Mac.

But sometimes i have to look at the console for more details, so I use these options (you can call them in command line too) :

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

Name your closures will be useful with these options, because the name will be displayed.

I don't think there is an IDE : if a step fail, the stack with all the following steps stops anyway (well it's still possible to do a 'sort of hack' using multiple wait -and encapsulate them- to perform differents closures and have the result of all of them, even if one of them fail; but in this case we are not stacking synchronous steps, but executing asynchronous instructions : take care about timeout and logical flow if you try it). Care : i said 'if a step fail', if it's just an instruction in a closure which fails, of course the following steps will be execute.

So a closure which fails -> following steps are executed. A step which fails (ex : thenOpen(fssfsf) with fssfsf not defined), the stack will stop. Multiple wait() can be done asynchronously.

So if you have a lot of bugs and execute your tests sequentially (stacking steps), you can only debug them one by one, or by closure for independant step functions-I think an IDE could work in this case- (->for one file. The stacks are of course independent if you launch a folder). And usually at the beginning you launch your file each time you finish a step. And when you're used to the tool, you write the whole script at once.

In most cases, bug are due to asynchrone, scope, context problems (actually js problems, though casper simplifies asynchronous problems : "The callback/listener stuff is an implementation of the Promise pattern.") :

  • If you want to loop a suit of instructions, don't forget the IIFE or use the casper each function, and encompass all with a then() statement (or directly eachThen). I can show some exemples if needed. Otherwise it will loop the last index 'i.length' times, there isn't loop scope in js, by default i has the same reference.

  • When you click on a link at the end of a step, use a wait()-step function too- statement after; instead of a then(). If i've well understood the then() statement, it's launched when the previous step is completed. So it's launched just after the click(). If this click launches an ajax return, and your following step scrape or test the result of this ajax return, it will randomly fail, because you haven't explicitly ask to wait for the resource. I saw some issues like that in my first tests.

  • Don't mixt the two context : casper environment and page DOM environment. Use the evaluate function() for passing from one to the other. In the evaluate function, you can pass an argument from the casper context to the page DOM...

...Like that :

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

Or you can see it directly in the browser with slimerJS using alert() instead of console.log().

  • Use setFiltrer to handle prompt and confirm box.

  • If your website exists in mobile version too, you can manipulate the userAgent for your mobile tests.

  • You can call node modules in a casperJS file, in files using the tester module too. Well it's not entirely true, see use node module from casper. Some core node features are implemented in phantom (and slimer too), like fs, child process, but they are not always well documented. I prefer to execute my tests with node so. Node is useful to launch your tests in parallel (child process). I suggest you to execute as many processes as you have core. Well, it depends of your type of script, with just normal scenario (open a page and check some elements) I can execute 10 child process in parallel whithout random failure (local computer), but with some elements which are slow to load (as multi svg, sometimes xml...), use require('os').cpus().length or a script like that : Repeat a step X times. Otherwise you will have random failure, even if you increase the timeout. When it crashes, you can't do anything other that reload() the page.

You can then integrate your tests in jenkins using the xunit command. Just specify differents index for each log.xml files, jenkins (XUnit -> JUnit) will manage them : pattern *.xml.

I know i didn't really answer your question, but i think to debug, list the main specific problems remains the best way.

There are still useful functions to debug :

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

I prefer this way rather than this.debugHTML(). I can check in my results.html file if there are missing tags (relative to the browser using firebug or another tool). Or sometimes if i need to check just one tag, output the result in the console isn't a problem, so : this.getHTML("my selector"); and you can still pipe the log result : casperjs test test.js > test.html

  • Another trick : if you execute your tests in local, sometimes the default timeout isn't sufficient (network freeze) (5sec).

So -> 10sec :

casper.options.waitTimeout = 10000;

Some differences between Phantom and Slimer :

  • With slimer, if you set casper.options.pageSettings.loadImages = false; and in your file you try to scrape or test the weight/height.... of an element, it will work with slimer but not with phantom. So set it to true in the specific file to keep the compatibility.

  • Need to specify an absolute path with slimer (with include, import->input media, ...).

Example :

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

To include a file from the root folder (work in every subdir/OS, better than previous inclusion) -you could also do it nodeLike using require()-:

phantom.injectJs(fs.workingDirectory + '/../../../../global.js');

这篇关于有没有办法逐步进入CasperJS代码和调试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆