Reputation: 15
I am trying to locate the element <a>
.
HTML:
<html><head></head><body>
<a href="https://www.google.com">Click Here!</a>
</body></html>
Below is the Selenium code using Xpath producing same results:
driver.findElement(By.xpath("self::node()/child::node()/child::body/child::a")).click(); //Statement1
driver.findElement(By.xpath("/child::node()/child::body/child::a")).click(); //Statement2
driver.findElement(By.xpath("child::node()/child::body/child::a")).click(); //Statement3
My understanding:
In Statement1, it mentions the initial context node as the self::node
. Here, we are passing our entire HTMLDocument
as the self::node()
. So, our initial context node is set to entire HTMLDocument
(which is also called as document root node(/)
). So, our initial context node is set to document root node(/)
In Statement2, it mentions the initial context node absolutely as the document root node(/)
.
But in Statement3, the initial context node is not mentioned.
So, does it mean that if we do not mention the initial context node, then will it be set to document root node(/)
by default ?
Please help to improve my understanding.
Upvotes: 0
Views: 80
Reputation: 8676
Your 1 and 3 statements are the same from the "context" standpoint (self
and child
are both xpath axes). Both have root of the document as the context (in Selenium it is called SearchContext
).
The context is root in that case because you lookup elements right within a driver. If you will have a WebElement
and try to look up elements inside that element your context won't be root
for 1 and 3 statements.
Below is some more detailed explanation..
Assume we have test.html
with the following content:
<A val="success A">
<B val="success B"/>
</A>
And the test like this:
@Test
public void test(){
driver.get("file:///path_to_page/test.hml");
WebElement a = driver.findElement(By.xpath("html/body/A")); // (1, 2)
System.out.println(a.getAttribute("val"));
try{
System.out.println(driver.findElement(By.xpath("body/A/B")).getAttribute("val")); // (3)
}catch (NoSuchElementException e){
System.out.println("body/A/B cannot be found as the context is root");
}
WebElement b = a.findElement(By.xpath("B")); // (4)
System.out.println(b.getAttribute("val"));
System.out.println(b.findElement(By.xpath("/html/body/A")).getAttribute("val")); // (5)
}
Here are few remarkable points:
A
, browser automatically adds html tags to make the html file valid. So it adds html
node and body
nodehtml/body/A
which has the root
contextB
using the path body/A/B
since the context is still root
.B
in the context of previously located A
./html/body/A
within the context of B
. Despite we use the B
as search context we still can find the element because we start the path from /
which means root
and ignores any search context.Upvotes: 1