1
0
Fork 0
mirror of https://github.com/thoughtbot/capybara-webkit synced 2023-03-27 23:22:28 -04:00
capybara-webkit/lib/capybara/webkit/connection.rb
Matthew Horan ea06a1b57f Forward stderr from server to stderr, drop stdout
We don't actually write anything to stdout. Also rename the stdout
option to stderr, since that's where we forward the output.
2013-02-04 19:53:32 -05:00

98 lines
2.1 KiB
Ruby

require 'socket'
require 'timeout'
require 'thread'
require 'open3'
module Capybara::Webkit
class Connection
SERVER_PATH = File.expand_path("../../../../bin/webkit_server", __FILE__)
WEBKIT_SERVER_START_TIMEOUT = 15
attr_reader :port
def initialize(options = {})
@socket_class = options[:socket_class] || TCPSocket
@output_target = options.has_key?(:stderr) ? options[:stderr] : $stderr
start_server
connect
end
def puts(string)
@socket.puts string
end
def print(string)
@socket.print string
end
def gets
@socket.gets
end
def read(length)
@socket.read(length)
end
private
def start_server
open_pipe
discover_port
forward_output_in_background_thread
end
def open_pipe
_, @pipe_stdout, @pipe_stderr, wait_thr = Open3.popen3(SERVER_PATH)
@pid = wait_thr[:pid]
register_shutdown_hook
end
def register_shutdown_hook
@owner_pid = Process.pid
at_exit do
if Process.pid == @owner_pid
kill_process
end
end
end
def kill_process
if RUBY_PLATFORM =~ /mingw32/
Process.kill(9, @pid)
else
Process.kill("INT", @pid)
end
rescue Errno::ESRCH
# This just means that the webkit_server process has already ended
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
end
end
def forward_output_in_background_thread
Thread.new do
Thread.current.abort_on_exception = true
IO.copy_stream(@pipe_stderr, @output_target)
end
end
def connect
Timeout.timeout(5) do
while @socket.nil?
attempt_connect
end
end
end
def attempt_connect
@socket = @socket_class.open("127.0.0.1", @port)
if defined?(Socket::TCP_NODELAY)
@socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)
end
rescue Errno::ECONNREFUSED
end
end
end