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

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"

Related

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]

Find Xpath to an element depending on the value of another element in a table row

I'm new to Xpath so if this doesn't contain all relevant information apologies & let me know what you need to solve it.
I am trying to find an Xpath to an "expand arrow" element which expands a row in a table. The "expand arrow" element isn't unique so I would like to select it based on text contained in another element on the same row. The layout is as follows:
<td id="__table2-rows-row10-col0">
<div class="sapUiTableCellFlex">
<span id="__table2-rows-row10- treeicon" title="Expand Node" role="button">
<div id="__hbox27-__clone101">
<div id="__data70-__clone101">
<div id="__data71-__clone101">
<span id="__text47-__clone101" title="sys-admin">sys-admin</span>
I'd like to select the element with title = "Expand Node"
<span id="__table2-rows-row10- treeicon" title="Expand Node" role="button">
based on the element with title or text = "sys-admin"
<span id="__text47-__clone101" title="sys-admin">sys-admin</span>
I've played around with various options but I can't seem to get it to work. Any ideas would be much appreciated!
Thanks
To locate the element with title as Expand Node with respect to the element with title or text as sys-admin you can use either of the following Locator Strategies:
xpath and title attribute:
"//span[#title='sys-admin']//ancestor::span[#title='Expand Node']"
xpath and text() attribute:
"//span[text()='sys-admin']//ancestor::span[#title='Expand Node']"
I eventually got it to work using the following xpath:
//span[#title='sys-admin']/../../preceding-sibling::span[#title='Expand Node']

Trying to use Selenium to find a specific entry in a list when what you type highlights that word

DOM:
<span class="item">Does not <span class="highlight">match</span>.</span>
<span class="item">Also not <span class="highlight">match</span>ing.</span>
<span class="item"><span class="highlight">match</span></span>
Issue:
I've got a list of items. When I type into a text box, it eliminates items that do not match, and highlights the ones that do inside a /span. The issue is that if I type something that matches multiple things, I want to select the EXACT String, and not the ones that partially match (see above DOM example... the ideal match would be the 3rd one).
So, is my only hope here to go one by one until I find my perfect match, or is there something else that I've been missing?
You are trying to find a span that has no text, with an inner span that has some highlighted text. Here is an XPath selector for that:
//span[#class='item'][not(text())]/span[#class='highlight'][‌​text()='match']

How to get the xpath for the span button

I am new to selenium IDE and trying to get the target in the right order.
I have tried many combination to get the right element when there is span for the button. I need to get the xpath for the "Read More" button.Can someone please advise how the target in the IDE should be.
Here is the code:
<div class="is_centered l_bottom_pad">
<a class="btn_teal_outline has_arrow" href="https://test.com/jobs/view.php?id=8">
<span>Read More</span>
</a>
</div>
In some browsers (I think it was mainly MSIE) it is necessary to address the <a> element, not its child <span> in order to click a button or link. So you should adress:
//a[span[text()='Read More']]
Or you go directly for LinkText ("Read More") instead of XPath!
Targeting for span button is very simple. Just see what is unique attribute in that element.
I feel the button text itself is unique.Try this one
xpath=.//span[text()='Read More']

Get xpath under particular tag

Am newbie to selenium (java).
I have to click on the menu item which is under <ul> tag as <li> items. I can able to get it with //*[#id='MainMenu']/li[5]/span xpath.
I do not want to hard code [5] of the list item, because item's position may change. It may not at 5th position all the time.
I wanted to get xpath for the particular item under particular tag with an id.
Edit:
This is how my html looks like. List item text will be loading dynamically.
<ul id="sfMainMenu" class="sf-menu ui-selectable">
<li class="ui-selected ui-selectee">
<span subnav="0" param="cmd=desk" filesrc="/Dashboard/Index"></span>
</li>
<li class="ui-selectee"></li>
<li class="ui-selectee"></li>
<li class="ui-selectee"></li>
<li class="ui-selectee">
<span subnav="18" param="cmd=desk" filesrc="../myFile.aspx"></span>
</li>
</ul>
Kindly suggest the approach with an example.
I suggest trying this:
//*[#id='MainMenu']/li[normalize-space() = 'The text you want']/span
Though if you could show us what the HTML in question actually looks like, we can provide a more reliable answer. XPath doesn't have any concept of "visual text", so if you have some text that's hidden within the li you're trying to retrieve, that could be considerably trickier.
I have solved by using filesrc attibute of span tag in the list item.
Xpath is:
//span[contains(#filesrc, 'myFile.aspx')]
As my .aspx file will be the same for any page, so I used filesrc attribute which contains the actual file name and is the only file name in that html page.
You can use the following
driver.FindElement(By.XPath("//li[contains(Text(),'Expected Text']")).Click();
Or you can avoid xpath all together by running a foreach loop on the relevant Class tag
foreach (IWebElement e in driver.FindElements(By.ClassName("ui-selectee")))
{
if (e.Displayed && e.Text == "Expected Text")
e.Click();
}