13 votes

capybara/selenium avec rspec avant le hook :all

Pour tenter de réduire le nombre de visites de pages avec Selenium, j'ai voulu appeler la méthode visit à partir d'un fichier de type before :all hook et exécuter tous mes exemples avec un seul chargement de page. Cependant, lorsque je spécifie before :all vs before :each le navigateur s'ouvre, mais l'url n'est jamais visitée. Voici un exemple simplifié et inventé...

describe 'foobar', :js => true do
  before :all do
    Capybara.default_wait_time = 10
    obj = Factory(:obj)
    visit obj_path(obj)
  end

  it 'should have foo' do
    page.should have_content('foo')
  end

  it 'should have bar' do
    page.should have_content('bar')
  end
end

Quand je l'ai réglé sur before :each cela fonctionne, mais la page se charge deux fois. Est-ce une limitation de Capybara ?

3voto

GladstoneKeep Points 1075

Cause du problème

Le deuxième exemple ne fonctionne pas parce que Capybara réinitialise la session après chaque exemple RSpec ; la page que vous visit -dans votre before :all Le bloc n'est plus ouvert à ce moment-là. C'est un comportement explicite de Capybara. C'est dans le capybara gemme, sous /lib/capybara/rspec.rb :

config.after do
  if self.class.include?(Capybara::DSL)
    Capybara.reset_sessions!
    Capybara.use_default_driver
  end
end

J'ai fait des recherches sur Google pendant quelques heures et j'ai trouvé plusieurs autres personnes aux prises avec ce problème, mais en vain.

J'ai également constaté qu'un patch qui permettrait à Capybara d'être configuré pas pour réinitialiser la session après que chaque exemple ait été proposé ... mais le créateur de Capybara jnicklas a refusé la demande de pull .

Solution

La solution la plus rapide -- mais peut-être pas la meilleure -- que j'ai trouvée (jusqu'à présent) est de monkey-patch Capybara ainsi :

module Capybara                                                                                                                                                                                  
  class << self                                                                                                                                                                                  
    alias_method :old_reset_sessions!, :reset_sessions!                                                                                                                                          
    def reset_sessions!; end                                                                                                                                                                     
  end                                                                                                                                                                                            
end

Cela rend juste reset_sessions! ne font rien quand ils sont appelés. Note : Attention aux effets secondaires involontaires ! (Vous pouvez toujours inverser le alias_method plus tard dans votre code si vous avez besoin que le comportement de réinitialisation par défaut se reproduise).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X