meatspace
meatspace

Reputation: 913

Is `@browser` the obligatory name for the ChromeDriver object when using Watir/Chrome?

I want to change the name of the @browser variable because I'm tired of typing it.

In env.rb:

before do
  @b = Watir::Browser.new :chrome 
end

This throws error:

Unable to pick a platform for the provided browser or element: nil. nil was passed to the PageObject constructor instead of a valid browser or element object. (RuntimeError)

before do
  @browser = Watir::Browser.new :chrome 
end

works as expected.

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

doesn't work either. Is there any way to modify this variable name?

Upvotes: 1

Views: 281

Answers (2)

Justin Ko
Justin Ko

Reputation: 46846

In general, you can store your browser instance in a variable of any name. Watir-Webdriver does not care, nor does Cheezy's page objects. The initialization of the page object only cares what the actual object passed in is - ie it must be a Watir::Browser or Watir::Element (or the Selenium-WebDriver equivalents).

However, this is not true when using the PageObject::PageFactory. In the on_page method, and implicitly visit_page and if_page, the code is hard-coded to look for a @browser variable.

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

The initialization of the page object is always done with @browser. When you stored the browser instance in @b, it meant that @browser was nil. This then led to the exception you saw. If you want to use the PageFactory as written, you will need to stick to @browser.

If the variable really bothers you, there is always the option for monkey patching. Simply re-define the on_page and on method to use whatever variable you like. The following redefines the method to use @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

Upvotes: 2

Chuck van der Linden
Chuck van der Linden

Reputation: 6660

The issue is somewhere else in your code. If you run just the line you provided (after requiring watir)

require 'watir-webdriver'
@b = Watir::Browser.new :chrome

in a IRB session it will work just fine..

Some other code dependency (page objects library perhaps) needs a browser object and is expecting a specific name, is getting a nill (un-initialized) object instead and complaining.

Also, unless you want the overhead of opening and closing the browser for each test (can add a ton of time) you may want to initialize the browser earlier, such as in a before_all hook, or early in the startup of your test code. Then just do something like clear cache and cookies in the before hook

Upvotes: 1

Related Questions