actionpack 6.0.0.beta1 → 6.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -10
- data/lib/abstract_controller/caching/fragments.rb +0 -1
- data/lib/abstract_controller/translation.rb +1 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +1 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
- data/lib/action_controller/metal/exceptions.rb +1 -1
- data/lib/action_controller/metal/force_ssl.rb +1 -2
- data/lib/action_controller/metal/helpers.rb +1 -1
- data/lib/action_controller/metal/implicit_render.rb +2 -2
- data/lib/action_controller/metal/live.rb +1 -1
- data/lib/action_controller/metal/redirecting.rb +6 -27
- data/lib/action_controller/metal/strong_parameters.rb +1 -1
- data/lib/action_dispatch/http/upload.rb +4 -1
- data/lib/action_dispatch/journey/path/pattern.rb +1 -1
- data/lib/action_dispatch/middleware/cookies.rb +2 -7
- data/lib/action_dispatch/middleware/debug_view.rb +7 -1
- data/lib/action_dispatch/middleware/exception_wrapper.rb +14 -10
- data/lib/action_dispatch/middleware/host_authorization.rb +2 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +1 -1
- data/lib/action_dispatch/routing.rb +14 -14
- data/lib/action_dispatch/system_test_case.rb +22 -2
- data/lib/action_dispatch/system_testing/browser.rb +15 -7
- data/lib/action_dispatch/system_testing/driver.rb +8 -1
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +1 -1
- data/lib/action_dispatch/testing/assertions/routing.rb +8 -1
- data/lib/action_dispatch/testing/integration.rb +2 -2
- data/lib/action_pack/gem_version.rb +1 -1
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88d35424bac0eece534cf329b1ab3b2fdb55d76f9709a047e78ebfaf5fa07374
|
4
|
+
data.tar.gz: 8914995ea3644de413b90e94b61c9fa9ed58f0dd2fdf365a3bee4fb355c7184e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d856ee7c126002bd2a0bb391cb9b1569f18fb766fc2d9ce8203791abf988359e0dce090caa5caee4e8268eb6b5fe4d584c28df9343e028b30e05cb4c0f8dc59
|
7
|
+
data.tar.gz: 3132bac5633fb26cb3a5de9995c702964334a9afc979fabceb0310829c5c04f1d9964c6413fa9965c9a035e1fb2f30a3f595fbddd5cc122568b6f345ff728325
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## Rails 6.0.0.beta2 (February 25, 2019) ##
|
2
|
+
|
3
|
+
* Make debug exceptions works in an environment where ActiveStorage is not loaded.
|
4
|
+
|
5
|
+
*Tomoyuki Kurosawa*
|
6
|
+
|
7
|
+
* `ActionDispatch::SystemTestCase.driven_by` can now be called with a block
|
8
|
+
to define specific browser capabilities.
|
9
|
+
|
10
|
+
*Edouard Chin*
|
11
|
+
|
12
|
+
|
1
13
|
## Rails 6.0.0.beta1 (January 18, 2019) ##
|
2
14
|
|
3
15
|
* Remove deprecated `fragment_cache_key` helper in favor of `combined_fragment_cache_key`.
|
@@ -11,16 +23,10 @@
|
|
11
23
|
|
12
24
|
*Rafael Mendonça França*
|
13
25
|
|
14
|
-
* Ensure external redirects are explicitly allowed
|
15
|
-
|
16
|
-
Add `fallback_location` and `allow_other_host` options to `redirect_to`.
|
17
|
-
|
18
|
-
*Gannon McGibbon*
|
19
|
-
|
20
26
|
* Introduce ActionDispatch::HostAuthorization
|
21
27
|
|
22
28
|
This is a new middleware that guards against DNS rebinding attacks by
|
23
|
-
|
29
|
+
explicitly permitting the hosts a request can be made to.
|
24
30
|
|
25
31
|
Each host is checked with the case operator (`#===`) to support `RegExp`,
|
26
32
|
`Proc`, `IPAddr` and custom objects as host allowances.
|
@@ -82,7 +88,7 @@
|
|
82
88
|
* Apply mapping to symbols returned from dynamic CSP sources
|
83
89
|
|
84
90
|
Previously if a dynamic source returned a symbol such as :self it
|
85
|
-
would be converted to a string
|
91
|
+
would be converted to a string implicitly, e.g:
|
86
92
|
|
87
93
|
policy.default_src -> { :self }
|
88
94
|
|
@@ -135,7 +141,7 @@
|
|
135
141
|
|
136
142
|
*Assain Jaleel*
|
137
143
|
|
138
|
-
* Raises `ActionController::RespondToMismatchError` with
|
144
|
+
* Raises `ActionController::RespondToMismatchError` with conflicting `respond_to` invocations.
|
139
145
|
|
140
146
|
`respond_to` can match multiple types and lead to undefined behavior when
|
141
147
|
multiple invocations are made and the types do not match:
|
@@ -160,7 +166,7 @@
|
|
160
166
|
|
161
167
|
*Aaron Kromer*
|
162
168
|
|
163
|
-
* Pass along arguments to underlying `get` method in `follow_redirect
|
169
|
+
* Pass along arguments to underlying `get` method in `follow_redirect!`
|
164
170
|
|
165
171
|
Now all arguments passed to `follow_redirect!` are passed to the underlying
|
166
172
|
`get` method. This for example allows to set custom headers for the
|
@@ -11,6 +11,7 @@ module AbstractController
|
|
11
11
|
# to translate many keys within the same controller / action and gives you a
|
12
12
|
# simple framework for scoping them consistently.
|
13
13
|
def translate(key, options = {})
|
14
|
+
options = options.dup
|
14
15
|
if key.to_s.first == "."
|
15
16
|
path = controller_path.tr("/", ".")
|
16
17
|
defaults = [:"#{path}#{key}"]
|
@@ -13,7 +13,7 @@ module ActionController
|
|
13
13
|
|
14
14
|
ACTION_OPTIONS = [:only, :except, :if, :unless]
|
15
15
|
URL_OPTIONS = [:protocol, :host, :domain, :subdomain, :port, :path]
|
16
|
-
REDIRECT_OPTIONS = [:status, :flash, :alert, :notice
|
16
|
+
REDIRECT_OPTIONS = [:status, :flash, :alert, :notice]
|
17
17
|
|
18
18
|
module ClassMethods # :nodoc:
|
19
19
|
def force_ssl(options = {})
|
@@ -41,7 +41,6 @@ module ActionController
|
|
41
41
|
host: request.host,
|
42
42
|
path: request.fullpath,
|
43
43
|
status: :moved_permanently,
|
44
|
-
allow_other_host: true,
|
45
44
|
}
|
46
45
|
|
47
46
|
if host_or_options.is_a?(Hash)
|
@@ -75,7 +75,7 @@ module ActionController
|
|
75
75
|
# Provides a proxy to access helper methods from outside the view.
|
76
76
|
def helpers
|
77
77
|
@helper_proxy ||= begin
|
78
|
-
proxy = ActionView::Base.
|
78
|
+
proxy = ActionView::Base.empty
|
79
79
|
proxy.config = config.inheritable_copy
|
80
80
|
proxy.extend(_helpers)
|
81
81
|
end
|
@@ -30,9 +30,9 @@ module ActionController
|
|
30
30
|
# :stopdoc:
|
31
31
|
include BasicImplicitRender
|
32
32
|
|
33
|
-
def default_render
|
33
|
+
def default_render
|
34
34
|
if template_exists?(action_name.to_s, _prefixes, variants: request.variant)
|
35
|
-
render
|
35
|
+
render
|
36
36
|
elsif any_templates?(action_name.to_s, _prefixes)
|
37
37
|
message = "#{self.class.name}\##{action_name} is missing a template " \
|
38
38
|
"for this request format and variant.\n" \
|
@@ -60,7 +60,7 @@ module ActionController
|
|
60
60
|
raise AbstractController::DoubleRenderError if response_body
|
61
61
|
|
62
62
|
self.status = _extract_redirect_to_status(options, response_options)
|
63
|
-
self.location =
|
63
|
+
self.location = _compute_redirect_to_location(request, options)
|
64
64
|
self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(response.location)}\">redirected</a>.</body></html>"
|
65
65
|
end
|
66
66
|
|
@@ -88,13 +88,9 @@ module ActionController
|
|
88
88
|
# All other options that can be passed to <tt>redirect_to</tt> are accepted as
|
89
89
|
# options and the behavior is identical.
|
90
90
|
def redirect_back(fallback_location:, allow_other_host: true, **args)
|
91
|
-
referer = request.headers
|
92
|
-
|
93
|
-
|
94
|
-
allow_other_host: allow_other_host,
|
95
|
-
**args,
|
96
|
-
}
|
97
|
-
redirect_to referer, response_options
|
91
|
+
referer = request.headers["Referer"]
|
92
|
+
redirect_to_referer = referer && (allow_other_host || _url_host_allowed?(referer))
|
93
|
+
redirect_to redirect_to_referer ? referer : fallback_location, **args
|
98
94
|
end
|
99
95
|
|
100
96
|
def _compute_redirect_to_location(request, options) #:nodoc:
|
@@ -118,23 +114,6 @@ module ActionController
|
|
118
114
|
public :_compute_redirect_to_location
|
119
115
|
|
120
116
|
private
|
121
|
-
def _compute_safe_redirect_to_location(request, options, response_options)
|
122
|
-
location = _compute_redirect_to_location(request, options)
|
123
|
-
location_options = options.is_a?(Hash) ? options : {}
|
124
|
-
if response_options[:allow_other_host] || _url_host_allowed?(location, location_options)
|
125
|
-
location
|
126
|
-
else
|
127
|
-
fallback_location = response_options.fetch(:fallback_location) do
|
128
|
-
raise ArgumentError, <<~MSG.squish
|
129
|
-
Unsafe redirect #{location.inspect},
|
130
|
-
use :fallback_location to specify a fallback
|
131
|
-
or :allow_other_host to redirect anyway.
|
132
|
-
MSG
|
133
|
-
end
|
134
|
-
_compute_redirect_to_location(request, fallback_location)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
117
|
def _extract_redirect_to_status(options, response_options)
|
139
118
|
if options.is_a?(Hash) && options.key?(:status)
|
140
119
|
Rack::Utils.status_code(options.delete(:status))
|
@@ -145,8 +124,8 @@ module ActionController
|
|
145
124
|
end
|
146
125
|
end
|
147
126
|
|
148
|
-
def _url_host_allowed?(url
|
149
|
-
URI(url.to_s).host
|
127
|
+
def _url_host_allowed?(url)
|
128
|
+
URI(url.to_s).host == request.host
|
150
129
|
rescue ArgumentError, URI::Error
|
151
130
|
false
|
152
131
|
end
|
@@ -795,7 +795,7 @@ module ActionController
|
|
795
795
|
@permitted = coder.map["ivars"][:@permitted]
|
796
796
|
when "!ruby/object:ActionController::Parameters"
|
797
797
|
# YAML's Object format. Only needed because of the format
|
798
|
-
#
|
798
|
+
# backwards compatibility above, otherwise equivalent to YAML's initialization.
|
799
799
|
@parameters, @permitted = coder.map["parameters"], coder.map["permitted"]
|
800
800
|
end
|
801
801
|
end
|
@@ -20,7 +20,6 @@ module ActionDispatch
|
|
20
20
|
# A +Tempfile+ object with the actual uploaded file. Note that some of
|
21
21
|
# its interface is available directly.
|
22
22
|
attr_accessor :tempfile
|
23
|
-
alias :to_io :tempfile
|
24
23
|
|
25
24
|
# A string with the headers of the multipart request.
|
26
25
|
attr_accessor :headers
|
@@ -84,6 +83,10 @@ module ActionDispatch
|
|
84
83
|
def eof?
|
85
84
|
@tempfile.eof?
|
86
85
|
end
|
86
|
+
|
87
|
+
def to_io
|
88
|
+
@tempfile.to_io
|
89
|
+
end
|
87
90
|
end
|
88
91
|
end
|
89
92
|
end
|
@@ -488,13 +488,8 @@ module ActionDispatch
|
|
488
488
|
end
|
489
489
|
|
490
490
|
def cookie_metadata(name, options)
|
491
|
-
|
492
|
-
metadata =
|
493
|
-
metadata[:purpose] = "cookie.#{name}"
|
494
|
-
|
495
|
-
metadata
|
496
|
-
else
|
497
|
-
{}
|
491
|
+
expiry_options(options).tap do |metadata|
|
492
|
+
metadata[:purpose] = "cookie.#{name}" if request.use_cookies_with_metadata
|
498
493
|
end
|
499
494
|
end
|
500
495
|
|
@@ -10,7 +10,13 @@ module ActionDispatch
|
|
10
10
|
RESCUES_TEMPLATE_PATH = File.expand_path("templates", __dir__)
|
11
11
|
|
12
12
|
def initialize(assigns)
|
13
|
-
|
13
|
+
paths = [RESCUES_TEMPLATE_PATH]
|
14
|
+
lookup_context = ActionView::LookupContext.new(paths)
|
15
|
+
super(lookup_context, assigns)
|
16
|
+
end
|
17
|
+
|
18
|
+
def compiled_method_container
|
19
|
+
self.class
|
14
20
|
end
|
15
21
|
|
16
22
|
def debug_params(params)
|
@@ -31,22 +31,34 @@ module ActionDispatch
|
|
31
31
|
"ActionController::MissingExactTemplate" => "missing_exact_template",
|
32
32
|
)
|
33
33
|
|
34
|
+
cattr_accessor :wrapper_exceptions, default: [
|
35
|
+
"ActionView::Template::Error"
|
36
|
+
]
|
37
|
+
|
34
38
|
attr_reader :backtrace_cleaner, :exception, :wrapped_causes, :line_number, :file
|
35
39
|
|
36
40
|
def initialize(backtrace_cleaner, exception)
|
37
41
|
@backtrace_cleaner = backtrace_cleaner
|
38
|
-
@exception =
|
42
|
+
@exception = exception
|
39
43
|
@wrapped_causes = wrapped_causes_for(exception, backtrace_cleaner)
|
40
44
|
|
41
45
|
expand_backtrace if exception.is_a?(SyntaxError) || exception.cause.is_a?(SyntaxError)
|
42
46
|
end
|
43
47
|
|
48
|
+
def unwrapped_exception
|
49
|
+
if wrapper_exceptions.include?(exception.class.to_s)
|
50
|
+
exception.cause
|
51
|
+
else
|
52
|
+
exception
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
44
56
|
def rescue_template
|
45
57
|
@@rescue_templates[@exception.class.name]
|
46
58
|
end
|
47
59
|
|
48
60
|
def status_code
|
49
|
-
self.class.status_code_for_exception(
|
61
|
+
self.class.status_code_for_exception(unwrapped_exception.class.name)
|
50
62
|
end
|
51
63
|
|
52
64
|
def application_trace
|
@@ -122,14 +134,6 @@ module ActionDispatch
|
|
122
134
|
Array(@exception.backtrace)
|
123
135
|
end
|
124
136
|
|
125
|
-
def original_exception(exception)
|
126
|
-
if @@rescue_responses.has_key?(exception.cause.class.name)
|
127
|
-
exception.cause
|
128
|
-
else
|
129
|
-
exception
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
137
|
def causes_for(exception)
|
134
138
|
return enum_for(__method__, exception) unless block_given?
|
135
139
|
|
@@ -3,8 +3,8 @@
|
|
3
3
|
require "action_dispatch/http/request"
|
4
4
|
|
5
5
|
module ActionDispatch
|
6
|
-
# This middleware guards from DNS rebinding attacks by
|
7
|
-
# hosts a request can be sent to.
|
6
|
+
# This middleware guards from DNS rebinding attacks by explicitly permitting
|
7
|
+
# the hosts a request can be sent to.
|
8
8
|
#
|
9
9
|
# When a request comes to an unauthorized host, the +response_app+
|
10
10
|
# application will be executed and rendered. If no +response_app+ is given, a
|
@@ -45,7 +45,7 @@ module ActionDispatch
|
|
45
45
|
backtrace_cleaner = request.get_header "action_dispatch.backtrace_cleaner"
|
46
46
|
wrapper = ExceptionWrapper.new(backtrace_cleaner, exception)
|
47
47
|
status = wrapper.status_code
|
48
|
-
request.set_header "action_dispatch.exception", wrapper.
|
48
|
+
request.set_header "action_dispatch.exception", wrapper.unwrapped_exception
|
49
49
|
request.set_header "action_dispatch.original_path", request.path_info
|
50
50
|
request.path_info = "/#{status}"
|
51
51
|
response = @exceptions_app.call(request.env)
|
@@ -2,6 +2,6 @@
|
|
2
2
|
<h1>Blocked host: <%= @host %></h1>
|
3
3
|
</header>
|
4
4
|
<div id="container">
|
5
|
-
<h2>To allow requests to <%= @host %>, add the following configuration:</h2>
|
6
|
-
<pre>
|
5
|
+
<h2>To allow requests to <%= @host %>, add the following to your environment configuration:</h2>
|
6
|
+
<pre>config.hosts << "<%= @host %>"</pre>
|
7
7
|
</div>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
Blocked host: <%= @host %>
|
2
2
|
|
3
|
-
To allow requests to <%= @host %>, add the following configuration:
|
3
|
+
To allow requests to <%= @host %>, add the following to your environment configuration:
|
4
4
|
|
5
|
-
|
5
|
+
config.hosts << "<%= @host %>"
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<div id="container">
|
11
11
|
<h2>
|
12
12
|
<%= h @exception.message %>
|
13
|
-
<% if @exception.message.match?
|
13
|
+
<% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
|
14
14
|
<br />To resolve this issue run: rails active_storage:install
|
15
15
|
<% end %>
|
16
16
|
</h2>
|
@@ -4,7 +4,7 @@
|
|
4
4
|
<% end %>
|
5
5
|
|
6
6
|
<%= @exception.message %>
|
7
|
-
<% if @exception.message.match?
|
7
|
+
<% if defined?(ActiveStorage) && @exception.message.match?(%r{#{ActiveStorage::Blob.table_name}|#{ActiveStorage::Attachment.table_name}}) %>
|
8
8
|
To resolve this issue run: rails active_storage:install
|
9
9
|
<% end %>
|
10
10
|
|
@@ -74,8 +74,8 @@ module ActionDispatch
|
|
74
74
|
# For routes that don't fit the <tt>resources</tt> mold, you can use the HTTP helper
|
75
75
|
# methods <tt>get</tt>, <tt>post</tt>, <tt>patch</tt>, <tt>put</tt> and <tt>delete</tt>.
|
76
76
|
#
|
77
|
-
# get 'post/:id'
|
78
|
-
# post 'post/:id'
|
77
|
+
# get 'post/:id', to: 'posts#show'
|
78
|
+
# post 'post/:id', to: 'posts#create_comment'
|
79
79
|
#
|
80
80
|
# Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
|
81
81
|
# URL will route to the <tt>show</tt> action.
|
@@ -83,7 +83,7 @@ module ActionDispatch
|
|
83
83
|
# If your route needs to respond to more than one HTTP method (or all methods) then using the
|
84
84
|
# <tt>:via</tt> option on <tt>match</tt> is preferable.
|
85
85
|
#
|
86
|
-
# match 'post/:id'
|
86
|
+
# match 'post/:id', to: 'posts#show', via: [:get, :post]
|
87
87
|
#
|
88
88
|
# == Named routes
|
89
89
|
#
|
@@ -94,7 +94,7 @@ module ActionDispatch
|
|
94
94
|
# Example:
|
95
95
|
#
|
96
96
|
# # In config/routes.rb
|
97
|
-
# get '/login'
|
97
|
+
# get '/login', to: 'accounts#login', as: 'login'
|
98
98
|
#
|
99
99
|
# # With render, redirect_to, tests, etc.
|
100
100
|
# redirect_to login_url
|
@@ -120,9 +120,9 @@ module ActionDispatch
|
|
120
120
|
#
|
121
121
|
# # In config/routes.rb
|
122
122
|
# controller :blog do
|
123
|
-
# get 'blog/show'
|
124
|
-
# get 'blog/delete'
|
125
|
-
# get 'blog/edit'
|
123
|
+
# get 'blog/show', to: :list
|
124
|
+
# get 'blog/delete', to: :delete
|
125
|
+
# get 'blog/edit', to: :edit
|
126
126
|
# end
|
127
127
|
#
|
128
128
|
# # provides named routes for show, delete, and edit
|
@@ -132,7 +132,7 @@ module ActionDispatch
|
|
132
132
|
#
|
133
133
|
# Routes can generate pretty URLs. For example:
|
134
134
|
#
|
135
|
-
# get '/articles/:year/:month/:day'
|
135
|
+
# get '/articles/:year/:month/:day', to: 'articles#find_by_id', constraints: {
|
136
136
|
# year: /\d{4}/,
|
137
137
|
# month: /\d{1,2}/,
|
138
138
|
# day: /\d{1,2}/
|
@@ -147,7 +147,7 @@ module ActionDispatch
|
|
147
147
|
# You can specify a regular expression to define a format for a parameter.
|
148
148
|
#
|
149
149
|
# controller 'geocode' do
|
150
|
-
# get 'geocode/:postalcode'
|
150
|
+
# get 'geocode/:postalcode', to: :show, constraints: {
|
151
151
|
# postalcode: /\d{5}(-\d{4})?/
|
152
152
|
# }
|
153
153
|
# end
|
@@ -156,13 +156,13 @@ module ActionDispatch
|
|
156
156
|
# expression modifiers:
|
157
157
|
#
|
158
158
|
# controller 'geocode' do
|
159
|
-
# get 'geocode/:postalcode'
|
159
|
+
# get 'geocode/:postalcode', to: :show, constraints: {
|
160
160
|
# postalcode: /hx\d\d\s\d[a-z]{2}/i
|
161
161
|
# }
|
162
162
|
# end
|
163
163
|
#
|
164
164
|
# controller 'geocode' do
|
165
|
-
# get 'geocode/:postalcode'
|
165
|
+
# get 'geocode/:postalcode', to: :show, constraints: {
|
166
166
|
# postalcode: /# Postalcode format
|
167
167
|
# \d{5} #Prefix
|
168
168
|
# (-\d{4})? #Suffix
|
@@ -178,13 +178,13 @@ module ActionDispatch
|
|
178
178
|
#
|
179
179
|
# You can redirect any path to another path using the redirect helper in your router:
|
180
180
|
#
|
181
|
-
# get "/stories"
|
181
|
+
# get "/stories", to: redirect("/posts")
|
182
182
|
#
|
183
183
|
# == Unicode character routes
|
184
184
|
#
|
185
185
|
# You can specify unicode character routes in your router:
|
186
186
|
#
|
187
|
-
# get "こんにちは"
|
187
|
+
# get "こんにちは", to: "welcome#index"
|
188
188
|
#
|
189
189
|
# == Routing to Rack Applications
|
190
190
|
#
|
@@ -192,7 +192,7 @@ module ActionDispatch
|
|
192
192
|
# index action in the PostsController, you can specify any Rack application
|
193
193
|
# as the endpoint for a matcher:
|
194
194
|
#
|
195
|
-
# get "/application.js"
|
195
|
+
# get "/application.js", to: Sprockets
|
196
196
|
#
|
197
197
|
# == Reloading routes
|
198
198
|
#
|
@@ -89,6 +89,24 @@ module ActionDispatch
|
|
89
89
|
# { js_errors: true }
|
90
90
|
# end
|
91
91
|
#
|
92
|
+
# Some drivers require browser capabilities to be passed as a block instead
|
93
|
+
# of through the +options+ hash.
|
94
|
+
#
|
95
|
+
# As an example, if you want to add mobile emulation on chrome, you'll have to
|
96
|
+
# create an instance of selenium's +Chrome::Options+ object and add
|
97
|
+
# capabilities with a block.
|
98
|
+
#
|
99
|
+
# The block will be passed an instance of <tt><Driver>::Options</tt> where you can
|
100
|
+
# define the capabilities you want. Please refer to your driver documentation
|
101
|
+
# to learn about supported options.
|
102
|
+
#
|
103
|
+
# class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
104
|
+
# driven_by :selenium, using: :chrome, screen_size: [1024, 768] do |driver_option|
|
105
|
+
# driver_option.add_emulation(device_name: 'iPhone 6')
|
106
|
+
# driver_option.add_extension('path/to/chrome_extension.crx')
|
107
|
+
# end
|
108
|
+
# end
|
109
|
+
#
|
92
110
|
# Because <tt>ActionDispatch::SystemTestCase</tt> is a shim between Capybara
|
93
111
|
# and Rails, any driver that is supported by Capybara is supported by system
|
94
112
|
# tests as long as you include the required gems and files.
|
@@ -134,8 +152,10 @@ module ActionDispatch
|
|
134
152
|
# driven_by :selenium, using: :firefox
|
135
153
|
#
|
136
154
|
# driven_by :selenium, using: :headless_firefox
|
137
|
-
def self.driven_by(driver, using: :chrome, screen_size: [1400, 1400], options: {})
|
138
|
-
|
155
|
+
def self.driven_by(driver, using: :chrome, screen_size: [1400, 1400], options: {}, &capabilities)
|
156
|
+
driver_options = { using: using, screen_size: screen_size, options: options }
|
157
|
+
|
158
|
+
self.driver = SystemTesting::Driver.new(driver, driver_options, &capabilities)
|
139
159
|
end
|
140
160
|
|
141
161
|
driven_by :selenium
|
@@ -29,20 +29,28 @@ module ActionDispatch
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
def capabilities
|
33
|
+
@option ||=
|
34
|
+
case type
|
35
|
+
when :chrome
|
36
|
+
::Selenium::WebDriver::Chrome::Options.new
|
37
|
+
when :firefox
|
38
|
+
::Selenium::WebDriver::Firefox::Options.new
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
32
42
|
private
|
33
43
|
def headless_chrome_browser_options
|
34
|
-
|
35
|
-
|
36
|
-
options.args << "--disable-gpu" if Gem.win_platform?
|
44
|
+
capabilities.args << "--headless"
|
45
|
+
capabilities.args << "--disable-gpu" if Gem.win_platform?
|
37
46
|
|
38
|
-
|
47
|
+
capabilities
|
39
48
|
end
|
40
49
|
|
41
50
|
def headless_firefox_browser_options
|
42
|
-
|
43
|
-
options.args << "-headless"
|
51
|
+
capabilities.args << "-headless"
|
44
52
|
|
45
|
-
|
53
|
+
capabilities
|
46
54
|
end
|
47
55
|
end
|
48
56
|
end
|
@@ -3,11 +3,12 @@
|
|
3
3
|
module ActionDispatch
|
4
4
|
module SystemTesting
|
5
5
|
class Driver # :nodoc:
|
6
|
-
def initialize(name, **options)
|
6
|
+
def initialize(name, **options, &capabilities)
|
7
7
|
@name = name
|
8
8
|
@browser = Browser.new(options[:using])
|
9
9
|
@screen_size = options[:screen_size]
|
10
10
|
@options = options[:options]
|
11
|
+
@capabilities = capabilities
|
11
12
|
end
|
12
13
|
|
13
14
|
def use
|
@@ -22,6 +23,8 @@ module ActionDispatch
|
|
22
23
|
end
|
23
24
|
|
24
25
|
def register
|
26
|
+
define_browser_capabilities(@browser.capabilities)
|
27
|
+
|
25
28
|
Capybara.register_driver @name do |app|
|
26
29
|
case @name
|
27
30
|
when :selenium then register_selenium(app)
|
@@ -31,6 +34,10 @@ module ActionDispatch
|
|
31
34
|
end
|
32
35
|
end
|
33
36
|
|
37
|
+
def define_browser_capabilities(capabilities)
|
38
|
+
@capabilities.call(capabilities) if @capabilities
|
39
|
+
end
|
40
|
+
|
34
41
|
def browser_options
|
35
42
|
@options.merge(options: @browser.options).compact
|
36
43
|
end
|
@@ -20,7 +20,7 @@ module ActionDispatch
|
|
20
20
|
# * [+inline+] Display the screenshot in the terminal using the
|
21
21
|
# iTerm image protocol (https://iterm2.com/documentation-images.html).
|
22
22
|
# * [+artifact+] Display the screenshot in the terminal, using the terminal
|
23
|
-
# artifact format (https://buildkite.github.io/terminal/inline-images/).
|
23
|
+
# artifact format (https://buildkite.github.io/terminal-to-html/inline-images/).
|
24
24
|
def take_screenshot
|
25
25
|
save_image
|
26
26
|
puts display_image
|
@@ -160,9 +160,16 @@ module ActionDispatch
|
|
160
160
|
@controller.singleton_class.include(_routes.url_helpers)
|
161
161
|
|
162
162
|
if @controller.respond_to? :view_context_class
|
163
|
-
|
163
|
+
view_context_class = Class.new(@controller.view_context_class) do
|
164
164
|
include _routes.url_helpers
|
165
165
|
end
|
166
|
+
|
167
|
+
custom_view_context = Module.new {
|
168
|
+
define_method(:view_context_class) do
|
169
|
+
view_context_class
|
170
|
+
end
|
171
|
+
}
|
172
|
+
@controller.extend(custom_view_context)
|
166
173
|
end
|
167
174
|
end
|
168
175
|
yield @routes
|
@@ -194,7 +194,7 @@ module ActionDispatch
|
|
194
194
|
# Adds request headers characteristic of XMLHttpRequest e.g. HTTP_X_REQUESTED_WITH.
|
195
195
|
# The headers will be merged into the Rack env hash.
|
196
196
|
# - +as+: Used for encoding the request with different content type.
|
197
|
-
# Supports `:json` by default and will set the
|
197
|
+
# Supports `:json` by default and will set the appropriate request headers.
|
198
198
|
# The headers will be merged into the Rack env hash.
|
199
199
|
#
|
200
200
|
# This method is rarely used directly. Use +#get+, +#post+, or other standard
|
@@ -335,7 +335,7 @@ module ActionDispatch
|
|
335
335
|
klass = APP_SESSIONS[app] ||= Class.new(Integration::Session) {
|
336
336
|
# If the app is a Rails app, make url_helpers available on the session.
|
337
337
|
# This makes app.url_for and app.foo_path available in the console.
|
338
|
-
if app.respond_to?(:routes)
|
338
|
+
if app.respond_to?(:routes) && app.routes.is_a?(ActionDispatch::Routing::RouteSet)
|
339
339
|
include app.routes.url_helpers
|
340
340
|
include app.routes.mounted_helpers
|
341
341
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actionpack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.0.
|
4
|
+
version: 6.0.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.0.0.
|
19
|
+
version: 6.0.0.beta2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 6.0.0.
|
26
|
+
version: 6.0.0.beta2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rack
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,28 +92,28 @@ dependencies:
|
|
92
92
|
requirements:
|
93
93
|
- - '='
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version: 6.0.0.
|
95
|
+
version: 6.0.0.beta2
|
96
96
|
type: :runtime
|
97
97
|
prerelease: false
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
100
|
- - '='
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version: 6.0.0.
|
102
|
+
version: 6.0.0.beta2
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
104
|
name: activemodel
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
106
106
|
requirements:
|
107
107
|
- - '='
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version: 6.0.0.
|
109
|
+
version: 6.0.0.beta2
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
112
|
version_requirements: !ruby/object:Gem::Requirement
|
113
113
|
requirements:
|
114
114
|
- - '='
|
115
115
|
- !ruby/object:Gem::Version
|
116
|
-
version: 6.0.0.
|
116
|
+
version: 6.0.0.beta2
|
117
117
|
description: Web apps on Rails. Simple, battle-tested conventions for building and
|
118
118
|
testing MVC web applications. Works with any Rack-compatible server.
|
119
119
|
email: david@loudthinking.com
|
@@ -301,8 +301,8 @@ homepage: http://rubyonrails.org
|
|
301
301
|
licenses:
|
302
302
|
- MIT
|
303
303
|
metadata:
|
304
|
-
source_code_uri: https://github.com/rails/rails/tree/v6.0.0.
|
305
|
-
changelog_uri: https://github.com/rails/rails/blob/v6.0.0.
|
304
|
+
source_code_uri: https://github.com/rails/rails/tree/v6.0.0.beta2/actionpack
|
305
|
+
changelog_uri: https://github.com/rails/rails/blob/v6.0.0.beta2/actionpack/CHANGELOG.md
|
306
306
|
post_install_message:
|
307
307
|
rdoc_options: []
|
308
308
|
require_paths:
|