I am automating test cases for a website using selenium-webdriver and cucumber in ruby. I need each feature to run in a particular order and using the same browser window. A
The Before hook is run before each scenario. This is why a new browser is opened each time.
Do the following instead (in the env.rb):
require "selenium-webdriver"
driver = Selenium::WebDriver.for :ie
accept_next_alert = true
driver.manage.timeouts.implicit_wait = 30
driver.manage.timeouts.script_timeout = 30
verification_errors = []
Before do
@driver = driver
end
at_exit do
driver.close
end
In this case, a browser will be opened at the start (before any tests). Then each test will grab that browser and continue using it.
Note: While it is usually okay to re-use the browser across tests. You should be careful about tests that need to be run in a specific order (ie become dependent). Dependent tests can be hard to debug and maintain.
I had a similar problem in creating a spec_helper file. I did the following (simplified for locally-run firefox) for my purposes and it works very, very reliably. RSpec will use the same browser window for all it blocks in your _spec.rb file.
Rspec.configure do |config|
config.before(:all) do
@driver = Selenium::WebDriver.for :firefox
end
config.after(:all) do
@driver.quit
end
end
If you switch to :each instead of :all, you can use a separate browser instance for each assertion block... again, with :each RSpec will give a new browser instance for each it. Both are useful depending on the circumstance.
As the answers solve the problem but do not answer the question "How to connect to an existing session".
I managed to do this with the following code since it is not officially supported.
# monkey-patch 2 methods
module Selenium
module WebDriver
class Driver
# Be able to set the driver
def set_bridge_to(b)
@bridge = b
end
# bridge is a private method, simply create a public version
def public_bridge
@bridge
end
end
end
end
caps = Selenium::WebDriver::Remote::Capabilities.send("chrome")
driver = Selenium::WebDriver.for(
:remote,
url: "http://chrome:4444/wd/hub",
desired_capabilities: caps
)
used_bridge = driver.bridge
driver.get('https://www.google.com')
# opens a new unused chrome window
driver2 = Selenium::WebDriver.for(
:remote,
url: "http://chrome:4444/wd/hub",
desired_capabilities: caps
)
driver2.close() # close unused chrome window
driver2.set_bridge_to(used_bridge)
driver2.title # => "Google"
Sadly this did not test work between 2 rescue jobs, will update this in the future when I made it work for my own use case.