tags:

views:

132

answers:

1

Hello!

I'm testing a web page using selenium. I want to get all the 'leaf elements and elements which contain text'. I use the following working XPath.

//*[. != '' or  not(*)]

This works great.

But now I want to loop through each of these elements and run some command on them. I actually want to get their Position, but I illustrate my problem by using GetXpathCount.

int elementCount = this.selenium.GetXpathCount("//*[. != '' or  not(*)]");
for (int i = 1; i <= elementCount; ++i)
{
    Console.WriteLine(this.selenium.GetXpathCount("//*[. != '' or  not(*)][" + i + "]"));
}

The value of elementCount is 242. And the console output is 142 45 30 13 4 4 1 1 1 1 0 0 0 0 0 0 ... [200 other zeros] The numbers on the console always sum to elementCount, but are always zero after ~10.

It became obvious to me that my XPath

//*[. != '' or  not(*)][1]

Does not have my intended meaning. And instead returns "all leaf elements and all elements containing text which are the first child of their parent" and is equivalent to

//*[(. != '' or  not(*)) and position() = 1]

So, I use brackets to correct this mistake:

(//*[(. != '' or  not(*))])[1]

Yay. The console output is now 1 1 1 1 1 1 1 1 1 1 1 1 1 1 for all elements. But let's update my looping code to actually perform an operation on the element @ path.

int elementCount = this.selenium.GetXpathCount("//*[. != '' or  not(*)]");
for (int i = 1; i <= elementCount; ++i)
{
    Console.WriteLine(this.selenium.GetElementPositionLeft("(//*[. != '' or  not(*)])[" + i + "]"));
}

NO!!! GetXpathCount works but GetElementPositionLeft (and others) all fail. What gives? How can I work around this?

Here's the Selenium Exception: {"ERROR: Element (//[. != '' or not()])[1] not found"} [Selenium.SeleniumException]: {"ERROR: Element (//[. != '' or not()])[1] not found"} Data: {System.Collections.ListDictionaryInternal} HelpLink: null InnerException: null Message: "ERROR: Element (//[. != '' or not()])[1] not found" Source: "ThoughtWorks.Selenium.Core"

+2  A: 

Selenium doesn't know what location strategy to use for (//*[. != '' or not(*)])[1]. Try preceding it with xpath=

As an alternative locator, I got this to work with the following (in Java):

int elementCount = selenium.getXpathCount("/descendant::*[. != '' or  not(*)]").intValue();
for (int i = 1; i <= elementCount; ++i) {
    System.out.println(i + ": " + selenium.getElementPositionLeft("xpath=/descendant::*[. != '' or  not(*)][" + i + "]"));
}
Dave Hunt
N00b mistake.Selenium assumes that it is an xpath when the starting characters are //. The function GetXpathCount also assumes all identifiers are xpaths.My mistake was that adding the brackets around the xpath (//path) broke Selenium and now I need to add the xpath=.Thanks
Kenn