I've following HTML snippet and out of it I want to retrieve only 3 text:
<div class="assigned" ng-repeat="counte">
3
<div class="ng-binding">Assigned</div>
</div>
But when I use following, it returns 3Assigned
driver.findElement(By.xpath(//div[#class='assigned'])).getText();
I only want to retrieve 3, how can I achieve that?
When you evaluate a nodes set's text, it returns the concatenated text of all text children, grandchildren, etc.
You can use the [1] indexer as a suffix to obtain just the first text:
driver.findElement(By.xpath("(//div[#class='assigned']/text())[1]")).getText();
Try out with :
xpath - > //div[#class='ng-binding']/preceding-sibling::text()
Related
Using Selenium 4.8 in .NET 6, I have the following html structure to parse.
<ul class="search-results">
<li>
<a href=//to somewhere>
<span class="book-desc">
<div class="book-title">some title</div>
<span class="book-author">some author</span>
</span>
</a>
</li>
</ul>
I need to find and click on the right li where the book-title matches my variable input (ideally ignore sentence case too) AND the book author also matches my variable input. So far I'm not getting that xpath syntax correct. I've tried different variations of something along these lines:
var matchingBooks = driver.FindElements(By.XPath($"//li[.//span[#class='book-author' and text()='{b.Authors}' and #class='book-title' and text()='{b.Title}']]"));
then I check if matchingBooks has a length before clicking on the first element. But matchingBooks is always coming back as 0.
class="book-author" belongs to span while class="book-title" belongs to div child element.
Also it cane be extra spaces additionally to the text, so it's better to use contains instead of exact equals validation.
So, instead of "//li[.//span[#class='book-author' and text()='{b.Authors}' and #class='book-title' and text()='{b.Title}']]" please try this:
"//li[.//span[#class='book-author' and(contains(text(),'{b.Authors}'))] and .//div[#class='book-title' and(contains(text(),'{b.Title}'))]]"
UPD
The following XPath should work. This is a example specific XPath I tried and it worked "//li[.//span[#class='book-author' and(contains(text(),'anima'))] and .//div[#class='book-title' and(contains(text(),'Coloring'))]]" for blood of the fold search input.
Also, I guess you should click on a element inside the li, not on the li itself. So, it's try to click the following element:
"//li[.//span[#class='book-author' and(contains(text(),'{b.Authors}'))] and .//div[#class='book-title' and(contains(text(),'{b.Title}'))]]//a"
How to find sibling element text using xpath
<label>
<span>some span</span>
</label>
<label>
Second Label
</label>
//label[normalize-space(text()) = 'some span']/following-sibling::label/text()
In Python we would do something like this :
driver.find_element(By.XPATH, "//label[//text()[normalize-space() = 'some span']]/following-sibling::label").text
basically Python Selenium bindings provide a text method for web element. getText() for Java.
Now if you want to heavily dependent on XPATH then you can try below XPATH :
//span[contains(text(),'some span')]/../following-sibling::label
or probably
//span[contains(text(),'some span')]/../following-sibling::label[contains(text(),'Second Label')]
I would use:
//label[span[text()='some span']]/following-sibling::label/text()
or if you only want to find that if it is actually the first following-element:(i.e: you don't want to find that label if there is a input in between)
//label[span[text()='some span']]/following-sibling::*[1][self::label]/text()
or if you only want to find that the first following label(if there even more following label-elements):
//label[span[text()='some span']]/following-sibling::label[1]/text()
The page contains a multi-select dropdown (similar to the one below)
The html code looks like the below:
<div class="button-and-dropdown-div>
<button class="Multi-Select-Button">multi-select button</button>
<div class="dropdown-containing-options>
<label class="dropdown-item">
<input class="checkbox">
"
Name
"
</label>
<label class="dropdown-item">
<input class="checkbox">
"
Address
"
</label>
</div>
After testing in firefox developer tools, I was finally able to figure out the xPath needed in order to get the text for a certain label ...
The below XPath statement will return the the text "Phone"
$x("(//label[#class='dropdown-item'])[4]/text()[2]")
The label contains multiple text items (although it looks like there is just one text object when looking at the UI) in the label element. There are actually two text elements within each label element. The first is always empty, the second contains the actual text (as shown in the below image when observing the element through the Firefox developer tool's console window):
Question:
How do I modify the XPath shown above in order to use in Selenium's FindElement?
Driver.FindElement(By.XPath("?"));
I know how to use the contains tool, but apparently not with more complex XPath statements. I was pretty sure one of the below would work but they did not (develop tool complain of a syntax error):
$x("(//label[#class='dropdown-item' and text()[2][contains(., 'Name')]]")
$x("(//label[#class='dropdown-item' and contains(text()[2], 'Name')]")
I am using the 'contains' in order to avoid white-space conflicts.
Additional for learning purposes (good for XPath debugging):
just in case anyone comes across this who is new to XPath, I wanted to show what the data structure of these label objects looked like. You can explore the data structure of objects within your webpage by using the Firefox Console window within the developer tools (F12). As you can see, the label element contains three sub-items; text which is empty, then the inpput checkbox, then some more text which has the actual text in it (not ideal). In the picture below, you can see the part of the webpage that corresponds to the label data structure.
If you are looking to find the element that contains "Name" given the HTML above, you can use
//label[#class='dropdown-item'][contains(.,'Name')]
So finally got it to work. The Firefox developer environment was correct when it stated there was a syntax problem with the XPath strings.
The following XPath string finally returned the desired result:
$x("//label[#class='dropdown-item' and contains(text()[2], 'Name')]")
I am trying to retrieve the text embedded inside the div tag. Partial html code is given below. I consulted the other existing answers, but the tag is located successfully but the text is coming back as empty string.My purpose is to retrieve the string between the 'div' tag as "You entered an invalid username or password, please try again."
I used the xpath
//div[#class='login-card js-login-card']/div[#role='alert']/div[2]
I used the css
.alert__heading.js-alert--error-text
This only getting back the tag name as div, but the text as an empty string.
Any ideas or corrections?
<div class="login-card js-login-card">
<div class="login-page__alert alert alert--error tt js-alert--error" role="alert">
<div class="alert__icon">
<div class="alert__heading js-alert--error-text">You entered an invalid username or password, please try again. </div>
</div>
<div id="cmePageWrapper" class="page-wrapper page-wrapper--card"> </div>
Try following xpath, as the required div tag is child node of div with class 'alert__icon':
//div[#class='login-card js-login-card']/div[#role='alert']/div[1]/div
Let me know, if it works for you.
Maybe you wanna try this
div[class*="error-text"]
If it didn't work try to get text by executing javascript code using this
$$( "div[class*="error-text"]" ).text() OR .val()/.html()
Good luck !
You could use contains with xpath, something like //div[contains(#class, 'error-text' ) ], using findelement will retrieve first element match the criteria. If it still returns empty, it means that the page might have more than one element which match the criteria
Hi i have the following code that searches for and retrieves the first paragraph after <h3>
//div[starts-with(#id,'content_div')]/h3[.='Course Content']/following-sibling::p[1]
Because i'm using the same code on multiple web pages, some of those pages do not contain <h3> and instead contain <h4> tag. What is the syntax to check if there is a <h3> tag and if not check for <h4>?
You can check if child element exists using predicate, e.g.:
//div[span]
It will select all div elements which have span
//div[starts-with(#id,'content_div')]/*[self::h3 or self::h4 and .='Course Content']/following-sibling::p[1]
If you're using XPath 2.0 then you can replace h3 by (h3|h4).
In XPath 1.0 you'll need to replace it by *[self::h3 or self::h4]