Reputation: 375
I'm working with CasperJS on a webpage that has a search box. Using Casper, I'm successfully able to perform a search and see that the form is filled and execute the search, however I'm having trouble specifically getting the number of results to test that it's valid.
When I look at the source of the webpage, I have the XPath of the element and it's nested in a few divs.
But when I try to either do assertExists()
on that path, or even return the result of getElementByXPath()
to a var, it doesn't work. In the first case the test fails and in the second case it prints null
.
This is the XPath:
//*[@id="total"]
Here is what the snippet of source looks like:
<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>
This is the CasperJS code, relevant to here.
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"]');
});
Upvotes: 2
Views: 222
Reputation: 61922
The CasperJS clientutils module is only defined in the page context. Whenever CasperJS starts, it injects those utils into the page for later convenience. The problem is that the page and its DOM are only accessible from inside of the evaluate()
function.
Another thing to remember is that you cannot get DOM nodes out of the page context. Either you do your stuff completely in the page context (inside of evaluate()
) or you get a representation of the node like the textContent
property:
var resultsNum = this.evaluate(function(){
return __utils__.getElementByXPath('//*[@id="total"]').textContent;
});
Here is the bit from the documentation (since CasperJS is built on top of 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!
The other thing is that if not otherwise noted through the name all functions assume that the selectors are CSS selectors. Looking at test.assertExists('//*[@id="total"]');
makes it clear that '//*[@id="total"]'
is not a CSS selector, but an XPath expression. You can use XPath expressions in CasperJS through the XPath utility:
var x = require('casper').selectXPath;
test.assertExists(x('//*[@id="total"]'));
or you can simply use the equivalent CSS selector:
test.assertExists('#total');
Upvotes: 1