2011-07-08 09:17:38 -04:00
|
|
|
require 'spec_helper'
|
2011-09-28 16:41:13 -04:00
|
|
|
require 'self_signed_ssl_cert'
|
2011-08-15 12:17:14 -04:00
|
|
|
require 'stringio'
|
2012-07-08 15:17:08 -04:00
|
|
|
require 'capybara/webkit/driver'
|
2011-09-24 17:55:18 -04:00
|
|
|
require 'socket'
|
|
|
|
require 'base64'
|
2011-07-06 08:30:52 -04:00
|
|
|
|
2012-07-08 15:17:08 -04:00
|
|
|
describe Capybara::Webkit::Browser do
|
2011-07-06 08:30:52 -04:00
|
|
|
|
2013-05-21 07:58:46 -04:00
|
|
|
let(:connection) { Capybara::Webkit::Connection.new }
|
|
|
|
let(:browser) { Capybara::Webkit::Browser.new(connection) }
|
2012-05-04 15:50:30 -04:00
|
|
|
let(:browser_ignore_ssl_err) do
|
2012-07-08 15:17:08 -04:00
|
|
|
Capybara::Webkit::Browser.new(Capybara::Webkit::Connection.new).tap do |browser|
|
2012-05-04 15:50:30 -04:00
|
|
|
browser.ignore_ssl_errors
|
2011-07-06 08:30:52 -04:00
|
|
|
end
|
|
|
|
end
|
2012-03-29 21:38:34 -04:00
|
|
|
let(:browser_skip_images) do
|
2012-07-08 15:17:08 -04:00
|
|
|
Capybara::Webkit::Browser.new(Capybara::Webkit::Connection.new).tap do |browser|
|
2012-03-29 21:38:34 -04:00
|
|
|
browser.set_skip_image_loading(true)
|
|
|
|
end
|
|
|
|
end
|
2011-10-14 15:49:07 -04:00
|
|
|
|
2011-09-28 16:41:13 -04:00
|
|
|
context 'handling of SSL validation errors' do
|
|
|
|
before do
|
|
|
|
# set up minimal HTTPS server
|
|
|
|
@host = "127.0.0.1"
|
2011-09-29 08:45:23 -04:00
|
|
|
@server = TCPServer.new(@host, 0)
|
|
|
|
@port = @server.addr[1]
|
2011-09-28 16:41:13 -04:00
|
|
|
|
|
|
|
# set up SSL layer
|
2011-09-29 08:45:23 -04:00
|
|
|
ssl_serv = OpenSSL::SSL::SSLServer.new(@server, $openssl_self_signed_ctx)
|
2011-09-28 16:41:13 -04:00
|
|
|
|
2011-09-29 08:45:23 -04:00
|
|
|
@server_thread = Thread.new(ssl_serv) do |serv|
|
2011-09-28 16:41:13 -04:00
|
|
|
while conn = serv.accept do
|
|
|
|
# read request
|
|
|
|
request = []
|
|
|
|
until (line = conn.readline.strip).empty?
|
|
|
|
request << line
|
|
|
|
end
|
|
|
|
|
|
|
|
# write response
|
|
|
|
html = "<html><body>D'oh!</body></html>"
|
|
|
|
conn.write "HTTP/1.1 200 OK\r\n"
|
|
|
|
conn.write "Content-Type:text/html\r\n"
|
|
|
|
conn.write "Content-Length: %i\r\n" % html.size
|
|
|
|
conn.write "\r\n"
|
|
|
|
conn.write html
|
|
|
|
conn.close
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-09-28 20:40:13 -04:00
|
|
|
after do
|
|
|
|
@server_thread.kill
|
2011-10-14 13:40:14 -04:00
|
|
|
@server.close
|
2011-09-28 20:40:13 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it "doesn't accept a self-signed certificate by default" do
|
2011-09-28 16:41:13 -04:00
|
|
|
lambda { browser.visit "https://#{@host}:#{@port}/" }.should raise_error
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'accepts a self-signed certificate if configured to do so' do
|
|
|
|
browser_ignore_ssl_err.visit "https://#{@host}:#{@port}/"
|
|
|
|
end
|
2012-03-30 15:00:51 -04:00
|
|
|
|
|
|
|
it "doesn't accept a self-signed certificate in a new window by default" do
|
|
|
|
browser.execute_script("window.open('about:blank')")
|
|
|
|
browser.window_focus(browser.get_window_handles.last)
|
|
|
|
lambda { browser.visit "https://#{@host}:#{@port}/" }.should raise_error
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'accepts a self-signed certificate in a new window if configured to do so' do
|
|
|
|
browser_ignore_ssl_err.execute_script("window.open('about:blank')")
|
|
|
|
browser_ignore_ssl_err.window_focus(browser_ignore_ssl_err.get_window_handles.last)
|
|
|
|
browser_ignore_ssl_err.visit "https://#{@host}:#{@port}/"
|
|
|
|
end
|
2011-09-28 16:41:13 -04:00
|
|
|
end
|
2011-10-06 11:07:20 -04:00
|
|
|
|
2012-03-29 21:38:34 -04:00
|
|
|
context "skip image loading" do
|
|
|
|
before(:each) do
|
|
|
|
# set up minimal HTTP server
|
|
|
|
@host = "127.0.0.1"
|
|
|
|
@server = TCPServer.new(@host, 0)
|
|
|
|
@port = @server.addr[1]
|
|
|
|
@received_requests = []
|
|
|
|
|
2012-05-14 21:25:08 -04:00
|
|
|
@server_thread = Thread.new do
|
|
|
|
while conn = @server.accept
|
2013-08-11 10:37:33 -04:00
|
|
|
Thread.new(conn) do |thread_conn|
|
2012-05-14 21:25:08 -04:00
|
|
|
# read request
|
|
|
|
request = []
|
2013-08-11 10:37:33 -04:00
|
|
|
until (line = thread_conn.readline.strip).empty?
|
2012-05-14 21:25:08 -04:00
|
|
|
request << line
|
|
|
|
end
|
|
|
|
|
|
|
|
@received_requests << request.join("\n")
|
|
|
|
|
|
|
|
# write response
|
|
|
|
html = <<-HTML
|
2012-03-29 21:38:34 -04:00
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<style>
|
|
|
|
body {
|
|
|
|
background-image: url(/path/to/bgimage);
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<img src="/path/to/image"/>
|
|
|
|
</body>
|
|
|
|
</html>
|
2012-05-14 21:25:08 -04:00
|
|
|
HTML
|
2013-08-11 10:37:33 -04:00
|
|
|
thread_conn.write "HTTP/1.1 200 OK\r\n"
|
|
|
|
thread_conn.write "Content-Type:text/html\r\n"
|
|
|
|
thread_conn.write "Content-Length: %i\r\n" % html.size
|
|
|
|
thread_conn.write "\r\n"
|
|
|
|
thread_conn.write html
|
|
|
|
thread_conn.write("\r\n\r\n")
|
|
|
|
thread_conn.close
|
2012-05-14 21:25:08 -04:00
|
|
|
end
|
2012-03-29 21:38:34 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
after(:each) do
|
|
|
|
@server_thread.kill
|
|
|
|
@server.close
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should load images in image tags by default" do
|
|
|
|
browser.visit("http://#{@host}:#{@port}/")
|
|
|
|
@received_requests.find {|r| r =~ %r{/path/to/image} }.should_not be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should load images in css by default" do
|
|
|
|
browser.visit("http://#{@host}:#{@port}/")
|
|
|
|
@received_requests.find {|r| r =~ %r{/path/to/image} }.should_not be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should not load images in image tags when skip_image_loading is true" do
|
|
|
|
browser_skip_images.visit("http://#{@host}:#{@port}/")
|
|
|
|
@received_requests.find {|r| r =~ %r{/path/to/image} }.should be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should not load images in css when skip_image_loading is true" do
|
|
|
|
browser_skip_images.visit("http://#{@host}:#{@port}/")
|
|
|
|
@received_requests.find {|r| r =~ %r{/path/to/bgimage} }.should be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-01-28 19:17:16 -05:00
|
|
|
describe "forking", skip_on_windows: true, skip_on_jruby: true do
|
2011-10-14 15:49:07 -04:00
|
|
|
it "only shuts down the server from the main process" do
|
|
|
|
browser.reset!
|
|
|
|
pid = fork {}
|
|
|
|
Process.wait(pid)
|
|
|
|
expect { browser.reset! }.not_to raise_error
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-09-24 17:55:18 -04:00
|
|
|
describe '#set_proxy' do
|
|
|
|
before do
|
|
|
|
@host = '127.0.0.1'
|
|
|
|
@user = 'user'
|
|
|
|
@pass = 'secret'
|
|
|
|
@url = "http://example.org/"
|
|
|
|
|
2011-09-29 08:50:59 -04:00
|
|
|
@server = TCPServer.new(@host, 0)
|
|
|
|
@port = @server.addr[1]
|
2011-09-24 17:55:18 -04:00
|
|
|
|
|
|
|
@proxy_requests = []
|
2011-09-29 08:50:59 -04:00
|
|
|
@proxy = Thread.new(@server, @proxy_requests) do |serv, proxy_requests|
|
2011-09-24 17:55:18 -04:00
|
|
|
while conn = serv.accept do
|
|
|
|
# read request
|
|
|
|
request = []
|
|
|
|
until (line = conn.readline.strip).empty?
|
|
|
|
request << line
|
|
|
|
end
|
|
|
|
|
|
|
|
# send response
|
|
|
|
auth_header = request.find { |h| h =~ /Authorization:/i }
|
|
|
|
if auth_header || request[0].split(/\s+/)[1] =~ /^\//
|
|
|
|
html = "<html><body>D'oh!</body></html>"
|
|
|
|
conn.write "HTTP/1.1 200 OK\r\n"
|
|
|
|
conn.write "Content-Type:text/html\r\n"
|
|
|
|
conn.write "Content-Length: %i\r\n" % html.size
|
|
|
|
conn.write "\r\n"
|
|
|
|
conn.write html
|
|
|
|
conn.close
|
|
|
|
proxy_requests << request if auth_header
|
|
|
|
else
|
|
|
|
conn.write "HTTP/1.1 407 Proxy Auth Required\r\n"
|
|
|
|
conn.write "Proxy-Authenticate: Basic realm=\"Proxy\"\r\n"
|
|
|
|
conn.write "\r\n"
|
|
|
|
conn.close
|
|
|
|
proxy_requests << request
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
browser.set_proxy(:host => @host,
|
|
|
|
:port => @port,
|
|
|
|
:user => @user,
|
|
|
|
:pass => @pass)
|
|
|
|
browser.visit @url
|
2013-08-11 10:36:53 -04:00
|
|
|
@proxy_requests.size.should eq 2
|
2011-09-24 17:55:18 -04:00
|
|
|
@request = @proxy_requests[-1]
|
|
|
|
end
|
|
|
|
|
|
|
|
after do
|
|
|
|
@proxy.kill
|
2011-10-14 13:38:12 -04:00
|
|
|
@server.close
|
2011-09-24 17:55:18 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'uses the HTTP proxy correctly' do
|
2013-08-11 10:37:59 -04:00
|
|
|
@request[0].should match(/^GET\s+http:\/\/example.org\/\s+HTTP/i)
|
2011-09-24 17:55:18 -04:00
|
|
|
@request.find { |header|
|
|
|
|
header =~ /^Host:\s+example.org$/i }.should_not be nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sends correct proxy authentication' do
|
|
|
|
auth_header = @request.find { |header|
|
|
|
|
header =~ /^Proxy-Authorization:\s+/i }
|
|
|
|
auth_header.should_not be nil
|
|
|
|
|
|
|
|
user, pass = Base64.decode64(auth_header.split(/\s+/)[-1]).split(":")
|
2013-08-11 10:36:53 -04:00
|
|
|
user.should eq @user
|
|
|
|
pass.should eq @pass
|
2011-09-24 17:55:18 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it "uses the proxies' response" do
|
|
|
|
browser.body.should include "D'oh!"
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'uses original URL' do
|
2013-08-11 10:36:53 -04:00
|
|
|
browser.current_url.should eq @url
|
2011-09-24 17:55:18 -04:00
|
|
|
end
|
|
|
|
|
2011-11-15 21:11:37 -05:00
|
|
|
it 'uses URLs changed by javascript' do
|
|
|
|
browser.execute_script "window.history.pushState('', '', '/blah')"
|
2013-08-11 10:36:53 -04:00
|
|
|
browser.current_url.should eq 'http://example.org/blah'
|
2011-11-15 21:11:37 -05:00
|
|
|
end
|
|
|
|
|
2011-09-24 17:55:18 -04:00
|
|
|
it 'is possible to disable proxy again' do
|
|
|
|
@proxy_requests.clear
|
2011-10-14 17:13:06 -04:00
|
|
|
browser.clear_proxy
|
2011-09-24 17:55:18 -04:00
|
|
|
browser.visit "http://#{@host}:#{@port}/"
|
2013-08-11 10:36:53 -04:00
|
|
|
@proxy_requests.size.should eq 0
|
2011-09-24 17:55:18 -04:00
|
|
|
end
|
|
|
|
end
|
2012-05-04 16:00:21 -04:00
|
|
|
|
|
|
|
it "doesn't try to read an empty response" do
|
2013-08-11 10:38:19 -04:00
|
|
|
connection = double("connection")
|
2012-05-04 16:00:21 -04:00
|
|
|
connection.stub(:puts)
|
|
|
|
connection.stub(:print)
|
|
|
|
connection.stub(:gets).and_return("ok\n", "0\n")
|
|
|
|
connection.stub(:read).and_raise(StandardError.new("tried to read empty response"))
|
|
|
|
|
2012-07-08 15:17:08 -04:00
|
|
|
browser = Capybara::Webkit::Browser.new(connection)
|
2012-05-04 16:00:21 -04:00
|
|
|
|
2013-08-11 10:38:42 -04:00
|
|
|
expect { browser.visit("/") }.not_to raise_error
|
2012-05-04 16:00:21 -04:00
|
|
|
end
|
2013-05-21 07:58:46 -04:00
|
|
|
|
|
|
|
describe '#command' do
|
|
|
|
context 'non-ok response' do
|
|
|
|
it 'raises an error of given class' do
|
|
|
|
error_json = '{"class": "ClickFailed"}'
|
|
|
|
|
|
|
|
connection.should_receive(:gets).ordered.and_return 'error'
|
|
|
|
connection.should_receive(:gets).ordered.and_return error_json.bytesize
|
|
|
|
connection.stub read: error_json
|
|
|
|
|
|
|
|
expect { browser.command 'blah', 'meh' }.to raise_error(Capybara::Webkit::ClickFailed)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2011-07-06 08:30:52 -04:00
|
|
|
end
|