diff --git a/README.md b/README.md index 46ff417f..9c383ef2 100644 --- a/README.md +++ b/README.md @@ -507,6 +507,12 @@ Finally, in drivers that support it, you can save a screenshot: page.save_screenshot('screenshot.png') ``` +Or have it save and automatically open: + +```ruby +save_and_open_screenshot +``` + ## Matching It is possible to customize how Capybara finds elements. At your disposal diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index 495935f3..4c252d83 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -42,8 +42,8 @@ module Capybara :execute_script, :evaluate_script, :visit, :go_back, :go_forward, :within, :within_fieldset, :within_table, :within_frame, :within_window, :save_page, :save_and_open_page, :save_screenshot, - :reset_session!, :response_headers, :status_code, - :title, :has_title?, :has_no_title?, :current_scope + :save_and_open_screenshot, :reset_session!, :response_headers, + :status_code, :title, :has_title?, :has_no_title?, :current_scope ] DSL_METHODS = NODE_METHODS + SESSION_METHODS @@ -360,8 +360,7 @@ module Capybara # @param [String] path The path to where it should be saved [optional] # def save_page(path=nil) - path ||= "capybara-#{Time.new.strftime("%Y%m%d%H%M%S")}#{rand(10**10)}.html" - path = File.expand_path(path, Capybara.save_and_open_page_path) + path ||= default_path('html') FileUtils.mkdir_p(File.dirname(path)) @@ -377,14 +376,7 @@ module Capybara # def save_and_open_page(file_name=nil) file_name = save_page(file_name) - - begin - require "launchy" - Launchy.open(file_name) - rescue LoadError - warn "Page saved to #{file_name} with save_and_open_page." - warn "Please install the launchy gem to open page automatically." - end + open_file(file_name) end ## @@ -394,7 +386,23 @@ module Capybara # @param [String] path A string of image path # @option [Hash] options Options for saving screenshot def save_screenshot(path, options={}) + path ||= default_path('png') + + FileUtils.mkdir_p(File.dirname(path)) + driver.save_screenshot(path, options) + path + end + + ## + # + # Save a screenshot of the page and open it for inspection + # + # @param [String] file_name The path to where it should be saved [optional] + # + def save_and_open_screenshot(file_name=nil) + file_name = save_screenshot(file_name) + open_file(file_name) end def document @@ -440,6 +448,22 @@ module Capybara private + def open_file(file_name) + begin + require "launchy" + Launchy.open(file_name) + rescue LoadError + warn "File saved to #{file_name}." + warn "Please install the launchy gem to open the file automatically." + end + end + + def default_path(extension) + timestamp = Time.new.strftime("%Y%m%d%H%M%S") + path = "capybara-#{timestamp}#{rand(10**10)}.#{extension}" + File.expand_path(path, Capybara.save_and_open_page_path) + end + def scopes @scopes ||= [document] end diff --git a/lib/capybara/spec/session/save_and_open_screenshot_spec.rb b/lib/capybara/spec/session/save_and_open_screenshot_spec.rb new file mode 100644 index 00000000..aee9fa40 --- /dev/null +++ b/lib/capybara/spec/session/save_and_open_screenshot_spec.rb @@ -0,0 +1,46 @@ +require 'launchy' + +Capybara::SpecHelper.spec '#save_and_open_screenshot' do + before do + @session.visit '/' + end + + it 'opens file from the default directory', :requires => [:screenshot] do + expected_file_regex = %r{capybara/capybara-\d+\.png} + @session.driver.stub(:save_screenshot) + Launchy.stub(:open) + + @session.save_and_open_screenshot + + expect(@session.driver).to have_received(:save_screenshot). + with(expected_file_regex, {}) + expect(Launchy).to have_received(:open).with(expected_file_regex) + end + + it 'opens file from the provided directory', :requires => [:screenshot] do + custom_path = 'screenshots/1.png' + @session.driver.stub(:save_screenshot) + Launchy.stub(:open) + + @session.save_and_open_screenshot(custom_path) + + expect(@session.driver).to have_received(:save_screenshot). + with(custom_path, {}) + expect(Launchy).to have_received(:open).with(custom_path) + end + + context 'when launchy cannot be required' do + it 'prints out a correct warning message', :requires => [:screenshot] do + file_path = File.join(Dir.tmpdir, 'test.png') + @session.stub(:require).with('launchy').and_raise(LoadError) + @session.stub(:warn) + + @session.save_and_open_screenshot(file_path) + + expect(@session).to have_received(:warn). + with("File saved to #{file_path}.") + expect(@session).to have_received(:warn). + with('Please install the launchy gem to open the file automatically.') + end + end +end diff --git a/lib/capybara/spec/session/screenshot.rb b/lib/capybara/spec/session/screenshot_spec.rb similarity index 79% rename from lib/capybara/spec/session/screenshot.rb rename to lib/capybara/spec/session/screenshot_spec.rb index bc02e327..d1f35e81 100644 --- a/lib/capybara/spec/session/screenshot.rb +++ b/lib/capybara/spec/session/screenshot_spec.rb @@ -4,11 +4,13 @@ Capybara::SpecHelper.spec "#save_screenshot" do before do @session.visit '/' - @session.save_screenshot image_path end it "should generate PNG file", :requires => [:screenshot] do + path = @session.save_screenshot image_path + magic = File.read(image_path, 4) expect(magic).to eq "\x89PNG" + expect(path).to eq image_path end end