I read the code in Selenium core and the xpath locate strategy is defined as
BrowserBot.prototype.locateElementByXPath = function(xpath, inDocument,
inWindow) {
var results = eval_xpath(xpath, inDocument, {
returnOnFirstMatch : true,
ignoreAttributesWithoutValue: this.ignoreAttributesWithoutValue,
allowNativeXpath : this.allowNativeXpath,
xpathLibrary : this.xpathLibrary,
namespaceResolver : this._namespaceResolver
});
return (results.length > 0) ? results[0] : null;
};
where the eval_xpath is a help class defined in htmlutils.js as follows,
/**
* Evaluates an xpath on a document, and returns a list containing nodes in
the
* resulting nodeset. The browserbot xpath methods are now backed by this
* function. A context node may optionally be provided, and the xpath will
be
* evaluated from that context.
*
* @param xpath the xpath to evaluate
* @param inDocument the document in which to evaluate the xpath.
* @param opts (optional) An object containing various flags that can
* modify how the xpath is evaluated. Here's a listing of
* the meaningful keys:
*
* contextNode:
* the context node from which to evaluate the xpath.
If
* unspecified, the context will be the root document
* element.
*
* namespaceResolver:
* the namespace resolver function. Defaults to null.
*
* xpathLibrary:
* the javascript library to use for XPath. "ajaxslt"
is
* the default. "javascript-xpath" is newer and
faster,
* but needs more testing.
*
* allowNativeXpath:
* whether to allow native evaluate(). Defaults to
true.
*
* ignoreAttributesWithoutValue:
* whether it's ok to ignore attributes without value
* when evaluating the xpath. This can greatly improve
* performance in IE; however, if your xpaths depend
on
* such attributes, you can't ignore them! Defaults to
* true.
*
* returnOnFirstMatch:
* whether to optimize the XPath evaluation to only
* return the first match. The match, if any, will
still
* be returned in a list. Defaults to false.
*/
function eval_xpath(xpath, inDocument, opts)
{
if (!opts) {
var opts = {};
}
var contextNode = opts.contextNode
? opts.contextNode : inDocument;
var namespaceResolver = opts.namespaceResolver
? opts.namespaceResolver : null;
var xpathLibrary = opts.xpathLibrary
? opts.xpathLibrary : null;
var allowNativeXpath = (opts.allowNativeXpath != undefined)
? opts.allowNativeXpath : true;
var ignoreAttributesWithoutValue = (opts.ignoreAttributesWithoutValue !=
undefined)
? opts.ignoreAttributesWithoutValue : true;
var returnOnFirstMatch = (opts.returnOnFirstMatch != undefined)
? opts.returnOnFirstMatch : false;
// Trim any trailing "/": not valid xpath, and remains from attribute
// locator.
if (xpath.charAt(xpath.length - 1) == '/') {
xpath = xpath.slice(0, -1);
}
// HUGE hack - remove namespace from xpath for IE
if (browserVersion && browserVersion.isIE) {
xpath = xpath.replace(/x:/g, '')
}
var nativeXpathAvailable = inDocument.evaluate;
var useNativeXpath = allowNativeXpath && nativeXpathAvailable;
var useDocumentEvaluate = useNativeXpath;
// When using the new and faster javascript-xpath library,
// we'll use the TestRunner's document object, not the App-Under-Test's
document.
// The new library only modifies the TestRunner document with the new
// functionality.
if (xpathLibrary == 'javascript-xpath' && !useNativeXpath) {
documentForXpath = document;
useDocumentEvaluate = true;
} else {
documentForXpath = inDocument;
}
var results = [];
// this is either native xpath or javascript-xpath via
TestRunner.evaluate
if (useDocumentEvaluate) {
try {
// Regarding use of the second argument to document.evaluate():
//
http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/a59ce20639c74ba1/a9d9f53e88e5ebb5
var xpathResult = documentForXpath
.evaluate((contextNode == inDocument ? xpath : '.' + xpath),
contextNode, namespaceResolver, 0, null);
}
catch (e) {
throw new SeleniumError("Invalid xpath: " +
extractExceptionMessage(e));
}
finally{
if (xpathResult == null) {
// If the result is null, we should still throw an Error.
throw new SeleniumError("Invalid xpath: " + xpath);
}
}
var result = xpathResult.iterateNext();
while (result) {
results.push(result);
result = xpathResult.iterateNext();
}
return results;
}
// If not, fall back to slower JavaScript implementation
// DGF set xpathdebug = true (using getEval, if you like) to turn on JS
XPath debugging
//xpathdebug = true;
var context;
if (contextNode == inDocument) {
context = new ExprContext(inDocument);
}
else {
// provide false values to get the default constructor values
context = new ExprContext(contextNode, false, false,
contextNode.parentNode);
}
context.setCaseInsensitive(true);
context.setIgnoreAttributesWithoutValue(ignoreAttributesWithoutValue);
context.setReturnOnFirstMatch(returnOnFirstMatch);
var xpathObj;
try {
xpathObj = xpathParse(xpath);
}
catch (e) {
throw new SeleniumError("Invalid xpath: " +
extractExceptionMessage(e));
}
var xpathResult = xpathObj.evaluate(context);
if (xpathResult && xpathResult.value) {
for (var i = 0; i < xpathResult.value.length; ++i) {
results.push(xpathResult.value[i]);
}
}
return results;
}
>From the line
if (browserVersion && browserVersion.isIE) {
xpath = xpath.replace(/x:/g, '')
}
seems the namespace is stripped for IE. What browser are you testing
against? And have you tried javascript-xpath library?
Seems javascript-xpath is handled differently from the default Ajaxslt lib.
Thanks,
Jian
On Fri, May 15, 2009 at 10:15 AM, Jian Fang <[email protected]>wrote:
> It is invalid only in Selenium, right? For xml document processing, you
> have to add name space there.
>
> I will check where caused the problem in Selenium core.
>
> Thanks,
>
> Jian
>
>
> On Fri, May 15, 2009 at 10:10 AM, Harihara Vinayakaram
> <[email protected]>wrote:
>
>> Hi
>> I remember reading that in general an XPath with namespace (any namespace)
>> is treated as Invalid
>> //xforms:lab...@id="message"]
>>
>> which is why a document.evaluate works for these types of expressions. I
>> have attached an example project which simulates the same
>>
>> Regards
>> Hari
>>
>>
>>
>> On Fri, May 15, 2009 at 6:20 PM, Jian Fang <[email protected]>wrote:
>>
>>> Would
>>>
>>> //descendant-or-self::xforms:lab...@id="message"]
>>>
>>> be a valid XPath in general?
>>>
>>> We can add a custom locate strategy for you, but the best way is to fix
>>> Selenium core itself
>>> if the XPath is valid in general. Could you provide us a test case so
>>> that I can dig into Selenium
>>> core to see what caused that problem?
>>>
>>> Thanks,
>>>
>>> Jian
>>>
>>>
>>> On Fri, May 15, 2009 at 8:44 AM, Harihara Vinayakaram
>>> <[email protected]>wrote:
>>>
>>>> Putting the namespace results in the following problem in Selenium
>>>>
>>>> Invalid xpath: //descendant-or-self::xforms:lab...@id="message"]
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> I had solved this problem in Selenium by using the Document.evaluate and
>>>> using a separate locator
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> method . Not sure how I can call the Document.evaluate in this case from
>>>> Tellurium
>>>>
>>>> Regards
>>>> Hari
>>>>
>>>>
>>>>
>>>>
>>>> On Thu, May 14, 2009 at 10:30 PM, Jian Fang
>>>> <[email protected]>wrote:
>>>>
>>>>> Maybe later, we can refactor this so that you can register the
>>>>> namespace in defineUi, i.e., put into a queue,
>>>>> and let Tellurium Core handle the actual registration automatically.
>>>>>
>>>>> On Thu, May 14, 2009 at 12:58 PM, Jian Fang
>>>>> <[email protected]>wrote:
>>>>>
>>>>>> For example, in the @BeforeClass or @Before method after you start the
>>>>>> Selenium server.
>>>>>>
>>>>>> On Thu, May 14, 2009 at 12:57 PM, Jian Fang <[email protected]
>>>>>> > wrote:
>>>>>>
>>>>>>> No, should put in your test class because it will talk to Selenium
>>>>>>> server to add the name space, which is a runtime call.
>>>>>>>
>>>>>>>
>>>>>>> On Thu, May 14, 2009 at 12:50 PM, Harihara Vinayakaram <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Can I call the registerNameSpace in the defineUi ?
>>>>>>>>
>>>>>>>>
>>>>>>>> On Thu, May 14, 2009 at 10:02 PM, Jian Fang <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> I added registerNamespace method for you and you can try to
>>>>>>>>> register the namespace before you make calls
>>>>>>>>> to Selenium server. Namespace is enabled on UI objects, for
>>>>>>>>> example,
>>>>>>>>>
>>>>>>>>> ui.Container(uid: "TEST", namespace: "ns2", clocator: [:]){
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> Somewhere, you should call
>>>>>>>>> registerNamespace("ns2", "http://tellurium.org/ns");
>>>>>>>>>
>>>>>>>>> you can do the same to add the namespace in and see if it works for
>>>>>>>>> you.
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>>
>>>>>>>>> Jian
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Thu, May 14, 2009 at 12:23 PM, Harihara Vinayakaram <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Hi
>>>>>>>>>> I have one question regarding the usage of custom classes. Can I
>>>>>>>>>> directly use the XPath rather than defining an UI module If so how
>>>>>>>>>> do I do
>>>>>>>>>> that ? .The reason I am asking this is because I have elements that
>>>>>>>>>> belong
>>>>>>>>>> to a different name space and the last time I remember I could not
>>>>>>>>>> define
>>>>>>>>>> those elements in the Ui
>>>>>>>>>>
>>>>>>>>>> Let me know
>>>>>>>>>>
>>>>>>>>>> Regards
>>>>>>>>>> Hari
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>> >>
>>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"tellurium-users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/tellurium-users?hl=en
-~----------~----~----~----~------~----~------~--~---