Hi, 如果有任何想法与我沟通, 请用: lifr_nj 在 msn.com

Ruby+Watir经验谈: 包装Watir::IE

上一篇 / 下一篇  2007-06-01 11:10:12

如果我们要设计一个测试某个Web Server的框架,可以想象会经常在不同的页面跳转。在跳转的时候,你会希望只需提供url path而不是完整的url。但Watir::IE的goto方法需要全路径,所以一种方法是这样

    ie.goto("http://#{$serverip}:#{$serverport}/addUser"); # 用全局变量的方式

但显然我们希望更好的调用方式是

    ie.goto("/addUser"); # 理想的调用方式

二者的易用性差别不言而喻。但这就需要修改Watir::IE的行为,让他能接受url path的方式。在这里也体现了Ruby的强大之处,它的class定义是open的,你可以在任意一个地方修改它。


module Watir
    # 修改Watir::IE就是这么简单
    class IE
    # 参数url定义了协议,地址,和端口
    # for example:
    #   * 10.10.10.10
    #   * 10.10.10.10:8080
    #   * http://10.10.10.10
    #   * https://10.10.10.10
    #
    # parameter 'attach' is a boolean, true means that if there is an existing IE browser,
    # don't launch a new one, jsut attach the ie object to it.
    #
    # @exception Watir::Exception::NoMatchingWindowFoundException if attaching failed
    def initialize(url, attach=false)
        Everbright::Basic.assert_true(!url.nil?, "occUrl shouldn't be nil")
        
        url = url.strip.upcase
        # "10.10.10.10" => [[nil, nil, "10.10.10.10"]]
        # "https://10.10.10.10" => [["https://", "https", "10.10.10.10"]]
        resultAry = url.scan( /^((https?):\/\/)?(.+)$/)
        @scheme, @occUrl = resultAry[0][0] || "http", resultAry[0][2]
        Everbright::Basic.assert_true(!@occUrl.nil?, "no site ip found from #{@occUrl}")

        if attach
        attach_init(:url, Regexp.compile(url))
        else
        create_browser_window
        set_defaults
        end
    end
        
    # 这个方法不应该被访问
        def IE.start( url = nil )
        raise Everbright::Basic::EverbrightException.new("The method shouldn't be called in Everbright framework")
        end

    # 这个方法不应该被访问
    def IE.attach(how, what)
        raise Everbright::Basic::EverbrightException.new("The method shouldn't be called in Everbright framework")
        end


    alias _goto goto

    # 我们需要重写goto方法
    #
        # URL is like: /gateway/login.jsp?user=.....
    # URL shouldn't be like: http://10.10.10.10/gateway/login.jsp.....
    def goto(path)
        return nil if path.nil?
        Everbright::Basic.assert_true(!(path =~ /^https?:\/\//), "URL should be like: /gateway/login....")
       
        log "goto: #{path}"
            _goto("#{@scheme}://#{@occUrl}#{path}")
        end

    end
end

这样,一个在其他语言里实现起来非常麻烦的功能,在ruby里只是a piece of cake.

在c++里,需要实现一个wrapper,把Watir::IE的每个方法都重写一遍,虽然大多数都是简单的转发。在java里要容易点,如果在容器里流行的是AOP拦截,应该也可以使用DynamicProxy这个高级功能,但总之没有ruby来的优美漂亮。

TAG: ruby watir

suoyuzishui的个人空间 引用 删除 suoyuzishui   /   2010-09-13 16:40:39
请教下:运行rb脚本,watir一直提示 element.rb:288:in 'enable?'问题, 这个有什么方法解决么
 

评分:0

我来说两句

Open Toolbar