capybara-webkit/spec/support/app_runner.rb

114 lines
2.5 KiB
Ruby

# Boots a single Capybara::Server for a Rack application that delegates to another, singleton Rack
# application that can be configured for each spec.
require 'sinatra/base'
module AppRunner
class << self
attr_accessor :app, :app_host, :browser, :configuration
end
def self.boot
app_container = lambda { |env| AppRunner.app.call(env) }
server = Capybara::Server.new(app_container)
server.boot
self.app_host = "http://127.0.0.1:#{server.port}"
end
def self.reset
self.app = lambda do |env|
[200, { 'Content-Type' => 'html', 'Content-Length' => 0 }, []]
end
self.browser = $webkit_browser
self.browser.reset!
self.configuration = Capybara::Webkit::Configuration.new
end
def run_application(app)
AppRunner.app = app
end
def configure
yield AppRunner.configuration
end
def fork_connection
AppRunner.fork_connection
end
def self.fork_connection
server = Capybara::Webkit::Server.new(options)
connection = Capybara::Webkit::Connection.new(server: server)
AppRunner.browser = Capybara::Webkit::Browser.new(connection)
connection
end
def driver_for_app(&body)
app = Class.new(ExampleApp, &body)
run_application app
AppRunner.build_driver
end
def driver_for_html(html)
run_application_for_html html
AppRunner.build_driver
end
def session_for_app(&body)
app = Class.new(ExampleApp, &body)
run_application app
Capybara::Session.new(:reusable_webkit, AppRunner.app)
end
def run_application_for_html(html)
run_application lambda { |env|
[200, { 'Content-Type' => 'text/html', 'Content-Length' => html.size.to_s }, [html]]
}
end
def self.build_driver
Capybara::Webkit::Driver.new(app, options.merge(browser: browser))
end
def self.options
configuration.to_hash
end
private_class_method :options
def self.included(example_group)
example_group.class_eval do
before { AppRunner.reset }
after { $webkit_browser.reset! }
end
end
end
class ExampleApp < Sinatra::Base
# Sinatra fixes invalid responses that would break QWebPage, so this middleware breaks them again
# for testing purposes.
class ResponseInvalidator
def initialize(app)
@app = app
end
def call(env)
response = @app.call(env)
if response.to_a[1]['X-Response-Invalid']
[404, {}, []]
else
response
end
end
end
use ResponseInvalidator
def invalid_response
[200, { 'X-Response-Invalid' => 'TRUE' }, []]
end
end
AppRunner.boot