Capivara com: js => verdadeiro faz com que o teste falhe

Sou novo em Capivara e estou testando em Rails em geral, então, por favor, me perdoe se esta é uma resposta simples.

Eu tenho esse teste

it "should be able to edit an assignment" do visit dashboard_path select(@project.client + " - " + @project.name, :from => "assignment_project_id") select(@team_member.first_name + " " + @team_member.last_name, :from => "assignment_person_id") click_button "Create assignment" page.should have_content(@team_member.first_name) end 

ele passa como está, mas se eu adicionar: js => true ele falha com

 cannot select option, no option with text 'Test client - Test project' in select box 'assignment_project_id' 

Estou usando o FactoryGirl para criar os dados e, conforme o teste passa sem o JS, sei que a parte está funcionando.

Eu tentei com o driver JS padrão e com o driver: webkit (com o capybara-webkit instalado)

Acho que não entendo o que está acontecendo com o JS para Capivara.

Por que o teste falharia com o JS on?

Eu li o readme da Capybara em https://github.com/jnicklas/capybara e isso resolveu meu problema.

Os aparelhos transacionais funcionam apenas no driver padrão Rack :: Test, mas não para outros drivers como o Selenium. Pepino cuida disso automaticamente, mas com Test :: Unit ou RSpec, você pode ter que usar a gem database_cleaner. Veja esta explicação (e código para a solução 2 e solução 3 ) para detalhes.

Mas basicamente é um problema de encadeamento que envolve a Capybara ter seu próprio encadeamento ao executar o driver não-Rack, o que faz com que o recurso de dispositivos transacionais use uma segunda conexão em outro contexto. Portanto, o encadeamento do driver nunca está no mesmo contexto da execução do rspec.

Felizmente isso pode ser facilmente resolvido (pelo menos, resolvido por mim) fazendo uma mudança dinâmica na estratégia DatabaseCleaner para usar:

 RSpec.configure do |config| config.use_transactional_fixtures = false config.before :each do if Capybara.current_driver == :rack_test DatabaseCleaner.strategy = :transaction else DatabaseCleaner.strategy = :truncation end DatabaseCleaner.start end config.after do DatabaseCleaner.clean end end 

Uma variação da resposta do brutuscat que corrigiu nossas especificações de resources (que todos usam capivara):

 config.before(:suite) do DatabaseCleaner.clean_with(:truncation) end config.before(:each) do # set the default DatabaseCleaner.strategy = :transaction end config.before(:each, type: :feature) do DatabaseCleaner.strategy = :truncation end config.before(:each) do DatabaseCleaner.start end config.append_after(:each) do DatabaseCleaner.clean end 

Há outra maneira de lidar com esse problema agora descrito e discutido aqui: Por que não usar conexões ActiveRecord compartilhadas para o Rspec + Selenium?