jnicklas/capybara — Issue #632: Only reset sessions if they've been used?
Author: jdelStrother
Created: 2012-02-03 17:56:22+00:00
State: open

Hi,

I introduced some :js specs into our spec suite recently and found our spec run times increased way more than I'd expect. After looking into it, I think it's caused by Capybara.reset_sessions! being a bit over-eager. For example, if I run a :js test (resulting in capybara adding a Selenium session to its session_pool), any subsequent controller specs (which will call session.reset! on all session_pool sessions) result in Selenium clearing cookies and visiting about:blank, on each individual example.

How about keeping track of which sessions have been accessed and only resetting those ones at the end of each example? AFAICT, the only public way to access a session is via Capybara.current_session, in which case something like this would be sufficient -

```diff

diff --git a/lib/capybara.rb b/lib/capybara.rb
index f1203de..73a8fd9 100644
--- a/lib/capybara.rb
+++ b/lib/capybara.rb
@@ -248,7 +248,17 @@ module Capybara
# @return [Capybara::Session] The currently used session
#
def current_session
- session_pool["#{current_driver}:#{session_name}:#{app.object_id}"] ||= Capybara::Session.new(current_driver, app)
+ session = (session_pool["#{current_driver}:#{session_name}:#{app.object_id}"] ||= Capybara::Session.new(current_driver, app))
+ sessions_to_reset << session
+ session
+ end
+
+ ##
+ #
+ # The list of sessions that will need resetting next time reset_sessions is called
+ #
+ def sessions_to_reset
+ @sessions_to_reset ||= Set.new
end

##
@@ -257,7 +267,8 @@ module Capybara
# as cookies.
#
def reset_sessions!
- session_pool.each { |mode, session| session.reset! }
+ sessions_to_reset.each{ |session| session.reset! }
+ sessions_to_reset.clear
end
alias_method :reset!, :reset_sessions!

```

This cuts our 4-minute spec-suite back down to around 3 minutes, or a saving of nearly 0.1s per example. WDYT?