Clear input field and enter new info using Watir? (Ruby, Watir) - ruby

Pretty positive you have to use .clear, or maybe not as it doesn't seem to be working for me, maybe i'm just implementing it wrong I'm unsure.
Example:
browser.div(:id => "formLib1").clear.type("input", "hi")
Can anyone tell me how to simply clear a field then enter in a new string?

Assuming we are talking about a text field (ie you are not trying to clear/input a div tag), the .set() and .value= methods automatically clear the text field before inputting the value.
So one of the following would work:
browser.text_field(:id, 'yourid').set('hi')
browser.text_field(:id, 'yourid').value = 'hi'
Note that it is usually preferred to use .set since .value= does not fire events.

I had a similar issue, and, for some reason, .set() and .value= were not available/working for the element.
The element was a Watir::Input:
browser.input(:id => "formLib1").to_subtype.clear
after clearing the field I was able to enter text.
browser.input(:id => "formLib1").send_keys "hi"

I had a similar issue, and, for some reason, .set() and .value= were not available for the element.
The element was a Watir::HTMLElement:
[2] pry(#<Object>)> field.class
=> Watir::HTMLElement
field.methods.grep /^(set|clear)$/
=> []
I resorted to sending the backspace key until the value of the field was "":
count = 0
while field.value != "" && count < 50
field.send_keys(:backspace)
count += 1
end
field.send_keys "hi"

Related

Selenium web driver getting the text from the for attribute of a label using Ruby

I have seen some examples of how to do this in Javascript or python, but am looking for how to find the text of the for attribute on a label. e.g.
<label for="thisIsTheTextNeeded">LabelText</label>
<input type="checkbox" id=thisIsTheTextNeeded">
We want to pick up the text from the for attribute on the label element. Then use that text as the id to find the checkbox.
The .NET solution might look like:
textWeNeed = selenium.getAttribute("//label[text()='LabelText']/#for");
I tried this in Ruby:
textWeNeed =
#browser.find_element("xpath//label[text()='LabelText']/#for")
and get the error:
expected "xpath//label[text()=input_value]/#for":String to respond to #shift (ArgumentError)
Any ideas?
Here is how I fixed it. Thanks for all the help!
element = #browser.find_element(:xpath=>"//label[text()=\'#{input_value}\']")
attrValue = element.attribute('for') listElement =
#browser.find_element(:id=>"#{attrValue}")
You should use the attribute method to get the value of the attribute. See the doc
element = #browser.find_element(:xpath, "//label[text()='LabelText']")
attrValue = element.attribute("for")
According to OP's comment and provided html I think the element needs some explicit wait
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
element = wait.until { #browser.find_element(:xpath => "//label[contains(text(),'My list name')]") }
attrValue = element.attribute("for")
find_element function requires Hash to search with xpath.
correct way is here,
textWeNeed =
#browser.find_element(xpath: "xpath//label[text()='LabelText']/#for")
below is wrong way(your code).
textWeNeed =
#browser.find_element("xpath//label[text()='LabelText']/#for")
I found in Ruby when looking for Strings best to use is :find: instead of :find_element:
textWeNeed =
#browser.find("xpath//label[text()='LabelText']/#for")
when presented with the error: "String to respond to #shift"

getting the value of text field using rspec selenium

How do we use selenium webdriver + ruby to check to see if the value of a text field is equal to a certain value?
I was doing:
#tester.browser.find_element(:id => "id_of_text_field").text.should == 'test value'
Why doesn't that work?
this test failed ... couldn't get the value of the text field.
Text fields do not have text. The value you see in the text field is actually the value of their value attribute.
You can get an element's value attribute by doing:
element['value']
Therefore, your test needs to do:
#tester.browser.find_element(:id => "id_of_text_field")['value'].should == 'test value'
Write as below using should eql(expected)
Passes if given and expected are of equal value, but not necessarily the same object.
# I write in below way, just for readability, you can write it in one line.
elem = #tester.browser.find_element(:id => "id_of_text_field")
elem.text.should eql('test value')

Parsing element text with capybara-webkit

I'm new to Ruby and Capybara and I'm trying to use capybara-webkit to scrape a website. All of the data I'm interested in lies in td tags with certain properties.
Where form is a particular form element I'm looking at, the following code works:
form.all('td').detect do |td|
if td['valign'] == 'top' && td['nowrap'] != 'nowrap'
print "#{td.text}\n"
end
end
The contents of all of the td elements I'm interested in are printed out correctly. However, when I try to then parse the text with a regex:
form.all('td').detect do |td|
if td['valign'] == 'top' && td['nowrap'] != 'nowrap'
print "#{td.text}\n"
val1, val2 = td.match(/(\d)(\d)/).captures # The real regex is more complex
end
end
...suddenly only the first td element is read/parsed. I've tried even just pushing each td.text value into an array for later parsing, but the same thing occurs. I've even tried making a clone of the td.text string and operating on that—no luck. There doesn't seem to be any sort of timeout on the page that would change the HTML elements. Absolutely no clue what could be causing this.
Any thoughts?

How do I read text from non visible elements with Watir (Ruby)?

There is a div on a page that is not visible but has some value I want to capture. Calling text on it returns me an empty string.
How do I get the value displayed without having to deal with the raw html? Can I force .text to return me the actual value regardless of the visiblity of the text in the browser?
irb(main):1341:0> d.first.visible?
=> false
irb(main):1344:0> d.first.html
=> "<div class=\"day\">7</div>"
irb(main):1345:0> d.first.text
=> ""
PS: There are many many divs (the page is caching response and display them accordingly). I considered changing all the display:none in the page or clicking to make them visible but I'd prefer to avoid this if possible.
If not possible a solution with changing all the display none would be the preferred work around.
PPS: Damned, I tried to overload the visible? method in the Watir::Element class to always return true, but that didn't do the trick.
irb(main):1502:0> d.first.visible?
=> true
irb(main):1504:0> d.first.text
=> ""
For the newer versions of Watir, there is now an Element#text_content method that does the below JavaScript work for you.
e = d.first
e.text_content
#=> "7"
For Old Versions of Watir (Original Answer):
You can use JavaScript to get this.
e = d.first
browser.execute_script('return arguments[0].textContent', e)
#=> "7"
Note that this would only work for Mozilla-like browsers. For IE-like browsers, you would need to use innerText. Though if you are using watir-classic it would simply be d.first.innerText (ie no execute_script required).
Using attribute_value:
Turns out you can make it simpler by using the attribute_value method. Seems it can get the same attribute values as javascript.
d.first.attribute_value('textContent')
#=> "7"
Using inner_html
If the element only includes text nodes (ie no elements), you can also use inner_html:
d.first.inner_html
#=> "7"
Try using the execute_script method do change the value of "visible" to visible. Something like document.getElementById('id').style.visibility = 'visible' assuming it has an ID. If it does not you can always ask the devs to put a test-id on the element (or just do it yourself).

Sinatra can't convert Symbol into Integer when making MongoDB query

This is a sort of followup to my other MongoDB question about the torrent indexer.
I'm making an open source torrent indexer (like a mini TPB, in essence), and offer both SQLite and MongoDB for backend, currently.
However, I'm having trouble with the MongoDB part of it. In Sinatra, I get when trying to upload a torrent, or search for one.
In uploading, one needs to tag the torrent — and it fails here. The code for adding tags is as follows:
def add_tag(tag)
if $sqlite
unless tag_exists? tag
$db.execute("insert into #{$tag_table} values ( ? )", tag)
end
id = $db.execute("select oid from #{$tag_table} where tag = ?", tag)
return id[0]
elsif $mongo
unless tag_exists? tag
$tag.insert({:tag => tag})
end
return $tag.find({:tag => tag})[:_id] #this is the line it presumably crashes on
end
end
It reaches line 105 (noted above), and then fails. What's going on? Also, as an FYI this might turn into a few other questions as solutions come in.
Thanks!
EDIT
So instead of returning the tag result with [:_id], I changed the block inside the elsif to:
id = $tag.find({:tag => tag})
puts id.inspect
return id
and still get an error. You can see a demo at http://torrent.hypeno.de and the source at http://github.com/tekknolagi/indexer/
Given that you are doing an insert(), the easiest way to get the id is:
id = $tag.insert({:tag => tag})
id will be a BSON::ObjectId, so you can use appropriate methods depending on the return value you want:
return id # BSON::ObjectId('5017cace1d5710170b000001')
return id.to_s # "5017cace1d5710170b000001"
In your original question you are trying to use the Collection.find() method. This returns a Mongo::Cursor, but you are trying to reference the cursor as a document. You need to iterate over the cursor using each or next, eg:
cursor = $tag.find_one({:tag => tag})
return cursor.next['_id'];
If you want a single document, you should be using Collection.find_one().
For example, you can find and return the _id using:
return $tag.find_one({:tag => tag})['_id']
I think the problem here is [:_id]. I dont know much about Mongo but `$tag.find({:tag => tag}) is probably retutning an array and passing a symbol to the [] array operator is not defined.

Resources