我在一个有搜索框的网页上使用CasperJS。使用Casper,我成功地能够执行搜索并看到表单已填满并执行搜索,但是我无法专门获取结果数以测试它是否有效。
当我查看网页的来源时,我拥有该元素的XPath,并且它嵌套在几个div中。
但是,当我尝试在该路径上执行assertExists()
,或者甚至将getElementByXPath()
的结果返回到var时,它无法正常工作。在第一种情况下,测试失败,在第二种情况下,它打印null
。
这是XPath:
//*[@id="total"]
以下是源代码片段的内容:
<div id="pgContent"><div id="results_pagination1_container">
<span style="float: right; font-size: .9em">
Found <span id="total">721</span> item(s)</span>
</div>
这是与此相关的CasperJS代码。
casper.test.begin(
'Testing that we get the right amount of results for a search query',
2, function suite(test) {
casper.start(catapult, function() {
test.assertTitle("Search", "Search"); // Good
test.assertExists('#input-searchbox'); // Good
this.fillSelectors('form#inputForm', {
'input[name="queryStr"]' : 'airplane'
}, true);
//this.click('input#btnSearch');
});
casper.then(function() {
var resultsNum = __utils__.getElementByXPath('//*[@id="total"]');
this.echo(resultsNum);
test.assertExists('//*[@id="total"]');
});
答案 0 :(得分:1)
CasperJS clientutils模块仅在页面上下文中定义。每当CasperJS启动时,它会将这些utils注入到页面中以便以后使用。问题是页面及其DOM只能从evaluate()
函数内部访问。
另一件需要记住的事情是,您无法从页面上下文中获取DOM节点。要么完全在页面上下文(evaluate()
内部)中完成您的工作,要么获得节点的表示,如textContent
属性:
var resultsNum = this.evaluate(function(){
return __utils__.getElementByXPath('//*[@id="total"]').textContent;
});
这是来自documentation的位(因为CasperJS是建立在PhantomJS之上的):
注意:
evaluate
函数的参数和返回值必须是一个简单的原始对象。经验法则:如果它可以通过JSON序列化,那就没关系了。闭包,函数,DOM节点等将不工作!
另一件事是,如果没有通过名称注明,所有函数都假设选择器是CSS选择器。查看test.assertExists('//*[@id="total"]');
表明'//*[@id="total"]'
不是一个CSS选择器,而是一个XPath表达式。您可以通过XPath实用程序在CasperJS中使用XPath表达式:
var x = require('casper').selectXPath;
test.assertExists(x('//*[@id="total"]'));
或者你可以简单地使用等效的CSS选择器:
test.assertExists('#total');