blowmage / minitest-rails-capybara

Capybara integration for MiniTest::Rails
http://blowmage.com/minitest-rails-capybara
MIT License
131 stars 40 forks source link

use_transactional_fixtures should be false with metadata[:js] #6

Closed allaire closed 11 years ago

allaire commented 11 years ago

Got bit by that today, When using Selenium, config.use_transactional_fixtures should be set to false.

Here is a paragraph I saw from a railscasts explaining the behavior: http://asciicasts.com/episodes/257-request-specs-and-capybara

"This time the first spec fails as the content “paint fence” is missing from the page. The database record that is created isn’t available to the Selenium tests and this is because our specs are using database transactions which aren’t compatible with Selenium. To fix this we can set the config.use_transactional_fixtures setting in the spec_helper file to false."

More on the topic: https://groups.google.com/forum/?fromgroups=#!topic/ruby-capybara/3ZLLVx52czw

blowmage commented 11 years ago

I dislike the approach outlined in that railscast. I am a fan of transactional fixtures and not a fan of database cleaner. I prefer to use db transactions on a shared connection instead.

For more information see the following gists:

https://gist.github.com/josevalim/470808 https://gist.github.com/mperham/3049152

That said, it is up to you. You are free to configure it as you like. You can add the following to your test_helper.rb file to remove the transactional fixtures when specifying a javascript driver:

class Capybara::Rails::TestCase
  before { self.use_transactional_fixtures = !metadata[:js] }
end
lukerohde commented 7 years ago

@blowmage I couldn't find a single example of how to get minitest working with capybara & a JS driver (selenium/poltergeist) on rails 4.2 without disabling transactional fixtures then using database_cleaner for all my tests on a shared connection.

Inspired by your suggestion of using my own db transaction I studied rails's fixtures.rb and defined Capybara::Rails::JSTestCase in my test_helpers.rb to give me a class I can use for my JS tests.

It temporarily monkey patches the shared connection, disables transactional fixtures and wraps your tests in a transaction which gets rolled back.

# Add this to test_helper.rb, then derive your JS tests classes from Capybara::Rails::JSTestCase
class Capybara::Rails::JSTestCase < Capybara::Rails::TestCase
  include Minitest::Capybara::Behaviour

  def monkey_patch_shared_connection
    @@connection_backup = ActiveRecord::Base.method(:connection)

    ActiveRecord::Base.define_singleton_method(:connection) do
       @@shared_connection ||= ConnectionPool::Wrapper.new(:size => 1) { retrieve_connection }
    end
  end

  def undo_monkey_patch
    ActiveRecord::Base.define_singleton_method(:connection, @@connection_backup)
  end

  def before_setup
    monkey_patch_shared_connection
    self.use_transactional_fixtures = false
    super
    ActiveRecord::Base.connection.begin_transaction #joinable:false, requires_new: true
  end

  def after_teardown
    ActiveRecord::Base.connection.rollback_transaction
    super
    self.use_transactional_fixtures = true
    undo_monkey_patch
  end
end