Capybara avec: js => true causes test to fail

Je suis nouveau chez Capybara et je teste Test Rails en général, alors pardonnez-moi s'il s'agit d'une réponse simple.

J'ai ce test

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 

Il passe tel quel, mais si j'ajoute: js => true, il échoue avec

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

J'utilise FactoryGirl pour créer les données, et lorsque le test passe sans JS, je sais que cette partie fonctionne.

J'ai essayé avec le pilote JS par défaut, et avec: le pilote webkit (avec capybara-webkit installé)

Je suppose que je ne comprends pas assez ce qui se passe sur JS pour Capybara.

Pourquoi le test échouerait-il avec JS?

J'ai lu le fichier légal de Capybara à l' adresse https://github.com/jnicklas/capybara et il a résolu mon problème.

Les luminaires transactionnels ne fonctionnent que dans le pilote Rack :: Test par défaut, mais pas pour les autres pilotes comme Selenium. Le concombre s'occupe automatiquement de cela, mais avec Test :: Unit ou RSpec, vous devrez peut-être utiliser le gem de la base de données. Voir cette explication (et le code pour la solution 2 et la solution 3 ) pour plus de détails.

Mais c'est essentiellement un problème de thread qui implique Capybara avoir son propre thread lors de l'exécution du pilote non-rack, ce qui rend la fonctionnalité des appareils transactionnels à utiliser une deuxième connexion dans un autre contexte. Donc, le thread du pilote ne se trouve jamais dans le même contexte que le rspec en cours d'exécution.

Heureusement, cela peut être facilement résolu (au moins, il m'a résolu) en faisant une modification dynamique dans la stratégie DatabaseCleaner à utiliser:

 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 

Une variante de la réponse de brutuscat qui a fixé nos caractéristiques (qui utilisent tous Capybara):

 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 

Il existe une autre façon de résoudre ce problème maintenant décrit et discuté ici: Pourquoi ne pas utiliser les connexions ActiveRecord partagées pour Rspec + Selenium?