使用 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');