If else not working - ruby

I am having trouble with this one, I try to change the conditions and add other options but still I got the same error.. can someone help me? Thanks a lot!
this is my codes:
require 'watir-webdriver'
require 'minitest/autorun'
require "win32ole"
class Login < Minitest::Unit::TestCase
$number_of_fails = 0
$number_of_success = 0
$fields = ["first_name", "middle_name", "last_name", "sss_number", "tin_number"]
# $to_enter = ["Helfe", "padayao", "Marquez", "1234rer", "9387373"]
def test_in()
#browser =Watir::Browser.new :firefox
#browser.goto 'http://gw01.nextix.org/login'
accept_next_alert=true
#browser.driver.manage.window.maximize
excel= WIN32OLE::new("excel.Application")
wrkbook=excel.Workbooks.Open("C:\\testing\\inputs.xlsx")
wrksheet = wrkbook.worksheets(1)
wrksheet.select
rows = 2
while rows <= 5
$username = wrksheet.cells(rows, "A").value
$password = wrksheet.cells(rows, "B").value
#browser.text_field(:name, "username").set($username)
sleep 3
#browser.text_field(:name, "password").set($password)
sleep 3
#browser.button(:name => 'login').click
sleep 3
rows = rows + 1
end
$Dashboard = #browser.link(:text, "Dashboard")
$Dashboard.exists?
$Dashboard.click
#browser.link(:text, "Users").click
#browser.button(:value,"Add New User").click
rows = 8
while rows <= 13
$fname = wrksheet.cells(rows, "A").value
$mname = wrksheet.cells(rows, "B").value
$lname = wrksheet.cells(rows, "C").value
$sss = wrksheet.cells(rows, "D").value
$tin = wrksheet.cells(rows, "E").value
#browser.text_field(:id, $fields[0]).set($fname)
sleep 5
#browser.text_field(:id, $fields[1]).set($mname)
sleep 5
#browser.text_field(:id, $fields[2]).set($lname)
sleep 5
#browser.text_field(:id, $fields[3]).set($sss)
sleep 5
#browser.text_field(:id, $fields[4]).set($tin)
#browser.send_keys :tab
rows += 1
for i in 0..4
if #browser.text_field(:id => $fields[i], :aria_invalid => "false")
$number_of_success = $number_of_success + 1
else
$number_of_fails = $number_of_fails + 1
end
end
end
puts "Number of Success: #{$number_of_success}"
puts "Number of Failures: #{$number_of_fails}"
end
end
The result:
User1#DOCUMENTATIONS /c/testing
$ ruby revised_login.rb
Warning: you should require 'minitest/autorun' instead.
Warning: or add 'gem "minitest"' before 'require "minitest/autorun"'
From:
c:/Ruby193/lib/ruby/1.9.1/minitest/autorun.rb:14:in `<top (required)>'
revised_login.rb:2:in `<main>'
MiniTest::Unit.autorun is now Minitest.autorun. From c:/Ruby193/lib/ruby/1.9.1/m
initest/autorun.rb:18:in `<top (required)>'
MiniTest::Unit::TestCase is now Minitest::Test. From revised_login.rb:5:in `<mai
n>'
Run options: --seed 13926
# Running:
Number of Success: 30
Number of Failures: 0
.
Finished in 287.038568s, 0.0035 runs/s, 0.0000 assertions/s.
1 runs, 0 assertions, 0 failures, 0 errors, 0 skips
User1#DOCUMENTATIONS /c/testing
$

Try to add this methods in your condition..
exists? – Returns whether this element actually exists.
present? – Returns true if the element exists and is visible on the
page
visible? – If any parent element isn’t visible then we cannot write
to the element. The only reliable way to determine this is to iterate
up the DOM element tree checking every element to make sure it’s
visible.

The ruby IF statement expects you to follow it with something that will return True or False. If you do not do that, If is going to 'punt' and treat anything returned that is not null, zero, or 'false' as TRUE. The method you are invoking is going to return a handle to an object not true or false and thus IF is going to treat that as 'true'
to prove this, use irb to create a watir browser object, navigate to a web page, and then try the following (note that the page I am on has no text field that matched the selection criteria)
irb(main):009:0> puts b.text_field(:aria_invalid => 'false')
#<Watir::TextField:0x00000001f042a8>
=> nil
irb(main):010:0> puts b.text_field(:aria_invalid => 'false').exists?
false
irb(main):011:0> puts "true" if b.text_field(:aria_invalid => 'false')
true
=> nil
irb(main):012:0> puts "false" unless b.text_field(:aria_invalid => 'false').exists?
false
=> nil
irb(main):016:0> puts b.text_field(:aria_invalid => 'false').exists? ? "true" : "false"
false
=> nil
you can see that the IF treats the (effectively empty) object being returned as 'true' even when the object does not exist in the dom. You need to add the .exists? method, then we get back a true or a false, and you can see that now the conditional responds as we would expect given the existence or non-existence of the object.

Related

Ruby method unable to pass Rspec test

I am trying to create a method that takes in a user input. It turns that user input into an integer, it then subtracts one from the user input. It also returns -1 if the user input is not a number. However the tests throws an error.
describe '#input_to_index' do
it 'converts a user_input to an integer' do
user_input = "1"
expect(input_to_index(user_input)).to be_a(Fixnum)
end
it 'subtracts 1 from the user_input' do
user_input = "6"
expect(input_to_index(user_input)).to be(5)
end
it 'returns -1 for strings without integers' do
user_input = "invalid"
expect(input_to_index(user_input)).to be(-1)
end
end
Here is my method:
def input_to_index(user_input)
user_input = user_input.to_i
user_input = user_input - 1
return -1 if !user_input.is_a? Numeric
end
It's because you're only returning something if !user_input.is_a?(Numeric) and you've already cast user_input to an integer.
-1 if false # => nil
-1 if true # => -1
So that last line in the method returns nil because the condition is never going to be met.
"a".to_i # => 0
"a".to_i.is_a?(Numeric) # => true
("a".to_i - 1).is_a?(Numeric) # => true
You don't even need that last line at all and things will work fine:
def input_to_index(user_input)
user_input = user_input.to_i
user_input = user_input - 1
end
input_to_index("1") # => 0
input_to_index("6") # => 5
input_to_index("invalid") # => -1
and more succinctly:
def input_to_index(user_input)
user_input.to_i - 1
end
input_to_index("1") # => 0
input_to_index("6") # => 5
input_to_index("invalid") # => -1
I'm sure there is a more eloquent way to do this, but you could do this:
def input_to_index(user_input)
user_input = user_input.to_i
user_input = user_input - 1
if !user_input.is_a? Numeric
-1
else
user_input
end
end
EDIT
This might be a more eloquent way to do it:
def input_to_index(user_input)
user_input = user_input.to_i - 1
!user_input.is_a?(Numeric) ? -1 : user_input
end
Below is the most eloquent way to do that:
def input_to_index(user_input)
user_input.to_i - 1
end
Credit: Simple Lime

Ruby undefined method `[]' for nil:NilClass

I'm trying to make nagios check for BBU (Battery Backup Unit), I have this ruby script called check_bbu
#!/usr/bin/ruby
require 'json'
output = %x{/usr/sbin/storcli /c0/bbu show j}
begin
j = JSON.parse(output)
result = j["Controllers"][0]["Command Status"]["Status"]
status = j["Controllers"][0]["Response Data"]["BBU_Info"][0]["State"]
rescue Exception => e
puts "CRITICAL: error reading BBU status: #{e}"
exit 2
end
if result != 'Success'
puts "CRITICAL: command not successful, result: #{result}"
exit 2
end
if status != 'Optimal'
puts "CRITICAL: BBU not optimal, status is #{status}"
exit 2
end
puts "OK: BBU is optimal"
But when I run this plugin I'm getting following error,
$ ./check_nrpe -u -t 30 -H foo.example.com -c check_bbu
CRITICAL: error reading BBU status: undefined method `[]' for nil:NilClass
What am I doing wrong in this ?
Seems your code break at
j = JSON.parse(output)
result = j["Controllers"][0]["Command Status"]["Status"]
status = j["Controllers"][0]["Response Data"]["BBU_Info"][0]["State"]
you should check which line
j == nil, and your want j["Controllers"]
result = j["Controllers"][0]["Command Status"]["Status"]
status = j["Controllers"][0]["Response Data"]["BBU_Info"][0]["State"]
cause undefined method '[]' for nil:NilClass by display j value first, and make sure json format match your code.
j = JSON.parse(output)
p j # display value
update:
your json format should match your code, otherwise it will raise error.
for example:
{
"Controllers": [
{
"Commandddd Status": { # format not match
"Status": "success"
}
}
]
}
# code and json format not match
j["Controllers"][0]["Command Status"] # nil
j["Controllers"][0]["Command Status"]["Status"]
=> nil["Status"] # boom!
For example to my comment, lets imagine that we have correct JSON:
j = {"Controllers" => [{"Comand Status" => {"status" => 'ok'}}]}
=> {"Controllers"=>[{"Comand Status"=>{"status"=>"ok"}}]}
so by typing your first line, it's should return correct result:
> j["Controllers"][0]["Comand Status"]["status"]
=> "ok"
But also you can get wrong JSON, for example:
j_e = {"Controllers" => []}
so now it's return error:
>j_e["Controllers"][0]["Comand Status"]["status"]
NoMethodError: undefined method `[]' for nil:NilClass
to solve it, you can use something like:
def try data, keys # there we take arguments: data == j, and keys == array with keys
return data if data.nil? # there we check: if data, that we send == nil, for example j = nil, array = ['first', etc..] we should stop this method and return nil as result
value = data[keys.shift] # on this line we try to get some data from j ##keys.shift will delete first element from array that we send to this method and return as `key` for `data`, for example data['Controllers'] so keys now will looks like: [0, 'Comand Status', 'status']
unless keys.empty? #on this line we check if on the pred line we was used the last key and keys now looks like: [] we: *return value and if it's not empty we just **call this method 1 more time
try(value, keys) #**value = [{"Comand Status" => {"status" => 'ok'}}] and keys = [0, 'Comand Status', 'status']
else
value #*nil or value
end
end
j = {"Controllers"=>[{"Comand Status"=>{"status"=>"ok"}}]}
try(j, ['Controllers', 0, 'Comand Status', 'status'])
>'ok'
try j, ['Controllers', 1, 'Comand Status', 'status']
> nil
in you code this should looks like:
require 'json'
def try data, keys
return data if data.nil?
value = data[keys.shift]
unless keys.empty?
try(value, keys)
else
value
end
end
output = %x{/usr/sbin/storcli /c0/bbu show j}
begin
j = JSON.parse(output)
result = try(j, ["Controllers", 0, "Command Status", "Status"])
status = try(j, ["Controllers", 0, "Response Data", "BBU_Info", 0, "State"])
rescue Exception => e
puts "CRITICAL: error reading BBU status: #{e}"
exit 2
end
if result != 'Success'
puts "CRITICAL: command not successful, result: #{result}"
exit 2
end
if status != 'Optimal'
puts "CRITICAL: BBU not optimal, status is #{status}"
exit 2
end
puts "OK: BBU is optimal"
Also, for Ruby 2.3.0+
it's much easier, just:
j.dig("Controllers", 0, "Comand Status", "status")

Errors locating elements with Ruby Watir and PhantomJS

I have a script that runs perfectly in the ChromeWebDriver but fails on PhantomJS. When I check if an element exists i get the following error:
[ERROR - 2014-01-07T19:31:55.878Z] WebElementLocator - _handleLocateCommand - El
ement(s) NOT Found: GAVE UP. Search Stop Time: 1389123115867
This doesn't really seem like an issue as the script continues. However, later on the script will fail unable to locate the following element:
question.div(:class => "choices")
This particular script visits a page that has test questions on it. They are in random order. The script decided what kind of question it is and chooses a random answer.
Thanks for any help. Here is the relevant code:
def QuestionType(question)
if question.div(:class => "questionPrompt").text_field.exists?
puts "FITB"
FITB(question)
#elsif question.div(:class => "choices").ul(:class =>"choices-list").li(:index => 1).checkbox.exists?
elsif question.checkbox.exists?
puts "Checkbox"
Checkbox(question)
else
puts "Radio"
Radio(question)
end
end
def FITB(question)
arn = Random.new.rand(0..10)
if arn == 0
answers.li(:index => arn).radio.set
else
idx = 0
begin
question.div(:class => "questionPrompt").text_field(:index => idx).set("Test #{idx}")
idx = idx + 1;
end while question.div(:class => "questionPrompt").text_field(:index => idx).exists?
end
puts "FITB Complete"
end
def Checkbox(question)
allAnswers = question.div(:class => "choices")
answers = allAnswers.ul
max = answers.lis.length - 1
arn = Random.new.rand(0..max)
if arn == 0
answers.li(:index => arn).radio.set
else
for i in 1..arn
answers.li(:index => i).checkbox.set
end
end
puts "Checkbox Complete"
end
def Radio(question)
allAnswers = question.div(:class => "choices")
answers = allAnswers.ul
max = answers.lis.length - 1
arn = Random.new.rand(0..max)
answers.li(:index => arn).radio.set
puts "Radio Complete"
end

Ruby(Hard Way) Ex48 - Why won't this Integer(param).to_s => "string"?

I've tried using Integer(word) which in irb => 1234 understandably, but when iI program num = word.to_s or Integer(word).to_s it still outputs an Integer.
I see the difference in the test, but the input doesn't matter right?
All ints should output as strings?
Why is this?
How can I fix it?
For context, I'm attempting to complete this exercise...
http://ruby.learncodethehardway.org/book/ex48.html
My code
class Lexicon
Pair = Struct.new(:token, :key)
def scan(stuff)
#words = stuff.split(" ")
return analyze
end
def analyze
hash = { "north" => :direction, "south" => :direction, "east" => :direction, "west" => :direction,
"go" => :verb, "stop" => :verb, "kill" => :verb, "eat" => :verb,
"the" => :stop, "in" => :stop, "of" => :stop, "from" => :stop, "at" => :stop, "it" => :stop,
"door" => :noun, "bear" => :noun, "princess" => :noun, "cabinet" => :noun}
#words.map do |word|
#hash.keys.include?(word) ? Pair.new(hash[word], word) : Pair.new(:error, word)
begin
Integer(word).to_s
#Integer(word)
#num = word.to_s
#Pair.new(:number, num)
Pair.new(:number, word)
rescue ArgumentError => x
if hash.keys.include?(word)
Pair.new(hash[word], word)
else
Pair.new(:error, word)
end
end
end
end
end
Terminal
$ ruby test_lexicon.rb
Run options:
# Running tests:
[4/6] LexiconTests#test_numbers = 0.00 s
1) Failure:
test_numbers(LexiconTests) [test_lexicon.rb:49]:
<[#<struct Lexicon::Pair token=:number, key="1234">]> expected but was
<[#<struct Lexicon::Pair token=:number, key=1234>]>.
Finished tests in 0.004981s, 1204.5774 tests/s, 2208.3919 assertions/s.
6 tests, 11 assertions, 1 failures, 0 errors, 0 skips
ruby -v: ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.3.0]
Exercise snippet (test file)
def test_numbers()
assert_equal(##lexicon.scan("1234"), [Pair.new(:number, 1234)])
result = ##lexicon.scan("3 91234")
assert_equal(result, [Pair.new(:number, 3),
Pair.new(:number, 91234)])
end
In this block:
Integer(word).to_s
Pair.new(:number, num)
You reference a variable num, which isn't declared in the code you've pasted. It seems that you're not testing what you think you're testing.
However, the failure:
<[#<struct Lexicon::Pair token=:number, key="1234">]> expected but was
<[#<struct Lexicon::Pair token=:number, key=1234>]>.
...is misleading. The test:
assert_equal(##lexicon.scan("1234"), [Pair.new(:number, 1234)])
...is looking for the result of ##lexicon.scan("1234") to be [Pair.new(:number, 1234)]. That is the expected and actual arguments to assert_equal are transposed.
So you are returning the String("1234") when actually the Integer(1234) is what is required.
In short, therefore, your block needs to be:
Pair.new(:number, Integer(word))
...and your tests should all pass.

syntax error, unexpected keyword_end, expecting '}' [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have gotten this syntax error message:
/usr/src/check_in/lib/check_in.rb:105: syntax error, unexpected keyword_end, expecting '}'
class CheckIn < Adhearsion::CallController
def run
answer
#play 'welcome.wav' # "Welcome to the PSG check in application."
logger.info "#{call.from.to_s} called at #{time.now.to_s}"
if verify_phone(call.from) == false # If it's not a site phone
logger.info "Number not recognised, routing to Ops"
#play 'not_site_phone.wav' # "Number not recognized."
#dial(sip:number) # Dial operations
hangup
else
user = verify_uid # Checks the User Id
end
if to_check_out?(user.uid)
check_out(user.uid)
else
update_shift(user.uid)
#play 'thank_you.wav'
end
end
def verify_uid
count = 1 # Generic count variable
input = ask 'enter_uid.wav', :limit => 5, :timeout => 5.seconds #takes user ID as DTMF
while (count <= 3 ) # Tracks the number of attempts
if User.find_by_uid(input.response) == nil # If user.find doesn't return anything
logger.info "Invalid user ID. ID entered = #{input.response} Attepmt = #{count}"
input = ask "please_try_again.wav", :limit => 5, :timeout => 10.seconds
count += 1 # Get user to try again
elsif count == 3
play "try_again_later.wav" #"Please try you again later"
logger.info "Tries exceeded, played try again later."
hangup
else
#user = User.find_by_uid(input) # Assigns the user variable to return.
logger.info "User ID: #{#user.uid} is valid"
return #user
end
end
end
def verify_phone(caller_id)
if Sites.find_by_site_phone(caller_id) != nil
return true
else
return false
end
end
def update_shift (user_id)
#user = User.find_by_uid(user_id) # Grabs the user object
if (#user.checked_in?) # If the user is already checked in assign the relevant attributes
#user.time_olc = time.now
#user.num_ci += 1
#user.check_in.create_check_in(:site_id => #user.site_id, uid => #user.uid, :time => time.now)
logger.info "#{#user.uid} checked in at #{#user.time_olc}"
else # Otherwise set all the attributes for the shift
#user.update_attributes(:checked_in? => true, :time_in => time.now, :time_olc => time.now, :num_ci => 1, :site_id => #user.site.find_by_site_phone(call.from))
#user.check_in.create_check_in(:site_id => #user.site_id, uid => #user.uid, :time => time.now)
logger.info "#{#user.uid} punched in at #{#user.time_in}"
end
end
def to_check_out?(user_id) # Method to see if the user has reached check out
#user = User.find_by_uid(user_id)
num_of_ci = #user.num_ci + #user.num_notifications
if (num_of_ci >= #user.site.shift_len)
return true
else
return false
end
end
def check_out!(user_id)
#user = User.find_by_uid(user_id)
input = ask 'check_out?.wav', :limit => 1, :timeout => 5.seconds
if (input == 1)
update(#user.uid)
else
#user.time_out = time.now
#user.time_olc = time.now
#user.update_attributes(:checked_in => false)
end
report_for_user(uid)
end
def secure
count = 1
play 'secure.wav'
sec = 5.times.map {Random.rand(0..9)
result = ask %w"#{sec[0]}, #{sec[1]}, #{sec[2]}, #{sec[3]}, #{sec[4]}", :limit => 5, :timeout => 5.seconds
while (count <= 3)
if (sec.join == result.response)
logger.info "Check in valid"
return true
elsif (count < 3)
result = ask 'please_try_again.wav', :limit => 5, :timeout => 5.seconds
else
play 'try_again_later.wav'
hangup
end
end
end
def report_for_user(user_id)
#user = Users.find_by_uid(user_id)
report = file.open("/report/#{user_id}-#{#user.site_id}-#{date.current}",w)
user_check_ins = #user.check_in.all
report.write("Time, Site ID, User ID")
user_check_ins.each do |check_in|
report.write("#{user.check_in.time}, #{user.check_in.site_id}, #{user.checkin.uid}")
check_in.destroy
end
end
def notify
foo = Users.all
foo.each do |user|
if user.checked_in?
t1 = Time.now #sets a time place holder
t2 = user.time_olc
convert_time = (t1.hour * 60 * 60) + (t1.min * 60) + t1.sec
convert_tolc = (t2.hour * 60 * 60) + (t2.min * 60) + t1.sec
if ((convert_time - convert_tolc)/60 > 75)
user.num_notification += 1
a = user.uid.to_s
logger.info "#{user.uid} hasn't checked in this hour"
# Adhearsion::OutboundCall.originate '+tel: Mobile' :from => ' ' do
# answer
# play a[0], a[1], a[2], a[3], a[4], 'has_not_checked_in.wav'
# hangup
# end
end
end
end
end
end
In this method you have opened one curly bracket '{' but not closed it.
def secure
count = 1
play 'secure.wav'
sec = 5.times.map {Random.rand(0..9)
result = ask %w"#{sec[0]}, #{sec[1]}, #{sec[2]}, #{sec[3]}, #{sec[4]}", :limit => 5, :timeout => 5.seconds
while (count <= 3)
if (sec.join == result.response)
logger.info "Check in valid"
return true
elsif (count < 3)
result = ask 'please_try_again.wav', :limit => 5, :timeout => 5.seconds
else
play 'try_again_later.wav'
hangup
end
end
end
you are missing a closing brace in secure method at the following line
sec = 5.times.map {Random.rand(0..9)

Resources