Actual xpath: (//div[#style='display: table-row;']//following-sibling::div)[38]
I am trying to divide this above xpath into 2 parts like this: //div[#style='display: table-row;'] & ./following-sibling::div[38].
This below code not working:
WebElement e = driver.findElement(By.xpath("//div[#style='display: table-row;']"));
WebElement f = e.findElement(By.xpath("./following-sibling::div[38]"));
System.out.println(f.getText());
But it's showing no element exception for WebElement f.
The original xpath contains a double slash after the div, while the xpath used in selenium only one. So you have to use
WebElement f = e.findElement(By.xpath(".//following-sibling::div[38]"));
where notice .// instead of ./.
A double slash // means any descendant node of the current node, while a single slash / means a node which is a direct child of the current.
Here you can see an easy example to understand the difference:
and the corresponding code in selenium (notice 1 element vs 3 elements)
Related
I have a table on a web page that its xpath differs from time to time but its class name doesn't. so I can handle it by its class name but my code needs the xpath of that element so how to get the xpath of that element?
OR how to deal with such elements that its xpath differs from time to time?
String xpath = "here sould be the xpath of that element";
wait_page_loading(By.xpath(table_xpath)); //this other function in my class wait the page loading
WebElement Webtable = driver.findElement(By.xpath(table_xpath));
List<WebElement> totalRowCount = Webtable.findElements(By.xpath(table_xpath + "/tbody/tr"));
if(totalRowCount.size() <= 1) {
throw new Exception("Can't find results in the problem page");
}
return totalRowCount.get(0).findElements(By.xpath("td")).get(6).getText();
Thanks a lot in advance.
I see a div and then we have a child table, please use the below xpath :
//div[#class='table-responsive']/table
Below xPath returns all the row values of the table.
//div[#class='table-responsive']/table/tbody/tr
how to deal with such elements that its xpath differs from time to
time?
If a xPath value partially dynamic I would suggest you to us contains method. For an example,
<input class = "User1235">
In above xPath the value 1235 is dynamic in this case you can create a xPath with contains
//input[contains(#class,'User')]
how to add the second css selector or xpath where the same element appears more than once.
WebElement element = driver.findElement(By.cssSelector("span.mat-content"));
I need to add the same css selector again but for the 2nd element
how do it do that.
This is for the first one which I have added as seen above:
HTML:
<span class="mat-content ng-tns-c143-2587"> = first one
HTML which I need to add -
<span class="mat-content ng-tns-c143-2589"> = How do I add the css selector using this html tag.
WebElement element2 = driver.findElement(By.cssSelector("span.mat-content")); = In this place how do I add it for the second element
If this span.mat-content represent multiple web element in HTMLDOM.
You can use findElements to grab them all.
List<WebElement> elements = driver.findElements(By.cssSelector("span.mat-content"));
Now elements is a list in Java-Selenium bindings.
You could do, elements.get(1) and this shall represent the second web element.
or You can iterate the entire list like this:
for (WebElement element : elements){
element.getText(); //Note that each `element` is a web web element.
}
If you do not wish to have the above way. You can try xpath indexing.
(//span[contains(#class,'span.mat-content')])[1]
should represent the first element.
and
(//span[contains(#class,'span.mat-content')])[2]
should represent the second element and so on..
[3], [4], .... [n]
just replace css with xpath. xpath indexing is not preferred choice.
List<WebElement> elements= driver.findElements(By.cssSelector("span.mat-
content"));
WebElement element2 = elements.get(1);
Should work
Below is the element and I need to find the class names matching with the first css- and ending with widget, How do i find it in selenium (java)?
Tried with the below code, but it didnt work
List<WebElement> list1 = driver.findElements(By.xpath("//body[starts-with(#class, 'css-')]"));
List<WebElement> list2 = driver.findElements(By.xpath("//body[contains(#class, 'css-')]"));
List<WebElement> list3 = driver.findElements(By.xpath("//body[ends-with(#class, 'widget')]"));
I use CSS selectors, to find any element of any type:
driver.findElements(By.CssSelector("[class^='css-'][class$='widget']"))
Where we find any element, which has a class attribute using [], that begins with ^= and ends with $=
To find a div:
driver.findElements(By.CssSelector("div[class^='css-'][class$='widget']"))
#elworthy's answer was in the right direction about the CssSelector which you can use and as per your code trials the following should work:
List<WebElement> list3 = driver.findElements(By.CssSelector("//body[class^='css-'][class$='widget']"));
However if you want to construct a xpath it is worth to mention Selenium supports xpath v1.0 and ends-with() is part of xpath v2.0. So the equivalent xpath will be:
List<WebElement> list1 = driver.findElements(By.xpath("//body[starts-with(#class, 'css-') and contains(#class, 'widget')]"));
I am trying to get value of HREF attribute but always it says incorrect Xpath.
Html Code :
I am trying code :
WebElement Link = driver.findElement(By.xpath("//table[contains(#class,'display')]/thead/tbody/tr/td/a"));
System.out.println(Link.getAttribute("href"));
I tried many xpath but none of them worked.
This should work:
WebElement Link = driver.findElement(By.xpath("//table[contains(#class,'display')]/tbody/tr/td/a"));
Explanation: tbody is not nested in thead.
Note that a path expression like this can return a set of several nodes, in document order. The findElement method only returns the first result node. So: if the a element you are looking for is no longer the first one in this table, the path expression breaks.
If the the href is unique, something like this would be less error-prone:
WebElement Link = driver.findElement(By.xpath("//table[contains(#class,'display')]//a[#href='/admin/client/product_overrides/edit/242625']"));
I am using selenium to test my web application and I can successfully find tags using By.xpath. However now and then I need to find child nodes within that node.
Example:
<div id="a">
<div>
<span />
<input />
</div>
</div>
I can do:
WebElement divA = driver.findElement( By.xpath( "//div[#id='a']" ) )
But now I need to find the input, so I could do:
driver.findElement( By.xpath( "//div[#id='a']//input" ) )
However, at that point in code I only have divA, not its xpath anymore... I would like to do something like this:
WebElement input = driver.findElement( divA, By.xpath( "//input" ) );
But such a function does not exist.
Can I do this anyhow?
BTW: Sometimes I need to find a <div> that has a certain decendent node. How can I ask in xpath for "the <div> that contains a <span> with the text 'hello world'"?
According to JavaDocs, you can do this:
WebElement input = divA.findElement(By.xpath(".//input"));
How can I ask in xpath for "the div-tag that contains a span with the
text 'hello world'"?
WebElement elem = driver.findElement(By.xpath("//div[span[text()='hello world']]"));
The XPath spec is a suprisingly good read on this.
If you have to wait there is a method presenceOfNestedElementLocatedBy that takes the "parent" element and a locator, e.g. a By.xpath:
WebElement subNode = new WebDriverWait(driver,10).until(
ExpectedConditions.presenceOfNestedElementLocatedBy(
divA, By.xpath(".//div/span")
)
);
For Finding All the ChildNodes you can use the below Snippet
List<WebElement> childs = MyCurrentWebElement.findElements(By.xpath("./child::*"));
for (WebElement e : childs)
{
System.out.println(e.getTagName());
}
Note that this will give all the Child Nodes at same level ->
Like if you have structure like this :
<Html>
<body>
<div> ---suppose this is current WebElement
<a>
<a>
<img>
<a>
<img>
<a>
It will give me tag names of 3 anchor tags here only . If you want all the child Elements recursively , you can replace the above code with
MyCurrentWebElement.findElements(By.xpath(".//*"));
Hope That Helps !!
I also found myself in a similar position a couple of weeks ago. You can also do this by creating a custom ElementLocatorFactory (or simply passing in divA into the DefaultElementLocatorFactory) to see if it's a child of the first div - you would then call the appropriate PageFactory initElements method.
In this case if you did the following:
PageFactory.initElements(new DefaultElementLocatorFactory(divA), pageObjectInstance));
// The Page Object instance would then need a WebElement
// annotated with something like the xpath above or #FindBy(tagName = "input")
The toString() method of Selenium's By-Class produces something like
"By.xpath: //XpathFoo"
So you could take a substring starting at the colon with something like this:
String selector = divA.toString().substring(s.indexOf(":") + 2);
With this, you could find your element inside your other element with this:
WebElement input = driver.findElement( By.xpath( selector + "//input" ) );
Advantage: You have to search only once on the actual SUT, so it could give you a bonus in performance.
Disadvantage: Ugly... if you want to search for the parent element with css selectory and use xpath for it's childs, you have to check for types before you concatenate...
In this case, Slanec's solution (using findElement on a WebElement) is much better.