Skip to content


Adds reset_session_after_each config option #419

wants to merge 2 commits into from

7 participants


Closes issue #418.

Allows user to set Capybara.reset_session_after_each = false.
This will prevent the session from being cleared after each rspec test.


From #418:

But there are times when I would prefer that management of the session state was left up to me (ex: to avoid the need to login before every test).

Aren't tests supposed to be independent? That is, aren't you introducing subtle dependencies on the execution order of your tests if you rely on your session persisting?


Yes! But I'm controlling the scope of those side effects using a wipe => :true selector on my describe blocks. I have a config.after(:all, :wipe => :true) hook that clears the database and wipes the session.

This allows me to not have to login (for example) before every single test.

It certainly gives me the power to shoot myself in the foot if I'm not careful, so I can understanding leaving capybara's default reset_session_after_each to true. But it also gives me the power to control exactly when state gets wiped, which is useful for improving test run times, and for writing nested describes.


I would like to use areset_session_after_each config option as well for the same reasons @kberridge mentioned.


I like the use case -- speeding up tests is always good -- but I wonder if it's not something that belongs into RSpec.

After all, there may be other gems (like DatabaseCleaner) registering before/after hooks that you'd also have to stop from running. Plus perhaps even your own context-specific setup and teardown code. I think this could reasonably be handled in a central place by RSpec.

I also wonder if there isn't a better alternative to the :wipe => true syntax, by the way. For example, you could write it this way:

describe do
  before :each
  it 'T1'
  it 'T2', :readonly => true
  it 'T3'
  after :each

Where :readonly indicates that a test doesn't modify its environment. This way the default behavior is still "safe", and you can't accidentally forget to set :wipe. So if B stands for all before hooks (both context-specific and anything registered by libraries like Capybara), and A for after hooks, then this might example be run as:

 B T1 A B T2 T3 A

thereby saving one A B (teardown and setup) cycle.

Hm. Just brainstorming.


The way we've been writing our rspec acceptance tests, all the it blocks are "readonly" and the describe blocks are what are what modify state. So that's why we put the :wipe => true on the describe block.

This allows you to nest describes and have the outer one do the wipe while the inner ones modify different state.


I'm not 100% convinced of this. It's a pretty uncommon usecase, and in case you really need it, you can hook Capybara into RSpec yourself, it's not a lot of code, and you can get full control over everything.

For the record, I solved the same problem by using token authentication, as opposed to username/password. On the first request, you just send the token and boom, you're logged in, no extra requests necessary. Sped up a test suite by almost 30%.


Closing this. I just don't think it's necessary.

@jnicklas jnicklas closed this

Can this be reconsidered? [rspec-rails includes vendor/capybara(rspec/rspec-rails@d0e790e), and that means hooking RSpec into Capybara "by ourselves" isn't possible.


I would also like this to be reconsidered. There are times when it would be preferable to not have the session reset after each spec.

I don't understand why you wouldn't want to give users more configuration options.


User may want to use another mechanism to make sure that tests are relatively independent (rspec/rspec-core#1811)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 24 additions and 2 deletions.
  1. +3 −0  lib/capybara.rb
  2. +1 −1  lib/capybara/rspec.rb
  3. +20 −1 spec/rspec_spec.rb
3  lib/capybara.rb
@@ -17,6 +17,7 @@ class << self
attr_accessor :server_port, :server_boot_timeout
attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements, :prefer_visible_elements
attr_accessor :save_and_open_page_path
+ attr_accessor :reset_session_after_each
@@ -36,6 +37,7 @@ class << self
# [default_wait_time = Integer] The number of seconds to wait for asynchronous processes to finish (Default: 2)
# [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: false)
# [prefer_visible_elements = Boolean] Whether to prefer visible elements over hidden elements (Default: true)
+ # [reset_session_after_each = Boolean] Whether to clear the session after each rspec test (Default: true)
# === DSL Options
@@ -236,6 +238,7 @@ module Selenium
config.ignore_hidden_elements = false
config.prefer_visible_elements = true
config.default_host = ""
+ config.reset_session_after_each = true
Capybara.register_driver :rack_test do |app|
2  lib/capybara/rspec.rb
@@ -13,7 +13,7 @@
# might not actually be used in all examples where it's included.
config.after do
if self.class.include?(Capybara::DSL)
- Capybara.reset_sessions!
+ Capybara.reset_sessions! if Capybara.reset_session_after_each
21 spec/rspec_spec.rb
@@ -15,12 +15,31 @@
page.body.should include('Cookie set to test_cookie')
- it "...then it is not availbable in the next" do
+ it "...then it is not available in the next" do
page.body.should_not include('test_cookie')
+ context "resetting session disabled" do
+ before(:all) do
+ Capybara.reset_session_after_each = false
+ end
+ after(:all) do
+ Capybara.reset_session_after_each = true
+ end
+ it "sets a cookie in one example..." do
+ visit('/set_cookie')
+ page.body.should include('Cookie set to test_cookie')
+ end
+ it "...then it is available in the next" do
+ visit('/get_cookie')
+ page.body.should include('test_cookie')
+ end
+ end
context "setting the current driver" do
it "sets the current driver in one example..." do
Capybara.current_driver = :selenium
Something went wrong with that request. Please try again.