Raise better errors if server fails to start

* When WEBKIT_SERVER_START_TIMEOUT was reached, @port would get set to
  nil. If execution of the SERVER_PROCESS returned immediately, @port
  would get set to 0. This lead to odd cross-platform behavior in
  #connect, which would try to connect to a nonsense port.
This commit is contained in:
Matthew Horan 2014-07-02 20:46:03 -04:00
parent 2cd9d32849
commit 144a43ff7b
3 changed files with 41 additions and 1 deletions

View File

@ -55,9 +55,19 @@ module Capybara::Webkit
@pipe_stdin, @pipe_stdout, @pipe_stderr, @wait_thr = Open3.popen3(SERVER_PATH)
end
def parse_port(line)
if match = line.to_s.match(/listening on port: (\d+)/)
match[1].to_i
else
raise ConnectionError, "#{SERVER_PATH} failed to start."
end
end
def discover_port
if IO.select([@pipe_stdout], nil, nil, WEBKIT_SERVER_START_TIMEOUT)
@port = ((@pipe_stdout.first || '').match(/listening on port: (\d+)/) || [])[1].to_i
@port = parse_port(@pipe_stdout.first)
else
raise ConnectionError, "#{SERVER_PATH} failed to start after #{WEBKIT_SERVER_START_TIMEOUT} seconds."
end
end

View File

@ -17,6 +17,9 @@ module Capybara::Webkit
class NoSuchWindowError < StandardError
end
class ConnectionError < StandardError
end
class JsonError
def initialize(response)
error = JSON.parse response

View File

@ -23,6 +23,33 @@ describe Capybara::Webkit::Connection do
expect { Process.getpgid(webkit_pid) }.to raise_error Errno::ESRCH
end
it "raises an error if the server has stopped", skip_on_windows: true do
path = 'false'
stub_const("Capybara::Webkit::Connection::SERVER_PATH", path)
expect { Capybara::Webkit::Connection.new }.
to raise_error(
Capybara::Webkit::ConnectionError,
"#{path} failed to start.")
end
it "raises an error if the server is not ready", skip_on_windows: true do
server_path = 'sleep 1'
stub_const("Capybara::Webkit::Connection::SERVER_PATH", server_path)
start_timeout = 0.5
stub_const("Capybara::Webkit::Connection::WEBKIT_SERVER_START_TIMEOUT", start_timeout)
error_string =
if defined?(::JRUBY_VERSION)
"#{server_path} failed to start."
else
"#{server_path} failed to start after #{start_timeout} seconds."
end
expect { Capybara::Webkit::Connection.new }.
to raise_error(Capybara::Webkit::ConnectionError, error_string)
end
it "boots a server to talk to" do
url = "http://#{@rack_server.host}:#{@rack_server.port}/"
connection.puts "Visit"