Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

If error occurs within a within_frame block, save the offending frame #291

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ gem 'rack', '~> 1.0'
gem 'rake', '~> 10.0'
gem 'appraisal', '~> 2.0'
gem 'aruba', '~> 0.14.0'
# gem 'debug'

# For using selenium driver
gem 'selenium-webdriver'
gem 'webdrivers'
gem 'puma', '~> 5.6'
12 changes: 10 additions & 2 deletions lib/capybara-screenshot/capybara.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,18 @@ def screenshot_and_open_image
end

module SessionScreenshotOverrides
def within_window(window_or_handle)
def within_window(window)
super
rescue Exception
Thread.current[:capybara_screenshot_offending_window] = window_or_handle
Thread.current[:capybara_screenshot_offending_window] = window

raise
end

def within_frame(frame)
super
rescue Exception
Thread.current[:capybara_screenshot_offending_frame] = frame

raise
end
Expand Down
22 changes: 21 additions & 1 deletion lib/capybara-screenshot/saver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def initialize(capybara, page, html_save=true, filename_prefix='screenshot')

def save
current_path do |path|
within_offending_window do
within_offending_window_or_frame do
if path.empty?
warn 'WARN: Screenshot could not be saved. `page.current_path` is empty.'
else
Expand Down Expand Up @@ -145,15 +145,35 @@ def which(cmd)
nil
end

def within_offending_window_or_frame
within_offending_window do
within_offending_frame do
yield
end
end
end

def within_offending_window
return yield unless Thread.current[:capybara_screenshot_offending_window]

page.within_window(Thread.current[:capybara_screenshot_offending_window]) do
yield
end

ensure
Thread.current[:capybara_screenshot_offending_window] = nil
end

def within_offending_frame
return yield unless Thread.current[:capybara_screenshot_offending_frame]

page.within_frame(Thread.current[:capybara_screenshot_offending_frame]) do
yield
end

ensure
Thread.current[:capybara_screenshot_offending_frame] = nil
end
end
end
end
76 changes: 76 additions & 0 deletions spec/feature/capybara_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
require 'spec_helper'

describe Capybara::Screenshot::RSpec, 'using with Capybara', type: :aruba do
include CommonSetup

before do
Capybara::Screenshot.capybara_tmp_path = expand_path('tmp')
end

def run_failing_case(code, error_message, format=nil)
run_case code, format: format
if error_message.kind_of?(Regexp)
expect(last_command_started.output).to match(error_message)
else
expect(last_command_started.output).to include(error_message)
end
end

def run_case(code, options = {})
write_file('spec/test_failure.rb', <<-RUBY)
#{ensure_load_paths_valid}
require 'rspec'
require 'capybara'
require 'capybara/rspec'
require 'capybara-screenshot'
require 'capybara-screenshot/rspec'

require 'webdrivers'
Capybara.register_driver :firefox do |app|
options = Selenium::WebDriver::Firefox::Options.new
options.args << '--headless'
capabilities = Selenium::WebDriver::Remote::Capabilities.firefox({})

Capybara::Selenium::Driver.new(
app,
browser: :firefox,
capabilities: [capabilities, options],
)
end
Capybara.default_driver = :firefox

#{setup_test_app}
#{code}
RUBY

cmd = cmd_with_format(options[:format])
run_simple_with_retry cmd

expect(last_command_started.output).to match('0 failures') if options[:assert_all_passed]
end

def cmd_with_format(format)
"rspec #{"--format #{format} " if format}#{expand_path('spec/test_failure.rb')}"
end

# TODO: within_window did not have tests before
it 'saves a screenshot for the correct window for failures ocurring inside within_window'

it 'saves a screenshot for the correct frame for failures ocurring inside within_frame' do
run_failing_case <<-RUBY, %r{Unable to find (visible )?link or button "you'll never find me"}
RSpec.describe '/has_frame', type: :feature do
it do
visit '/has_frame'
expect(page.body).to include('This is the has_frame page')

within_frame 'different_page_frame' do
puts page.body
expect(page.body).to include('This is a different page')
click_on "you'll never find me"
end
end
end
RUBY
expect('tmp/screenshot.html').to have_file_content(/This is a different page/)
end
end
6 changes: 6 additions & 0 deletions spec/support/test_app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,10 @@ class TestApp < Sinatra::Base
get '/different_page' do
'This is a different page'
end

get '/has_frame' do
'This is the has_frame page
<iframe src="/different_page" id="different_page_frame">
</iframe'
end
end