2012-04-20 7 views
9

Sto provando a creare un selettore di data con Capybara utilizzando i campi predefiniti di data, ora e data/ora. Sto usando il metodo within per trovare le caselle di selezione per il campo, ma quando uso xPath per trovare la casella corretta lascia l'ambito within e trova la prima occorrenza sulla pagina dell'elemento.capybara - Trova con xPath sta rientrando nell'ambito di applicazione

Ecco il codice che sto usando. La pagina su cui sto eseguendo il test ha 2 campi datetime ma posso solo farlo cambiare prima a causa di questo errore. Al momento ho un contenitore div con id che avvolge il campo datetime, ma ho intenzione di cambiare il codice per trovare l'etichetta.

module Marketron 
    module DateTime 

    def select_date(field, options = {}) 
     date_parse = Date.parse(options[:with]) 

     year = date_parse.year.to_s 
     month = date_parse.strftime('%B') 
     day = date_parse.day.to_s 

     within("div##{field}") do 
     find(:xpath, "//select[contains(@id, \"_#{FIELDS[:year]}\")]").select(year) 
     find(:xpath, "//select[contains(@id, \"_#{FIELDS[:month]}\")]").select(month) 
     find(:xpath, "//select[contains(@id, \"_#{FIELDS[:day]}\")]").select(day) 
     end 

    end 

    def select_time(field, options = {}) 
     require "time" 
     time_parse = Time.parse(options[:with]) 

     hour = time_parse.hour.to_s.rjust(2, '0') 
     minute = time_parse.min.to_s.rjust(2, '0') 

     within("div##{field}") do 
     find(:xpath, "//select[contains(@id, \"_#{FIELDS[:hour]}\")]").find(:xpath, "option[contains(@value, '#{hour}')]").select_option 
     find(:xpath, "//select[contains(@id, \"_#{FIELDS[:minute]}\")]").find(:xpath, "option[contains(@value, '#{minute}')]").select_option 

     end 

    end 

    def select_datetime(field, options = {}) 
     select_date(field, options) 
     select_time(field, options) 
    end 

    private 

     FIELDS = {year: "1i", month: "2i", day: "3i", hour: "4i", minute: "5i"} 

    end 
end 

World(Marketron::DateTime) 

risposta

25

È necessario specificare nel XPath che si desidera avviare con il nodo corrente con l'aggiunta di un . al punto di partenza:

find(:xpath, ".//select[contains(@id, \"_#{FIELDS[:year]}\")]") 

Esempio:

Ho testato una pagina HTML di questo (speriamo di non semplificare troppo la pagina):

<html> 
    <div id='div1'> 
     <span class='container'>  
      <span id='field_01'>field 1</span> 
     </span> 
    </div> 
    <div id='div2'> 
     <span class='container'> 
      <span id='field_02'>field 2</span> 
     </span> 
    </div> 
</html> 

Utilizzando l'all'interno dei metodi, si può vedere il problema quando si esegue questa operazione:

within("div#div1"){ puts find(:xpath, "//span[contains(@id, \"field\")]").text } 
#=> field 1 
within("div#div2"){ puts find(:xpath, "//span[contains(@id, \"field\")]").text } 
#=> field 1 

Ma si può vedere che, ma specificando l'XPath per guardare dentro il nodo corrente (vale a dire utilizzando .), si ottengono i risultati che desidera:

within("div#div1"){ puts find(:xpath, ".//span[contains(@id, \"field\")]").text } 
#=> field 1 
within("div#div2"){ puts find(:xpath, ".//span[contains(@id, \"field\")]").text } 
#=> field 2 
Problemi correlati