Skip to content

Commit

Permalink
Fix failure screenshots on Rails 7.1
Browse files Browse the repository at this point in the history
  • Loading branch information
JonRowe committed Nov 14, 2023
1 parent 51e3cdc commit e9851b5
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
46 changes: 46 additions & 0 deletions lib/rspec/rails/example/system_example_group.rb
Expand Up @@ -44,6 +44,52 @@ def method_name
].join("_").tr(CHARS_TO_TRANSLATE.join, "_").byteslice(0...200).scrub("") + "_#{rand(1000)}"
end

if ::Rails::VERSION::STRING.to_f >= 7.1
# @private
# Allows failure screenshot to work whilst not exposing metadata
class SuppressRailsScreenshotMetadata
def initialize
@example_data = {}
end

def [](key)
if @example_data.key?(key)
@example_data[key]
else
raise_wrong_scope_error
end
end

def []=(key, value)
if key == :failure_screenshot_path
@example_data[key] = value
else
raise_wrong_scope_error
end
end

def method_missing(_name, *_args, &_block)
raise_wrong_scope_error
end

private

def raise_wrong_scope_error
raise RSpec::Core::ExampleGroup::WrongScopeError,
"`metadata` is not available from within an example " \
"(e.g. an `it` block) or from constructs that run in the " \
"scope of an example (e.g. `before`, `let`, etc). It is " \
"only available on an example group (e.g. a `describe` or "\
"`context` block)"
end
end

# @private
def metadata
@metadata ||= SuppressRailsScreenshotMetadata.new
end
end

# Delegates to `Rails.application`.
def app
::Rails.application
Expand Down
47 changes: 47 additions & 0 deletions spec/rspec/rails/example/system_example_group_spec.rb
Expand Up @@ -92,6 +92,53 @@ def take_screenshot
end
end

describe '#take_screenshot', if: ::Rails::VERSION::STRING.to_f >= 7.1 do
it 'handles Rails calling metadata' do
allow(Capybara::Session).to receive(:instance_created?).and_return(true)
group = RSpec::Core::ExampleGroup.describe do
include SystemExampleGroup

before do
driven_by(:selenium)
end

def page
instance_double(Capybara::Session, save_screenshot: nil)
end
end
example = group.it('fails') { raise }
group.run

expect(example.metadata[:execution_result].exception).to be_a RuntimeError
end
end

describe '#metadata', if: ::Rails::VERSION::STRING.to_f >= 7.1 do
let(:group) do
RSpec::Core::ExampleGroup.describe do
include SystemExampleGroup
end
end

it 'fakes out the rails expected method' do
example = group.it('does nothing') {
metadata[:failure_screenshot_path] = :value
expect(metadata[:failure_screenshot_path]).to eq(:value)
}
group.run
expect(example.execution_result.status).to eq :passed
end

it 'still raises correctly if you use it for something else' do
examples = []
examples << group.it('fails nothing') { metadata[:other] = :value }
examples << group.it('fails nothing') { metadata[:other] }
examples << group.it('fails nothing') { metadata.key?(:any) }
group.run
expect(examples.map(&:execution_result)).to all have_attributes status: :failed
end
end

describe "hook order" do
it 'calls Capybara.reset_sessions (TestUnit after_teardown) after any after hooks' do
calls_in_order = []
Expand Down

0 comments on commit e9851b5

Please sign in to comment.