Question

From my understanding of the docs this general approach should work:

begin
 try1
rescue
 try2
rescue
 try3
.
.
.
rescue
 puts "Everybody failed, sorry man!"
end

However whenever I try to open up a Watir-Webdriver browser, it never seems to try beyond the second $browser = Watir::Browser.new, ending the script in line 189 with Connection refused - connect(2) (Errno::ECONNREFUSED)

Code.rb:

begin
 $browser = Watir::Browser.new(:firefox, :profile => "botmode") # **line 186**

rescue
 $browser = Watir::Browser.new(:remote, :url => "http://127.0.0.1:4444/wd/hub", :desired_capabilities => :firefox)   # **line 189**

rescue  # local selenium htmlunit
  puts __LINE__.to_s + ": #{$!}"    
#  $browser = Watir::Browser.new(:remote, :url => "http://127.0.0.1:4444/wd/hub", :desired_capabilities => :htmlunit)  # but needs Javascript for AJAX support...
  $browser = Watir::Browser.new(:remote, :url => "http://127.0.0.1:4444/wd/hub", :desired_capabilities => Selenium::WebDriver::Remote::Capabilities.htmlunit(:javascript_enabled => true, :cssSelectorsEnabled=>true, :nativeEvents=>false) ) 

rescue # Try to use VentanaPC if still failing..  
 $browser = Watir::Browser.new(:remote, :url => "http://5.19.111.226:4444/wd/hub", :desired_capabilities => :firefox)  

rescue  # no browser left to failover to
  puts __LINE__.to_s + ": #{$@.to_s}"
end

# ruby -v
ruby 1.9.2p290 (2011-07-09 revision 32553) [i686-linux]

To make line 186 fail, I deliberately set DISPLAY=:88 in advance to a non-existent Xserver, so this error is okay: 186: unable to obtain stable firefox connection in 60 seconds (127.0.0.1:7055)

Where am I going wrong here, or is there a better way to do this? Is this something particular to Selenium or Watir?

Was it helpful?

Solution

Your assumption is wrong, this does not work as you expect:

irb(main):062:0> begin
irb(main):063:1*   raise StandardError
irb(main):064:1> rescue
irb(main):065:1>   puts "test1"
irb(main):066:1>   raise StandardError
irb(main):067:1> rescue
irb(main):068:1>   puts "test2"
irb(main):069:1> end
test1
StandardError: StandardError
    from (irb):66:in `rescue in irb_binding'
    from (irb):62
    from /usr/bin/irb:12:in `<main>'

test2 is not printed. Multiple rescues are for different exception types, you can't catch errors in other rescue blocks like that. You could instead use nested begin/rescue blocks, but this case seems complex enough to use a more general approach:

methods = [
  lambda { Watir::Browser.new(:firefox, :profile => "botmode") },
  lambda { Watir::Browser.new(:remote, :url => "http://127.0.0.1:4444/wd/hub", :desired_capabilities => :firefox) },
  lambda { Watir::Browser.new(:remote, :url => "http://127.0.0.1:4444/wd/hub", :desired_capabilities => Selenium::WebDriver::Remote::Capabilities.htmlunit(:javascript_enabled => true, :cssSelectorsEnabled=>true, :nativeEvents=>false) ) },
  lambda { Watir::Browser.new(:remote, :url => "http://5.19.111.226:4444/wd/hub", :desired_capabilities => :firefox) },
]

def get_first_successful(methods)
  methods.each do |m|
    begin
      return m.call
    rescue
    end
  end
  nil
end

$browser = get_first_successful(methods)

This will select the first method which doesn't fail. However, I don't see how the last one could be successful if the second one failed, you might rethink your options here.

OTHER TIPS

The first rescue will catch any StandardError. So will the others, but since those errors are already caught by the first rescue, they will never have chance to actually encounter any StandardError.

Multiple rescues are for rescuing from different exception types; what you have is a single block with a bunch of unqualified rescues, so only one will trigger. You want nested begin/rescue/ends, or a different approach altogether.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top