Doing integration tests on apps with real-time multi-user features like chat is incredibly useful since it’s a pain to hop between multiple browsers with different users logged in to test them manually. It wasn’t immediately obvious to me that this capability is built into Capybara, but after spotting this post I adapted it slightly for RSpec request specs since that’s what I use.
A helpful helper
Here’s the helper I use to manage which browser is in use:
# spec/requests/helpers.rb
def in_browser(name)
old_session = Capybara.session_name
Capybara.session_name = name
yield
Capybara.session_name = old_session
end
Example spec
Here’s how it looks in practice:
# spec/requests/chat.rb
it "allows chatting" do
in_browser(:one) do
sign_in_as "joe"
visit "/chat"
end
in_browser(:two) do
sign_in_as "bob"
visit "/chat"
end
in_browser(:one) do
page.should have_content("bob just entered the chat")
add_comment "Hey Bob"
end
in_browser(:two) do
page.should have_content("Hey Bob")
add_comment "Hey Joe"
end
in_browser(:one) do
page.should have_content("Hey Joe")
end
end
This assumes the helpers signinas and add_comment exist, just for the sake of keeping the example short.
At first it was tempting to use a helper like as_user(:bob)
, but each time Capybara.session_name
is set to a new value it opens a new browser instance, so across a bunch of request specs opening as different user names you could end up with a lot of browsers open which can have a substantial memory footprint.