diff --git a/CHANGELOG.md b/CHANGELOG.md index b2849b7..cc4758b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ * Fix click checking when svg element is overlapping (Thomas Walpole) [Issue #616] * Fix null status code when some pages redirect (Thomas Walpole) [Issue #524] * Fix cases where page isn't always scrolled when needed for a mouse click (Thomas Walpole) [Issue #520] +* Add scheme to URL passed to browser by inspector to support the "open" + command (Nuru) [Issue #579] +* Support resuming from debug pause by sending a signal (Nuru) [Issue #654] + ### 1.7.0 ### diff --git a/lib/capybara/poltergeist/driver.rb b/lib/capybara/poltergeist/driver.rb index 7140bc7..98d3446 100644 --- a/lib/capybara/poltergeist/driver.rb +++ b/lib/capybara/poltergeist/driver.rb @@ -288,7 +288,10 @@ module Capybara::Poltergeist def debug if @options[:inspector] - inspector.open + # Fall back to default scheme + scheme = URI.parse(browser.current_url).scheme rescue nil + scheme = 'http' if scheme != 'https' + inspector.open(scheme) pause else raise Error, "To use the remote debugging, you have to launch the driver " \ @@ -297,8 +300,23 @@ module Capybara::Poltergeist end def pause - STDERR.puts "Poltergeist execution paused. Press enter to continue." - STDIN.gets + # STDIN is not necessarily connected to a keyboard. It might even be closed. + # So we need a method other than keypress to continue. + STDERR.puts "Poltergeist execution paused. Press enter (or run 'kill -CONT #{Process.pid}') to continue." + + signal = false + old_trap = trap('SIGCONT') { signal = true; STDERR.puts "\nSignal SIGCONT received" } + keyboard = IO.select([STDIN], nil, nil, 1) until keyboard || signal # wait for data on STDIN or signal SIGCONT received + + begin + input = STDIN.read_nonblock(80) # clear out the read buffer + puts unless input && input =~ /\n\z/ + rescue EOFError, IO::WaitReadable # Ignore problems reading from STDIN. + end unless signal + + trap('SIGCONT', old_trap) # Restore the previuos signal handler, if there was one. + + STDERR.puts 'Continuing' end def wait? diff --git a/lib/capybara/poltergeist/inspector.rb b/lib/capybara/poltergeist/inspector.rb index a5a3934..0f4f3cf 100644 --- a/lib/capybara/poltergeist/inspector.rb +++ b/lib/capybara/poltergeist/inspector.rb @@ -18,15 +18,15 @@ module Capybara::Poltergeist @browser ||= self.class.detect_browser end - def url - "//localhost:#{port}/" + def url(scheme) + "#{scheme}://localhost:#{port}/" end - def open + def open(scheme) if browser - Process.spawn(browser, url) + Process.spawn(browser, url(scheme)) else - raise Error, "Could not find a browser executable to open #{url}. " \ + raise Error, "Could not find a browser executable to open #{url(scheme)}. " \ "You can specify one manually using e.g. `:inspector => 'chromium'` " \ "as a configuration option for Poltergeist." end diff --git a/spec/unit/driver_spec.rb b/spec/unit/driver_spec.rb index 0c26b76..dc5abd6 100644 --- a/spec/unit/driver_spec.rb +++ b/spec/unit/driver_spec.rb @@ -66,6 +66,32 @@ module Capybara::Poltergeist expect(subject.inspector).to be_a(Inspector) expect(subject.inspector.browser).to eq('foo') end + + it 'can pause indefinitely' do + expect { + Timeout::timeout(3) do + subject.pause + end + }.to raise_error(Timeout::Error) + end + + it 'can pause and resume with keyboard input' do + IO.pipe do |read_io, write_io| + stub_const('STDIN', read_io) + write_io.write "\n" + Timeout::timeout(3) do + subject.pause + end + end + end + + it 'can pause and resume with signal' do + Thread.new { sleep(2); Process.kill('CONT', Process.pid); } + Timeout::timeout(4) do + subject.pause + end + end + end context 'with a :timeout option' do diff --git a/spec/unit/inspector_spec.rb b/spec/unit/inspector_spec.rb index 9da227d..2ab74ee 100644 --- a/spec/unit/inspector_spec.rb +++ b/spec/unit/inspector_spec.rb @@ -14,20 +14,25 @@ module Capybara::Poltergeist it 'has a url' do subject = Inspector.new(nil, 1234) - expect(subject.url).to eq('//localhost:1234/') + expect(subject.url('http')).to eq('http://localhost:1234/') end it 'can be opened' do subject = Inspector.new('chromium', 1234) - expect(Process).to receive(:spawn).with('chromium', '//localhost:1234/') - subject.open + expect(Process).to receive(:spawn).with('chromium', 'http://localhost:1234/') + subject.open('http') + end + + it 'can be opened with https URL' do + subject = Inspector.new('chromium', 1234) + allow(Process).to receive(:spawn).with('chromium', 'https://localhost:1234/') + subject.open('https') end it 'raises an error on open when the browser is unknown' do subject = Inspector.new(nil, 1234) allow(subject).to receive_messages(browser: nil) - - expect { subject.open }.to raise_error(Capybara::Poltergeist::Error) + expect { subject.open('http') }.to raise_error(Capybara::Poltergeist::Error) end end end