zoukankan      html  css  js  c++  java
  • 如何使watirwebdriver支持选择中文的下拉菜单

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

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

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

    1 def select(str_or_rx)
    2 select_by :text, str_or_rx
    3 end
    4
    5 #select方法又调用了select_by方法
    6 def select_by(how, str_or_rx)
    7 assert_exists
    8
    9 case str_or_rx
    10 when String, Numeric
    11 select_by_string(how, str_or_rx.to_s)
    12 when Regexp
    13 select_by_regexp(how, str_or_rx)
    14 else
    15 raise TypeError, "expected String or Regexp, got #{str_or_rx.inspect}:#{str_or_rx.class}"
    16 end
    17 end
    18
    19 #当select的参数是String的时候调用select_by_string方法
    20 def select_by_string(how, string)
    21 xpath = option_xpath_for(how, string)
    22
    23 if multiple?
    24 elements = @element.find_elements(:xpath, xpath)
    25 no_value_found(string) if elements.empty?
    26
    27 elements.each { |e| e.click unless e.selected? }
    28 elements.first.text
    29 else
    30 begin
    31 e = @element.find_element(:xpath, xpath)
    32 rescue WebDriver::Error::NoSuchElementError
    33 no_value_found(string)
    34 end
    35
    36 e.click unless e.selected?
    37
    38 safe_text(e)
    39 end
    40 end
    41
    42 #select_by_string方法调用了option_xpath_for方法来生成该option的xpath
    43 def option_xpath_for(how, string)
    44 string = XpathSupport.escape string
    45
    46 case how
    47 when :text
    48 ".//option[normalize-space()=#{string} or @label=#{string}]"
    49 when :value
    50 ".//option[@value=#{string}]"
    51 else
    52 raise Error, "unknown how: #{how.inspect}"
    53 end
    54 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方法。

  • 相关阅读:
    python基础 2
    python基础 1
    进程
    进程作业
    上海python14期第二次阶段性考试
    面向对向之元类
    面向对向
    笔试题
    模块(2)
    模块作业
  • 原文地址:https://www.cnblogs.com/nbkhic/p/2104657.html
Copyright © 2011-2022 走看看