actionpack 7.0.8.1 → 7.2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +94 -500
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +119 -106
- data/lib/abstract_controller/caching/fragments.rb +51 -52
- data/lib/abstract_controller/caching.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +94 -67
- data/lib/abstract_controller/collector.rb +6 -6
- data/lib/abstract_controller/deprecator.rb +9 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +121 -91
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +3 -16
- data/lib/abstract_controller/rendering.rb +14 -13
- data/lib/abstract_controller/translation.rb +12 -30
- data/lib/abstract_controller/url_for.rb +9 -5
- data/lib/abstract_controller.rb +8 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/api.rb +78 -73
- data/lib/action_controller/base.rb +199 -141
- data/lib/action_controller/caching.rb +16 -11
- data/lib/action_controller/deprecator.rb +9 -0
- data/lib/action_controller/form_builder.rb +21 -16
- data/lib/action_controller/log_subscriber.rb +19 -5
- data/lib/action_controller/metal/allow_browser.rb +123 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +187 -174
- data/lib/action_controller/metal/content_security_policy.rb +26 -25
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +65 -54
- data/lib/action_controller/metal/default_headers.rb +6 -2
- data/lib/action_controller/metal/etag_with_flash.rb +4 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +18 -14
- data/lib/action_controller/metal/exceptions.rb +19 -9
- data/lib/action_controller/metal/flash.rb +12 -10
- data/lib/action_controller/metal/head.rb +20 -16
- data/lib/action_controller/metal/helpers.rb +64 -67
- data/lib/action_controller/metal/http_authentication.rb +214 -200
- data/lib/action_controller/metal/implicit_render.rb +21 -17
- data/lib/action_controller/metal/instrumentation.rb +22 -12
- data/lib/action_controller/metal/live.rb +125 -92
- data/lib/action_controller/metal/logging.rb +6 -4
- data/lib/action_controller/metal/mime_responds.rb +151 -142
- data/lib/action_controller/metal/parameter_encoding.rb +34 -32
- data/lib/action_controller/metal/params_wrapper.rb +58 -58
- data/lib/action_controller/metal/permissions_policy.rb +14 -13
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +110 -84
- data/lib/action_controller/metal/renderers.rb +50 -49
- data/lib/action_controller/metal/rendering.rb +103 -82
- data/lib/action_controller/metal/request_forgery_protection.rb +279 -161
- data/lib/action_controller/metal/rescue.rb +12 -8
- data/lib/action_controller/metal/streaming.rb +174 -132
- data/lib/action_controller/metal/strong_parameters.rb +598 -473
- data/lib/action_controller/metal/testing.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +23 -14
- data/lib/action_controller/metal.rb +145 -61
- data/lib/action_controller/railtie.rb +25 -9
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +105 -66
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +157 -128
- data/lib/action_controller.rb +17 -3
- data/lib/action_dispatch/constants.rb +34 -0
- data/lib/action_dispatch/deprecator.rb +9 -0
- data/lib/action_dispatch/http/cache.rb +28 -29
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +69 -49
- data/lib/action_dispatch/http/filter_parameters.rb +27 -12
- data/lib/action_dispatch/http/filter_redirect.rb +22 -1
- data/lib/action_dispatch/http/headers.rb +23 -21
- data/lib/action_dispatch/http/mime_negotiation.rb +37 -48
- data/lib/action_dispatch/http/mime_type.rb +60 -30
- data/lib/action_dispatch/http/mime_types.rb +5 -1
- data/lib/action_dispatch/http/parameters.rb +12 -10
- data/lib/action_dispatch/http/permissions_policy.rb +32 -34
- data/lib/action_dispatch/http/rack_cache.rb +4 -0
- data/lib/action_dispatch/http/request.rb +132 -79
- data/lib/action_dispatch/http/response.rb +136 -103
- data/lib/action_dispatch/http/upload.rb +19 -15
- data/lib/action_dispatch/http/url.rb +75 -73
- data/lib/action_dispatch/journey/formatter.rb +19 -6
- data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +6 -5
- data/lib/action_dispatch/journey/parser.rb +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +2 -0
- data/lib/action_dispatch/journey/path/pattern.rb +18 -15
- data/lib/action_dispatch/journey/route.rb +12 -9
- data/lib/action_dispatch/journey/router/utils.rb +16 -15
- data/lib/action_dispatch/journey/router.rb +13 -10
- data/lib/action_dispatch/journey/routes.rb +6 -4
- data/lib/action_dispatch/journey/scanner.rb +4 -2
- data/lib/action_dispatch/journey/visitors.rb +2 -0
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/log_subscriber.rb +25 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +7 -6
- data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
- data/lib/action_dispatch/middleware/callbacks.rb +4 -0
- data/lib/action_dispatch/middleware/cookies.rb +192 -194
- data/lib/action_dispatch/middleware/debug_exceptions.rb +36 -27
- data/lib/action_dispatch/middleware/debug_locks.rb +18 -13
- data/lib/action_dispatch/middleware/debug_view.rb +9 -2
- data/lib/action_dispatch/middleware/exception_wrapper.rb +181 -27
- data/lib/action_dispatch/middleware/executor.rb +9 -1
- data/lib/action_dispatch/middleware/flash.rb +65 -46
- data/lib/action_dispatch/middleware/host_authorization.rb +22 -17
- data/lib/action_dispatch/middleware/public_exceptions.rb +12 -8
- data/lib/action_dispatch/middleware/reloader.rb +9 -5
- data/lib/action_dispatch/middleware/remote_ip.rb +88 -83
- data/lib/action_dispatch/middleware/request_id.rb +15 -8
- data/lib/action_dispatch/middleware/server_timing.rb +8 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +7 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +14 -7
- data/lib/action_dispatch/middleware/session/cookie_store.rb +32 -25
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +42 -28
- data/lib/action_dispatch/middleware/ssl.rb +60 -45
- data/lib/action_dispatch/middleware/stack.rb +15 -9
- data/lib/action_dispatch/middleware/static.rb +40 -34
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +47 -38
- data/lib/action_dispatch/railtie.rb +12 -4
- data/lib/action_dispatch/request/session.rb +39 -27
- data/lib/action_dispatch/request/utils.rb +10 -3
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +59 -9
- data/lib/action_dispatch/routing/mapper.rb +686 -639
- data/lib/action_dispatch/routing/polymorphic_routes.rb +70 -61
- data/lib/action_dispatch/routing/redirection.rb +52 -38
- data/lib/action_dispatch/routing/route_set.rb +106 -62
- data/lib/action_dispatch/routing/routes_proxy.rb +16 -19
- data/lib/action_dispatch/routing/url_for.rb +131 -122
- data/lib/action_dispatch/routing.rb +152 -150
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +27 -19
- data/lib/action_dispatch/system_testing/driver.rb +16 -22
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +53 -31
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +9 -7
- data/lib/action_dispatch/testing/assertions/response.rb +36 -26
- data/lib/action_dispatch/testing/assertions/routing.rb +203 -95
- data/lib/action_dispatch/testing/assertions.rb +5 -1
- data/lib/action_dispatch/testing/integration.rb +240 -229
- data/lib/action_dispatch/testing/request_encoder.rb +6 -1
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +14 -9
- data/lib/action_dispatch/testing/test_request.rb +4 -2
- data/lib/action_dispatch/testing/test_response.rb +34 -19
- data/lib/action_dispatch.rb +52 -21
- data/lib/action_pack/gem_version.rb +5 -3
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +18 -17
- metadata +91 -32
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionDispatch
|
4
6
|
module SystemTesting
|
5
7
|
class Browser # :nodoc:
|
6
|
-
attr_reader :name
|
8
|
+
attr_reader :name
|
7
9
|
|
8
10
|
def initialize(name)
|
9
11
|
@name = name
|
@@ -21,35 +23,32 @@ module ActionDispatch
|
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
26
|
+
def options
|
27
|
+
@options ||=
|
28
|
+
case type
|
29
|
+
when :chrome
|
30
|
+
::Selenium::WebDriver::Chrome::Options.new
|
31
|
+
when :firefox
|
32
|
+
::Selenium::WebDriver::Firefox::Options.new
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
24
36
|
def configure
|
25
|
-
|
26
|
-
yield options if block_given? && options
|
37
|
+
yield options if block_given?
|
27
38
|
end
|
28
39
|
|
29
|
-
# driver_path
|
30
|
-
#
|
31
|
-
# update the webdriver once and avoid race conditions when using
|
32
|
-
# parallel tests.
|
40
|
+
# driver_path is lazily initialized by default. Eagerly set it to avoid race
|
41
|
+
# conditions when using parallel tests.
|
33
42
|
def preload
|
34
43
|
case type
|
35
44
|
when :chrome
|
36
|
-
::Selenium::WebDriver::Chrome
|
45
|
+
resolve_driver_path(::Selenium::WebDriver::Chrome)
|
37
46
|
when :firefox
|
38
|
-
::Selenium::WebDriver::Firefox
|
47
|
+
resolve_driver_path(::Selenium::WebDriver::Firefox)
|
39
48
|
end
|
40
49
|
end
|
41
50
|
|
42
51
|
private
|
43
|
-
def initialize_options
|
44
|
-
@options ||=
|
45
|
-
case type
|
46
|
-
when :chrome
|
47
|
-
::Selenium::WebDriver::Chrome::Options.new
|
48
|
-
when :firefox
|
49
|
-
::Selenium::WebDriver::Firefox::Options.new
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
52
|
def set_default_options
|
54
53
|
case name
|
55
54
|
when :headless_chrome
|
@@ -71,6 +70,15 @@ module ActionDispatch
|
|
71
70
|
capabilities.add_argument("-headless")
|
72
71
|
end
|
73
72
|
end
|
73
|
+
|
74
|
+
def resolve_driver_path(namespace)
|
75
|
+
# The path method has been deprecated in 4.20.0
|
76
|
+
if Gem::Version.new(::Selenium::WebDriver::VERSION) >= Gem::Version.new("4.20.0")
|
77
|
+
namespace::Service.driver_path = ::Selenium::WebDriver::DriverFinder.new(options, namespace::Service.new).driver_path
|
78
|
+
else
|
79
|
+
namespace::Service.driver_path = ::Selenium::WebDriver::DriverFinder.path(options, namespace::Service)
|
80
|
+
end
|
81
|
+
end
|
74
82
|
end
|
75
83
|
end
|
76
84
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionDispatch
|
4
6
|
module SystemTesting
|
5
7
|
class Driver # :nodoc:
|
@@ -12,19 +14,11 @@ module ActionDispatch
|
|
12
14
|
@name = @options.delete(:name) || driver_type
|
13
15
|
@capabilities = capabilities
|
14
16
|
|
15
|
-
if [:poltergeist, :webkit].include?(driver_type)
|
16
|
-
ActiveSupport::Deprecation.warn <<~MSG.squish
|
17
|
-
Poltergeist and capybara-webkit are not maintained already.
|
18
|
-
Driver registration of :poltergeist or :webkit is deprecated and will be removed in Rails 7.1.
|
19
|
-
You can still use :selenium, and also :cuprite is available for alternative to Poltergeist.
|
20
|
-
MSG
|
21
|
-
end
|
22
|
-
|
23
17
|
if driver_type == :selenium
|
24
18
|
gem "selenium-webdriver", ">= 4.0.0"
|
25
19
|
require "selenium/webdriver"
|
26
20
|
@browser = Browser.new(options[:using])
|
27
|
-
@browser.preload
|
21
|
+
@browser.preload unless @options[:browser] == :remote
|
28
22
|
else
|
29
23
|
@browser = nil
|
30
24
|
end
|
@@ -38,7 +32,7 @@ module ActionDispatch
|
|
38
32
|
|
39
33
|
private
|
40
34
|
def registerable?
|
41
|
-
[:selenium, :
|
35
|
+
[:selenium, :cuprite, :rack_test, :playwright].include?(@driver_type)
|
42
36
|
end
|
43
37
|
|
44
38
|
def register
|
@@ -47,10 +41,9 @@ module ActionDispatch
|
|
47
41
|
Capybara.register_driver name do |app|
|
48
42
|
case @driver_type
|
49
43
|
when :selenium then register_selenium(app)
|
50
|
-
when :poltergeist then register_poltergeist(app)
|
51
|
-
when :webkit then register_webkit(app)
|
52
44
|
when :cuprite then register_cuprite(app)
|
53
45
|
when :rack_test then register_rack_test(app)
|
46
|
+
when :playwright then register_playwright(app)
|
54
47
|
end
|
55
48
|
end
|
56
49
|
end
|
@@ -65,16 +58,6 @@ module ActionDispatch
|
|
65
58
|
end
|
66
59
|
end
|
67
60
|
|
68
|
-
def register_poltergeist(app)
|
69
|
-
Capybara::Poltergeist::Driver.new(app, @options.merge(window_size: @screen_size))
|
70
|
-
end
|
71
|
-
|
72
|
-
def register_webkit(app)
|
73
|
-
Capybara::Webkit::Driver.new(app, Capybara::Webkit::Configuration.to_hash.merge(@options)).tap do |driver|
|
74
|
-
driver.resize_window_to(driver.current_window_handle, *@screen_size)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
61
|
def register_cuprite(app)
|
79
62
|
Capybara::Cuprite::Driver.new(app, @options.merge(window_size: @screen_size))
|
80
63
|
end
|
@@ -83,6 +66,17 @@ module ActionDispatch
|
|
83
66
|
Capybara::RackTest::Driver.new(app, respect_data_method: true, **@options)
|
84
67
|
end
|
85
68
|
|
69
|
+
def register_playwright(app)
|
70
|
+
screen = { width: @screen_size[0], height: @screen_size[1] } if @screen_size
|
71
|
+
options = {
|
72
|
+
screen: screen,
|
73
|
+
viewport: screen,
|
74
|
+
**@options
|
75
|
+
}.compact
|
76
|
+
|
77
|
+
Capybara::Playwright::Driver.new(app, **options)
|
78
|
+
end
|
79
|
+
|
86
80
|
def setup
|
87
81
|
Capybara.current_driver = name
|
88
82
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionDispatch
|
4
6
|
module SystemTesting
|
5
7
|
module TestHelpers
|
@@ -7,48 +9,58 @@ module ActionDispatch
|
|
7
9
|
module ScreenshotHelper
|
8
10
|
# Takes a screenshot of the current page in the browser.
|
9
11
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# automating visual testing. You can take multiple screenshots per test
|
13
|
-
#
|
14
|
-
#
|
12
|
+
# `take_screenshot` can be used at any point in your system tests to take a
|
13
|
+
# screenshot of the current state. This can be useful for debugging or
|
14
|
+
# automating visual testing. You can take multiple screenshots per test to
|
15
|
+
# investigate changes at different points during your test. These will be named
|
16
|
+
# with a sequential prefix (or 'failed' for failing tests)
|
17
|
+
#
|
18
|
+
# The default screenshots directory is `tmp/screenshots` but you can set a
|
19
|
+
# different one with `Capybara.save_path`
|
20
|
+
#
|
21
|
+
# You can use the `html` argument or set the
|
22
|
+
# `RAILS_SYSTEM_TESTING_SCREENSHOT_HTML` environment variable to save the HTML
|
23
|
+
# from the page that is being screenshotted so you can investigate the elements
|
24
|
+
# on the page at the time of the screenshot
|
15
25
|
#
|
16
|
-
#
|
26
|
+
# You can use the `screenshot` argument or set the
|
27
|
+
# `RAILS_SYSTEM_TESTING_SCREENSHOT` environment variable to control the output.
|
28
|
+
# Possible values are:
|
29
|
+
# `simple` (default)
|
30
|
+
# : Only displays the screenshot path. This is the default value.
|
17
31
|
#
|
18
|
-
#
|
19
|
-
#
|
32
|
+
# `inline`
|
33
|
+
# : Display the screenshot in the terminal using the iTerm image protocol
|
34
|
+
# (https://iterm2.com/documentation-images.html).
|
20
35
|
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
36
|
+
# `artifact`
|
37
|
+
# : Display the screenshot in the terminal, using the terminal artifact
|
38
|
+
# format (https://buildkite.github.io/terminal-to-html/inline-images/).
|
24
39
|
#
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
# * [+inline+] Display the screenshot in the terminal using the
|
30
|
-
# iTerm image protocol (https://iterm2.com/documentation-images.html).
|
31
|
-
# * [+artifact+] Display the screenshot in the terminal, using the terminal
|
32
|
-
# artifact format (https://buildkite.github.io/terminal-to-html/inline-images/).
|
33
|
-
def take_screenshot
|
40
|
+
#
|
41
|
+
def take_screenshot(html: false, screenshot: nil)
|
42
|
+
showing_html = html || html_from_env?
|
43
|
+
|
34
44
|
increment_unique
|
35
|
-
save_html if
|
45
|
+
save_html if showing_html
|
36
46
|
save_image
|
37
|
-
|
47
|
+
show display_image(html: showing_html, screenshot_output: screenshot)
|
38
48
|
end
|
39
49
|
|
40
|
-
# Takes a screenshot of the current page in the browser if the test
|
41
|
-
# failed.
|
50
|
+
# Takes a screenshot of the current page in the browser if the test failed.
|
42
51
|
#
|
43
|
-
#
|
52
|
+
# `take_failed_screenshot` is called during system test teardown.
|
44
53
|
def take_failed_screenshot
|
45
|
-
|
54
|
+
return unless failed? && supports_screenshot? && Capybara::Session.instance_created?
|
55
|
+
|
56
|
+
take_screenshot
|
57
|
+
metadata[:failure_screenshot_path] = relative_image_path if Minitest::Runnable.method_defined?(:metadata)
|
46
58
|
end
|
47
59
|
|
48
60
|
private
|
49
61
|
attr_accessor :_screenshot_counter
|
50
62
|
|
51
|
-
def
|
63
|
+
def html_from_env?
|
52
64
|
ENV["RAILS_SYSTEM_TESTING_SCREENSHOT_HTML"] == "1"
|
53
65
|
end
|
54
66
|
|
@@ -62,7 +74,7 @@ module ActionDispatch
|
|
62
74
|
end
|
63
75
|
|
64
76
|
def image_name
|
65
|
-
sanitized_method_name = method_name.
|
77
|
+
sanitized_method_name = method_name.gsub(/[^\w]+/, "-")
|
66
78
|
name = "#{unique}_#{sanitized_method_name}"
|
67
79
|
name[0...225]
|
68
80
|
end
|
@@ -87,10 +99,15 @@ module ActionDispatch
|
|
87
99
|
"#{absolute_path}.png"
|
88
100
|
end
|
89
101
|
|
102
|
+
def relative_image_path
|
103
|
+
"#{absolute_path.relative_path_from(Rails.root)}.png"
|
104
|
+
end
|
105
|
+
|
90
106
|
def absolute_html_path
|
91
107
|
"#{absolute_path}.html"
|
92
108
|
end
|
93
109
|
|
110
|
+
# rubocop:disable Lint/Debugger
|
94
111
|
def save_html
|
95
112
|
page.save_page(absolute_html_path)
|
96
113
|
end
|
@@ -98,6 +115,7 @@ module ActionDispatch
|
|
98
115
|
def save_image
|
99
116
|
page.save_screenshot(absolute_image_path)
|
100
117
|
end
|
118
|
+
# rubocop:enable Lint/Debugger
|
101
119
|
|
102
120
|
def output_type
|
103
121
|
# Environment variables have priority
|
@@ -109,11 +127,15 @@ module ActionDispatch
|
|
109
127
|
output_type
|
110
128
|
end
|
111
129
|
|
112
|
-
def
|
130
|
+
def show(img)
|
131
|
+
puts img
|
132
|
+
end
|
133
|
+
|
134
|
+
def display_image(html:, screenshot_output:)
|
113
135
|
message = +"[Screenshot Image]: #{image_path}\n"
|
114
|
-
message << +"[Screenshot HTML]: #{html_path}\n" if
|
136
|
+
message << +"[Screenshot HTML]: #{html_path}\n" if html
|
115
137
|
|
116
|
-
case output_type
|
138
|
+
case screenshot_output || output_type
|
117
139
|
when "artifact"
|
118
140
|
message << "\e]1338;url=artifact://#{absolute_image_path}\a\n"
|
119
141
|
when "inline"
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionDispatch
|
4
|
-
# This is a class that abstracts away an asserted response. It purposely
|
5
|
-
#
|
6
|
-
#
|
6
|
+
# This is a class that abstracts away an asserted response. It purposely does
|
7
|
+
# not inherit from Response because it doesn't need it. That means it does not
|
8
|
+
# have headers or a body.
|
7
9
|
class AssertionResponse
|
8
10
|
attr_reader :code, :name
|
9
11
|
|
@@ -14,9 +16,9 @@ module ActionDispatch
|
|
14
16
|
error: "5XX"
|
15
17
|
}
|
16
18
|
|
17
|
-
# Accepts a specific response status code as an Integer (404) or String
|
18
|
-
#
|
19
|
-
#
|
19
|
+
# Accepts a specific response status code as an Integer (404) or String ('404')
|
20
|
+
# or a response status range as a Symbol pseudo-code (:success, indicating any
|
21
|
+
# 200-299 status code).
|
20
22
|
def initialize(code_or_name)
|
21
23
|
if code_or_name.is_a?(Symbol)
|
22
24
|
@name = code_or_name
|
@@ -36,7 +38,7 @@ module ActionDispatch
|
|
36
38
|
|
37
39
|
private
|
38
40
|
def code_from_name(name)
|
39
|
-
GENERIC_RESPONSE_CODES[name] || Rack::Utils
|
41
|
+
GENERIC_RESPONSE_CODES[name] || Rack::Utils.status_code(name)
|
40
42
|
end
|
41
43
|
|
42
44
|
def name_from_code(code)
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionDispatch
|
4
6
|
module Assertions
|
5
|
-
# A small suite of assertions that test responses from
|
7
|
+
# A small suite of assertions that test responses from Rails applications.
|
6
8
|
module ResponseAssertions
|
7
9
|
RESPONSE_PREDICATES = { # :nodoc:
|
8
10
|
success: :successful?,
|
@@ -13,24 +15,25 @@ module ActionDispatch
|
|
13
15
|
|
14
16
|
# Asserts that the response is one of the following types:
|
15
17
|
#
|
16
|
-
# *
|
17
|
-
# *
|
18
|
-
# *
|
19
|
-
# *
|
18
|
+
# * `:success` - Status code was in the 200-299 range
|
19
|
+
# * `:redirect` - Status code was in the 300-399 range
|
20
|
+
# * `:missing` - Status code was 404
|
21
|
+
# * `:error` - Status code was in the 500-599 range
|
22
|
+
#
|
20
23
|
#
|
21
|
-
# You can also pass an explicit status number like
|
22
|
-
#
|
23
|
-
#
|
24
|
+
# You can also pass an explicit status number like `assert_response(501)` or its
|
25
|
+
# symbolic equivalent `assert_response(:not_implemented)`. See
|
26
|
+
# `Rack::Utils::SYMBOL_TO_STATUS_CODE` for a full list.
|
24
27
|
#
|
25
|
-
#
|
26
|
-
#
|
28
|
+
# # Asserts that the response was a redirection
|
29
|
+
# assert_response :redirect
|
27
30
|
#
|
28
|
-
#
|
29
|
-
#
|
31
|
+
# # Asserts that the response code was status code 401 (unauthorized)
|
32
|
+
# assert_response 401
|
30
33
|
def assert_response(type, message = nil)
|
31
34
|
message ||= generate_response_message(type)
|
32
35
|
|
33
|
-
if RESPONSE_PREDICATES.
|
36
|
+
if RESPONSE_PREDICATES.key?(type)
|
34
37
|
assert @response.public_send(RESPONSE_PREDICATES[type]), message
|
35
38
|
else
|
36
39
|
assert_equal AssertionResponse.new(type).code, @response.response_code, message
|
@@ -39,23 +42,30 @@ module ActionDispatch
|
|
39
42
|
|
40
43
|
# Asserts that the response is a redirect to a URL matching the given options.
|
41
44
|
#
|
42
|
-
#
|
43
|
-
#
|
45
|
+
# # Asserts that the redirection was to the "index" action on the WeblogController
|
46
|
+
# assert_redirected_to controller: "weblog", action: "index"
|
44
47
|
#
|
45
|
-
#
|
46
|
-
#
|
48
|
+
# # Asserts that the redirection was to the named route login_url
|
49
|
+
# assert_redirected_to login_url
|
47
50
|
#
|
48
|
-
#
|
49
|
-
#
|
51
|
+
# # Asserts that the redirection was to the URL for @customer
|
52
|
+
# assert_redirected_to @customer
|
50
53
|
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
|
54
|
-
|
55
|
-
|
54
|
+
# # Asserts that the redirection matches the regular expression
|
55
|
+
# assert_redirected_to %r(\Ahttp://example.org)
|
56
|
+
#
|
57
|
+
# # Asserts that the redirection has the HTTP status code 301 (Moved
|
58
|
+
# # Permanently).
|
59
|
+
# assert_redirected_to "/some/path", status: :moved_permanently
|
60
|
+
def assert_redirected_to(url_options = {}, options = {}, message = nil)
|
61
|
+
options, message = {}, options unless options.is_a?(Hash)
|
62
|
+
|
63
|
+
status = options[:status] || :redirect
|
64
|
+
assert_response(status, message)
|
65
|
+
return true if url_options === @response.location
|
56
66
|
|
57
67
|
redirect_is = normalize_argument_to_redirection(@response.location)
|
58
|
-
redirect_expected = normalize_argument_to_redirection(
|
68
|
+
redirect_expected = normalize_argument_to_redirection(url_options)
|
59
69
|
|
60
70
|
message ||= "Expected response to be a redirect to <#{redirect_expected}> but was a redirect to <#{redirect_is}>"
|
61
71
|
assert_operator redirect_expected, :===, redirect_is, message
|
@@ -93,7 +103,7 @@ module ActionDispatch
|
|
93
103
|
end
|
94
104
|
|
95
105
|
def code_with_name(code_or_name)
|
96
|
-
if RESPONSE_PREDICATES.
|
106
|
+
if RESPONSE_PREDICATES.value?("#{code_or_name}?".to_sym)
|
97
107
|
code_or_name = RESPONSE_PREDICATES.invert["#{code_or_name}?".to_sym]
|
98
108
|
end
|
99
109
|
|