Is it possible to get element by class in selenium webdriver ruby? - ruby

I have a class like this:
<div class="qa-share-message ng-isolate-scope ng-valid ta-root
ng-dirty focussed" ng-model="message" text-angular="">
I want to type in this field. i have tried this:
driver.find_elements(:class, "qa-share-message").send_keys("This is a test message")
After running the code it shows error:
undefined method `send_keys' for [#<Selenium::WebDriver::Element:0x65990040 id="33">]:Array
Is it possible to get element by class?

You obviously got elements by class. Look:
undefined method `send_keys' for [# Selenium::WebDriver::Element:0x65990040 id="33"]:Array
the error above clearly says: the call to find_elements succeeded and returned an Array instance, containing Elements. Everything you now need is to either send_keys to each found element:
driver.find_elements(:class, "qa-share-message").each do |e|
e.send_keys("This is a test message")
end
or to send it to one of them, e.g. to the very first one:
driver.find_elements(:class, "qa-share-message")
.first
.send_keys("This is a test message")

Related

Undefined method 'count' when using '.map' in Watir

I'm using Watir to load all apps in a directory with infinite scroll and count them:
grid = browser.divs(class: 'rows')[1]
app_urls = grid.map { |app| app.a(class: 'element Link clickable-element').href }
app_urls.count
but I'm getting the following error:
in `method_missing': undefined method `count' for #<Watir::Map: located: false; {:class=>"rows", :tag_name=>"div", :index=>1} --> {:tag_name=>"map"}> (NoMethodError)
Why can't I use .map in this case and how should I count the number of apps instead?
grid is a single Watr::Div element. This means that #map is actually the method for looking for a map element rather than the Enumerable one.
Assuming you're wanting to iterate over the divs with class "row", then it should be:
grid = browser.divs(class: 'rows')

Why the object returned is Enumerable?

I don't understand why do I get an Enumerable instead of an object. When I run this code :
- #posts.each do |post|
= Comment.find(id: post.id).title
I've got this error :
undefined method `title' for #Enumerator: Comment:find({:id=>1})>
If I check in the console I get also Enumerator :
[2] pry(#<Sinatra::Application>)> Comment.find 1
=> #<Enumerator: ...>
I just want to have my object like #<Comment #id=1 #content="great" #post_id=1>
I'm working with Sinatra and Datamapper.
The query you're looking for is:
Comment.first(id: post.id).title
Which is a short version of:
Comment.all(id: post.id).first.title
There is no find in Datamapper (that I know of). What you're actually seeing is the result of Ruby's Enumerable#find: http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-find, which must be a part of Datamapper objects.

Why does mechanize raise NoMethodError on my page2.links.each method chain?

Error
mySpiderScript.rb:119:in ` block (3 levels) in <main>': undefined method `links' for #<Mechanize::Image:0x120a7e38> (NoMethodError)
Code
agent2 = Mechanize.new
page2 = agent2.get('http://www.mywebsite.net')
page2.links.each do |link2| #line 119
name = link2.href.to_s
How do I fix this so that the script keeps running?
Update
Here is what page2.body returns.
����JFIF���ICC_PROFILE�lcms0mntrRGB XYZ �*acspAPPL���-lcms
desc8cprt#Nwtpt�chad�,rXYZ�bXYZ�gXYZ�rTRC
gTRC, bTRCL chrml$mluc
enUSsRGB built-inmluc
enUS2No copyright, use freelyXYZ ���-sf32
Y� J����*��������������XYZ o�8��XYZ $����XYZ b����paraff��
Y�raff��
Y�raff��
[chrm��T{L���&f\��
$.' ",#(7),01444'9=82<.342��C
2!!22222222222222222222222222222222222222222222222222��"����������
?����
From the comments:
[T]he body is not a valid mechanize object. How to skip it?
There are lot of ways to validate your object before trying to invoke a method on it. One way is to use the poorly-documented safe navigation operator (&.) introduced in Ruby 2.3.0. For example, using your existing code:
page2&.links&.each do |link2|
This will return nil if the object in page2 doesn't respond to #links, or the result of page2.links doesn't respond to #each. Program flow will then continue after the #each block formed by your page2&.links&.each method chain.

Can't convert Configatron::Store to String error when value used as parameter to Object.const_get

I recently replaced a home-grown configuration module with Configatron, but I'm unable to get one use case working.
When I attempt to use a configatron value as an argument to Object.const_get like this:
def formatter_class
Object.const_get(configatron.formatter)
end
I get the following error:
file.rb:10:in `const_get': can't convert Configatron::Store to String
(Configatron::Store#to_str gives Configatron::Store) (TypeError)
The configatron assignment looks like this (simplified):
configatron.formatter = case
when condition?
'ExportFormat'
else
'ScreenFormat'
end
Even if I do configatron.formatter = 'ScreenFormat', I get the same error.
I've tried variations on the formatter_class method too. This fails:
def formatter_class
Object.const_get(configatron['formatter'])
end
Of course, this succeeds, but won't fulfill my use case:
def formatter_class
Object.const_get('ScreenFormat')
end
What am I doing wrong?
I solved my issue. Turns out you can call configatron.whatever and it will return a Configatron::Store if it's not initialized.
I inserted a call to configatron.has_key? 'formatter' before accessing the value. When it returned false, I figured out that the error was occurring in a code path where the value hadn't been initialized yet. Once I initialized the value, the error no longer occurs.
Happens when .yml config file is missing. Or the key that you are looking for is not there.
Location:
/config/NAME.yml

dashing job undefined map method error

I'm using the dashing dashboard to display some data. Part of my code for one of the jobs uses the map! function in ruby:
vars = arr.map! { |element| element.gsub(/.{3}$/, '' )}
and when I try to run the dashboard using dashing start, I get the following error :
scheduler caught exception:
undefined method map! for #<Hash: 0x......>
If I run the code on its own as a ruby program, I get the correct result.
The documentation for the JSON module indicates that the parse method will "...convert your string into a hash." See http://www.ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html#module-JSON-label-Parsing+JSON.
Try calling just map on your hash instead of calling map!:
vars = arr.map { |element| element.gsub(/.{3}$/, '' )}
The difference is that map will return a new array with the results of running your block once for every element in the Hash. Also, map is defined in the Enumerable module, which is included by Hash, but map! is not defined in Enumerable. See http://www.ruby-doc.org/core-2.0.0/Enumerable.html#method-i-map.

Resources