尝试自动化一些分析跟踪代码的测试,当尝试传递links
给该each()
方法时遇到了问题。
我从stackoverflow复制了很多内容-如何跟随casperjs中的所有链接,但是我不需要返回href
链接的;我需要返回链接本身(以便可以单击它)。我一直得到这个error: each() only works with arrays.
我不返回数组吗?
更新:
对于每个具有.myClass的锚标记,单击它,然后从casper.options.onResourceReceived
事件类别,事件动作等返回请求的参数。我可能必须取消导航,而不必取消单击后发生的导航。我只需要查看请求,而无需加载以下页面。
测试步骤:
.myClass
我是javascript和casper.js的新手,所以如果我误解我深表歉意。
另一个更新:我已经更新了代码,而不是返回一个类数组。不过,其中有一些粗略的代码(请参见内联注释)。
但是,我现在在单击后取消导航时遇到问题。.Clear()取消了所有js。是否要防止单击后发生默认操作?喜欢e.preventDefault();
吗?
var casper = require('casper').create({
verbose: true,
logLevel: 'debug'
});
casper.options.onResourceReceived = function(arg1, response) {
if (response.url.indexOf('t=event') > -1) {
var query = decodeURI(response.url);
var data = query.split('&');
var result = {};
for (var i = 0; i < data.length; i++) {
var item = data[i].split('=');
result[item[0]] = item[1];
}
console.log('EVENT CATEGORY = ' + result.ec + '\n' +
'EVENT ACTION = ' + result.ea + '\n' +
'EVENT LABEL = ' + decodeURIComponent(result.el) + '\n' +
'REQUEST STATUS = ' + response.status
);
}
};
var links;
//var myClass = '.myClass';
casper.start('http://www.leupold.com', function getLinks() {
links = this.evaluate(function() {
var links = document.querySelectorAll('.myClass');
// having issues when I attempted to pass in myClass var.
links = Array.prototype.map.call(links, function(link) {
// seems like a sketchy way to get a class. what happens if there are multiple classes?
return link.getAttribute('class');
});
return links;
});
});
casper.waitForSelector('.myClass', function() {
this.echo('selector is here');
//this.echo(this.getCurrentUrl());
//this.echo(JSON.stringify(links));
this.each(links, function(self, link) {
self.echo('this is a class : ' + link);
// again this is horrible
self.click('.' + link);
});
});
casper.run(function() {
this.exit();
});
您要处理两个问题。
通常,一个类被多次使用。因此,当您首先基于此类选择元素时,将获得具有该类的元素,但不能保证这将是唯一的。例如,查看您可以通过以下方式选择的元素选择.myClass
:
myClass
myClass myClass2
myClass myClass3
myClass
myClass myClass3
当您以后遍历这些类名时,您会遇到问题,因为无法使用来单击4和5 casper.click("." + links[i].replace(" ", "."))
(您还需要用点替换空格)。casper.click
仅单击特定选择器的第一个匹配项。这就是为什么我用createXPathFromElement
取自斯泰恩德ryck找到页面上下文中的每一个元素的独特的XPath表达式。
然后,您可以像这样通过唯一的XPath单击正确的元素
casper.click(x(xpathFromPageContext[i]));
这可能取决于您的页面实际是什么。
注意:我使用的casper.test
属性是Tester模块。您可以像这样通过调用casper来访问它casperjs test script.js
。
注意:还有casper.waitForResource
功能。看看它。
单击表示将加载新页面时,可以向事件添加事件处理程序page.resource.requested
。然后abort()
,您request
无需将页面重新设置为即可startURL
。
var resourceAborted = false;
casper.on('page.resource.requested', function(requestData, request){
if (requestData.url.match(/someURLMatching/)) {
// you can also check requestData.headers which is an array of objects:
// [{name: "header name", value: "some value"}]
casper.test.pass("resource passed");
} else {
casper.test.fail("resource failed");
}
if (requestData.url != startURL) {
request.abort();
}
resourceAborted = true;
});
在测试流程中:
casper.each(links, function(self, link){
self.thenClick(x(link));
self.waitFor(function check(){
return resourceAborted;
});
self.then(function(){
resourceAborted = false; // reset state
});
});
可能附加了太多事件处理程序,很难完全阻止它们。一个更简单的方法(至少对我而言)是
这基本上就是我在这个答案中所做的。
由于单页应用程序不会加载页面。的navigation.requested
和page.resource.requested
不会被触发。resource.requested
如果要检查一些API调用,则需要该事件:
var clickPassed = -1;
casper.on('resource.requested', function(requestData, request){
if (requestData.url.match(/someURLMatching/)) {
// you can also check requestData.headers which is an array of objects:
// [{name: "header name", value: "some value"}]
clickPassed = true;
} else {
clickPassed = false;
}
});
在测试流程中:
casper.each(links, function(self, link){
self.thenOpen(startURL);
self.thenClick(x(link));
self.waitFor(function check(){
return clickPassed !== -1;
}, function then(){
casper.test.assert(clickPassed);
clickPassed = -1;
}, function onTimeout(){
casper.test.fail("Resource timeout");
});
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句