actionpack 6.0.3.3 → 6.1.1
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 +267 -222
- data/MIT-LICENSE +1 -1
- data/lib/abstract_controller.rb +1 -0
- data/lib/abstract_controller/base.rb +35 -2
- data/lib/abstract_controller/callbacks.rb +2 -2
- data/lib/abstract_controller/helpers.rb +105 -90
- data/lib/abstract_controller/rendering.rb +9 -9
- data/lib/abstract_controller/translation.rb +8 -2
- data/lib/action_controller.rb +2 -3
- data/lib/action_controller/api.rb +2 -2
- data/lib/action_controller/base.rb +4 -2
- data/lib/action_controller/caching.rb +0 -1
- data/lib/action_controller/log_subscriber.rb +3 -3
- data/lib/action_controller/metal.rb +2 -2
- data/lib/action_controller/metal/conditional_get.rb +11 -3
- data/lib/action_controller/metal/content_security_policy.rb +1 -1
- data/lib/action_controller/metal/cookies.rb +3 -1
- data/lib/action_controller/metal/data_streaming.rb +1 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +2 -4
- data/lib/action_controller/metal/exceptions.rb +33 -0
- data/lib/action_controller/metal/head.rb +7 -4
- data/lib/action_controller/metal/helpers.rb +11 -1
- data/lib/action_controller/metal/http_authentication.rb +4 -2
- data/lib/action_controller/metal/implicit_render.rb +1 -1
- data/lib/action_controller/metal/instrumentation.rb +11 -9
- data/lib/action_controller/metal/live.rb +1 -1
- data/lib/action_controller/metal/logging.rb +20 -0
- data/lib/action_controller/metal/mime_responds.rb +6 -2
- data/lib/action_controller/metal/parameter_encoding.rb +35 -4
- data/lib/action_controller/metal/params_wrapper.rb +14 -8
- data/lib/action_controller/metal/permissions_policy.rb +46 -0
- data/lib/action_controller/metal/redirecting.rb +1 -1
- data/lib/action_controller/metal/rendering.rb +6 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +48 -24
- data/lib/action_controller/metal/rescue.rb +1 -1
- data/lib/action_controller/metal/strong_parameters.rb +103 -15
- data/lib/action_controller/renderer.rb +24 -13
- data/lib/action_controller/test_case.rb +62 -56
- data/lib/action_dispatch.rb +3 -2
- data/lib/action_dispatch/http/cache.rb +12 -10
- data/lib/action_dispatch/http/content_disposition.rb +2 -2
- data/lib/action_dispatch/http/content_security_policy.rb +5 -1
- data/lib/action_dispatch/http/filter_parameters.rb +1 -1
- data/lib/action_dispatch/http/filter_redirect.rb +1 -1
- data/lib/action_dispatch/http/headers.rb +3 -2
- data/lib/action_dispatch/http/mime_negotiation.rb +20 -8
- data/lib/action_dispatch/http/mime_type.rb +28 -15
- data/lib/action_dispatch/http/parameters.rb +1 -19
- data/lib/action_dispatch/http/permissions_policy.rb +173 -0
- data/lib/action_dispatch/http/request.rb +26 -8
- data/lib/action_dispatch/http/response.rb +17 -16
- data/lib/action_dispatch/http/url.rb +3 -2
- data/lib/action_dispatch/journey.rb +0 -2
- data/lib/action_dispatch/journey/formatter.rb +53 -28
- data/lib/action_dispatch/journey/gtg/builder.rb +22 -36
- data/lib/action_dispatch/journey/gtg/simulator.rb +8 -7
- data/lib/action_dispatch/journey/gtg/transition_table.rb +6 -4
- data/lib/action_dispatch/journey/nfa/dot.rb +0 -11
- data/lib/action_dispatch/journey/nodes/node.rb +4 -3
- data/lib/action_dispatch/journey/parser.rb +13 -13
- data/lib/action_dispatch/journey/parser.y +1 -1
- data/lib/action_dispatch/journey/path/pattern.rb +13 -18
- data/lib/action_dispatch/journey/route.rb +7 -18
- data/lib/action_dispatch/journey/router.rb +26 -30
- data/lib/action_dispatch/journey/router/utils.rb +6 -4
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +9 -2
- data/lib/action_dispatch/middleware/cookies.rb +74 -33
- data/lib/action_dispatch/middleware/debug_exceptions.rb +10 -17
- data/lib/action_dispatch/middleware/debug_view.rb +1 -1
- data/lib/action_dispatch/middleware/exception_wrapper.rb +29 -17
- data/lib/action_dispatch/middleware/host_authorization.rb +25 -5
- data/lib/action_dispatch/middleware/public_exceptions.rb +1 -1
- data/lib/action_dispatch/middleware/remote_ip.rb +5 -4
- data/lib/action_dispatch/middleware/request_id.rb +4 -5
- data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -2
- data/lib/action_dispatch/middleware/session/cookie_store.rb +2 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +2 -0
- data/lib/action_dispatch/middleware/ssl.rb +12 -7
- data/lib/action_dispatch/middleware/stack.rb +18 -0
- data/lib/action_dispatch/middleware/static.rb +154 -93
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +2 -5
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +100 -8
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +21 -1
- data/lib/action_dispatch/railtie.rb +3 -2
- data/lib/action_dispatch/request/session.rb +2 -8
- data/lib/action_dispatch/request/utils.rb +26 -2
- data/lib/action_dispatch/routing/inspector.rb +8 -7
- data/lib/action_dispatch/routing/mapper.rb +102 -71
- data/lib/action_dispatch/routing/polymorphic_routes.rb +12 -11
- data/lib/action_dispatch/routing/redirection.rb +3 -3
- data/lib/action_dispatch/routing/route_set.rb +49 -41
- data/lib/action_dispatch/routing/url_for.rb +1 -0
- data/lib/action_dispatch/system_test_case.rb +29 -24
- data/lib/action_dispatch/system_testing/browser.rb +33 -27
- data/lib/action_dispatch/system_testing/driver.rb +6 -7
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +47 -6
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +4 -7
- data/lib/action_dispatch/testing/assertions.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +2 -4
- data/lib/action_dispatch/testing/assertions/routing.rb +5 -5
- data/lib/action_dispatch/testing/integration.rb +38 -27
- data/lib/action_dispatch/testing/test_process.rb +29 -4
- data/lib/action_dispatch/testing/test_request.rb +3 -3
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/gem_version.rb +3 -3
- metadata +21 -22
- data/lib/action_controller/metal/force_ssl.rb +0 -58
- data/lib/action_dispatch/http/parameter_filter.rb +0 -12
- data/lib/action_dispatch/journey/nfa/builder.rb +0 -78
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -47
- data/lib/action_dispatch/journey/nfa/transition_table.rb +0 -119
@@ -145,6 +145,7 @@ module ActionDispatch
|
|
145
145
|
|
146
146
|
%w(edit new).each do |action|
|
147
147
|
module_eval <<-EOT, __FILE__, __LINE__ + 1
|
148
|
+
# frozen_string_literal: true
|
148
149
|
def #{action}_polymorphic_url(record_or_hash, options = {})
|
149
150
|
polymorphic_url_for_action("#{action}", record_or_hash, options)
|
150
151
|
end
|
@@ -173,15 +174,15 @@ module ActionDispatch
|
|
173
174
|
end
|
174
175
|
|
175
176
|
class HelperMethodBuilder # :nodoc:
|
176
|
-
CACHE = {
|
177
|
+
CACHE = { path: {}, url: {} }
|
177
178
|
|
178
179
|
def self.get(action, type)
|
179
|
-
type = type.
|
180
|
+
type = type.to_sym
|
180
181
|
CACHE[type].fetch(action) { build action, type }
|
181
182
|
end
|
182
183
|
|
183
|
-
def self.url; CACHE[
|
184
|
-
def self.path; CACHE[
|
184
|
+
def self.url; CACHE[:url][nil]; end
|
185
|
+
def self.path; CACHE[:path][nil]; end
|
185
186
|
|
186
187
|
def self.build(action, type)
|
187
188
|
prefix = action ? "#{action}_" : ""
|
@@ -227,9 +228,9 @@ module ActionDispatch
|
|
227
228
|
end
|
228
229
|
|
229
230
|
if options.empty?
|
230
|
-
recipient.
|
231
|
+
recipient.public_send(method, *args)
|
231
232
|
else
|
232
|
-
recipient.
|
233
|
+
recipient.public_send(method, *args, options)
|
233
234
|
end
|
234
235
|
end
|
235
236
|
|
@@ -246,7 +247,7 @@ module ActionDispatch
|
|
246
247
|
end
|
247
248
|
|
248
249
|
def handle_string_call(target, str)
|
249
|
-
target.
|
250
|
+
target.public_send get_method_for_string str
|
250
251
|
end
|
251
252
|
|
252
253
|
def handle_class(klass)
|
@@ -254,7 +255,7 @@ module ActionDispatch
|
|
254
255
|
end
|
255
256
|
|
256
257
|
def handle_class_call(target, klass)
|
257
|
-
target.
|
258
|
+
target.public_send get_method_for_class klass
|
258
259
|
end
|
259
260
|
|
260
261
|
def handle_model(record)
|
@@ -276,7 +277,7 @@ module ActionDispatch
|
|
276
277
|
mapping.call(target, [record], suffix == "path")
|
277
278
|
else
|
278
279
|
method, args = handle_model(record)
|
279
|
-
target.
|
280
|
+
target.public_send(method, *args)
|
280
281
|
end
|
281
282
|
end
|
282
283
|
|
@@ -340,8 +341,8 @@ module ActionDispatch
|
|
340
341
|
end
|
341
342
|
|
342
343
|
[nil, "new", "edit"].each do |action|
|
343
|
-
CACHE[
|
344
|
-
CACHE[
|
344
|
+
CACHE[:url][action] = build action, "url"
|
345
|
+
CACHE[:path][action] = build action, "path"
|
345
346
|
end
|
346
347
|
end
|
347
348
|
end
|
@@ -65,15 +65,15 @@ module ActionDispatch
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def escape(params)
|
68
|
-
|
68
|
+
params.transform_values { |v| Rack::Utils.escape(v) }
|
69
69
|
end
|
70
70
|
|
71
71
|
def escape_fragment(params)
|
72
|
-
|
72
|
+
params.transform_values { |v| Journey::Router::Utils.escape_fragment(v) }
|
73
73
|
end
|
74
74
|
|
75
75
|
def escape_path(params)
|
76
|
-
|
76
|
+
params.transform_values { |v| Journey::Router::Utils.escape_path(v) }
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -110,8 +110,10 @@ module ActionDispatch
|
|
110
110
|
@url_helpers_module.undef_method url_name
|
111
111
|
end
|
112
112
|
routes[key] = route
|
113
|
-
|
114
|
-
|
113
|
+
|
114
|
+
helper = UrlHelper.create(route, route.defaults, name)
|
115
|
+
define_url_helper @path_helpers_module, path_name, helper, PATH
|
116
|
+
define_url_helper @url_helpers_module, url_name, helper, UNKNOWN
|
115
117
|
|
116
118
|
@path_helpers << path_name
|
117
119
|
@url_helpers << url_name
|
@@ -169,30 +171,30 @@ module ActionDispatch
|
|
169
171
|
end
|
170
172
|
|
171
173
|
class UrlHelper
|
172
|
-
def self.create(route, options, route_name
|
174
|
+
def self.create(route, options, route_name)
|
173
175
|
if optimize_helper?(route)
|
174
|
-
OptimizedUrlHelper.new(route, options, route_name
|
176
|
+
OptimizedUrlHelper.new(route, options, route_name)
|
175
177
|
else
|
176
|
-
new
|
178
|
+
new(route, options, route_name)
|
177
179
|
end
|
178
180
|
end
|
179
181
|
|
180
182
|
def self.optimize_helper?(route)
|
181
|
-
|
183
|
+
route.path.requirements.empty? && !route.glob?
|
182
184
|
end
|
183
185
|
|
184
|
-
attr_reader :
|
186
|
+
attr_reader :route_name
|
185
187
|
|
186
188
|
class OptimizedUrlHelper < UrlHelper
|
187
189
|
attr_reader :arg_size
|
188
190
|
|
189
|
-
def initialize(route, options, route_name
|
191
|
+
def initialize(route, options, route_name)
|
190
192
|
super
|
191
193
|
@required_parts = @route.required_parts
|
192
194
|
@arg_size = @required_parts.size
|
193
195
|
end
|
194
196
|
|
195
|
-
def call(t, args, inner_options)
|
197
|
+
def call(t, method_name, args, inner_options, url_strategy)
|
196
198
|
if args.size == arg_size && !inner_options && optimize_routes_generation?(t)
|
197
199
|
options = t.url_options.merge @options
|
198
200
|
options[:path] = optimized_helper(args)
|
@@ -249,15 +251,14 @@ module ActionDispatch
|
|
249
251
|
end
|
250
252
|
end
|
251
253
|
|
252
|
-
def initialize(route, options, route_name
|
254
|
+
def initialize(route, options, route_name)
|
253
255
|
@options = options
|
254
256
|
@segment_keys = route.segment_keys.uniq
|
255
257
|
@route = route
|
256
|
-
@url_strategy = url_strategy
|
257
258
|
@route_name = route_name
|
258
259
|
end
|
259
260
|
|
260
|
-
def call(t, args, inner_options)
|
261
|
+
def call(t, method_name, args, inner_options, url_strategy)
|
261
262
|
controller_options = t.url_options
|
262
263
|
options = controller_options.merge @options
|
263
264
|
hash = handle_positional_args(controller_options,
|
@@ -266,7 +267,7 @@ module ActionDispatch
|
|
266
267
|
options,
|
267
268
|
@segment_keys)
|
268
269
|
|
269
|
-
t._routes.url_for(hash, route_name, url_strategy)
|
270
|
+
t._routes.url_for(hash, route_name, url_strategy, method_name)
|
270
271
|
end
|
271
272
|
|
272
273
|
def handle_positional_args(controller_options, inner_options, args, result, path_params)
|
@@ -312,8 +313,7 @@ module ActionDispatch
|
|
312
313
|
#
|
313
314
|
# foo_url(bar, baz, bang, sort_by: 'baz')
|
314
315
|
#
|
315
|
-
def define_url_helper(mod,
|
316
|
-
helper = UrlHelper.create(route, opts, route_key, url_strategy)
|
316
|
+
def define_url_helper(mod, name, helper, url_strategy)
|
317
317
|
mod.define_method(name) do |*args|
|
318
318
|
last = args.last
|
319
319
|
options = \
|
@@ -323,7 +323,7 @@ module ActionDispatch
|
|
323
323
|
when ActionController::Parameters
|
324
324
|
args.pop.to_h
|
325
325
|
end
|
326
|
-
helper.call
|
326
|
+
helper.call(self, name, args, options, url_strategy)
|
327
327
|
end
|
328
328
|
end
|
329
329
|
end
|
@@ -334,7 +334,7 @@ module ActionDispatch
|
|
334
334
|
|
335
335
|
attr_accessor :formatter, :set, :named_routes, :default_scope, :router
|
336
336
|
attr_accessor :disable_clear_and_finalize, :resources_path_names
|
337
|
-
attr_accessor :default_url_options
|
337
|
+
attr_accessor :default_url_options, :draw_paths
|
338
338
|
attr_reader :env_key, :polymorphic_mappings
|
339
339
|
|
340
340
|
alias :routes :set
|
@@ -366,6 +366,7 @@ module ActionDispatch
|
|
366
366
|
self.named_routes = NamedRouteCollection.new
|
367
367
|
self.resources_path_names = self.class.default_resources_path_names
|
368
368
|
self.default_url_options = {}
|
369
|
+
self.draw_paths = []
|
369
370
|
|
370
371
|
@config = config
|
371
372
|
@append = []
|
@@ -476,6 +477,14 @@ module ActionDispatch
|
|
476
477
|
end
|
477
478
|
|
478
479
|
def url_helpers(supports_path = true)
|
480
|
+
if supports_path
|
481
|
+
@url_helpers_with_paths ||= generate_url_helpers(true)
|
482
|
+
else
|
483
|
+
@url_helpers_without_paths ||= generate_url_helpers(false)
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
def generate_url_helpers(supports_path)
|
479
488
|
routes = self
|
480
489
|
|
481
490
|
Module.new do
|
@@ -588,14 +597,14 @@ module ActionDispatch
|
|
588
597
|
if route.segment_keys.include?(:controller)
|
589
598
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
590
599
|
Using a dynamic :controller segment in a route is deprecated and
|
591
|
-
will be removed in Rails 6.
|
600
|
+
will be removed in Rails 6.2.
|
592
601
|
MSG
|
593
602
|
end
|
594
603
|
|
595
604
|
if route.segment_keys.include?(:action)
|
596
605
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
597
606
|
Using a dynamic :action segment in a route is deprecated and
|
598
|
-
will be removed in Rails 6.
|
607
|
+
will be removed in Rails 6.2.
|
599
608
|
MSG
|
600
609
|
end
|
601
610
|
|
@@ -641,14 +650,6 @@ module ActionDispatch
|
|
641
650
|
end
|
642
651
|
|
643
652
|
class Generator
|
644
|
-
PARAMETERIZE = lambda do |name, value|
|
645
|
-
if name == :controller
|
646
|
-
value
|
647
|
-
else
|
648
|
-
value.to_param
|
649
|
-
end
|
650
|
-
end
|
651
|
-
|
652
653
|
attr_reader :options, :recall, :set, :named_route
|
653
654
|
|
654
655
|
def initialize(named_route, options, recall, set)
|
@@ -732,10 +733,10 @@ module ActionDispatch
|
|
732
733
|
end
|
733
734
|
end
|
734
735
|
|
735
|
-
# Generates a path from routes, returns
|
736
|
-
#
|
736
|
+
# Generates a path from routes, returns a RouteWithParams or MissingRoute.
|
737
|
+
# MissingRoute will raise ActionController::UrlGenerationError.
|
737
738
|
def generate
|
738
|
-
@set.formatter.generate(named_route, options, recall
|
739
|
+
@set.formatter.generate(named_route, options, recall)
|
739
740
|
end
|
740
741
|
|
741
742
|
def different_controller?
|
@@ -760,13 +761,18 @@ module ActionDispatch
|
|
760
761
|
end
|
761
762
|
|
762
763
|
def generate_extras(options, recall = {})
|
763
|
-
|
764
|
-
|
765
|
-
|
764
|
+
if recall
|
765
|
+
options = options.merge(_recall: recall)
|
766
|
+
end
|
767
|
+
|
768
|
+
route_name = options.delete :use_route
|
769
|
+
generator = generate(route_name, options, recall)
|
770
|
+
path_info = path_for(options, route_name, [])
|
771
|
+
[URI(path_info).path, generator.params.except(:_recall).keys]
|
766
772
|
end
|
767
773
|
|
768
|
-
def generate(
|
769
|
-
Generator.new(
|
774
|
+
def generate(route_name, options, recall = {}, method_name = nil)
|
775
|
+
Generator.new(route_name, options, recall, self).generate
|
770
776
|
end
|
771
777
|
private :generate
|
772
778
|
|
@@ -786,12 +792,12 @@ module ActionDispatch
|
|
786
792
|
options.delete(:relative_url_root) || relative_url_root
|
787
793
|
end
|
788
794
|
|
789
|
-
def path_for(options, route_name = nil)
|
790
|
-
url_for(options, route_name, PATH)
|
795
|
+
def path_for(options, route_name = nil, reserved = RESERVED_OPTIONS)
|
796
|
+
url_for(options, route_name, PATH, nil, reserved)
|
791
797
|
end
|
792
798
|
|
793
799
|
# The +options+ argument must be a hash whose keys are *symbols*.
|
794
|
-
def url_for(options, route_name = nil, url_strategy = UNKNOWN)
|
800
|
+
def url_for(options, route_name = nil, url_strategy = UNKNOWN, method_name = nil, reserved = RESERVED_OPTIONS)
|
795
801
|
options = default_url_options.merge options
|
796
802
|
|
797
803
|
user = password = nil
|
@@ -811,9 +817,11 @@ module ActionDispatch
|
|
811
817
|
end
|
812
818
|
|
813
819
|
path_options = options.dup
|
814
|
-
|
820
|
+
reserved.each { |ro| path_options.delete ro }
|
815
821
|
|
816
|
-
|
822
|
+
route_with_params = generate(route_name, path_options, recall)
|
823
|
+
path = route_with_params.path(method_name)
|
824
|
+
params = route_with_params.params
|
817
825
|
|
818
826
|
if options.key? :params
|
819
827
|
params.merge! options[:params]
|
@@ -855,7 +863,7 @@ module ActionDispatch
|
|
855
863
|
params.each do |key, value|
|
856
864
|
if value.is_a?(String)
|
857
865
|
value = value.dup.force_encoding(Encoding::BINARY)
|
858
|
-
params[key] = URI.
|
866
|
+
params[key] = URI::DEFAULT_PARSER.unescape(value)
|
859
867
|
end
|
860
868
|
end
|
861
869
|
req.path_parameters = params
|
@@ -107,6 +107,7 @@ module ActionDispatch
|
|
107
107
|
@_routes = nil
|
108
108
|
super
|
109
109
|
end
|
110
|
+
ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
|
110
111
|
|
111
112
|
# Hook overridden in controller to add request information
|
112
113
|
# with +default_url_options+. Application logic should not
|
@@ -1,10 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
gem "capybara", ">=
|
3
|
+
gem "capybara", ">= 3.26"
|
4
4
|
|
5
5
|
require "capybara/dsl"
|
6
6
|
require "capybara/minitest"
|
7
|
-
require "selenium/webdriver"
|
8
7
|
require "action_controller"
|
9
8
|
require "action_dispatch/system_testing/driver"
|
10
9
|
require "action_dispatch/system_testing/browser"
|
@@ -27,7 +26,7 @@ module ActionDispatch
|
|
27
26
|
#
|
28
27
|
# Here is an example system test:
|
29
28
|
#
|
30
|
-
# require
|
29
|
+
# require "application_system_test_case"
|
31
30
|
#
|
32
31
|
# class Users::CreateTest < ApplicationSystemTestCase
|
33
32
|
# test "adding a new user" do
|
@@ -120,18 +119,6 @@ module ActionDispatch
|
|
120
119
|
super
|
121
120
|
self.class.driven_by(:selenium) unless self.class.driver?
|
122
121
|
self.class.driver.use
|
123
|
-
@proxy_route = if ActionDispatch.test_app
|
124
|
-
Class.new do
|
125
|
-
include ActionDispatch.test_app.routes.url_helpers
|
126
|
-
include ActionDispatch.test_app.routes.mounted_helpers
|
127
|
-
|
128
|
-
def url_options
|
129
|
-
default_url_options.merge(host: Capybara.app_host)
|
130
|
-
end
|
131
|
-
end.new
|
132
|
-
else
|
133
|
-
nil
|
134
|
-
end
|
135
122
|
end
|
136
123
|
|
137
124
|
def self.start_application # :nodoc:
|
@@ -170,16 +157,34 @@ module ActionDispatch
|
|
170
157
|
self.driver = SystemTesting::Driver.new(driver, **driver_options, &capabilities)
|
171
158
|
end
|
172
159
|
|
173
|
-
|
174
|
-
|
175
|
-
@
|
176
|
-
|
177
|
-
|
160
|
+
private
|
161
|
+
def url_helpers
|
162
|
+
@url_helpers ||=
|
163
|
+
if ActionDispatch.test_app
|
164
|
+
Class.new do
|
165
|
+
include ActionDispatch.test_app.routes.url_helpers
|
166
|
+
include ActionDispatch.test_app.routes.mounted_helpers
|
167
|
+
|
168
|
+
def url_options
|
169
|
+
default_url_options.reverse_merge(host: Capybara.app_host || Capybara.current_session.server_url)
|
170
|
+
end
|
171
|
+
end.new
|
172
|
+
end
|
178
173
|
end
|
179
|
-
end
|
180
174
|
|
181
|
-
|
182
|
-
|
175
|
+
def method_missing(name, *args, &block)
|
176
|
+
if url_helpers.respond_to?(name)
|
177
|
+
url_helpers.public_send(name, *args, &block)
|
178
|
+
else
|
179
|
+
super
|
180
|
+
end
|
181
|
+
end
|
183
182
|
|
184
|
-
|
183
|
+
def respond_to_missing?(name, include_private = false)
|
184
|
+
url_helpers.respond_to?(name)
|
185
|
+
end
|
186
|
+
end
|
185
187
|
end
|
188
|
+
|
189
|
+
ActiveSupport.run_load_hooks :action_dispatch_system_test_case, ActionDispatch::SystemTestCase
|
190
|
+
ActionDispatch::SystemTestCase.start_application
|
@@ -3,10 +3,11 @@
|
|
3
3
|
module ActionDispatch
|
4
4
|
module SystemTesting
|
5
5
|
class Browser # :nodoc:
|
6
|
-
attr_reader :name
|
6
|
+
attr_reader :name, :options
|
7
7
|
|
8
8
|
def initialize(name)
|
9
9
|
@name = name
|
10
|
+
set_default_options
|
10
11
|
end
|
11
12
|
|
12
13
|
def type
|
@@ -20,23 +21,9 @@ module ActionDispatch
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
headless_chrome_browser_options
|
27
|
-
when :headless_firefox
|
28
|
-
headless_firefox_browser_options
|
29
|
-
end
|
30
|
-
end
|
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
|
24
|
+
def configure
|
25
|
+
initialize_options
|
26
|
+
yield options if block_given? && options
|
40
27
|
end
|
41
28
|
|
42
29
|
# driver_path can be configured as a proc. The webdrivers gem uses this
|
@@ -47,14 +34,14 @@ module ActionDispatch
|
|
47
34
|
case type
|
48
35
|
when :chrome
|
49
36
|
if ::Selenium::WebDriver::Service.respond_to? :driver_path=
|
50
|
-
::Selenium::WebDriver::Chrome::Service.driver_path
|
37
|
+
::Selenium::WebDriver::Chrome::Service.driver_path&.call
|
51
38
|
else
|
52
39
|
# Selenium <= v3.141.0
|
53
40
|
::Selenium::WebDriver::Chrome.driver_path
|
54
41
|
end
|
55
42
|
when :firefox
|
56
43
|
if ::Selenium::WebDriver::Service.respond_to? :driver_path=
|
57
|
-
::Selenium::WebDriver::Firefox::Service.driver_path
|
44
|
+
::Selenium::WebDriver::Firefox::Service.driver_path&.call
|
58
45
|
else
|
59
46
|
# Selenium <= v3.141.0
|
60
47
|
::Selenium::WebDriver::Firefox.driver_path
|
@@ -63,17 +50,36 @@ module ActionDispatch
|
|
63
50
|
end
|
64
51
|
|
65
52
|
private
|
66
|
-
def
|
67
|
-
|
68
|
-
|
53
|
+
def initialize_options
|
54
|
+
@options ||=
|
55
|
+
case type
|
56
|
+
when :chrome
|
57
|
+
::Selenium::WebDriver::Chrome::Options.new
|
58
|
+
when :firefox
|
59
|
+
::Selenium::WebDriver::Firefox::Options.new
|
60
|
+
end
|
61
|
+
end
|
69
62
|
|
70
|
-
|
63
|
+
def set_default_options
|
64
|
+
case name
|
65
|
+
when :headless_chrome
|
66
|
+
set_headless_chrome_browser_options
|
67
|
+
when :headless_firefox
|
68
|
+
set_headless_firefox_browser_options
|
69
|
+
end
|
71
70
|
end
|
72
71
|
|
73
|
-
def
|
74
|
-
|
72
|
+
def set_headless_chrome_browser_options
|
73
|
+
configure do |capabilities|
|
74
|
+
capabilities.add_argument("--headless")
|
75
|
+
capabilities.add_argument("--disable-gpu") if Gem.win_platform?
|
76
|
+
end
|
77
|
+
end
|
75
78
|
|
76
|
-
|
79
|
+
def set_headless_firefox_browser_options
|
80
|
+
configure do |capabilities|
|
81
|
+
capabilities.add_argument("-headless")
|
82
|
+
end
|
77
83
|
end
|
78
84
|
end
|
79
85
|
end
|