Arnab Datta Arnab Datta - 7 months ago 57
Ruby Question

Multiple sessions in capybara

Background



I want to test logging in as multiple users on my webapp, and I am using cucumber and capybara to do this. I found this link on how to handle multiple sessions, but unfortunately, it doesn't look like cucumber can find the
in_session
method that is defined. How can I access it?

Cucumber scenario



Given I go to teacher login in Steve's browser

When I enter "Steve" in the username field
And I enter "StevesPassword" in the password field
And I click login
Then I should see "Steve Lastname" as the current user

When I go to teacher login in Lisa's browser
And I enter "Lisa" in the username field
And I enter "LisasPassword" in the password field
And I click login
Then I should see "Lisa Lastname" as the current user


Ruby code



#standard_definitions/switching_sessions.rb
When /^(.*) in (.*) browser$/ do |next_step, name|
in_session(name) do
step next_step
end
end





#features/support/sessions.rb
module Capybara
module Driver
module Sessions
def set_session(id)
Capybara.instance_variable_set("@session_pool", {
"#{Capybara.current_driver}#{Capybara.app.object_id}" => $sessions[id]
})
end

def in_session(id, &block)
$sessions ||= {}
$sessions[:default] ||= Capybara.current_session
$sessions[id] ||= Capybara::Session.new(Capybara.current_driver, Capybara.app)
set_session(id)

yield

set_session(:default)
end
end
end
end


Errors



When I run this, I get the following:

Scenario: multiple users # features/Provebank/Provebank.feature:23
Given I go to teacher login in Steve's browser # features/step_definitions/standard_definitions/switching_sessions.rb:5
undefined method `in_session' for Capybara::Driver::Sessions:Module (NoMethodError)
./features/step_definitions/standard_definitions/switching_sessions.rb:8:in `/^(.*) in (.*) browser$/'
features/test.feature:24:in `Given I go to teacher login in Steve's browser'

Answer

As mentioned at the top of the article you linked "This is now included in the Capybara library." - except the method is named Capybara.using_session rather than in_session, so you don't need features/support/session.rb. Note that the way your test is written, and the code in the link you shared, only the steps ending in "in xxxx's browser" would actually occur in a different session, not the ones you have tabbed over under those lines. To make each of those groups of steps occur in their own sessions you would either need "in xxx's browser" on every line or instead use Capybara.session_name = <name> in a step which would then be used for future steps. If setting the session_name directly you may wish to reset it to :default in an After block if you want future scenarios to default to that session.

# only next_step will be executed in the alternate session
When /^(.) in (.*) browser$/ do |next_step, name|
  Capybara.using_session(name) do
     step next_step
  end 
end

# all future steps will be executed in the alternate session
# you probably want to reset this to :default in an After block
Given /^I switch to (.*) browser$/ do |name|
  Capybara.session_name = name
end