saucelabs/sauce_ruby — pull request #33 by rtyler (2012-03-06 19:36:15+00:00)
Title: DRAFT: Allow Capybara/Cucumber tests to use one tunnel and multiple drivers

*Note*: This pull request builds on top of/requires the contents of pull request #32

----

There is no need for us to tear-down the `Sauce::Connect` tunnel more than once per-process-lifetime when testing with cucumber and capybara, but introducing the `$sauce_tunnel` global we can ensure that the test will run a bajillion times faster by not tearing down the tunnel every time it closes/quits a `Sauce::Selenium2` driver.

Currently I still have some custom-code locally that handles wrapping each "Scenario" (in cucumber parlance) with something that creates a new job on Sauce and handles closing the browser when it's completed. Effectively this:

```
Around('@selenium') do |scenario, block|
session_id = nil

if sauce?
Sauce.config do |config|
config.build = ENV['BUILD_NUMBER'] || 0
config.name = "#{scenario.feature.file} - #{scenario.name}"
config.browser_url = ENV['BASE_URL'] || 'http://127.0.0.1:3000'
end

Capybara.current_driver = :sauce
# I will need this for later, driver.browser should be an instance of
# Sauce::Selenium2 at this point
driver = Capybara.current_session.driver
session_id = driver.browser.session_id
end

block.call

if sauce? and !session_id.nil?
driver.browser.quit # finish the job in Sauce Labs
driver.instance_variable_set(:@browser, nil) # This is necessary to generate a new @browser in the "next" scenario

config = Sauce::Config.new
sauce_url = "http://#{config.username}:#{config.access_key}@saucelabs.com/rest/v1/#{config.username}/jobs/#{session_id}"

data = {
:passed => !scenario.failed?,
'custom-data' => {:commit => ENV['GIT_COMMIT'],
:node_name => ENV['NODE_NAME'],
:job_name => ENV['JOB_NAME']}}
response = Typhoeus::Request.put(sauce_url,
:headers => {:Content_Type => "application/json"},
:body => JSON::dump(data))
puts "Sending meta-data to Sauce Labs returned: #{response.code}"
end
end
```

I'm still thinking of how to integrate portions of this into the sauce gem itself, but I wanted to get the rest of the code in front of some more eyes.