capybara-найти с xPath выходит за рамки

Я пытаюсь построить селектор даты с помощью Capybara, используя поля даты, времени и времени по умолчанию Rails. Я использую within метод поиска полей выбора для поля, но когда я использую xPath для поиска правильного поля, он оставляет within scope и найдите первое вхождение на странице элемента.

вот код, который я использую. Страница, на которой я тестирую, имеет 2 поля datetime, но я могу заставить ее изменить только первую из-за этой ошибки. В данный момент я имейте контейнер div с id, который обертывает поле datetime, но я планирую переключить код, чтобы найти по метке.

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)

1 ответов


вы должны указать в xpath, что вы хотите начать с текущего узла, добавив . для начала:

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

пример:

я протестировал HTML-страницу этого (надеюсь, не слишком упрощая вашу страницу):

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

используя методы внутри, вы можете увидеть свою проблему, когда вы это сделаете:

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

но вы можете видеть, что, но указав xpath, чтобы посмотреть в текущем узле (т. е. используя .), вы получаете результаты, которые вы хотите:

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