1
0
Fork 0
mirror of https://github.com/thoughtbot/capybara-webkit synced 2023-03-27 23:22:28 -04:00

Forward stderr via Open3#popen3

Forwarding stderr via 2>&1 causes an additional child process to be
spawned.  Killing that process does not kill webkit_server.

JavaScipt console messages and alerts are now written to the logger
instead of directly to stdout.
This commit is contained in:
Matthew Horan 2012-11-22 10:30:43 -05:00
parent fbead1ebb5
commit 2ceab4e525
5 changed files with 20 additions and 40 deletions

View file

@ -1,6 +1,7 @@
require 'socket' require 'socket'
require 'timeout' require 'timeout'
require 'thread' require 'thread'
require 'open3'
module Capybara::Webkit module Capybara::Webkit
class Connection class Connection
@ -11,8 +12,7 @@ module Capybara::Webkit
def initialize(options = {}) def initialize(options = {})
@socket_class = options[:socket_class] || TCPSocket @socket_class = options[:socket_class] || TCPSocket
@stdout = options.has_key?(:stdout) ? options[:stdout] : $stdout @output_target = options.has_key?(:stdout) ? options[:stdout] : $stdout
@command = options[:command] || SERVER_PATH
start_server start_server
connect connect
end end
@ -38,12 +38,12 @@ module Capybara::Webkit
def start_server def start_server
open_pipe open_pipe
discover_port discover_port
forward_stdout_in_background_thread forward_output_in_background_thread
end end
def open_pipe def open_pipe
@pipe = IO.popen(@command) _, @pipe_stdout, @pipe_stderr, wait_thr = Open3.popen3(SERVER_PATH)
@pid = @pipe.pid @pid = wait_thr[:pid]
register_shutdown_hook register_shutdown_hook
end end
@ -65,40 +65,19 @@ module Capybara::Webkit
end end
def discover_port def discover_port
if IO.select([@pipe], nil, nil, WEBKIT_SERVER_START_TIMEOUT) if IO.select([@pipe_stdout], nil, nil, WEBKIT_SERVER_START_TIMEOUT)
@port = ((@pipe.first || '').match(/listening on port: (\d+)/) || [])[1].to_i @port = ((@pipe_stdout.first || '').match(/listening on port: (\d+)/) || [])[1].to_i
end end
end end
def forward_stdout_in_background_thread def forward_output_in_background_thread
@stdout_thread = Thread.new do Thread.new do
Thread.current.abort_on_exception = true Thread.current.abort_on_exception = true
forward_stdout IO.copy_stream(@pipe_stdout, @output_target)
end end
end Thread.new do
Thread.current.abort_on_exception = true
def forward_stdout IO.copy_stream(@pipe_stderr, @output_target)
while pipe_readable?
line = @pipe.readline
if @stdout
@stdout.write(line)
@stdout.flush
end
end
rescue EOFError
end
if !defined?(RUBY_ENGINE) || (RUBY_ENGINE == "ruby" && RUBY_VERSION <= "1.8")
# please note the use of IO::select() here, as it is used specifically to
# preserve correct signal handling behavior in ruby 1.8.
# https://github.com/thibaudgg/rb-fsevent/commit/d1a868bf8dc72dbca102bedbadff76c7e6c2dc21
# https://github.com/thibaudgg/rb-fsevent/blob/1ca42b987596f350ee7b19d8f8210b7b6ae8766b/ext/fsevent/fsevent_watch.c#L171
def pipe_readable?
IO.select([@pipe])
end
else
def pipe_readable?
!@pipe.eof?
end end
end end

View file

@ -22,12 +22,14 @@ describe Capybara::Webkit::Connection do
io = StringIO.new io = StringIO.new
redirected_connection = Capybara::Webkit::Connection.new(:stdout => io) redirected_connection = Capybara::Webkit::Connection.new(:stdout => io)
script = 'console.log("hello world")' script = 'console.log("hello world")'
redirected_connection.puts "EnableLogging"
redirected_connection.puts 0
redirected_connection.puts "Execute" redirected_connection.puts "Execute"
redirected_connection.puts 1 redirected_connection.puts 1
redirected_connection.puts script.to_s.bytesize redirected_connection.puts script.to_s.bytesize
redirected_connection.print script redirected_connection.print script
sleep(0.5) sleep(0.5)
io.string.should include "hello world\n" io.string.should include "hello world \n"
end end
it "returns the server port" do it "returns the server port" do

View file

@ -2042,8 +2042,7 @@ describe Capybara::Webkit::Driver do
end end
let(:driver) do let(:driver) do
command = "#{Capybara::Webkit::Connection::SERVER_PATH} 2>&1" connection = Capybara::Webkit::Connection.new(:stdout => output)
connection = Capybara::Webkit::Connection.new(:command => command, :stdout => output)
browser = Capybara::Webkit::Browser.new(connection) browser = Capybara::Webkit::Browser.new(connection)
Capybara::Webkit::Driver.new(AppRunner.app, :browser => browser) Capybara::Webkit::Driver.new(AppRunner.app, :browser => browser)
end end

View file

@ -22,7 +22,7 @@ RSpec.configure do |c|
end end
require 'capybara/webkit' require 'capybara/webkit'
connection = Capybara::Webkit::Connection.new(:socket_class => TCPSocket, :stdout => nil) connection = Capybara::Webkit::Connection.new(:socket_class => TCPSocket)
$webkit_browser = Capybara::Webkit::Browser.new(connection) $webkit_browser = Capybara::Webkit::Browser.new(connection)
if ENV['DEBUG'] if ENV['DEBUG']

View file

@ -139,13 +139,13 @@ void WebPage::javaScriptConsoleMessage(const QString &message, int lineNumber, c
if (!sourceID.isEmpty()) if (!sourceID.isEmpty())
fullMessage = sourceID + "|" + QString::number(lineNumber) + "|" + fullMessage; fullMessage = sourceID + "|" + QString::number(lineNumber) + "|" + fullMessage;
m_consoleMessages.append(fullMessage.replace("\n", "\\n")); m_consoleMessages.append(fullMessage.replace("\n", "\\n"));
std::cout << qPrintable(fullMessage) << std::endl; m_manager->logger() << qPrintable(fullMessage);
} }
void WebPage::javaScriptAlert(QWebFrame *frame, const QString &message) { void WebPage::javaScriptAlert(QWebFrame *frame, const QString &message) {
Q_UNUSED(frame); Q_UNUSED(frame);
m_alertMessages.append(message); m_alertMessages.append(message);
std::cout << "ALERT: " << qPrintable(message) << std::endl; m_manager->logger() << "ALERT:" << qPrintable(message);
} }
bool WebPage::javaScriptConfirm(QWebFrame *frame, const QString &message) { bool WebPage::javaScriptConfirm(QWebFrame *frame, const QString &message) {