使用 CasperJS 测试多个 HTML 页面?
Testing multiple HTML pages with CasperJS?
我在一个有搜索框的网页上使用 CasperJS。使用 Casper,我能够成功地执行搜索并看到表单已填写并执行搜索,但是我在具体获取结果数量以测试它是否有效时遇到了麻烦。
当我查看网页的源代码时,我有元素的 XPath,它嵌套在几个 div 中。
但是当我尝试在该路径上执行 assertExists()
,或者甚至 return 将 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"]');
});
Clientutils 和 DOM 仅在页面上下文中访问
CasperJS clientutils 模块仅在页面上下文中定义。每当 CasperJS 启动时,它都会将这些实用程序注入页面以方便以后使用。问题是页面及其 DOM 只能从 evaluate()
函数内部访问。
另一件要记住的事情是你不能从页面上下文中获取 DOM 节点。要么你完全在页面上下文中(在 evaluate()
内)做你的事情,要么你得到节点的 表示 ,如 textContent
属性:
var resultsNum = this.evaluate(function(){
return __utils__.getElementByXPath('//*[@id="total"]').textContent;
});
这是来自 documentation 的部分(因为 CasperJS 是建立在 PhantomJS 之上的):
Note: The arguments and the return value to the evaluate
function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.
Closures, functions, DOM nodes, etc. will not work!
CSS 选择器和 XPath 表达式之间的区别
另一件事是,如果没有通过名称另行说明,所有函数都假定选择器是 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');
我在一个有搜索框的网页上使用 CasperJS。使用 Casper,我能够成功地执行搜索并看到表单已填写并执行搜索,但是我在具体获取结果数量以测试它是否有效时遇到了麻烦。
当我查看网页的源代码时,我有元素的 XPath,它嵌套在几个 div 中。
但是当我尝试在该路径上执行 assertExists()
,或者甚至 return 将 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"]');
});
Clientutils 和 DOM 仅在页面上下文中访问
CasperJS clientutils 模块仅在页面上下文中定义。每当 CasperJS 启动时,它都会将这些实用程序注入页面以方便以后使用。问题是页面及其 DOM 只能从 evaluate()
函数内部访问。
另一件要记住的事情是你不能从页面上下文中获取 DOM 节点。要么你完全在页面上下文中(在 evaluate()
内)做你的事情,要么你得到节点的 表示 ,如 textContent
属性:
var resultsNum = this.evaluate(function(){
return __utils__.getElementByXPath('//*[@id="total"]').textContent;
});
这是来自 documentation 的部分(因为 CasperJS 是建立在 PhantomJS 之上的):
Note: The arguments and the return value to the
evaluate
function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.Closures, functions, DOM nodes, etc. will not work!
CSS 选择器和 XPath 表达式之间的区别
另一件事是,如果没有通过名称另行说明,所有函数都假定选择器是 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');