2010-10-06 6 views
17

Sembra che stia avendo problemi a testare le chiazze javascript che faccio con jQuery quando uso Capybara e Selenium. Il comportamento previsto è che un modulo venga generato dinamicamente quando un utente fa clic sul link "aggiungi risorsa". Capybara sarà in grado di fare clic sul collegamento, ma non riesce a riconoscere i nuovi elementi del modulo (ad esempio "risorsa [nome]").Capybara non riconosce gli elementi DOM aggiunti dinamicamente?

C'è un modo per ricaricare DOM per Capybara, o c'è qualche elemento di questa gemma che non ho ancora appreso?

Grazie in anticipo!

== Modifica ==

Attualmente provare la mia fortuna con il selenio di:

wait_for_element 

metodo.

== Modifica ==

Continuo a ricevere un " 'wait_for_element` metodo non definito per la classe nill" quando si tenta di effettuare le seguenti operazioni:

@selenium.wait_for_element 

Sembra che quel metodo specifico, o forse wait_for con un enorme selettore che accede all'elemento DOM che mi aspetto sia la linea di condotta corretta, ma ora cercare di ottenere la sessione di selenio sta iniziando a essere un enorme mal di testa.

risposta

17

Uso il driver WebDiriver per Capybara in RSpec, che ho configurato e utilizzato in questo modo e sicuramente gestirà JS e non ha bisogno di ricaricare il dom. La chiave utilizza un wait_until e una condizione che sarà vera al termine della risposta AJAX.

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 

ho anche capito un hack per rallentare WebDriver ieri sera, in questo modo, se si desidera guardare le cose in 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 

Come qualcun altro ha detto, se hai trovato un timeout in attesa dell'elemento, è possibile vedere in alto:

Capybara.default_wait_time = 10 
+0

grazie a @ebeland. ora dopo molti mesi di utilizzo di qualcosa di simile nei nostri test al lavoro, il metodo 'wait_until' è senza dubbio il modo corretto per andare :) –

+4

' wait_until' è stato rimosso da Capybara 2.0.0. [Vedi questo post del blog] (http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara) –

7

Dalla documentazione Capybara:

Quando si lavora con asincrono JavaScript, si potrebbe venire attraverso situazioni in cui si sta tentando di interagire con un elemento che non è ancora presente nella pagina. Capybara si occupa automaticamente di questo in attesa della visualizzazione degli elementi nella pagina .

Si potrebbe avere una certa fortuna aumentando il tempo di attesa:

Capybara.default_wait_time = 10 

Se questo non aiuta, allora io vi avrei encorage contattare qualcuno dal progetto su GitHub, scrivere alla mailing list o presentare un rapporto di problema.

+3

+1 qui. Capybara usa questo tempo di attesa predefinito per chiamate di metodo come 'has_selector?' 'Has_css?' E così via. Quindi puoi usare questi metodi per aspettare che l'elemento appaia, usando qualcosa come: 'has_css? (" A # myinput ",: visible => true)' che attenderà fino a quando l'elemento è sullo schermo prima di procedere. – bergyman

+0

dove dovrei mettere 'Capybara.default_wait_time = 10'? –

+1

@AlexanderSupertramp nel tuo 'spec/rails_helper.rb' se ne hai uno, altrimenti il ​​tuo' spec/spec_helper.rb'. – thomasfedb

0

Anche wait_until eliminato da Capybara 2.0.Ancora questo è utile e prendi il codice dal basso:

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