Finding XPATH in single nested div statement, when the classname is shared among multiple classnames - selenium

So im currently trying to write a test/learn how to use Selenium. One of the issues I am running in to is that I need to select specfically the number 262 in this nested div.
The issue I ran into is that if I make the xpath //div[#class='np_amount inline'] that I get multiple results going down the entire page, and if I make it //div[#class='np_field_amount_etc'], then I get all three items in the row, and not just the number 262.
However, the initial div class (np_field_amount_etc) is unique. What xpath command would I write in order to only select the 262 in this series of div's?
<div class="np_field_amount_etc">
<div class="np_label inline">Total Calories</div>
<div class="np_amount inline">262 </div>
<div class="np_dv inline">14</div>
</div>

I think, somethings like this:
//div[#class='np_field_amount_etc']/div[#class='np_amount inline']
is what you want.

Related

Click on parent element based on two conditions in child elements Selenium Driver

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"

Selenium XPATH selecting next sibling

<div class="block wbc">
<span></span>
<span> text_value </span>
</div>
for getting text in second span where does below code go wrong?
driver.find_element(X_PATH,"*//div[#class='block']/span[1]")
For trying by yourself, maybe I write sth wrong here is link
https://soundcloud.com/daydoseofhouse/snt-whats-wrong/s-jmbaiBDyQ0d?si=233b2f843a2c4a7c8afd6b9161369717&utm_source=clipboard&utm_medium=text&utm_campaign=social_sharing
And my code; still giving an error
playbackTimeline__duration =driver.find_element(By.XPATH,"*//div[#class='playbackTimeline__duration']/span[2]")
For finding web element clearly:
//*[#id="app"]/div[4]/section/div/div[3]/div[3]/div/div[3]/span[2]
But I will not use this way, I need declare with class method or CSS Selector at least
If you are sure that you always need the second span use this XPath:
*//div[#class='playbackTimeline__duration']/span[2]
If you need the first span that has actual text use this:
*//div[#class='playbackTimeline__duration']/span[normalize-space()][1]
If the #class has more than only playbackTimeline__duration in it you can use:
*//div[contains(#class,'playbackTimeline__duration')]/span[2]
If there are more div's like that use:
*//div[contains(#class,'playbackTimeline__duration')][1]/span[2]

Choose the correct element from the list of objects with the same className

Quick one, i am trying to avoid using xpath and using css selectors due to performance issues xpath can have so i would like to know the right approach of locating for example "A" in the list
<div class="input-search-suggests" xpath="1">
<div class="input-search-suggests-item">A</div>
<div class="input-search-suggests-item">B</div>
<div class="input-search-suggests-item">C</div>
</div>
Currently i am locating A using xpath / span but it would be indeed sufficient locating all elements and then grabbing A from the list that have same class which is "input-search-suggests-item"
#FindBy(xpath = "//span[contains(text(),'A')]")
CSS_SELECTOR does not have support for direct text what xpath has.
What this means is, for the below xpath
xpath = "//span[contains(text(),'A')]"
based on text A you can not write a css selector.
Instead to locate A using css selector, you can do :
div.input-search-suggests > div.input-search-suggests-item
In Selenium something like this :
#FindBy(cssSelector= "div.input-search-suggests > div.input-search-suggests-item")
Even though it will have 3 matching nodes, but findElement will take the first web element.
Also you may wanna look at nth-child(n)
div.input-search-suggests > nth-child(1)
to make use of index to locate A, B, C
Here is the Reference Link

Selenium - Search for an element within element

Hi I want to hold element references in files somewhere. and then in run time search for elements withing referenced elements in Selenium how to do that.
For example- a Frame contains multiple text boxes -and multiple frames of similar properties exist where the textboxes are also duplicate. Something like I wanna reference the text box under a particular frame. But i wanna predefine the frame. and the specify that search under that frame[Something like Aliases in Testcomplete]
For Example - similar concept exist in Cheezy's Page-Objects. but not quite.
if you have a structure like this:
<div class='some class'>
<input class='input-button' value='submit'>Submit</input>
</div>
<div class='some class2'>
<input class='input-button' value='submit'>Submit</input>
</div>
and you want to find the first 'Submit' which is within the 'some class' div, you can do this:
parent_element = driver.find_element(:xpath, "//div[#class='some class']")
child_element = parent_element.find_element(:xpath, ".//input")
p.s. this is ruby code.

How do I select a particular dynamic div, using Selenium when I don't have a unique id or name?

Only the content of the div is unique. So, in the following dynamically generated html, only "My Article-1245" is unique:
<div class="col-md-4 article">
<h2>
My Article-1245
Delete
Edit
</h2>
<p>O ephemeral text! Here today, gone tomorrow. Not terribly important, but necessary</p>
</div>
How do I select the edit/delete link of this specific div, using Selenium? assertText/verifyText requires an element locator, but I do not have any unique id/name (out of my control). There will be many such div blocks, with other content text, all dynamically generated.
Any help would be appreciated.
If text 'My Article' appears each time, you may use following:
//For Delete
driver.findElement(By.xpath("//h2[contains(text(),'My Article-')]/a[text()='Delete']"));
//For Edit
driver.findElement(By.xpath("//h2[contains(text(),'My Article-')]/a[text()='Edit']"));
Hope it meets your requirement :)
Matching by text is always a bad automated testing concept. If you want to keep clean and reliable test scripts, then :
Contact your web dev to add unique identifiers to the elements
Suck it up, and create selectors based on what's there.
You are able to create a CSS selector based on what you want.
What you should do is create the selector using parent-child relationships:
driver.findElement(By.cssSelector("div.article:nth-child(X) a[href^='delete']"));
As I am ignorant of your appp, this is also assuming that all of your article classes are under the same parent. You would substitute X with the number of the div you want to refer to. e.g.:
<div id="someparent">
<div class="...article" />
<div class="...article" />
...
</div>