链式 Watir 命令

Chain Watir commands

例如,我想将浏览器的用户代理作为 http://www.useragentstring.com/ 的输出,并将其存储在一个变量中。目前,我可以在多行中完成

require 'watir'
b = Watir::Browser.new(:chrome)
b.goto('http://www.useragentstring.com/')
agent = b.textarea.text
b.close

理想情况下,我想在一行中完成。像

require 'watir'
agent = Watir::Browser.new(:chrome).goto('http://www.useragentstring.com/').textarea.text

但是失败了

NoMethodError: undefined method `textarea' for "http://www.useragentstring.com/":String`

因此,虽然 goto 部分有效,但其余部分无效。由于 watir 允许我们做类似 wait_until_present.click 的事情,我希望也有一些方法可以链接这些方法。这可能吗?

虽然 goto 方法不支持链接,但您可以为 Watir::Browser 创建自定义方法,如下所示

class Watir::Browser
  def chain_goto(url)
    goto(url)
    self
  end
end

然后你可以像这样使用 Watir::Browser.new(:firefox).chain_goto('http://www.useragentstring.com/').textarea.text

所以完整的代码会像

require 'watir'

class Watir::Browser
  def chain_goto(url)
    goto(url)
    self
  end
end

b = Watir::Browser.new(:firefox).chain_goto('http://www.useragentstring.com/'.textarea.text

您可以使用 tap 方法使任何东西都可以链接。如 Ruby Docs:

所述

Yields self to the block, and then returns self. The primary purpose of this method is to “tap into” a method chain, in order to perform operations on intermediate results within the chain.

这意味着您可以使用 tap 来调用 goto 并且仍然有 Watir::Browser 实例来调用 textarea:

agent = Watir::Browser.new(:chrome).tap{ |b| b.goto('http://www.useragentstring.com/') }.textarea.text