昨天发现了Ruby Watir里的一个小问题,没有办法在Text Field里输入中文。虽然已经hack了,但是还是不太爽,G.H.Hardy说:

Beauty is the first test: there is no permanent place in this world for ugly mathematics.

感动了我好久。现在换个说法:

Beauty is the first test: there is no permanent place in this world for ugly hack code.

这个问题也不太难出理,ruby作为C的front interface在字符串处理上有很深的C的痕迹,嗯,10年前我还是个C程序员嘛,按照从前的做法区分ASCII码。

1 def characters_in(value) 
2   index = 0
3   while index < value.length 
4     len = value[index] > 128 ? 2 : 1
5     yield value[index, len]
6     index += len
7   end 
8 end

把TextField里的doKeyPress改一下:

1 characters_in(value) {|c| 
2   sleep @ieController.typingspeed
3   @o.value = @o.value.to_s + c
4   fire_key_events}

搞定!但是还是很丑,直接把别人的code改了,contributing to eclipse里说要contribute不要随便change别人的代码。好吧,好在ruby扩展起来也不难:

 1 require 'Watir'
 2 
 3 module Watir
 4   module Cn
 5     class IE <Watir::IE
 6       def text_field(how , what=nil)
 7         return TextField.new(self, how, what)
 8       end
 9     end
10     
11     class TextField < Watir::TextField
12       def doKeyPress( value )
13         begin
14           maxLength = @o.maxLength
15           if value.length > maxLength
16             value = suppliedValue[0 .. maxLength ]
17             @ieController.log " Supplied string is #{suppliedValue.length} chars, which exceeds the max length (#{maxLength}) of the field. Using value: #{value}"
18           end
19         rescue
20           # probably a text area - so it doesnt have a max Length
21           maxLength = -1
22          end
23                        
24         Cn.characters_in(value) {|c| 
25           sleep @ieController.typingspeed
26           @o.value = @o.value.to_s + c
27           fire_key_events}
28       end
29     end
30     
31     def Cn.characters_in(value) 
32       index = 0
33       while index < value.length 
34         len = value[index] > 128 ? 2 : 1
35         yield value[index, len]
36         index += len
37       end 
38     end
39   end
40 end

测试一下:

require 'watir-cn'

ie 
= Watir::Cn::IE.start('http://www.google.com')
ie.text_field(:name, 
'q').set('Ruby Watir 功能测试'

成功。最后一步是贡献社区,直接登到rubyforge,找到Watir然后submit了两个patch:一个直接修改watir库的一个是独立的watir-cn的。推荐大家使用第二个的patch。地址在:http://rubyforge.org/tracker/index.php?func=detail&aid=3232&group_id=104&atid=489