class Selenium::Server

Wraps the remote server jar

Usage:

server = Selenium::Server.new('/path/to/selenium-server-standalone.jar')
server.start

Automatically download the given version:

server = Selenium::Server.get '2.6.0'
server.start

or the latest version:

server = Selenium::Server.get :latest
server.start

Run the server in the background:

server = Selenium::Server.new(jar, :background => true)
server.start

Add additional arguments:

server = Selenium::Server.new(jar)
server << ["--additional", "args"]
server.start

Constants

CL_RESET

Attributes

background[RW]

Whether to launch the server in the background

log[RW]

Path to log file, or 'true' for stdout.

port[RW]

The server port

timeout[RW]

The server timeout

Public Class Methods

download(required_version) click to toggle source

Download the given version of the selenium-server-standalone jar.

# File lib/selenium/server.rb, line 50
def self.download(required_version)
  required_version = latest if required_version == :latest
  download_file_name = "selenium-server-standalone-#{required_version}.jar"

  if File.exists? download_file_name
    return download_file_name
  end

  begin
    open(download_file_name, "wb") do |destination|
      net_http.start("selenium-release.storage.googleapis.com") do |http|
        resp = http.request_get("/#{required_version[/(\d+\.\d+)\./, 1]}/#{download_file_name}") do |response|
          total = response.content_length
          progress = 0
          segment_count = 0

          response.read_body do |segment|
            progress += segment.length
            segment_count += 1

            if segment_count % 15 == 0
              percent = (progress.to_f / total.to_f) * 100
              print "#{CL_RESET}Downloading #{download_file_name}: #{percent.to_i}% (#{progress} / #{total})"
              segment_count = 0
            end

            destination.write(segment)
          end
        end

        unless resp.kind_of? Net::HTTPSuccess
          raise Error, "#{resp.code} for #{download_file_name}"
        end
      end
    end
  rescue
    FileUtils.rm download_file_name if File.exists? download_file_name
    raise
  end

  download_file_name
end
get(required_version, opts = {}) click to toggle source
# File lib/selenium/server.rb, line 42
def self.get(required_version, opts = {})
  new(download(required_version), opts)
end
latest() click to toggle source

Ask Google Code what the latest selenium-server-standalone version is.

# File lib/selenium/server.rb, line 97
def self.latest
  require 'rexml/document'
  net_http.start("selenium-release.storage.googleapis.com") do |http|
    REXML::Document.new(http.get("/").body).root.get_elements("//Contents/Key").map { |e|
      e.text[/selenium-server-standalone-(\d+\.\d+\.\d+)\.jar/, 1]
    }.compact.max
  end
end
new(jar, opts = {}) click to toggle source

@param [String] jar Path to the server jar. @param [Hash] opts the options to create the server process with

@option opts [Integer] :port Port the server should listen on (default: 4444). @option opts [Integer] :timeout Seconds to wait for server launch/shutdown (default: 30) @option opts [true,false] :background Run the server in the background (default: false) @option opts [true,false,String] :log Either a path to a log file,

or true to pass server log to stdout.

@raise [Errno::ENOENT] if the jar file does not exist

# File lib/selenium/server.rb, line 142
def initialize(jar, opts = {})
  raise Errno::ENOENT, jar unless File.exist?(jar)

  @jar        = jar
  @host       = "127.0.0.1"
  @port       = opts.fetch(:port, 4444)
  @timeout    = opts.fetch(:timeout, 30)
  @background = opts.fetch(:background, false)
  @log        = opts[:log]

  @additional_args = []
end

Private Class Methods

net_http() click to toggle source
# File lib/selenium/server.rb, line 188
def self.net_http
  http_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']

  if http_proxy
    http_proxy = "http://#{http_proxy}" unless http_proxy.start_with?("http://")
    uri = URI.parse(http_proxy)

    Net::HTTP::Proxy(uri.host, uri.port)
  else
    Net::HTTP
  end
end

Public Instance Methods

<<(arg) click to toggle source
# File lib/selenium/server.rb, line 178
def <<(arg)
  if arg.kind_of?(Array)
    @additional_args += arg
  else
    @additional_args << arg.to_s
  end
end
start() click to toggle source
# File lib/selenium/server.rb, line 155
def start
  process.start
  poll_for_service

  process.wait unless @background
end
stop() click to toggle source
# File lib/selenium/server.rb, line 162
def stop
  begin
    Net::HTTP.get(@host, "/selenium-server/driver/?cmd=shutDownSeleniumServer", @port)
  rescue Errno::ECONNREFUSED
  end

  stop_process if @process
  poll_for_shutdown

  @log_file.close if @log_file
end
webdriver_url() click to toggle source
# File lib/selenium/server.rb, line 174
def webdriver_url
  "http://#{@host}:#{@port}/wd/hub"
end

Private Instance Methods

poll_for_service() click to toggle source
# File lib/selenium/server.rb, line 233
def poll_for_service
  unless socket.connected?
    raise Error, "remote server not launched in #{@timeout} seconds"
  end
end
poll_for_shutdown() click to toggle source
# File lib/selenium/server.rb, line 239
def poll_for_shutdown
  unless socket.closed?
    raise Error, "remote server not stopped in #{@timeout} seconds"
  end
end
process() click to toggle source
# File lib/selenium/server.rb, line 215
def process
  @process ||= (
    cp = ChildProcess.build("java", "-jar", @jar, "-port", @port.to_s, *@additional_args)
    io = cp.io

    if @log.kind_of?(String)
      @log_file = File.open(@log, "w")
      io.stdout = io.stderr = @log_file
    elsif @log
      io.inherit!
    end

    cp.detach = @background

    cp
  )
end
socket() click to toggle source
# File lib/selenium/server.rb, line 245
def socket
  @socket ||= WebDriver::SocketPoller.new(@host, @port, @timeout)
end
stop_process() click to toggle source
# File lib/selenium/server.rb, line 201
def stop_process
  return unless @process.alive?

  begin
    @process.poll_for_exit(5)
  rescue ChildProcess::TimeoutError
    @process.stop
  end
rescue Errno::ECHILD
  # already dead
ensure
  @process = nil
end