2010-10-06 6 views
17

Je semble avoir du mal à tester les choses javascript slick que je fais avec jQuery lorsque vous utilisez Capybara et Selenium. Le comportement attendu est pour qu'un formulaire soit généré dynamiquement lorsqu'un utilisateur clique sur le lien "ajouter une ressource". Capybara pourra cliquer sur le lien, mais ne reconnaîtra pas les nouveaux éléments de formulaire (c'est-à-dire "ressource [nom]").Capybara ne reconnaît pas les éléments DOM ajoutés dynamiquement?

Existe-t-il un moyen de recharger le DOM pour Capybara, ou y at-il un élément de cette gemme que je n'ai pas encore appris?

Merci d'avance!

== == Modifier

en train d'essayer ma chance avec du sélénium: méthode

wait_for_element 

.

== == Modifier

Je continue à obtenir une "méthode non définie « wait_for_element` pour la classe Nill" en essayant de faire ce qui suit:

@selenium.wait_for_element 

Il semble que cette méthode spécifique, ou peut-être wait_for avec un énorme sélecteur accédant à l'élément DOM, je m'attends à ce que ce soit le bon plan d'action, mais maintenant essayer d'obtenir la session de sélénium commence à être un énorme casse-tête.

Répondre

17

J'utilise le pilote basé sur Webdriver pour Capybara dans RSpec, que je configure et utilise comme ceci et il va certainement gérer JS et n'a pas besoin d'un rechargement de la dom. La clé utilise wait_until et une condition qui sera vraie lorsque votre réponse AJAX sera terminée.

before(:each) do 
    select_driver(example) 
    logout 
    login('databanks') 
end 

def select_driver(example) 
    if example.metadata[:js] 
    Capybara.current_driver = :selenium 
    else 
    Capybara.use_default_driver 
    end 
end 

it "should let me delete a scenario", :js=>true do 
    select("Mysite Search", :from=>'scenario_id') 
    wait_until{ page.has_content?('mysite_searchterms')}  
    click_on "delete"  
    wait_until{ !page.has_content?('mysite_searchterms')} 
    visit '/databanks' 
    page.should_not have_content('Mysite Search') 
    end 

Je me suis aussi un hack pour ralentir WebDriver hier soir, comme ça, si vous voulez regarder les choses dans slo-mo:

#set a command delay 
    require 'selenium-webdriver' 

    module ::Selenium::WebDriver::Remote 
    class Bridge 
     def execute(*args) 
     res = raw_execute(*args)['value'] 
     sleep 0.5 
     res 
     end 
    end 
    end 

Comme quelqu'un a mentionné, si vous obtenez un délai d'expiration en attente de l'élément, vous pouvez regarder en augmentant ceci:

Capybara.default_wait_time = 10 
+0

merci @ebeland. maintenant après plusieurs mois d'utilisation de quelque chose de similaire dans nos tests au travail, la méthode 'wait_until' est sans aucun doute la bonne façon de procéder :) –

+4

' wait_until' a été retiré de Capybara 2.0.0. [Voir cet article de blog] (http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara) –

7

Des Capybara docs:

Lorsque vous travaillez avec JavaScript asynchrone , vous pourriez rencontrer des situations où vous essayez de interagir avec un élément qui ne encore présent sur la page. En attente de l'affichage des éléments sur la page .

Vous pourriez avoir un peu de chance d'augmenter le temps d'attente:

Capybara.default_wait_time = 10 

Si cela ne vous aide pas alors je vous encorage de contacter quelqu'un du projet sur GitHub, écrivez à la liste de diffusion ou soumettre un rapport de problème.

+3

+1 ici. Capybara utilise ce temps d'attente par défaut pour les appels de méthode tels que 'has_selector?' 'Has_css?' Et ainsi de suite. Vous pouvez donc utiliser ces méthodes pour attendre que l'élément apparaisse, en utilisant quelque chose comme: 'has_css? (" A # myinput ",: visible => true)' qui attendra que l'élément apparaisse à l'écran avant de continuer. – bergyman

+0

où devrais-je mettre 'Capybara.default_wait_time = 10'? –

+1

@AlexanderSupertramp dans votre 'spec/rails_helper.rb' si vous en avez un, sinon votre' spec/spec_helper.rb'. – thomasfedb

0

Même wait_until supprimé de Capybara 2.0.Encore c'est utile et saisir le code ci-dessous:

def wait_until(delay = 1) 
seconds_waited = 0 
while ! yield && seconds_waited < Capybara.default_wait_time  
    sleep delay  
    seconds_waited += 1 
    end 
    raise "Waited for #{Capybara.default_wait_time} seconds but condition did not become true" unless yield 
end 
Questions connexes