From 59895db44b73b9a333387eee2078fda8feec9ce5 Mon Sep 17 00:00:00 2001
From: Maxim Perepelitsa <n0xff@outlook.com>
Date: Fri, 9 Nov 2018 01:03:04 +0700
Subject: Reset sessions on failed system test screenshot

Reset Capybara sessions if `take_failed_screenshot` raise exception
in system test `after_teardown`.
---
 actionpack/CHANGELOG.md                            |  7 ++++++
 .../test_helpers/setup_and_teardown.rb             |  7 ++++--
 railties/test/application/test_runner_test.rb      | 25 ++++++++++++++++++++++
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 81201795d4..97d7049cba 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,3 +1,10 @@
+*   Reset Capybara sessions if failed system test screenshot raising an exception.
+
+    Reset Capybara sessions if `take_failed_screenshot` raise exception
+    in system test `after_teardown`.
+
+    *Maxim Perepelitsa*
+
 *   Use request object for context if there's no controller
 
     There is no controller instance when using a redirect route or a
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 e47d5020f4..600e9c733b 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
@@ -17,8 +17,11 @@ module ActionDispatch
         end
 
         def after_teardown
-          take_failed_screenshot
-          Capybara.reset_sessions!
+          begin
+            take_failed_screenshot
+          ensure
+            Capybara.reset_sessions!
+          end
         ensure
           super
         end
diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb
index 5c34b205c9..e98a41fb26 100644
--- a/railties/test/application/test_runner_test.rb
+++ b/railties/test/application/test_runner_test.rb
@@ -703,6 +703,31 @@ module ApplicationTests
       end
     end
 
+    def test_reset_sessions_on_failed_system_test_screenshot
+      app_file "test/system/reset_sessions_on_failed_system_test_screenshot_test.rb", <<~RUBY
+        require "application_system_test_case"
+
+        class ResetSessionsOnFailedSystemTestScreenshotTest < ApplicationSystemTestCase
+          ActionDispatch::SystemTestCase.class_eval do
+            def take_failed_screenshot
+              raise Capybara::CapybaraError
+            end
+          end
+
+          Capybara.instance_eval do
+            def reset_sessions!
+              puts "Capybara.reset_sessions! called"
+            end
+          end
+
+          test "dummy" do
+          end
+        end
+      RUBY
+      output = run_test_command("test/system/reset_sessions_on_failed_system_test_screenshot_test.rb")
+      assert_match "Capybara.reset_sessions! called", output
+    end
+
     def test_system_tests_are_not_run_with_the_default_test_command
       app_file "test/system/dummy_test.rb", <<-RUBY
         require "application_system_test_case"
-- 
cgit v1.2.3