首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

怎么使watir-webdriver支持选择中文的下拉菜单

2012-07-18 
如何使watir-webdriver支持选择中文的下拉菜单今天将waitr代码移植至watir-webdriver时,发现watir-webdriv

如何使watir-webdriver支持选择中文的下拉菜单
今天将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_rxend#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}"  endend#当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)  endend#select_by_string方法调用了option_xpath_for方法来生成该option的xpathdef 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}"  endend


可以看出原来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)  endendWatir::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  endend #class eval

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

热点排行