class LapisLazuli::Browser

Extension to the Watir browser

This class handles initialization, for the most part. BrowserModules included here can rely on world being set to the current cucumber world object, and for some WorldModules to exist in it (see assertions in constructor).

Attributes

browser_args[R]

Public Class Methods

add_browser(b) click to toggle source
# File lib/lapis_lazuli/browser.rb, line 46
def add_browser(b)
  # Add destructor for all browsers
  Runtime.instance.set_if(self, :browsers, LapisLazuli::Browser.method(:close_all))
  @@browsers.push(b)
end
browsers() click to toggle source
# File lib/lapis_lazuli/browser.rb, line 42
def browsers
  return @@browsers
end
check_world?() click to toggle source
# File lib/lapis_lazuli/browser.rb, line 60
def check_world?
  assert @@world.respond_to?(:config), "Need to include LapisLazuli::WorldModule::Config in your cucumber world."
  assert @@world.respond_to?(:log), "Need to include LapisLazuli::WorldModule::Logging in your cucumber world."
  assert @@world.respond_to?(:error), "Need to include LapisLazuli::WorldModule::Error in your cucumber world."
  assert @@world.respond_to?(:has_proxy?), "Need to include LapisLazuli::WorldModule::Proxy in your cucumber world."
end
close_all(reason = nil) click to toggle source
# File lib/lapis_lazuli/browser.rb, line 226
def self.close_all(reason = nil)
  # A running browser should exist and we are allowed to close it
  if @@browsers.length != 0 and @@world.env_or_config("close_browser_after") != "never"
    # Notify user
    @@world.log.debug("Closing all browsers")
    # Close each browser
    @@browsers.each do |b|
      b.close reason, true
    end

    # Make sure the array is cleared
    @@browsers = []
  end
end
new(*args) click to toggle source
# File lib/lapis_lazuli/browser.rb, line 73
def initialize(*args)
  # The class only works with some modules loaded; they're loaded by the
  # Browser module, but we can't be sure that's been used.
  LapisLazuli::Browser.check_world?

  self.start(*args)

  # Add registered world modules.
  if not LapisLazuli::WorldModule::Browser.browser_modules.nil?
    LapisLazuli::WorldModule::Browser.browser_modules.each do |ext|
      self.extend(ext)
    end
  end
end
remove_browser(b) click to toggle source
# File lib/lapis_lazuli/browser.rb, line 52
def remove_browser(b)
  @@browsers.delete(b)
end
set_world(w) click to toggle source
# File lib/lapis_lazuli/browser.rb, line 56
def set_world(w)
  @@world = w
end

Public Instance Methods

close(reason = nil, remove_from_list = true) click to toggle source

Closes the browser and updates LL so that it will open a new one if needed

# File lib/lapis_lazuli/browser.rb, line 134
def close(reason = nil, remove_from_list = true)
  if not @browser.nil?
    if not reason.nil?
      reason = " after #{reason}"
    else
      reason = ""
    end

    world.log.debug "Closing browser#{reason}: #{@browser}"
    @browser.close
    if remove_from_list
      LapisLazuli::Browser.remove_browser(self)
    end
    @browser = nil
  end
end
close_after_scenario(scenario) click to toggle source

Close after scenario will close the browser depending on the close_browser_after configuration

Valid config options: feature, scenario, end, never Default: feature

# File lib/lapis_lazuli/browser.rb, line 163
def close_after_scenario(scenario)
  # Determine the config
  close_browser_after = world.env_or_config("close_browser_after")
  case close_browser_after
  when "scenario"
    # We always close it
    LapisLazuli::Browser.close_all close_browser_after
  when "never"
    # Do nothing: party time, excellent!
  when "feature"
    if is_last_scenario?(scenario)
      # Close it
      LapisLazuli::Browser.close_all close_browser_after
    end
  else
    # close after 'end' is now default
    # Also ignored here - this is handled  in World.browser_destroy
  end
end
create(*args) click to toggle source

Creates a new browser instance.

# File lib/lapis_lazuli/browser.rb, line 98
def create(*args)
  return Browser.new(*args)
end
destroy(world) click to toggle source
# File lib/lapis_lazuli/browser.rb, line 221
def destroy(world)
  # Primary browser should also close other browsers
  LapisLazuli::Browser.close_all("end")
end
initialize_copy(source) click to toggle source

Support browser.dup to create a duplicate

Calls superclass method
# File lib/lapis_lazuli/browser.rb, line 89
def initialize_copy(source)
  super
  @browser = create_driver(*@browser_args)
  # Add this browser to the list of all browsers
  LapisLazuli::Browser.add_browser(self)
end
is_last_scenario?(scenario) click to toggle source
# File lib/lapis_lazuli/browser.rb, line 183
def is_last_scenario?(scenario)
  begin
    feature_file = File.read(scenario.location.file)
    gherkin_object = Gherkin::Parser.new.parse(feature_file)
    last_line = gherkin_object[:feature][:children].last[:scenario][:examples].last[:table_body].last[:location][:line] rescue nil
    unless last_line
      last_line = gherkin_object[:feature][:children].last[:scenario][:location][:line] rescue nil
    end
    if last_line
      return last_line == scenario.location.line
    else
      warn 'Failed to find the last line of the feature trying to determine if this is the last scenario running.'
      return false
    end
  rescue Exception => e
    warn 'Something went wrong trying to determine if this is the last sceanrio of the feature.'
    warn e
  end
end
is_open?() click to toggle source

Return if the browser is open

# File lib/lapis_lazuli/browser.rb, line 108
def is_open?
  return !@browser.nil?
end
method_missing(meth, *args, &block) click to toggle source
Calls superclass method
# File lib/lapis_lazuli/browser.rb, line 214
def method_missing(meth, *args, &block)
  if !@browser.nil? and @browser.respond_to? meth
    return @browser.send(meth.to_s, *args, &block)
  end
  return super
end
quit() click to toggle source

Same as close

# File lib/lapis_lazuli/browser.rb, line 153
def quit
  self.close
end
respond_to?(meth) click to toggle source

Map any missing method to the browser object Example ll.browser.goto “www.spritecloud.com

Calls superclass method
# File lib/lapis_lazuli/browser.rb, line 207
def respond_to?(meth)
  if !@browser.nil? and @browser.respond_to? meth
    return true
  end
  return super
end
restart(*args) click to toggle source

Close and create a new browser

# File lib/lapis_lazuli/browser.rb, line 126
def restart(*args)
  world.log.debug "Restarting browser"
  self.close
  self.start(*args)
end
start(*args) click to toggle source

Start the browser if it's not yet open.

# File lib/lapis_lazuli/browser.rb, line 114
def start(*args)
  if @browser.nil?
    @browser = init(*args)
    # Add this browser to the list of all browsers
    LapisLazuli::Browser.add_browser(self)
    # Making sure all browsers are gracefully closed when the exit event is triggered.
    at_exit { LapisLazuli::Browser::close_all 'exit event trigger' }
  end
end
world() click to toggle source
# File lib/lapis_lazuli/browser.rb, line 102
def world
  @@world
end

Private Instance Methods

create_driver(*args) click to toggle source

Create a new browser depending on settings Always cached the supplied arguments

# File lib/lapis_lazuli/browser.rb, line 253
def create_driver(*args)
  # Remove device information from optional_data and create a separate variable for it
  device = args[1] ? args[1].delete(:device) : nil
  # If device is set, load it from the devices.yml config
  unless device.nil?
    begin
      world.add_config_from_file('./config/devices.yml')
    rescue
      raise '`./config/devices.yml` was not found. See http://testautomation.info/Lapis_Lazuli:Device_Simulation for more information'
    end
    if world.has_config? "devices.#{device}"
      device_configuration = world.config "devices.#{device}"
    else
      raise "Requested device `#{device}` was not found in the configuration. See http://testautomation.info/Lapis_Lazuli:Device_Simulation for more information"
    end
  end

  # Run-time dependency.
  begin
    require 'selenium-webdriver'
    require 'watir'
  rescue LoadError => err
    raise LoadError, "#{err}: you need to add 'watir' to your Gemfile before using the browser."
  end

  begin
    browser_instance = Watir::Browser.new(*args)
    # Resize the browser if the device simulation requires it
    if !device_configuration.nil? and !device_configuration['width'].nil? and !device_configuration['height'].nil?
      browser_instance.window.resize_to(device_configuration['width'], device_configuration['height'])
    end
  rescue Selenium::WebDriver::Error::UnknownError => err
    raise err
  end
  browser_instance
end
init(*args) click to toggle source

The main browser window for testing

# File lib/lapis_lazuli/browser.rb, line 245
def init(*args)
  # Store the optional data so on restart of the browser it still has the correct configuration
  create_driver(*args)
end