Introduce API for global configuration

Users were generally confused about where to configure things like
allowed URLs. Because they were reset in between each sessions, they
needed to be applied repeatedly in a before block.

This introduces an API for global configuration, which will be applied
for every session. It also deprecates the per-session configuration
methods, as those are less likely to be useful.
This commit is contained in:
Joe Ferris 2015-04-10 17:00:32 -04:00
parent bcbcdabd37
commit 519d90306b
8 changed files with 490 additions and 281 deletions

View File

@ -82,6 +82,60 @@ If you're using capybara-webkit with Sinatra, don't forget to set
Capybara.app = MySinatraApp.new
```
Configuration
-------------
You can configure global options using `Capybara::Webkit.configure`:
``` ruby
Capybara::Webkit.configure do |config|
# Enable debug mode. Prints a log of everything the driver is doing.
config.debug = true
# By default, requests to outside domains (anything besides localhost) will
# result in a warning. Several methods allow you to change this behavior.
# Silently return an empty 200 response for any requests to unknown URLs.
config.block_unknown_urls
# Allow pages to make requests to any URL without issuing a warning.
config.allow_unknown_urls
# Allow a specifc domain without issuing a warning.
config.allow_url("example.com")
# Allow a specifc URL and path without issuing a warning.
config.allow_url("example.com/some/path")
# Wildcards are allowed in URL expressions.
config.allow_url("*.example.com")
# Silently return an empty 200 response for any requests to the given URL.
config.block_url("example.com")
# Timeout if requests take longer than 5 seconds
config.timeout = 5
# Don't raise errors when SSL certificates can't be validated
config.ignore_ssl_errors
# Don't load images
config.skip_image_loading
# Use a proxy
config.use_proxy(
host: "example.com",
port: 1234,
user: "proxy",
pass: "secret"
)
end
```
These options will take effect for all future sessions and only need to be set
once. It's recommended that you configure these in your `spec_helper.rb` or
`test_helper.rb` rather than a `before` or `setup` block.
Offline Application Cache
-------------------------
@ -127,24 +181,6 @@ page.driver.cookies["alpha"]
page.driver.header 'Referer', 'https://www.thoughtbot.com'
```
**block_unknown_urls**: By default, capybara-webkit will warn when a request is made to a URL other than 127.0.0.1 or localhost. This option will block such unknown URLs instead.
```ruby
page.driver.block_unknown_urls
```
**allow_url**: Allow requests to a URL. This will silence unknown URL warnings, or permit requests to a URL when `block_unknown_urls` is used. Allowed URLs are reset on `Driver#reset!`.
```ruby
page.driver.allow_url 'example.com/*.js'
```
**allow_unknown_urls**: Allow requests to all URLs. This will silence unknown URL warnings, or permit requests to all URLs when `block_unknown_urls` is used. Allowed URLs are reset on `Driver#reset!`.
```ruby
page.driver.allow_unknown_urls
```
Contributing
------------

View File

@ -2,17 +2,22 @@ require "capybara"
module Capybara
module Webkit
def self.configure(&block)
Capybara::Webkit::Configuration.modify(&block)
end
end
end
require "capybara/webkit/driver"
require "capybara/webkit/configuration"
Capybara.register_driver :webkit do |app|
Capybara::Webkit::Driver.new(app)
Capybara::Webkit::Driver.new(app, Capybara::Webkit::Configuration.to_hash)
end
Capybara.register_driver :webkit_debug do |app|
driver = Capybara::Webkit::Driver.new(app)
driver.enable_logging
driver
Capybara::Webkit::Driver.new(
app,
Capybara::Webkit::Configuration.to_hash.merge(debug: true)
)
end

View File

@ -0,0 +1,98 @@
module Capybara
module Webkit
class Configuration
class << self
private
def instance
@instance ||= new
end
end
def self.to_hash
instance.freeze.to_hash
end
def self.modify
if instance.frozen?
raise "All configuration must take place before the driver starts"
else
yield instance
end
end
attr_accessor :allowed_urls
attr_writer :block_unknown_urls
attr_accessor :blocked_urls
attr_accessor :debug
attr_writer :ignore_ssl_errors
attr_accessor :proxy
attr_accessor :timeout
attr_writer :skip_image_loading
def initialize
@allowed_urls = []
@blocked_urls = []
@block_unknown_urls = false
@debug = false
@ignore_ssl_errors = false
@proxy = nil
@skip_image_loading = false
@timeout = -1
end
def allow_url(url)
@allowed_urls << url
end
def block_url(url)
@blocked_urls << url
end
def block_unknown_urls
@block_unknown_urls = true
end
def block_unknown_urls?
@block_unknown_urls
end
def allow_unknown_urls
allow_url("*")
end
def ignore_ssl_errors
@ignore_ssl_errors = true
end
def ignore_ssl_errors?
@ignore_ssl_errors
end
def skip_image_loading
@skip_image_loading = true
end
def skip_image_loading?
@skip_image_loading
end
def use_proxy(proxy)
@proxy = proxy
end
def to_hash
{
allowed_urls: allowed_urls,
block_unknown_urls: block_unknown_urls?,
blocked_urls: blocked_urls,
debug: debug,
ignore_ssl_errors: ignore_ssl_errors?,
proxy: proxy,
skip_image_loading: skip_image_loading?,
timeout: timeout
}
end
end
end
end

View File

@ -12,25 +12,31 @@ module Capybara::Webkit
@app = app
@options = options
@browser = options[:browser] || Browser.new(Connection.new(options))
apply_options
end
def enable_logging
deprecate_and_replace_with_config "enable_logging", "debug = true"
@browser.enable_logging
end
def allow_url(url)
deprecate_and_replace_with_config "allow_url", "allow_url(#{url.inspect})"
@browser.allow_url(url)
end
def block_url(url)
deprecate_and_replace_with_config "block_url", "block_url(#{url.inspect})"
@browser.block_url(url)
end
def block_unknown_urls
deprecate_and_replace_with_config "block_unknown_urls"
@browser.block_unknown_urls
end
def allow_unknown_urls
deprecate_and_replace_with_config "allow_unknown_urls"
@browser.allow_url("*")
end
@ -254,6 +260,7 @@ module Capybara::Webkit
def reset!
@browser.reset!
apply_options
end
def has_shortcircuit_timeout?
@ -300,10 +307,15 @@ module Capybara::Webkit
end
def timeout
deprecate_and_replace_with_config "timeout"
@browser.timeout
end
def timeout=(timeout)
deprecate_and_replace_with_config(
"timeout=",
"timeout = #{timeout.inspect}"
)
@browser.timeout = timeout
end
@ -333,5 +345,44 @@ module Capybara::Webkit
raise Capybara::ModalNotFound,
"Timed out waiting for modal dialog#{" with #{options[:original_text]}" if options[:original_text]}"
end
def apply_options
if @options[:debug]
@browser.enable_logging
end
if @options[:block_unknown_urls]
@browser.block_unknown_urls
end
if @options[:ignore_ssl_errors]
@browser.ignore_ssl_errors
end
if @options[:skip_image_loading]
@browser.set_skip_image_loading(true)
end
if @options[:proxy]
@browser.set_proxy(@options[:proxy])
end
if @options[:timeout]
@browser.timeout = @options[:timeout]
end
Array(@options[:allowed_urls]).each { |url| @browser.allow_url(url) }
Array(@options[:blocked_urls]).each { |url| @browser.block_url(url) }
end
def deprecate_and_replace_with_config(deprecated_method, config_syntax = deprecated_method)
warn "[DEPRECATION] #{deprecated_method} is deprecated. " \
"Please use Capybara::Webkit.configure instead:\n\n" \
" Capybara::Webkit.configure do |config|\n" \
" config.#{config_syntax}\n" \
" end\n\n" \
"This option is global and can be configured once" \
" (not in a `before` or `setup` block)."
end
end
end

View File

@ -9,144 +9,6 @@ describe Capybara::Webkit::Browser do
let(:connection) { Capybara::Webkit::Connection.new }
let(:browser) { Capybara::Webkit::Browser.new(connection) }
let(:browser_ignore_ssl_err) do
Capybara::Webkit::Browser.new(Capybara::Webkit::Connection.new).tap do |browser|
browser.ignore_ssl_errors
end
end
let(:browser_skip_images) do
Capybara::Webkit::Browser.new(Capybara::Webkit::Connection.new).tap do |browser|
browser.set_skip_image_loading(true)
end
end
context 'handling of SSL validation errors' do
before do
# set up minimal HTTPS server
@host = "127.0.0.1"
@server = TCPServer.new(@host, 0)
@port = @server.addr[1]
# set up SSL layer
ssl_serv = OpenSSL::SSL::SSLServer.new(@server, $openssl_self_signed_ctx)
@server_thread = Thread.new(ssl_serv) do |serv|
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
after do
@server_thread.kill
@server.close
end
it "doesn't accept a self-signed certificate by default" do
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
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
end
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 = []
@server_thread = Thread.new do
while conn = @server.accept
Thread.new(conn) do |thread_conn|
# read request
request = []
until (line = thread_conn.readline.strip).empty?
request << line
end
@received_requests << request.join("\n")
# write response
html = <<-HTML
<html>
<head>
<style>
body {
background-image: url(/path/to/bgimage);
}
</style>
</head>
<body>
<img src="/path/to/image"/>
</body>
</html>
HTML
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
end
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
describe "forking", skip_on_windows: true, skip_on_jruby: true do
it "only shuts down the server from the main process" do
@ -157,97 +19,6 @@ describe Capybara::Webkit::Browser do
end
end
describe '#set_proxy' do
before do
@host = '127.0.0.1'
@user = 'user'
@pass = 'secret'
@url = "http://example.org/"
@server = TCPServer.new(@host, 0)
@port = @server.addr[1]
@proxy_requests = []
@proxy = Thread.new(@server, @proxy_requests) do |serv, proxy_requests|
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
@proxy_requests.size.should eq 2
@request = @proxy_requests[-1]
end
after do
@proxy.kill
@server.close
end
it 'uses the HTTP proxy correctly' do
@request[0].should match(/^GET\s+http:\/\/example.org\/\s+HTTP/i)
@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(":")
user.should eq @user
pass.should eq @pass
end
it "uses the proxies' response" do
browser.body.should include "D'oh!"
end
it 'uses original URL' do
browser.current_url.should eq @url
end
it 'uses URLs changed by javascript' do
browser.execute_script "window.history.pushState('', '', '/blah')"
browser.current_url.should eq 'http://example.org/blah'
end
it 'is possible to disable proxy again' do
@proxy_requests.clear
browser.clear_proxy
browser.visit "http://#{@host}:#{@port}/"
@proxy_requests.size.should eq 0
end
end
it "doesn't try to read an empty response" do
connection = double("connection")
connection.stub(:puts)

View File

@ -0,0 +1,16 @@
require "spec_helper"
describe Capybara::Webkit::Configuration do
it "returns a hash and then prevents future modification" do
Capybara::Webkit.configure do |config|
config.debug = true
end
result = Capybara::Webkit::Configuration.to_hash
expect(result).to include(debug: true)
expect { Capybara::Webkit.configure {} }.to raise_error(
"All configuration must take place before the driver starts"
)
end
end

View File

@ -3,6 +3,7 @@
require 'spec_helper'
require 'capybara/webkit/driver'
require 'base64'
require 'self_signed_ssl_cert'
describe Capybara::Webkit::Driver do
include AppRunner
@ -1808,7 +1809,7 @@ describe Capybara::Webkit::Driver do
context "no response app" do
let(:driver) do
driver_for_html(<<-HTML, browser)
driver_for_html(<<-HTML, browser: browser)
<html><body>
<form action="/error"><input type="submit"/></form>
</body></html>
@ -2657,10 +2658,12 @@ CACHE MANIFEST
end
before do
driver.block_url "http://example.org/path/to/file"
driver.block_url "http://example.*/foo/*"
driver.block_url "http://example.com"
driver.block_url "#{AppRunner.app_host}/script"
configure do |config|
config.block_url "http://example.org/path/to/file"
config.block_url "http://example.*/foo/*"
config.block_url "http://example.com"
config.block_url "#{AppRunner.app_host}/script"
end
end
it "should not fetch urls blocked by host" do
@ -2707,7 +2710,7 @@ CACHE MANIFEST
describe "url whitelisting", skip_if_offline: true do
it_behaves_like "output writer" do
let(:driver) do
driver_for_html(<<-HTML, browser)
driver_for_html(<<-HTML, browser: browser)
<<-HTML
<html>
<body>
@ -2727,8 +2730,11 @@ CACHE MANIFEST
end
it "can allow specific hosts" do
driver.allow_url("example.com")
driver.allow_url("www.example.com")
configure do |config|
config.allow_url("example.com")
config.allow_url("www.example.com")
end
visit("/")
expect(stderr).not_to include("http://example.com/path")
@ -2739,7 +2745,7 @@ CACHE MANIFEST
end
it "can allow all hosts" do
driver.allow_unknown_urls
configure(&:allow_unknown_urls)
visit("/")
expect(stderr).not_to include("http://example.com/path")
@ -2759,7 +2765,7 @@ CACHE MANIFEST
end
it "can block unknown hosts" do
driver.block_unknown_urls
configure(&:block_unknown_urls)
visit("/")
expect(stderr).not_to include("http://example.com/path")
@ -2770,7 +2776,7 @@ CACHE MANIFEST
end
it "can allow urls with wildcards" do
driver.allow_url("*/path")
configure { |config| config.allow_url("*/path") }
visit("/")
expect(stderr).to include("www.example.com")
@ -2820,29 +2826,29 @@ CACHE MANIFEST
end
it "should not raise a timeout error when zero" do
driver.timeout = 0
configure { |config| config.timeout = 0 }
lambda { visit("/") }.should_not raise_error
end
it "should raise a timeout error" do
driver.timeout = 1
configure { |config| config.timeout = 1 }
lambda { visit("/") }.should raise_error(Timeout::Error, "Request timed out after 1 second(s)")
end
it "should not raise an error when the timeout is high enough" do
driver.timeout = 10
configure { |config| config.timeout = 10 }
lambda { visit("/") }.should_not raise_error
end
it "should set the timeout for each request" do
driver.timeout = 10
configure { |config| config.timeout = 10 }
lambda { visit("/") }.should_not raise_error
driver.timeout = 1
lambda { visit("/") }.should raise_error(Timeout::Error)
end
it "should set the timeout for each request" do
driver.timeout = 1
configure { |config| config.timeout = 1 }
lambda { visit("/") }.should raise_error(Timeout::Error)
driver.reset!
driver.timeout = 10
@ -2850,7 +2856,7 @@ CACHE MANIFEST
end
it "should raise a timeout on a slow form" do
driver.timeout = 3
configure { |config| config.timeout = 3 }
visit("/")
driver.status_code.should eq 200
driver.timeout = 1
@ -2859,26 +2865,25 @@ CACHE MANIFEST
end
it "get timeout" do
driver.timeout = 10
driver.timeout.should eq 10
driver.timeout = 3
driver.timeout.should eq 3
configure { |config| config.timeout = 10 }
driver.browser.timeout.should eq 10
end
end
describe "logger app" do
it_behaves_like "output writer" do
let(:driver) do
driver_for_html("<html><body>Hello</body></html>", browser)
driver_for_html("<html><body>Hello</body></html>", browser: browser)
end
it "logs nothing before turning on the logger" do
it "logs nothing in normal mode" do
configure { |config| config.debug = false }
visit("/")
stderr.should_not include logging_message
end
it "logs its commands after turning on the logger" do
driver.enable_logging
it "logs its commands in debug mode" do
configure { |config| config.debug = true }
visit("/")
stderr.should include logging_message
end
@ -3049,7 +3054,7 @@ CACHE MANIFEST
it_behaves_like "output writer" do
let(:driver) do
count = 0
driver_for_app browser do
driver_for_app browser: browser do
get "/" do
count += 1
<<-HTML
@ -3094,7 +3099,7 @@ CACHE MANIFEST
context "when the driver process crashes" do
let(:driver) do
driver_for_app browser do
driver_for_app browser: browser do
get "/" do
"<html><body>Relaunched</body></html>"
end
@ -3112,6 +3117,223 @@ CACHE MANIFEST
end
end
context "handling of SSL validation errors" do
before do
# set up minimal HTTPS server
@host = "127.0.0.1"
@server = TCPServer.new(@host, 0)
@port = @server.addr[1]
# set up SSL layer
ssl_serv = OpenSSL::SSL::SSLServer.new(@server, $openssl_self_signed_ctx)
@server_thread = Thread.new(ssl_serv) do |serv|
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
after do
@server_thread.kill
@server.close
end
context "with default settings" do
it "doesn't accept a self-signed certificate" do
lambda { driver.visit "https://#{@host}:#{@port}/" }.should raise_error
end
it "doesn't accept a self-signed certificate in a new window" do
driver.execute_script("window.open('about:blank')")
driver.switch_to_window(driver.window_handles.last)
lambda { driver.visit "https://#{@host}:#{@port}/" }.should raise_error
end
end
context "ignoring SSL errors" do
it "accepts a self-signed certificate if configured to do so" do
configure(&:ignore_ssl_errors)
driver.visit "https://#{@host}:#{@port}/"
end
it "accepts a self-signed certificate in a new window when configured" do
configure(&:ignore_ssl_errors)
driver.execute_script("window.open('about:blank')")
driver.switch_to_window(driver.window_handles.last)
driver.visit "https://#{@host}:#{@port}/"
end
end
let(:driver) { driver_for_html("", browser: browser) }
let(:browser) { Capybara::Webkit::Browser.new(connection) }
let(:connection) { Capybara::Webkit::Connection.new }
end
context "skip image loading" do
let(:driver) do
driver_for_app do
requests = []
get "/" do
<<-HTML
<html>
<head>
<style>
body {
background-image: url(/path/to/bgimage);
}
</style>
</head>
<body>
<img src="/path/to/image"/>
</body>
</html>
HTML
end
get "/requests" do
<<-HTML
<html>
<body>
#{requests.map { |path| "<p>#{path}</p>" }.join}
</body>
</html>
HTML
end
get %r{/path/to/(.*)} do |path|
requests << path
end
end
end
it "should load images by default" do
visit("/")
requests.should match_array %w(image bgimage)
end
it "should not load images when disabled" do
configure(&:skip_image_loading)
visit("/")
requests.should eq []
end
let(:requests) do
visit "/requests"
driver.find("//p").map(&:text)
end
end
describe "#set_proxy" do
before do
@host = "127.0.0.1"
@user = "user"
@pass = "secret"
@url = "http://example.org/"
@server = TCPServer.new(@host, 0)
@port = @server.addr[1]
@proxy_requests = []
@proxy = Thread.new(@server, @proxy_requests) do |serv, proxy_requests|
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
configure do |config|
config.allow_url("example.org")
config.use_proxy host: @host, port: @port, user: @user, pass: @pass
end
driver.visit @url
@proxy_requests.size.should eq 2
@request = @proxy_requests[-1]
end
after do
@proxy.kill
@server.close
end
let(:driver) do
driver_for_html("", browser: nil)
end
it "uses the HTTP proxy correctly" do
@request[0].should match(/^GET\s+http:\/\/example.org\/\s+HTTP/i)
@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(":")
user.should eq @user
pass.should eq @pass
end
it "uses the proxy's response" do
driver.html.should include "D'oh!"
end
it "uses original URL" do
driver.current_url.should eq @url
end
it "uses URLs changed by javascript" do
driver.execute_script %{window.history.pushState("", "", "/blah")}
driver.current_url.should eq "http://example.org/blah"
end
it "is possible to disable proxy again" do
@proxy_requests.clear
driver.browser.clear_proxy
driver.visit "http://#{@host}:#{@port}/"
@proxy_requests.size.should eq 0
end
end
def driver_url(driver, path)
URI.parse(driver.current_url).merge(path).to_s
end

View File

@ -5,7 +5,7 @@ require 'sinatra/base'
module AppRunner
class << self
attr_accessor :app, :app_host
attr_accessor :app, :app_host, :configuration
end
def self.boot
@ -19,12 +19,18 @@ module AppRunner
self.app = lambda do |env|
[200, { 'Content-Type' => 'html', 'Content-Length' => 0 }, []]
end
self.configuration = Capybara::Webkit::Configuration.new
end
def run_application(app)
AppRunner.app = app
end
def configure
yield AppRunner.configuration
end
def driver_for_app(*driver_args, &body)
app = Class.new(ExampleApp, &body)
run_application app
@ -50,8 +56,12 @@ module AppRunner
private
def build_driver(browser = $webkit_browser)
Capybara::Webkit::Driver.new(AppRunner.app, :browser => browser)
def build_driver(overrides = {})
options = AppRunner.configuration.
to_hash.
merge(browser: $webkit_browser).
merge(overrides)
Capybara::Webkit::Driver.new(AppRunner.app, options)
end
def self.included(example_group)