This post originated from an RSS feed registered with Ruby Buzz
by .
Original Post: Selenium and XHTML
Feed Title: cfis
Feed URL: http://cfis.savagexi.com/articles.rss
Feed Description: Charlie's Blog
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by
Latest Posts From cfis
Advertisement
Last month I blogged about
Selenium, which is an open source project that let's you test web applications
running in a variety of browser. Unfortunately, Selenium doesn't
work out of the box with
XHTML - any XPath expressions you use stop working.
I fixed this last
month in my local copy, but I've noticed other people are starting to have
the same issue. The problem is that Selenium does not implement a namespace
resolver as described in
the Mozilla XPath documentation. For html documents, XPath expressions look like
this:
div/p[@id="foo"]
For XHTML documents, they must include a namespace prefix like this:
x:div/x:p[@id="foo"]
The choice of "x" is random, however, its what XPath
Checker (a Firefox extension) uses.
Luckily, Selenium is easily extensible
since JavaScript is a language that gets
out of your way. The fix is to add the following code into your
user-extensions.js file:
PageBot.prototype.namespaceResolver =function(prefix){if(prefix =='html'|| prefix =='xhtml'|| prefix =='x'){return'http://www.w3.org/1999/xhtml';}elseif(prefix =='mathml'){return'http://www.w3.org/1998/Math/MathML'}else{thrownewError("Unknown namespace: "+ prefix +".")}}PageBot.prototype.findElementUsingFullXPath =function(xpath, inDocument){if(browserVersion.isIE &&!inDocument.evaluate){addXPathSupport(inDocument);}// HUGE hack - remove namespace from xpath for IEif(browserVersion.isIE) xpath = xpath.replace(/x:/g,'')// Use document.evaluate() if it's availableif(inDocument.evaluate){// cfis//return inDocument.evaluate(xpath,
inDocument, null, 0, null).iterateNext();return inDocument.evaluate(xpath, inDocument,this.namespaceResolver,0,null).iterateNext();}// If not, fall back to slower JavaScript implementationvar context =newXPathContext(); context.expressionContextNode = inDocument;var xpathResult =newXPathParser().parse(xpath).evaluate(context);if(xpathResult && xpathResult.toArray){return xpathResult.toArray()[0];}returnnull;};
There are two big hacks. First, the hard-coded "x" prefix. And second, Internet
Explorer does not support XHTML so the code strips out any namespace prefixes.
Last, if you are using the Firefox Selenium
IDE, make sure to point it at your updated user-extensions.js file (do
this using the options menu).