aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb2
-rw-r--r--actionpack/lib/action_dispatch/routing/polymorphic_routes.rb8
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb35
-rw-r--r--actionpack/lib/action_dispatch/routing/url_for.rb4
-rw-r--r--actionpack/lib/action_dispatch/system_test_case.rb28
-rw-r--r--actionpack/lib/action_dispatch/system_testing/browser.rb27
-rw-r--r--actionpack/lib/action_dispatch/system_testing/driver.rb28
-rw-r--r--actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb45
-rw-r--r--actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb11
10 files changed, 103 insertions, 87 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 6e06c70dc2..dea6c4482e 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -2054,7 +2054,7 @@ module ActionDispatch
# your url helper definition, e.g:
#
# direct :browse, page: 1, size: 10 do |options|
- # [ :products, options.merge(params.permit(:page, :size)) ]
+ # [ :products, options.merge(params.permit(:page, :size).to_h.symbolize_keys) ]
# end
#
# In this instance the `params` object comes from the context in which the the
diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
index 984ded1ff5..e89ea8b21d 100644
--- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
+++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
@@ -40,7 +40,7 @@ module ActionDispatch
#
# Example usage:
#
- # edit_polymorphic_path(@post) # => "/posts/1/edit"
+ # edit_polymorphic_path(@post) # => "/posts/1/edit"
# polymorphic_path(@post, format: :pdf) # => "/posts/1.pdf"
#
# == Usage with mounted engines
@@ -104,7 +104,7 @@ module ActionDispatch
end
if mapping = polymorphic_mapping(record_or_hash_or_array)
- return mapping.call(self, [record_or_hash_or_array, options])
+ return mapping.call(self, [record_or_hash_or_array, options], false)
end
opts = options.dup
@@ -128,7 +128,7 @@ module ActionDispatch
end
if mapping = polymorphic_mapping(record_or_hash_or_array)
- return mapping.call(self, [record_or_hash_or_array, options], only_path: true)
+ return mapping.call(self, [record_or_hash_or_array, options], true)
end
opts = options.dup
@@ -273,7 +273,7 @@ module ActionDispatch
def handle_model_call(target, record)
if mapping = polymorphic_mapping(target, record)
- mapping.call(target, [record], only_path: suffix == "path")
+ mapping.call(target, [record], suffix == "path")
else
method, args = handle_model(record)
target.send(method, *args)
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index c4719f8a71..8a9a48938b 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -164,13 +164,13 @@ module ActionDispatch
@path_helpers_module.module_eval do
define_method(:"#{name}_path") do |*args|
- helper.call(self, args, only_path: true)
+ helper.call(self, args, true)
end
end
@url_helpers_module.module_eval do
define_method(:"#{name}_url") do |*args|
- helper.call(self, args)
+ helper.call(self, args, false)
end
end
end
@@ -509,6 +509,10 @@ module ActionDispatch
@_proxy.url_for(options)
end
+ def route_for(name, *args)
+ @_proxy.route_for(name, *args)
+ end
+
def optimize_routes_generation?
@_proxy.optimize_routes_generation?
end
@@ -613,26 +617,14 @@ module ActionDispatch
@block = block
end
- def call(t, args, outer_options = {})
+ def call(t, args, only_path = false)
options = args.extract_options!
- url_options = eval_block(t, args, options)
-
- case url_options
- when String
- t.url_for(url_options)
- when Hash
- t.url_for(url_options.merge(outer_options))
- when ActionController::Parameters
- if url_options.permitted?
- t.url_for(url_options.to_h.merge(outer_options))
- else
- raise ArgumentError, "Generating a URL from non sanitized request parameters is insecure!"
- end
- when Array
- opts = url_options.extract_options!
- t.url_for(url_options.push(opts.merge(outer_options)))
+ url = t.url_for(eval_block(t, args, options))
+
+ if only_path
+ "/" + url.partition(%r{(?<!/)/(?!/)}).last
else
- t.url_for([url_options, outer_options])
+ url
end
end
@@ -860,8 +852,7 @@ module ActionDispatch
params[key] = URI.parser.unescape(value)
end
end
- old_params = req.path_parameters
- req.path_parameters = old_params.merge params
+ req.path_parameters = params
app = route.app
if app.matches?(req) && app.dispatcher?
begin
diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb
index 3e564f13d8..d199bece96 100644
--- a/actionpack/lib/action_dispatch/routing/url_for.rb
+++ b/actionpack/lib/action_dispatch/routing/url_for.rb
@@ -192,6 +192,10 @@ module ActionDispatch
end
end
+ def route_for(name, *args) # :nodoc:
+ public_send(:"#{name}_url", *args)
+ end
+
protected
def optimize_routes_generation?
diff --git a/actionpack/lib/action_dispatch/system_test_case.rb b/actionpack/lib/action_dispatch/system_test_case.rb
index d6388d8fb7..f908607e50 100644
--- a/actionpack/lib/action_dispatch/system_test_case.rb
+++ b/actionpack/lib/action_dispatch/system_test_case.rb
@@ -1,8 +1,8 @@
require "capybara/dsl"
+require "capybara/minitest"
require "action_controller"
require "action_dispatch/system_testing/driver"
require "action_dispatch/system_testing/server"
-require "action_dispatch/system_testing/browser"
require "action_dispatch/system_testing/test_helpers/screenshot_helper"
require "action_dispatch/system_testing/test_helpers/setup_and_teardown"
@@ -81,15 +81,23 @@ module ActionDispatch
# tests as long as you include the required gems and files.
class SystemTestCase < IntegrationTest
include Capybara::DSL
+ include Capybara::Minitest::Assertions
include SystemTesting::TestHelpers::SetupAndTeardown
include SystemTesting::TestHelpers::ScreenshotHelper
+ def initialize(*) # :nodoc:
+ super
+ self.class.superclass.driver.use
+ end
+
def self.start_application # :nodoc:
Capybara.app = Rack::Builder.new do
map "/" do
run Rails.application
end
end
+
+ SystemTesting::Server.new.run
end
# System Test configuration options
@@ -104,21 +112,13 @@ module ActionDispatch
# driven_by :selenium, using: :firefox
#
# driven_by :selenium, screen_size: [800, 800]
- def self.driven_by(driver, using: :chrome, screen_size: [1400, 1400])
- driver = if selenium?(driver)
- SystemTesting::Browser.new(using, screen_size)
- else
- SystemTesting::Driver.new(driver)
- end
-
- setup { driver.use }
- teardown { driver.reset }
-
- SystemTesting::Server.new.run
+ def self.driven_by(driver, using: :chrome, screen_size: [1400, 1400], options: {})
+ @driver = SystemTesting::Driver.new(driver, using: using, screen_size: screen_size, options: options)
end
- def self.selenium?(driver) # :nodoc:
- driver == :selenium
+ # Returns the driver object for the initialized system test
+ def self.driver
+ @driver ||= SystemTestCase.driven_by(:selenium)
end
end
diff --git a/actionpack/lib/action_dispatch/system_testing/browser.rb b/actionpack/lib/action_dispatch/system_testing/browser.rb
deleted file mode 100644
index 14ea06459d..0000000000
--- a/actionpack/lib/action_dispatch/system_testing/browser.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-require "action_dispatch/system_testing/driver"
-
-module ActionDispatch
- module SystemTesting
- class Browser < Driver # :nodoc:
- def initialize(name, screen_size)
- super(name)
- @name = name
- @screen_size = screen_size
- end
-
- def use
- register
- super
- end
-
- private
- def register
- Capybara.register_driver @name do |app|
- Capybara::Selenium::Driver.new(app, browser: @name).tap do |driver|
- driver.browser.manage.window.size = Selenium::WebDriver::Dimension.new(*@screen_size)
- end
- end
- end
- end
- end
-end
diff --git a/actionpack/lib/action_dispatch/system_testing/driver.rb b/actionpack/lib/action_dispatch/system_testing/driver.rb
index 8decb54419..5cf17883f7 100644
--- a/actionpack/lib/action_dispatch/system_testing/driver.rb
+++ b/actionpack/lib/action_dispatch/system_testing/driver.rb
@@ -1,18 +1,34 @@
module ActionDispatch
module SystemTesting
class Driver # :nodoc:
- def initialize(name)
+ def initialize(name, **options)
@name = name
+ @browser = options[:using]
+ @screen_size = options[:screen_size]
+ @options = options[:options]
end
def use
- @current = Capybara.current_driver
- Capybara.current_driver = @name
+ register if selenium?
+ setup
end
- def reset
- Capybara.current_driver = @current
- end
+ private
+ def selenium?
+ @name == :selenium
+ end
+
+ def register
+ Capybara.register_driver @name do |app|
+ Capybara::Selenium::Driver.new(app, { browser: @browser }.merge(@options)).tap do |driver|
+ driver.browser.manage.window.size = Selenium::WebDriver::Dimension.new(*@screen_size)
+ end
+ end
+ end
+
+ def setup
+ Capybara.current_driver = @name
+ end
end
end
end
diff --git a/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb b/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb
index ddc961cf84..3078e035a3 100644
--- a/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb
+++ b/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb
@@ -8,9 +8,20 @@ module ActionDispatch
# +take_screenshot+ can be used at any point in your system tests to take
# a screenshot of the current state. This can be useful for debugging or
# automating visual testing.
+ #
+ # The screenshot will be displayed in your console, if supported.
+ #
+ # You can set the +RAILS_SYSTEM_TESTING_SCREENSHOT+ environment variable to
+ # control the output. Possible values are:
+ # * [+inline+ (default)] display the screenshot in the terminal using the
+ # iTerm image protocol (http://iterm2.com/documentation-images.html).
+ # * [+simple+] only display the screenshot path.
+ # This is the default value if the +CI+ environment variables
+ # is defined.
+ # * [+artifact+] display the screenshot in the terminal, using the terminal
+ # artifact format (http://buildkite.github.io/terminal/inline-images/).
def take_screenshot
save_image
- puts "[Screenshot]: #{image_path}"
puts display_image
end
@@ -22,7 +33,7 @@ module ActionDispatch
# fails add +take_failed_screenshot+ to the teardown block before clearing
# sessions.
def take_failed_screenshot
- take_screenshot if failed?
+ take_screenshot if failed? && supports_screenshot?
end
private
@@ -38,14 +49,32 @@ module ActionDispatch
page.save_screenshot(Rails.root.join(image_path))
end
+ def output_type
+ # Environment variables have priority
+ output_type = ENV["RAILS_SYSTEM_TESTING_SCREENSHOT"] || ENV["CAPYBARA_INLINE_SCREENSHOT"]
+
+ # If running in a CI environment, default to simple
+ output_type ||= "simple" if ENV["CI"]
+
+ # Default
+ output_type ||= "inline"
+
+ output_type
+ end
+
def display_image
- if ENV["CAPYBARA_INLINE_SCREENSHOT"] == "artifact"
- "\e]1338;url=artifact://#{image_path}\a"
- else
+ message = "[Screenshot]: #{image_path}\n"
+
+ case output_type
+ when "artifact"
+ message << "\e]1338;url=artifact://#{image_path}\a\n"
+ when "inline"
name = inline_base64(File.basename(image_path))
image = inline_base64(File.read(image_path))
- "\e]1337;File=name=#{name};height=400px;inline=1:#{image}\a"
+ message << "\e]1337;File=name=#{name};height=400px;inline=1:#{image}\a\n"
end
+
+ message
end
def inline_base64(path)
@@ -55,6 +84,10 @@ module ActionDispatch
def failed?
!passed? && !skipped?
end
+
+ def supports_screenshot?
+ Capybara.current_driver != :rack_test
+ end
end
end
end
diff --git a/actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb b/actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb
index 491559eedf..187ba2cc5f 100644
--- a/actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb
+++ b/actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb
@@ -10,9 +10,9 @@ module ActionDispatch
end
def after_teardown
- super
take_failed_screenshot
Capybara.reset_sessions!
+ super
end
end
end
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 5fa0b727ab..b46a97413a 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -192,11 +192,10 @@ module ActionDispatch
# HTTP methods in integration tests. +#process+ is only required when using a
# request method that doesn't have a method defined in the integration tests.
#
- # This method returns a Response object, which one can use to
- # inspect the details of the response. Furthermore, if this method was
- # called from an ActionDispatch::IntegrationTest object, then that
- # object's <tt>@response</tt> instance variable will point to the same
- # response object.
+ # This method returns the response status, after performing the request.
+ # Furthermore, if this method was called from an ActionDispatch::IntegrationTest object,
+ # then that object's <tt>@response</tt> instance variable will point to a Response object
+ # which one can use to inspect the details of the response.
#
# Example:
# process :get, '/author', params: { since: 201501011400 }
@@ -572,7 +571,7 @@ module ActionDispatch
# end
#
# assert_response :success
- # assert_equal({ id: Arcticle.last.id, title: "Ahoy!" }, response.parsed_body)
+ # assert_equal({ id: Article.last.id, title: "Ahoy!" }, response.parsed_body)
# end
# end
#