Retrieve text from span element in watir webdriver - watir

I have the following:
<ul class="a">
<li class="b">
<a class="c">
<span class="d">
<strong>text</strong>
</span>
</a>
</li>
</ul>
I'm trying to get the "text" from the span.
When I try:
puts browser.ul( :class =>'a').li( :class =>'b').link(:class =>'c').span(:class =>'d')
I get the span element back. #<Watir::Span:0x007fa1d11edb18> as i should.
But when trying:
puts browser.ul( :class =>'a').li( :class =>'b').link(:class =>'c').span(:class =>'d').text
im getting an error saying :
unable to locate element, using {:class=>'b', :tag_name=>"li"}
Any ideas ?

It would help if you could point to the page where the problem is reproducible, even if that means that you create a page yourself, put it in dropbox and make it public.
Did you even try to replicate the problem with the html and ruby code that you have posted? I am asking because the problem is not reproducible with the provided code. Take a look yourself:
> browser.ul( :class =>'a').li( :class =>'b').link(:class =>'c').span(:class =>'d')
=> #<Watir::Span:0x..fa66c75ff618434cc located=false selector={:class=>"d", :tag_name=>"span"}>
> browser.ul( :class =>'a').li( :class =>'b').link(:class =>'c').span(:class =>'d').text
=> "text"
As far as I understood, you are surprised that when you provide some code, Watir returns an element, but when you want to execute a method on the element, it complains that it can not find the element.
Take a closer look at the ruby object that represents element on a page:
#<Watir::Span:0x..fa66c75ff618434cc located=false selector={:class=>"d", :tag_name=>"span"}>
Please notice located=false. As far as I know, that means that watir creates a ruby object before trying to access it, so the first line of your code does not raise any exceptions. But then when you try to use the element, watir can not find it on the page and complains.

Related

How can I get text from span(s) in dirs which are located in table?

I have just only recently started using selenium and I can't get it to work properly.
I need to get a text from (s) which are inside dives which are inside a table.
Like this:
<td class="some-class">
"""many divs above"""
<div class="props">
<span>text</span>
<span class="mr2">text</span>
</div>
"""/many divs above"""
</td>
So, I need to get 'text(s)' from spans, but also there are many td s like this one and inside divs, classes repeat.
Moreover, how can I get it as a list?
I have tried this:
el = browser.find_elements_by_css_selector('dir.props > span')
print(el)
for i in el:
dict_of_orders.append(i.text)
print(dict_of_orders)
However, it returns only empty lists.
Any advice?:)
Thanks ahead for any help!
You have a typo in your CSS selector. It should be div instead of dir:
el = browser.find_elements_by_css_selector('div.props > span')
I don't know if that will fix your problem, but you'll have to fix that.
Another thing I would try is, instead of text, use the innerText attribute, like this:
dict_of_orders.append(i.get_attribute('innerText'))
Hello for future someone like me. My problem was solved by adding the delay.
Check it, maybe a site that you're trying to parse is slow.
time.sleep(5) was the answer.
el =browser.find_elements_by_xpath("//div[#class='props']/span")

How to enter text into a react-selectize-control using Watir

I have the following code on the page:
<div class="col-md-5 col-lg-3">
<div class="react-selectize bootstrap3 root-node simple-select open">
<div class="react-selectize-control">
<div class="react-selectize-placeholder">testing!</div>
<div class="react-selectize-search-field-and-selected-values">
<input class="resizable-input" style="width: 4px;" type="input">
If I physically select the input field and then run the following using watir-classic:
BROWSER.div(:class => 'col-md-5 col-lg-3')
.div(:class => 'react-selectize-search-field-and-selected-values')
.text_field(:class => 'resizable-input')
.send_keys('Magg')
it will enter Magg into the field, but if I don't manually select the field I can't seem to get watir to enter the text.
I've tried the following:
BROWSER.div(:class => 'col-md-5 col-lg-3')
.div(:class => 'react-selectize-search-field-and-selected-values')
.text_field(:class => 'resizable-input')
with
.set('Magg')
.fire_event('onfocus')
.fire_event('mousedown')
.fire_event('mouseup')
using
.parent.text_field(:class => 'resizable-input')
.parent.input(:class => 'resizable-input').set('Magg')
.input(:class => 'resizable-input').set('Magg')
.input(:class => 'resizable-input').send_keys('Magg')
I've been working with the developer using the control and neither of us can figure out how to give the control focus so that the send_keys works without manually selecting the control. Any guidance would be greatly appreciated.
First - obligatory warning that Watir Classic is deprecated and you should be using Watir WebDriver. (which may fix this issue)
Second - technically: div(:class => 'col-md-5 col-lg-3') should be div(:css => '.col-md-5.col-lg-3') since class should be singular.
Have you tried just doing element.fire_event(:click) before element.set?
Be aware that your HTML has an invalid 'type' value for the input tag. Per W3.org the type of 'input' is not a valid type choice for an input tag.
That is likely what is causing the method you expect to work (such as .set) to fail. It also means that all the watir methods to return the more specific sub-types of input (e.g. .text_field) will not work to select that tag.
Watir defines the specific input related methods (such as .set, .unset) according to the specific sub-type of input tag, and has methods to select those specific input types (such as .button). Normally you'd select an input tag using the method for it's sub-type, but because that value is not valid, that is not an option in this case, and you are forced to use .input. But as we just discussed, the input object in watir does not have methods like .set defined. So your only fallback is to use .sendkeys to send keystrokes to the element.
If it was me I'd write up a bug on that HTML, that it is not using a proper value for 'type' per the W3 spec.
Fixing the HTML to be valid will likely cause it to work far better with Watir or any other automation tool, especially those based on webdriver.

How do I clear a text field which is defined with in a div?

For the html:
<div class="controls">
<input type="text" id="13796781312861791131776">
I tried the following to clear the text field:
#browser.div(:class => /controls/).text_field(:topics_text_field, id:'13796781312861791131776').clear
Which gave the the following error:
expected one of [String, Regexp], got {:id=>"13796781312861791131776"}:Hash (TypeError)
Note: I am using Ruby 2.0.
It's because of how you're defining the attributes of the text field.
You are basically telling Watir that your text field can be identified by the Hash key/value pair of
:topics_text_field => :id=> '13796781312861791131776'
Watir doesn't know what to do with this (understandably, because that is a nonsensical key/value pair), so it throws an error telling you that you gave it something it didn't expect.
I would give you advice about exactly how to define it correctly, but you didn't include any of the HTML for the page containing this div and text field.
Does
#browser.div(:class => /controls/).text_field(:id, "13796781312861791131776").clear
work?
Sorry, I couldn't include the topics_text_field part since you didn't include that in the html.

How to click on link element with specific text using watir?

I'm not able to click on text link 'Add' using watir:
PAGE:
<div id="divAdd" style="float: right">
<a onclick="SwitchView('2')" style="color: #1B56A7; cursor: pointer;">Add</a>
</div>
Watir CODE:
browser.link(:text =>"Add").click
EXCEPTION:
Unable to locate element, using {:tag_name=>["a"], :text=>"Add"}
Please help me how to handle this?
If the page has a lot of ajax and javascript going on, you may just have to wait a little bit for the client side code to finish rendering the page after it has been loaded from the browser.
Try this
browser.link(:text =>"Add").when_present.click
If that does not work, then make sure the item is not in a frame or something..
btw, if there is more than one link on the page with the text 'Add' then you may have to specify a container outside the link that lets you identify which link you want. eg.
browser.div(id: => "divAdd").link.when_present.click
If
This would be my way of doing it.
while browser.div(:class, 'containerDIV').a(:text, 'Add').exists? do
browser.div(:class, 'containerDIV').a(:text, 'Add').click
end

How to extract the hover box information in watir and print it to a STDOUT

I have to print the hover box information content on to stdout and i tried it in the below fashion it didn't work for me .
data = $browser.div(:class => "homeSectionLabel textWidget",:text => /Pool A/ ).hover
print "Data #{data} \n"
And the other problem that i have other widget called Pool B with same class name . How to access that hover information
<div class="widgetContainer poolContainer">
<div class="healthBadge healthUnknown" style="top: -5px; left: -5px;"></div>
<div class="homeSectionLabel textWidget">Pool‌·A</div>
<div class="perfDisplay homePoolPerf">
</div>
<div class="homePoolVolText textWidget">9‌·Volumes,‌·0‌·Snapshots</div>
<div class="spaceMeterContainer poolMeter" style="width: 265px; height: 20px;">
</div>
<table class="tableWidget homeTiers" cellspacing="0" cellpadding="0" border="0">
</table>
</div>
Anyhelp is really appreciated .
Thanks!
Aditya
This is not much of an answer at the moment, but what I have to say won't fit in a comment
The 'content' as in the text within a div is normally accessed with the .text method
'tooltip' text can be done in a number of ways, it could be via alt attributes, it could be via javascript triggered via an 'onmouseover' event, or it could be CSS driven usually via the :hover psuedoclass.
if a div is merely changing it's display property or location so that it becomes visible to the user, then all you need to do is figure out how to locate that div, and get the .text from it
mydata = browser.div(:how => 'what').text
If the content of the div (or some other container) is changing as a result of the mouseover/hover, then you need to simulate the action, wait a brief bit to allow client side code to run, and THEN get the .text from the container that was changed.
Without seeing a page that has the code working on it, it is hard to tell which is the case, although given that I see nothing like 'onmouseover' in the code you supplied, my first bet would be on this being CSS driven.
The code you have above is returning the result of the div object executing the .hover method, and that is going to be nil as far as I know since that method causes something to happen, but does NOT return a value.
Is the 'Pool A' the text you are trying to capture, or is it what you mouse_over to cause the other text to become visible to the user? If it is what you mouseover, then have you searched the HTML to see if you can find the text that appears in some other div?
If you just need to get the text from every div of a given class, then try something like this
browser.divs(:class => "homeSectionLabel textWidget").each do |div|
puts div.text
end
Based on the most recent comment, this will gather the class names from all of the divs on the page and print it to the console.
$browser.divs.each do |div|
puts div.class
end
Replace "puts div.class" with a file directive if you want it in a file. Any output here is simple Ruby.

Resources