RSpec+Capybara request specs w/ JS not working

一曲冷凌霜 提交于 2019-12-22 09:32:55

问题


I cannot get request specs working when using Javascript. My specs pass if I run them without Javascript (the page is built to work with or without JS).

Specifically, the specs fail when I do assertions like Post.should have(1).record. Capybara just doesn't pick up the records from the DB, and the database is not cleaned between runs.

I've tried using DatabaseCleaner with transactional fixtures disabled - the common approach to this, I guess. No dice.

I've also tried (and, would ideally prefer) running without DatabaseCleaner, using transactional fixtures and forcing AR to share the same connection between threads (a patch described by José Valim). Again, no dice.

Additionally, I've also tried switching between Capybara-webkit and Selenium - the issue persists.

I've put up a sample app with just a basic Post scaffold, that replicates the problem: https://github.com/cabgfx/js-specs There's a spec_helper.rb with transactional fixtures and AR shared connection, and a spec_helper_database_cleaner.rb for the other scenario.

I normally use Spork, but I've disabled it in both spec_helper.rb files, just to eliminate a potential point of failure (in both apps; the "real" one and the sample app).

I develop locally using Pow on a Macbook Air, running OS X 10.7.3 with MRI 1.9.3 thru RVM. (I also tried on 1.9.2).

Hope I'm making sense - any guidance/help/pointers are greatly appreciated!


回答1:


Matt - thanks a lot for taking time to assist me! I tried setting it up with your spec_helper, using Selenium as the javascript driver.

The spec still failed - but I could see the correct behavior being executed in Firefox... Then it dawned on me, that the problem might occur because of Capybara not waiting for AJAX requests to finish.

I then reverted to my initial spec_helper (with Spork and no DatabaseCleaner), and simply used Capybara's wait_until { page.has_content? "text I'm inserting with JS" }.

I updated the sample app, and just added sleep 1 in the request spec, so you can see for yourself. It now works with and without Spork, and the AR monkey patch seems to work perfectly.




回答2:


I have tried your code with the spec_helper.rb listed below and the test passes. Note that the syntax for triggering database cleaner is a bit different than in your spec_helper_database_cleaner.rb.

We're using this in production, and we've also tried the modification suggested by Jose Valim but it didn't work for us - this did.

require 'rubygems'
require 'spork'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'

Spork.prefork do
  # Loading more in this block will cause your tests to run faster. However,
  # if you change any configuration or code from libraries loaded here, you'll
  # need to restart spork for it take effect.

  # This file is copied to spec/ when you run 'rails generate rspec:install'
  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  require 'rspec/rails'
  require 'rspec/autorun'

  # Add this to load Capybara integration:
  require 'capybara/rspec'
  require 'capybara/rails'

  include Capybara::DSL

  # Requires supporting ruby files with custom matchers and macros, etc,
  # in spec/support/ and its subdirectories.
  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

  RSpec.configure do |config|
    # ## Mock Framework
    #
    # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
    #
    # config.mock_with :mocha
    # config.mock_with :flexmock
    # config.mock_with :rr

    # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
    config.fixture_path = "#{::Rails.root}/spec/fixtures"

    # If you're not using ActiveRecord, or you'd prefer not to run each of your
    # examples within a transaction, remove the following line or assign false
    # instead of true.
    config.use_transactional_fixtures = false

    # If true, the base class of anonymous controllers will be inferred
    # automatically. This will be the default behavior in future versions of
    # rspec-rails.
    config.infer_base_class_for_anonymous_controllers = false

    # Include sign_in & sign_out for tests
    # config.include Devise::TestHelpers, :type => :controller

    # Use database_cleaner to ensure a known good test db state as we can't use
    # transactional fixures due to selenium testing
    config.before(:suite) do
      DatabaseCleaner.strategy = :truncation
      DatabaseCleaner.clean_with(:truncation)
    end

    config.before(:each) do
      DatabaseCleaner.start
    end

    config.after(:each) do
      DatabaseCleaner.clean
    end
  end
end

Spork.each_run do
  # This code will be run each time you run your specs.
end



回答3:


José's suggestion worked for me but not when I used Spork. But adding this to spec_helper.rb did:

Spork.prefork do
  RSpec.configure do |config|
    # Make it so poltergeist (out of thread) tests can work with transactional fixtures
    # http://www.opinionatedprogrammer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/#post-441060846
    ActiveRecord::ConnectionAdapters::ConnectionPool.class_eval do
      def current_connection_id
        Thread.main.object_id
      end
    end
  end
end

Source: http://www.opinionatedprogrammer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/#post-441060846



来源:https://stackoverflow.com/questions/9984113/rspeccapybara-request-specs-w-js-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!