Get specific element in webdriver containing text - ruby

What are some good ways to retrieve a specific element in WebDriver/Selenium2 based only on the text inside the element?
<div class="page">
<ul id="list">
<li>Apple</li>
<li>Orange</li>
<li>Banana</li>
<li>Grape</li>
</ul>
</div>
Essentially, I'd like to write something like this to retrieve the specific element:
#driver.find_element(:id, "list").find_element(:text, "Orange")
This is very similar to how I would use a selector when finding text inside a link (i.e. :link_text or :partial_link_text), but I would like to find elements by text inside normal, non-link elements.
Any suggestions? How do you deal with this issue? (In case you were wondering, I am using Ruby.)

You could do that with xPath. Something like this for your example:
#driver.find_element(:id, "list").find_element(:xpath, './/*[contains(., "Orange")]')

A couple years late, but I was just going to ask this question and answer it so other could find it...
I used a css selector to get all the li elements and then filtered the array based on the text:
#driver.find_elements(css: '#list > li').select {|el| el.text == 'Orange'}.first
You could then .click or .send_keys :return to select the option.

Related

XPath: How do I find a page element which contains another element, using the full text of both?

I have an HTML page which contains the following:
<div class="book-info">
The book is <i>Italicized Title</i> by Author McWriter
</div>
When I view this in Chrome Dev Tools, it looks like:
<div class="book-info">
"The book is "
<i>Italicized Title</i>
" by Author McWriter"
</div>
I need a way to find this single div using XPath.
Constraints:
There are many book-info divs on the page, so I can't just look for a div with that class.
Any part of the text within the book-info div might also appear in another, but the complete text within the div is unique. So I want to match the entire text, if possible.
It is not guaranteed that an <i> will exist within the book-info div. The following could also exist, and I need to be able to find it as well (but my code is working for this case):
<div class="book-info">
"Author McWriter's Legacy"
</div>
I think I can detect whether the div I'm looking for contains an <i> or not, and construct a different XPath expression depending on that.
Things I have tried:
//div[text()=concat("The book is ","Italicized Title"," by Author McWriter")]
//div[text()=concat("The book is ","<i>Italicized Title"</i>," by Author McWriter")]
//div[text()=concat("The book is ",[./i[text()="Italicized Title"]," by Author McWriter")]
//div[concat(text()="The book is ", i[text()="Italicized Title"],text()=" by Author McWriter")]
None of these worked for me. What XPath expression would?
You can use this combination of XPath-1.0 predicates in one expression. It matches both cases:
//div[#class="book-info" and ((i and contains(text()[1],"The book is") and contains(text()[2],"by Author McWriter")) or (not(i) and contains(string(.),"Author McWriter&apos;s Legacy")))]

protractor using xpath //*[contains('text')] error element not visible

Hi I have this element from a dropdown menu I try to select:
<div class="tt-suggestion tt-selectable">
<strong class="tt-highlight">Auto Customer</strong>
</div>
If I use element(by.xpath("//strong[contains(text(),'Auto Customer')]")).click(); I can select it no problem. But if I use element(by.xpath("//*[contains(text(),'Auto Customer')]")).click(); I get "Failed: element not visible"
Can someone explain this to me please?
Thank you
Because the * in //*[contains(text(),'Auto Customer')] means any tag, not only the strong Tag. But //strong[contains(text(),'Auto Customer')] must be strong Tag.
//*[contains(text(),'Auto Customer')] should find more then one elements on page, and the first one is not visible. You can try this xpath in Chrome DevTool's Element Tab to see how many elements it can find and the first one is visible or not.

Find text in unordered list and click on link within that list item

In a ruby script that uses watir, I'm trying to find text within an list item within an unordered list, then click on the link within that list item. In the sample below, I want to find "Apple" and have it click on the link that takes you to http://samplegrocerystore.com/tehnc34.
<div class="col-login">
<img class="logo" src="/images/hello.png" />
<h1 style="margin-top:15px;">Select Account</h1>
You have multiple accounts -- please select the one you would like to log in with.
<ul>
<li><h3>The Grocery Store</h3><h4>Chapter: Apple (#01)</h4>
<br/><strong>Login to this account</strong>
</li><li>
<h3>The Grocery Store</h3><h4>Chapter: Banana (#02)</h4>
<br/><strong>Login to this account</strong>
</li>
</ul>
</div>
I guess you are saying that you don't know the link href ahead of time?
Assuming you have opened the page in question using a Watir::Browser variable called browser:
Working off the unique text in the list item (Apple),
browser.li(:text, /Apple/).link(:text, 'Login to this account').click
should click the desired link.
Or if you do know the link href ahead of time, it is easier to use that:
browser.link(:href, 'http://samplegrocerystore.com/tehnc34').click
Either one should work, though if your web page is fairly complicated using a regex to find the word Apple might be slowish.
Based on your HTML, you can use the find method on a lists collection to locate the element with the specified text and then click on the link within the list element:
li = lists.find { |el| el.text.include? "Apple"}
li.a.click
try the following in irb:
browser.h4(:text => /Apple/).links.count
browser.h4(:text => /Apple/).parent.links.count
browser.h4(:text => /Apple/).parent.parent.links.count
until you find your answer with just 1 link, then that's your immediate link following the 'Apple' text. Then just call it like below:
browser.h4(:text => /Apple/).parent.link.click

Xpath of a text containing Bold text

I am trying to click on the link whose site is www.qualtrapharma.com‎ by searching in google
"qualtra" but there is problem in writing xpath as <cite> tag contains <B> tag inside it. How to do any any one suggest?
<div class="f kv" style="white-space:nowrap">
<cite class="vurls">
www.
<b>qualtra</b>
pharma.com/
</cite>
<div>
You may overcome this by using the '.' in the XPath, which stands for the 'text in the current node'.
The XPath would look like the following:
//cite[.='www.qualtrapharma.com/']

Selenium: Extracting only Text with out any sub elements from <p>

Below is the sample code
<p>
I want this Text
<sup> not this </sup>
.(Need this too).
<sup> and not this </sup>
</p>
Using Selenium RC, selenium.getText("//...") bring us the all the text including which are in < sup >.
Is there any way to get the text from <p> without <sup> tags ?
Please let me know. Thanks
Your only option is to get the text of the three elements and manipulate the parts you don't want away. That, or resort to using getEval() to run some JavaScript that get's the <P> element's innerHTML property, then remove the parts inside the <SUP> elements yourself.

Resources