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"