Class: Selenium::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/selenium/server.rb

Overview

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

Defined Under Namespace

Classes: Error

Constant Summary collapse

CL_RESET =
WebDriver::Platform.windows? ? '' : "\r\e[0K"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(jar, opts = {}) ⇒ Server

Returns a new instance of Server.

Parameters:

  • jar (String)

    Path to the server jar.

  • opts (Hash) (defaults to: {})

    the options to create the server process with

Options Hash (opts):

  • :port (Integer)

    Port the server should listen on (default: 4444).

  • :timeout (Integer)

    Seconds to wait for server launch/shutdown (default: 30)

  • :background (true, false)

    Run the server in the background (default: false)

  • :log (true, false, String)

    Either a path to a log file, or true to pass server log to stdout.

Raises:

  • (Errno::ENOENT)

    if the jar file does not exist


177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/selenium/server.rb', line 177

def initialize(jar, opts = {})
  raise Errno::ENOENT, jar unless File.exist?(jar)

  @jar        = jar
  @host       = '127.0.0.1'
  @role       = opts.fetch(:role, 'standalone')
  @port       = opts.fetch(:port, 4444)
  @timeout    = opts.fetch(:timeout, 30)
  @background = opts.fetch(:background, false)
  @log        = opts[:log]
  @log_file   = nil
  @additional_args = []
end

Instance Attribute Details

#backgroundObject

The Mode of the Server :standalone, #hub, #node


163
164
165
# File 'lib/selenium/server.rb', line 163

def background
  @background
end

#logObject

The Mode of the Server :standalone, #hub, #node


163
164
165
# File 'lib/selenium/server.rb', line 163

def log
  @log
end

#portObject

The Mode of the Server :standalone, #hub, #node


163
164
165
# File 'lib/selenium/server.rb', line 163

def port
  @port
end

#roleObject

The Mode of the Server :standalone, #hub, #node


163
164
165
# File 'lib/selenium/server.rb', line 163

def role
  @role
end

#timeoutObject

The Mode of the Server :standalone, #hub, #node


163
164
165
# File 'lib/selenium/server.rb', line 163

def timeout
  @timeout
end

Class Method Details

.download(required_version = :latest) ⇒ String

Download the given version of the selenium-server jar and return location

Parameters:

  • required_version (String, Symbol) (defaults to: :latest)

    X.Y.Z defaults to ':latest'

Returns:

  • (String)

    location of downloaded file


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/selenium/server.rb', line 80

def download(required_version = :latest)
  required_version = latest if required_version == :latest
  download_file_name = "selenium-server-#{required_version}.jar"

  return download_file_name if File.exist? download_file_name

  begin
    server = 'https://github.com/seleniumhq/selenium/releases/download'
    released = Net::HTTP.get_response(URI.parse("#{server}/selenium-#{required_version}/#{download_file_name}"))
    redirected = URI.parse released.header['location']

    File.open(download_file_name, 'wb') do |destination|
      download_server(redirected, destination)
    end
  rescue StandardError
    FileUtils.rm download_file_name if File.exist? download_file_name
    raise
  end

  download_file_name
end

.download_server(uri, destination) ⇒ Object


131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/selenium/server.rb', line 131

def download_server(uri, destination)
  net_http_start('github-releases.githubusercontent.com') do |http|
    request = Net::HTTP::Get.new uri
    resp = http.request(request) 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).zero?
          percent = progress.fdiv(total) * 100
          print "#{CL_RESET}Downloading #{destination.path}: #{percent.to_i}% (#{progress} / #{total})"
          segment_count = 0
        end

        destination.write(segment)
      end
    end

    raise Error, "#{resp.code} for #{destination.path}" unless resp.is_a? Net::HTTPSuccess
  end
end

.get(required_version = :latest, opts = {}) ⇒ Selenium::Server

Download the given version of the selenium-server jar and return instance

Parameters:

  • required_version (String, Symbol) (defaults to: :latest)

    X.Y.Z defaults to ':latest'

  • opts (Hash) (defaults to: {})

Returns:


69
70
71
# File 'lib/selenium/server.rb', line 69

def get(required_version = :latest, opts = {})
  new(download(required_version), opts)
end

.latestObject

Ask GitHub what the latest selenium-server version is.


106
107
108
109
110
111
112
113
114
115
# File 'lib/selenium/server.rb', line 106

def latest
  @latest ||= begin
    net_http_start('api.github.com') do |http|
      json = http.get('/repos/seleniumhq/selenium/releases').body
      all_assets = JSON.parse(json).map { |release| release['assets'] }.flatten
      server_assets = all_assets.map { |asset| asset['name'][/selenium-server-(\d+\.\d+\.\d+)\.jar/, 1] }.compact
      server_assets.map { |version| Gem::Version.new(version) }.max.version
    end
  end
end

.net_http_start(address, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


119
120
121
122
123
124
125
126
127
128
129
# File 'lib/selenium/server.rb', line 119

def net_http_start(address, &block)
  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.start(address, nil, uri.host, uri.port, &block)
  else
    Net::HTTP.start(address, use_ssl: true, &block)
  end
end

Instance Method Details

#<<(arg) ⇒ Object


214
215
216
217
218
219
220
# File 'lib/selenium/server.rb', line 214

def <<(arg)
  if arg.is_a?(Array)
    @additional_args += arg
  else
    @additional_args << arg.to_s
  end
end

#startObject


191
192
193
194
195
196
# File 'lib/selenium/server.rb', line 191

def start
  process.start
  poll_for_service

  process.wait unless @background
end

#stopObject


198
199
200
201
202
203
204
205
206
207
208
# File 'lib/selenium/server.rb', line 198

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
end

#webdriver_urlObject


210
211
212
# File 'lib/selenium/server.rb', line 210

def webdriver_url
  "http://#{@host}:#{@port}/wd/hub"
end