如何使watir-webdriver支持选择中文的下拉菜单

17 篇文章 0 订阅
14 篇文章 1 订阅

今天将waitr代码移植至watir-webdriver时,发现watir-webdriver的Select.select(text)方法似乎不支持中文的text。

也就是说watir-webdriver的select方法无法选择中文的option。

研究了一下源码发现Select.select方法是这样实现的:

def select(str_or_rx)
  select_by :text, str_or_rx
end
 
#select方法又调用了select_by方法
def select_by(how, str_or_rx)
  assert_exists
 
  case str_or_rx
  when String, Numeric
    select_by_string(how, str_or_rx.to_s)
  when Regexp
    select_by_regexp(how, str_or_rx)
  else
    raise TypeError, "expected String or Regexp, got #{str_or_rx.inspect}:#{str_or_rx.class}"
  end
end
 
#当select的参数是String的时候调用select_by_string方法
def select_by_string(how, string)
  xpath = option_xpath_for(how, string)
 
  if multiple?
    elements = @element.find_elements(:xpath, xpath)
    no_value_found(string) if elements.empty?
 
    elements.each { |e| e.click unless e.selected? }
    elements.first.text
  else
    begin
      e = @element.find_element(:xpath, xpath)
    rescue WebDriver::Error::NoSuchElementError
      no_value_found(string)
    end
 
    e.click unless e.selected?
 
    safe_text(e)
  end
end
 
#select_by_string方法调用了option_xpath_for方法来生成该option的xpath
def option_xpath_for(how, string)
  string = XpathSupport.escape string
 
  case how
  when :text
    ".//option[normalize-space()=#{string} or @label=#{string}]"
  when :value
    ".//option[@value=#{string}]"
  else
    raise Error, "unknown how: #{how.inspect}"
  end
end


可以看出原来Select.select(text)方法实际上是使用text参数构造了1个值为".//option[normalize-space()=#{text}" 或者 "@label=#{string}]"的xpath字符串,然后使用find_element方法来找到需要被选中的option。

说到底,select方法需要构造xpath,然后通过xpath来定位对象。所以其不支持中文的问题很可能是由于webdriver的元素定位方法不支持带有中文的xpath所导致。当然,上述原因只是猜测,至于真正的终极原因则需要去仔细研究find_element方法。由于时间有限,在这里就不再纠结这个问题了。

当然,既然watir-webdriver可能原生不支持select方法选择中文的option,我们就需要自己动手写出属于自己的、支持中文option的定位方法来。具体代码如下:

Watir::Option.class_eval do
 
  def value
    assert_exists
    @element.attribute(:value)
  end
 
end
 
Watir::Select.class_eval do
 
  def getAllContents
    contents = []
    options.each do |o|
      contents.push o.text rescue next 
    end #each
    contents
  end #def
 
  alias :get_all_contents :getAllContents
 
  def getAllValues
    values = []
    options.each do |o|
      values.push o.value
    end
    values
  end #def 
 
  alias :get_all_values :getAllValues
 
  # 返回select list 下所有的option
  # 提供value => text的键值对
  def text_to_value
    the_hash = {}   
    values = getAllValues
    getAllContents.each_with_index do |t, i|
      the_hash[t] = values[i]
    end
    the_hash
  end #def
 
  def my_select text #也可以直接覆盖原生select方法
    begin 
      select text
    rescue
      select_value text_to_value[text]
    end 
  end
 
end #class eval

上述代码的思路是首先给Option类增加value方法,然后在Select类中增加获取当前select_list的所有option的text及value的方法。当原生的select方法无法选择到option的时候就去获取这个option对应的value,然后使用select_value方法去选择。从一般性上考虑,该方法可以替代原生的select方法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值