Add support for temporarily switching between multiple named sessions.

This commit is contained in:
Tristan Dunn 2011-01-09 17:47:28 -05:00
parent b382a0e769
commit fbd45c3a89
2 changed files with 86 additions and 1 deletions

View File

@ -57,7 +57,7 @@ module Capybara
# @return [Capybara::Session] The currently used session
#
def current_session
session_pool["#{current_driver}#{app.object_id}"] ||= Capybara::Session.new(current_driver, app)
session_pool[session_namespace] ||= Capybara::Session.new(current_driver, app)
end
##
@ -70,8 +70,34 @@ module Capybara
end
alias_method :reset!, :reset_sessions!
##
#
# Switch to a different session, referenced by name, execute the provided block and return to
# the default session. This is useful for testing interactions between two browser sessions.
#
def in_session(name, &block)
return unless block_given?
namespace = "#{session_namespace}:#{name}"
previous_session = current_session
session_pool[namespace] ||= Capybara::Session.new(current_driver, app)
self.current_session = session_pool[namespace]
yield
ensure
self.current_session = previous_session
end
private
def current_session=(session)
session_pool[session_namespace] = session
end
def session_namespace
"#{current_driver}#{app.object_id}"
end
def session_pool
@session_pool ||= {}
end
@ -79,6 +105,15 @@ module Capybara
extend(self)
##
#
# Shortcut to working in a different session. This is useful when Capybara is included
# in a class or module.
#
def in_session(name, &block)
Capybara.in_session(name, &block)
end
##
#
# Shortcut to accessing the current session. This is useful when Capybara is included in a

View File

@ -125,6 +125,47 @@ describe Capybara do
end
end
describe "#in_session" do
let!(:default_session) { Capybara.current_session }
before do
@object_ids = { :default => default_session.object_id }
end
it "should create unique sessions by name" do
Capybara.in_session(:bob) { @object_ids[:bob] = Capybara.current_session.object_id }
Capybara.in_session(:sue) { @object_ids[:sue] = Capybara.current_session.object_id }
@object_ids.values.uniq.length.should == 3
end
it "should cache sessions by name" do
Capybara.in_session(:bob) { @object_ids[:bob] = Capybara.current_session.object_id }
Capybara.in_session(:sue) { @object_ids[:sue] = Capybara.current_session.object_id }
Capybara.in_session(:bob) do
@object_ids[:bob].should == Capybara.current_session.object_id
end
Capybara.in_session(:sue) do
@object_ids[:sue].should == Capybara.current_session.object_id
end
end
it "should reset the session to the default, even if an exception occurs" do
begin
Capybara.in_session(:raise) { raise }
rescue Exception
end
Capybara.current_session.should == default_session
end
it "should yield the passed block" do
called = false
Capybara.in_session(:other) { called = true }
called.should == true
end
end
describe 'the DSL' do
before do
@session = Capybara
@ -152,6 +193,15 @@ describe Capybara do
foo.page.click_link('ullamco')
foo.page.body.should include('Another World')
end
it "should provide an 'in_session' shortcut" do
klass = Class.new do
include Capybara
end
Capybara.should_receive(:in_session).with(:name)
foo = klass.new
foo.in_session(:name)
end
end
end