Skip to content

Commit 15c9c2d

Browse files
committed
Fix failure screenshots on Rails 7.1
1 parent 9681266 commit 15c9c2d

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

lib/rspec/rails/example/system_example_group.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,49 @@ def method_name
4444
].join("_").tr(CHARS_TO_TRANSLATE.join, "_").byteslice(0...200).scrub("") + "_#{rand(1000)}"
4545
end
4646

47+
if ::Rails::VERSION::STRING.to_f >= 7.1
48+
class SuppressRailsScreenshotMetadata
49+
def initialize
50+
@example_data = {}
51+
end
52+
53+
def [](key)
54+
if @example_data.key?(key)
55+
@example_data[key]
56+
else
57+
raise_wrong_scope_error
58+
end
59+
end
60+
61+
def []=(key, value)
62+
if key == :failure_screenshot_path
63+
@example_data[key] = value
64+
else
65+
raise_wrong_scope_error
66+
end
67+
end
68+
69+
def method_missing(_name, *_args, &_block)
70+
raise_wrong_scope_error
71+
end
72+
73+
private
74+
75+
def raise_wrong_scope_error
76+
raise RSpec::Core::ExampleGroup::WrongScopeError,
77+
"`metadata` is not available on an example group (e.g. a " \
78+
"`describe` or `context` block). It is only available from " \
79+
"within individual examples (e.g. `it` blocks) or from " \
80+
"constructs that run in the scope of an example (e.g. " \
81+
"`before`, `let`, etc)."
82+
end
83+
end
84+
85+
def metadata
86+
@metadata ||= SuppressRailsScreenshotMetadata.new
87+
end
88+
end
89+
4790
# Delegates to `Rails.application`.
4891
def app
4992
::Rails.application

spec/rspec/rails/example/system_example_group_spec.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,53 @@ def take_screenshot
9292
end
9393
end
9494

95+
describe '#take_screenshot', if: ::Rails::VERSION::STRING.to_f >= 7.1 do
96+
it 'handles Rails calling metadata' do
97+
allow(Capybara::Session).to receive(:instance_created?).and_return(true)
98+
group = RSpec::Core::ExampleGroup.describe do
99+
include SystemExampleGroup
100+
101+
before do
102+
driven_by(:selenium)
103+
end
104+
105+
def page
106+
instance_double(Capybara::Session, save_screenshot: nil)
107+
end
108+
end
109+
example = group.it('fails') { raise }
110+
group.run
111+
112+
expect(example.metadata[:execution_result].exception).to be_a RuntimeError
113+
end
114+
end
115+
116+
describe '#metadata', if: ::Rails::VERSION::STRING.to_f >= 7.1 do
117+
let(:group) do
118+
RSpec::Core::ExampleGroup.describe do
119+
include SystemExampleGroup
120+
end
121+
end
122+
123+
it 'fakes out the rails expected method' do
124+
example = group.it('does nothing') {
125+
metadata[:failure_screenshot_path] = :value
126+
expect(metadata[:failure_screenshot_path]).to eq(:value)
127+
}
128+
group.run
129+
expect(example.execution_result.status).to eq :passed
130+
end
131+
132+
it 'still raises correctly if you use it for something else' do
133+
examples = []
134+
examples << group.it('fails nothing') { metadata[:other] = :value }
135+
examples << group.it('fails nothing') { metadata[:other] }
136+
examples << group.it('fails nothing') { metadata.key?(:any) }
137+
group.run
138+
expect(examples.map(&:execution_result)).to all have_attributes status: :failed
139+
end
140+
end
141+
95142
describe "hook order" do
96143
it 'calls Capybara.reset_sessions (TestUnit after_teardown) after any after hooks' do
97144
calls_in_order = []

0 commit comments

Comments
 (0)