capybara - 使用xPath查找离开内部作用域 [英] capybara - Find with xPath is leaving the within scope

查看:180
本文介绍了capybara - 使用xPath查找离开内部作用域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用默认的Rails日期,时间和日期时间字段与Capybara构建一个日期选择器。我使用方法内的找到字段的选择框,但是当我使用xPath找到正确的框,它留下 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]} \)]
find(:xpath,// select [contains(@id,\_#{FIELDS [:month]} \)]。 xpath//选择[包含(@id,\_#{FIELDS [:day]} \)])。select(day)
end

end

def select_time(field,options = {})
需要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 {field})do
find(:xpath,// select [include(@id,\_#{FIELDS [:hour]} \)] 选项[包含(@id,\_#{FIELDS [:分])选项[contains(@value,'#{hour}') } \)])。find(:xpath,option [contains(@value,'#{minute}')])。select_option

end
$ b b end

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

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

end
end

世界(Marketron :: DateTime)


解决方案

您应该在xpath中指定要从当前节点开始,通过向开始添加 / p>

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

示例:

我测试了一个HTML页面(希望不会过于简化你的页面):

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

使用within方法时,您可以在执行此操作时看到问题:

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

但你可以看到,但是指定xpath来查看当前节点code>。),你会得到你想要的结果:

  #div1){puts find(:xpath,。//span[contains(@id,\field\)])。字段1 
within(div#div2){puts find(:xpath,。//span[contains(eeid,\field\))。text}
#=>字段2


I am trying to build a date selector with Capybara using the default Rails date, time, and datetime fields. I am using the within method to find the select boxes for the field but when I use xPath to find the correct box it leaves the within scope and find the first occurrence on the page of the element.

Here is the code I am using. The page I am testing on has 2 datetime fields but I can only get it to change the first because of this error. At the moment I have an div container with id that wraps up the datetime field but I do plan on switching the code to find by the label.

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)

解决方案

You should specify in the xpath that you want to start with the current node by adding a . to the start:

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

Example:

I tested an HTML page of this (hopefully not over simplifying your page):

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

Using the within methods, you can see your problem when you do this:

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

But you can see that but specifying the xpath to look within the current node (ie using .), you get the results you want:

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

这篇关于capybara - 使用xPath查找离开内部作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆