I am getting an error with (..).each do |x| .. end in ruby - ruby

I am getting error for the below part of code:
element = driver.find_element :name => "used_by"
element.send_keys "371101"
element = driver.find_element :name => "btnSearch"
element.click
all_table_data = driver.find_element(:tag_name, "td").text
all_table_data.each do |td|
puts td.text
end
print element
Error:
D:\Ruby script>ruby filedownload.rb
filedownload.rb:24:in `<main>': undefined method `each' for #<Selenium::WebDrive
r::Element:0x2556be8> (NoMethodError)
D:\Ruby script>
can anyone help me to fix the error?

find_element only returns the first element matching the given arguments.
What you probably what is the find_elements method which finds all elements matching the given arguments:
all_table_data = driver.find_elements(:tag_name, "td")
all_table_data.each do |td|
puts td.text
end

Related

undefined method `text' for nil:NilClass (NoMethodError) for and action that was excuted

I have the following code:
def find_status(arg)
10.times do
table = table_element(:css => 'css.path')
break if table.visible?
end
table = table_element(:css => 'css.path')
if table.visible?
table.each do |row|
STDOUT.puts row[1].text
match = /^#{arg}\n(String \S+) at .+/.match(row[1].text)
return match[1] if match
end
end
return "status unknown"
end
Now the problem is that I'm getting the following error:
undefined method `text' for nil:NilClass (NoMethodError)
The weird part is that it prints exactly what I wanted it to print and points out that the error is on the "STDOUT" row.
So to sum it up it's executing the command but says row is a nil value.
Help would be appreciated.
If I understand this correctly, just test for nil first, then use the row text if a row exists.
STDOUT.puts row[1] ? row[1].text : 'nil'

Parsing through nested hash using .present? - undefined method `[]' for nil:NilClass (NoMethodError)

***EDITED 2nd time to show that I need to handle looking in multiple locations.
EDITED to show exception being raise even when handler built in.
I am currently parsing through responses from an API that includes arrays that I've converted into a hash using
hash_table = xml_response.to_h
The challenge is that sometimes the data I'm looking for is located in different locations, and when I use a key method:
data_i_need = hash_table['key1']['key2'][0]
if there's nothing there, it throws this error:
undefined method `[]' for nil:NilClass (NoMethodError)
I've tried using:
if hash_table['key1']['key2'][0].present?
data_i_need = hash_table['key1']['key2'][0]
puts "data was here"
elsif hash_table['key3']['key4'][0].present?
data_i_need = hash_table['key3']['key4'][0]
puts "data here"
elsif hash_table['key5']['key6'][0].present?
data_i_need = hash_table['key5']['key6'][0]
puts "data here"
else
"data not found"
end
But it throws the same error:
undefined method `[]' for nil:NilClass (NoMethodError)
you should check for the presence all the previous hash key because if one of them is nil, the exception will be raised
hash_table['key1'].present? && hash_table['key1']['key2'].present? && hash_table['key1']['key2']['key3'].present? && hash_table['key1']['key2']['key3'][0].present?
Update:
To return "not found", you can catch the exception like this:
data_i_need = begin
hash_table['key1']['key2']['key3'][0]
rescue NoMethodError
"data not found"
end
Update 2:
You can use this function to check if the keys exist in the hash in the if else condition statements:
h = {:a => {:b => {0 => 1}}, :c => 2}
def has_nested_keys?(hash, *keys)
keys.inject(hash) do |result, key|
result = result[key]
end
true
rescue
false
end
has_nested_keys?(h, :a, :b, 0) #=> true
has_nested_keys?(h, :c, :d, 0) #=> false

Ruby/calabash: undefined method `each' for 2:Fixnum (NoMethodError)

I'm stuck with an error while creating some auto test in calabash. So my code is:
Then /^I set some site$/ do
arr=["Google.com","Youtube.com"]
for i in arr.length {
touch("* id:'browserActivity_linLout_toolbar_url'")
sleep 5
currentSite=arr[i]
keyboard_enter_text (currentSite)
sleep 10
press_enter_button
i=i+1
sleep 20
}
end
end
When I try to run my test I get this error:
undefined method each' for 2:Fixnum (NoMethodError)
./features/step_definitions/calabash_steps.rb:339:in/^I set some site$/'
features/my_first.feature:6:in `Then I set some site'
Any ideas how to solve it?
You are writing the for loop with the wrong syntax. In Ruby, use:
for element in arr
#...
currentSite = element
#...
end
Or better, without for:
arr.each do |element|
#...
currentSite = element
#...
end

undefined method `artist' for nil:NilClass (NoMethodError)

I am getting this error when I run the following code:
#!/usr/bin/env ruby -rubygems
require File.join(File.dirname(__FILE__), 'authentication')
require "csv" # faster_csv (ruby 1.9)
lines = CSV.read(File.join(File.dirname(__FILE__), 'karaoke.csv')) # Exported an Excel file as CSV
lines.slice!(0) # remove header line
collection = StorageRoom::Collection.find('collection ID')
Song = collection.entry_class
lines.each do |row|
karaoke = Song.new(:artist => row[0], :song => row[1], :genre => row[2], :file => StorageRoom::File.new_with_filename("#{karaoke.artist}#{karaoke.song}.mov"))
if karaoke.save
puts "Misuero Karaoke Latino saved: #{karaoke.artist}, #{karaoke.song}, #{karaoke.genre}"
else
puts "Misuero Karaoke Latino could not be saved: #{karaoke.errors.join(', ')}"
end
end
And the error is:
import_csv.rb:15:in `block in <main>': undefined method `artist' for nil:NilClass (NoMethodError)
from import_csv.rb:14:in `each'
from import_csv.rb:14:in `<main>'
I'm interested in learning why this error occurred as well as the solution. Thanks in advance!
Look at line 15 (import_csv.rb:15 tells you where to search for the issue):
karaoke = Song.new(:artist => row[0], :song => row[1], :genre => row[2],
:file => StorageRoom::File.new_with_filename("#{karaoke.artist}#{karaoke.song}.mov"))
In the right part of assignment expression you use karaoke.artist and karaoke.song to construct :file part of your Song, but karaoke variable is uninitialized yet (it appears on the left). In fact ruby interpreter defined karaoke variable when it saw the assignment operator and started evaluation of right-hand part of assignment expression (to initialize variable) and failed, because defined variable has nil value.
It appears that the problem lies in your assignment of the karaoke variable. When you are assigning anything to a new variable, the right side of the assignment is computed before the left side. So, at the moment your code gets to line 15, the karaoke variable is nil.
So, when you use the karaoke variable in the method StorageRoom::File.new_with_filename, it is a nil object. karaoke does not contain anything until the entire right side of the assignment is computed. Then it is tied to the karaoke variable.
You should consider using something like row[0] and row[2] instead of karaoke.artist and karaoke.genre.
It means you are calling artist method on a nil/Null
possibly try replacing #{karaoke.artist}#{karaoke.song} with #{row[0]}#{row[1]})
karaoke = Song.new(:artist => row[0], :song => row[1], :genre => row[2], :file => StorageRoom::File.new_with_filename("#{row[0]}#{row[1]}.mov"))
You can't use karaoke object in initializing of itself.
In ruby when you write(assuming that you've never used "a" variable before)
a = some_expression_or_value
the interpreter calculates the value of the "right part" which is some expression or value and then assigns it to the variable. Your variable karaoke hasn't been used before which means that it's value is nil. That's why you get this error.

Ruby Net:LDAP- NoMethodError for attributes that don't exist

I'm doing a simple Net:LDAP search and when I'm outputting an entry's attribute that may not exist for every entry, I get an error "NoMethodError: undefined method 'some_attribute'"
Here is the code:
require 'rubygems'
require 'net/ldap'
ldap = Net::LDAP.new
ldap.host = 'ldap.example.com'
ldap.port = 389
if ldap.bind
filter = Net::LDAP::Filter.eq( "sn", "Smith" )
treebase = "ou=people,o=company"
ldap.search( :base => treebase, :filter => filter, :return_result => false) do |entry|
puts #{entry.some_attribute}
end
end
else
puts "bind unsuccessful"
end
I tried also doing:
if entry.respond_to?(some_attribute)
puts "#{entry.some_attribute}"
end
That didn't work, it returns as false for every entry (when some entries have the attribute).
Ruby is expecting a symbol in the respond_to? method call.
ruby-1.8.7-p299 > class Foo
ruby-1.8.7-p299 ?> attr_accessor :some_attr
ruby-1.8.7-p299 ?> end
=> nil
ruby-1.8.7-p299 > Foo.new.respond_to?(some_attr)
NameError: undefined local variable or method `some_attr' for #<Object:0xb77ce950>
from (irb):4
ruby-1.8.7-p299 > Foo.new.respond_to?(:some_attr)
=> true

Resources