2012-04-20 16 views
9

Tôi đang cố gắng tạo bộ chọn ngày với Capybara bằng cách sử dụng các trường Ngày, giờ và các trường ngày tháng mặc định của Rails. Tôi đang sử dụng phương pháp within để tìm các hộp chọn cho trường nhưng khi tôi sử dụng xPath để tìm đúng hộp, nó rời khỏi phạm vi within và tìm sự xuất hiện đầu tiên trên trang của phần tử.capybara - Tìm với xPath đang rời khỏi phạm vi trong phạm vi

Đây là mã tôi đang sử dụng. Các trang tôi đang thử nghiệm trên có 2 lĩnh vực datetime nhưng tôi chỉ có thể nhận được nó để thay đổi đầu tiên vì lỗi này. Hiện tại tôi có một vùng chứa div có id kết thúc tốt với trường datetime nhưng tôi có kế hoạch chuyển mã để tìm theo nhãn.

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) 

Trả lời

25

Bạn nên xác định trong xpath mà bạn muốn bắt đầu với nút hiện tại bằng cách thêm một . khi bắt đầu:

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

Ví dụ:

Tôi đã thử nghiệm một trang HTML của điều này (hy vọng không đơn giản hóa trang của bạn):

<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> 

Sử dụng trong phương pháp này, bạn có thể thấy vấn đề của bạn khi bạn làm điều này:

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 

Nhưng bạn có thể thấy rằng nhưng xác định xpath để nhìn vào bên trong nút hiện hành (tức là sử dụng .), bạn sẽ có được kết quả mà bạn muốn:

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