forked from rspec/rspec-rails
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsystem_example_group.rb
127 lines (106 loc) · 3.98 KB
/
system_example_group.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
module RSpec
module Rails
# @api public
# Container class for system tests
module SystemExampleGroup
extend ActiveSupport::Concern
include RSpec::Rails::RailsExampleGroup
include RSpec::Rails::Matchers::RedirectTo
include RSpec::Rails::Matchers::RenderTemplate
include ActionDispatch::Integration::Runner
include ActionDispatch::Assertions
include ActionController::TemplateAssertions
# Special characters to translate into underscores for #method_name
CHARS_TO_TRANSLATE = ['/', '.', ':', ',', "'", '"', " "].freeze
# @private
module BlowAwayTeardownHooks
# @private
def before_teardown
end
# @private
def after_teardown
end
end
# for the SystemTesting Screenshot situation
def passed?
return false if RSpec.current_example.exception
return true unless defined?(::RSpec::Expectations::FailureAggregator)
failure_notifier = ::RSpec::Support.failure_notifier
return true unless failure_notifier.is_a?(::RSpec::Expectations::FailureAggregator)
failure_notifier.failures.empty? && failure_notifier.other_errors.empty?
end
# @private
def method_name
@method_name ||= [
self.class.name.underscore,
RSpec.current_example.description.underscore
].join("_").tr(CHARS_TO_TRANSLATE.join, "_").byteslice(0...200).scrub("") + "_#{rand(1000)}"
end
# Delegates to `Rails.application`.
def app
::Rails.application
end
included do |other|
ActiveSupport.on_load(:action_dispatch_system_test_case) do
ActionDispatch::SystemTesting::Server.silence_puma = true
end
begin
require 'capybara'
require 'action_dispatch/system_test_case'
rescue LoadError => e
abort """
LoadError: #{e.message}
System test integration requires Rails >= 5.1 and has a hard
dependency on a webserver and `capybara`, please add capybara to
your Gemfile and configure a webserver (e.g. `Capybara.server =
:webrick`) before attempting to use system specs.
""".gsub(/\s+/, ' ').strip
end
if ::Rails::VERSION::STRING >= '6.0'
original_before_teardown =
::ActionDispatch::SystemTesting::TestHelpers::SetupAndTeardown.instance_method(:before_teardown)
end
original_after_teardown =
::ActionDispatch::SystemTesting::TestHelpers::SetupAndTeardown.instance_method(:after_teardown)
other.include ::ActionDispatch::SystemTesting::TestHelpers::SetupAndTeardown
other.include ::ActionDispatch::SystemTesting::TestHelpers::ScreenshotHelper
other.include BlowAwayTeardownHooks
attr_reader :driver
if ActionDispatch::SystemTesting::Server.respond_to?(:silence_puma=)
ActionDispatch::SystemTesting::Server.silence_puma = true
end
def initialize(*args, &blk)
super(*args, &blk)
@driver = nil
self.class.before do
# A user may have already set the driver, so only default if driver
# is not set
driven_by(:selenium) unless @driver
end
end
def driven_by(driver, **driver_options, &blk)
@driver = ::ActionDispatch::SystemTestCase.driven_by(driver, **driver_options, &blk).tap(&:use)
end
before do
@routes = ::Rails.application.routes
end
after do
orig_stdout = $stdout
$stdout = StringIO.new
begin
original_before_teardown.bind(self).call
ensure
myio = $stdout
myio.rewind
RSpec.current_example.metadata[:extra_failure_lines] = myio.readlines
$stdout = orig_stdout
end
end
around do |example|
example.run
original_after_teardown.bind(self).call
end
end
end
end
end