A Happy RSpec, Capybara and DatabaseCleaner Setup
RSpec, Capybara and DatabaseCleaner don't play nicely in the sandbox—here's how to get them to cooperate.
 
    There have been a few times where I ran into problems with RSpec Capybara feature specs and DatabaseCleaner. Spec issues arise because most Capybara JavaScript drivers run your specs on a different thread than the app. This Stack Overflow Answer provides a great explanation.
Now, the accepted answer the SO answer of simply turning off transactional_fixtures in RSpec and using the :truncation cleaning strategy in before/after hooks will work. However, when working in a large app (20+ minutes for full specs) this will slow your spec suite down dramatically. Why? From the DatabaseCleaner [documentation](DatabaseCleaner on which cleaning strategy is fastest:
For the SQL libraries the fastest option will be to use :transaction as transactions are simply rolled back.
After some research and lots of head banging, below is the configuration I have finally come to be happy with that gives us the best of all three worlds:
- DatabaseCleaner owns the cleaning and acts as we want it to.
- We get to add feature specs and increase coverage.
- Our test suite speed is only minimally impacted since we use :transactioncleaning andtransactional_fixtureseverywhere except our feature specs.
# spec/spec_helper.rb
RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end
  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end
  config.before(:each, js: true) do
    DatabaseCleaner.strategy = :truncation
  end
  config.before(:each) do
    DatabaseCleaner.start
  end
  config.after(:each) do
    DatabaseCleaner.clean
  end
  config.before(:context, js: true) do
   self.use_transactional_fixtures = false
  end
  config.after(:context, js: true) do
    DatabaseCleaner.clean_with(:truncation)
    self.use_transactional_fixtures = true
  end
end
How this works
Simply tag your feature specs with a js: true block and everything will just work:
# spec/features/my_feature_spec.rb
RSpec.describe "my feature", js: true do 
  # do the testing stuff
end
As mentioned before, this js: true tag will  disable RSpec's use of transactional fixtures and set the cleaning strategy to :truncation.
One final note: this configuration will get more complicated if you use other test dependencies or configurations. Typically, you'll want to make sure those are loaded after DatabaseCleaner is configured.