Cucumber 当使用Watir/Chrome时,“@browser”是ChromeDriver对象的必选名称吗?

Cucumber 当使用Watir/Chrome时,“@browser”是ChromeDriver对象的必选名称吗?,cucumber,watir,watir-webdriver,selenium-chromedriver,Cucumber,Watir,Watir Webdriver,Selenium Chromedriver,我想更改@browser变量的名称,因为我已经厌倦了键入它 在env.rb中: before do @b = Watir::Browser.new :chrome end 这会引发错误: 无法为提供的浏览器或元素选择平台:nil。 nil被传递给PageObject构造函数,而不是有效的浏览器或元素对象。(运行时错误) 一切正常 @browser = Watir::Browser.new :chrome @b = @browser 也不行。有没有办法修改这个变量名?问题出在代码的其他地

我想更改
@browser
变量的名称,因为我已经厌倦了键入它

env.rb
中:

before do
  @b = Watir::Browser.new :chrome 
end
这会引发错误:

无法为提供的浏览器或元素选择平台:nil。
nil被传递给PageObject构造函数,而不是有效的浏览器或元素对象。(运行时错误)

一切正常

@browser = Watir::Browser.new :chrome
@b = @browser

也不行。有没有办法修改这个变量名?

问题出在代码的其他地方。如果您只运行您提供的线路(在要求watir后)

在IRB会话中,它可以正常工作

其他一些代码依赖项(可能是page objects library)需要一个浏览器对象,并且需要一个特定的名称,但得到的是一个nill(未初始化)对象,并发出抱怨


此外,除非您想要为每个测试打开和关闭浏览器的开销(可能会增加大量时间),否则您可能希望更早地初始化浏览器,例如在before_all钩子中,或者在测试代码启动的早期。然后在before钩子中执行清除缓存和cookies之类的操作。通常,您可以将浏览器实例存储在任何名称的变量中。Watir Webdriver不在乎,Cheezy的页面对象也不在乎。页面对象的初始化只关心传入的实际对象是什么,即它必须是
Watir::Browser
Watir::Element
(或等效的Selenium WebDriver)

但是,使用
PageObject::PageFactory
时,情况并非如此。在,并且隐式地
访问_页面
如果_页面
,代码被硬编码以查找
@浏览器
变量

def on_page(page_class, params={:using_params => {}}, visit=false, &block)
  page_class = class_from_string(page_class) if page_class.is_a? String
  return super(page_class, params, visit, &block) unless page_class.ancestors.include? PageObject
  merged = page_class.params.merge(params[:using_params])
  page_class.instance_variable_set("@merged_params", merged) unless merged.empty?
  @current_page = page_class.new(@browser, visit)
  block.call @current_page if block
  @current_page
end
页面对象的初始化始终使用
@browser
完成。当您将浏览器实例存储在
@b
中时,这意味着
@browser
nil
。这导致了您看到的异常。如果您想使用所编写的
页面工厂
,则需要坚持使用
@浏览器

如果这个变量真的让你烦恼,那么总是有猴子补丁的选择。只需重新定义页面上的
上的
方法,即可使用您喜欢的任何变量。以下内容重新定义了使用
@b
的方法:

require 'page-object'

module PageObject
  module PageFactory
    def on_page(page_class, params={:using_params => {}}, visit=false, &block)
      page_class = class_from_string(page_class) if page_class.is_a? String
      return super(page_class, params, visit, &block) unless page_class.ancestors.include? PageObject
      merged = page_class.params.merge(params[:using_params])
      page_class.instance_variable_set("@merged_params", merged) unless merged.empty?
      @current_page = page_class.new(@b, visit)
      block.call @current_page if block
      @current_page
    end
    alias_method :on, :on_page
  end
end

看到整个例外情况会有所帮助。您使用的是Cheezy的页面对象gem吗?我相信这是一个例外。如果是这样,根据您使用gem的方式,它必须是
@browser
。Watir本身并不关心您使用的变量名。如果您正在创建页面对象并将@browser(或任何内容)传递到new()中,那么您应该可以随意调用它。我以前在使用多个webdriver实例驱动多个窗口进行测试时做过这件事。@JustinKo我在使用Cheezy的gem。你能详细说明一下“…取决于你如何使用宝石…”吗?抱歉,本应添加完全异常。请参见编辑后的问题。
def on_page(page_class, params={:using_params => {}}, visit=false, &block)
  page_class = class_from_string(page_class) if page_class.is_a? String
  return super(page_class, params, visit, &block) unless page_class.ancestors.include? PageObject
  merged = page_class.params.merge(params[:using_params])
  page_class.instance_variable_set("@merged_params", merged) unless merged.empty?
  @current_page = page_class.new(@browser, visit)
  block.call @current_page if block
  @current_page
end
require 'page-object'

module PageObject
  module PageFactory
    def on_page(page_class, params={:using_params => {}}, visit=false, &block)
      page_class = class_from_string(page_class) if page_class.is_a? String
      return super(page_class, params, visit, &block) unless page_class.ancestors.include? PageObject
      merged = page_class.params.merge(params[:using_params])
      page_class.instance_variable_set("@merged_params", merged) unless merged.empty?
      @current_page = page_class.new(@b, visit)
      block.call @current_page if block
      @current_page
    end
    alias_method :on, :on_page
  end
end