RSpec + Capybara requisitar specs w / JS não funciona

Não consigo obter especificações de solicitações ao usar o Javascript. Minhas especificações passam se eu as executar sem Javascript (a página foi criada para funcionar com ou sem JS).

Especificamente, as especificações falham quando faço asserções como Post.should have(1).record . Capybara simplesmente não pega os registros do database, e o database não é limpo entre as execuções.

Eu tentei usar DatabaseCleaner com dispositivos elétricos transacionais desativados – a abordagem comum para isso, eu acho. Sem dados.

Eu também tentei (e preferiria) correr sem o DatabaseCleaner, usando fixtures transacionais e forçando o AR a compartilhar a mesma conexão entre threads ( um patch descrito por José Valim ). Mais uma vez, não há dados.

Além disso, eu também tentei alternar entre Capybara-webkit e Selenium – o problema persiste.

Eu coloquei um aplicativo de exemplo com apenas um scaffold Post, que replica o problema: https://github.com/cabgfx/js-specs Há um spec_helper.rb com acessórios transacionais e conexão compartilhada AR, e um spec_helper_database_cleaner. rb para o outro cenário.

Eu normalmente uso o Spork, mas o desabilitei em ambos os arquivos spec_helper.rb, apenas para eliminar um potencial ponto de falha (em ambos os aplicativos, o “real” e o aplicativo de amostra).

Eu desenvolvo localmente usando o Pow em um Macbook Air, rodando o OS X 10.7.3 com o MRI 1.9.3 até o RVM. (Eu também tentei no 1.9.2).

Espero que eu esteja fazendo sentido – qualquer orientação / ajuda / pointers são muito apreciados!

Matt – muito obrigado por ter tempo para me ajudar! Eu tentei configurá-lo com o seu spec_helper, usando o Selenium como o driver javascript.

A especificação ainda falhou – mas eu pude ver o comportamento correto sendo executado no Firefox … Então ocorreu-me que o problema poderia ocorrer por causa da Capybara não esperar que as requisições AJAX terminassem.

Em seguida, reverti para o meu spec_helper inicial (com o Spork e o DatabaseCleaner) e simplesmente usei o wait_until { page.has_content? "text I'm inserting with JS" } wait_until { page.has_content? "text I'm inserting with JS" } .

Atualizei o aplicativo de amostra e adicionei o sleep 1 na especificação da solicitação, para que você possa ver por si mesmo. Agora funciona com e sem o Spork, e o patch de macaco AR parece funcionar perfeitamente.

Eu tentei o seu código com o spec_helper.rb listado abaixo e o teste foi aprovado. Observe que a syntax para acionar o limpador de database é um pouco diferente de seu spec_helper_database_cleaner.rb .

Estamos usando isso em produção, e também tentamos a modificação sugerida por Jose Valim, mas não funcionou para nós – isso aconteceu.

 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 

A sugestão de José funcionou para mim, mas não quando eu usei o Spork. Mas adicionando isso ao spec_helper.rb fez:

 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 

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