From 1c161c6092e5936c1cf4983ed230ca1a6dc812ef Mon Sep 17 00:00:00 2001 From: Ryunosuke SATO Date: Tue, 10 Jul 2012 13:50:15 +0900 Subject: [PATCH] Support `Capybara::Session#save_screenshot` --- README.md | 8 +++++++ lib/capybara/driver/base.rb | 4 ++++ lib/capybara/selenium/driver.rb | 4 ++++ lib/capybara/session.rb | 12 +++++++++- lib/capybara/spec/driver.rb | 16 ++++++++++++++ lib/capybara/spec/session/screenshot.rb | 29 +++++++++++++++++++++++++ spec/driver/selenium_driver_spec.rb | 1 + spec/dsl_spec.rb | 1 + spec/session/rack_test_session_spec.rb | 1 + spec/session/selenium_session_spec.rb | 1 + 10 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 lib/capybara/spec/session/screenshot.rb diff --git a/README.md b/README.md index d4a4efff..9a0ec6ed 100644 --- a/README.md +++ b/README.md @@ -474,6 +474,14 @@ that this may break with more complicated expressions: result = page.evaluate_script('4 + 4'); ``` +### Saving screenshot + +In drivers which support it, you can save screenshot: + +```ruby +page.save_screenshot('screenshot.png') +``` + ### Debugging It can be useful to take a snapshot of the page as it currently is and take a diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb index c4855511..df2da3fb 100644 --- a/lib/capybara/driver/base.rb +++ b/lib/capybara/driver/base.rb @@ -27,6 +27,10 @@ class Capybara::Driver::Base raise Capybara::NotSupportedByDriverError end + def save_screenshot(path, options={}) + raise Capybara::NotSupportedByDriverError + end + def response_headers raise Capybara::NotSupportedByDriverError end diff --git a/lib/capybara/selenium/driver.rb b/lib/capybara/selenium/driver.rb index 1a0f7835..cff577c1 100644 --- a/lib/capybara/selenium/driver.rb +++ b/lib/capybara/selenium/driver.rb @@ -62,6 +62,10 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base browser.execute_script "return #{script}" end + def save_screenshot(path, options={}) + browser.save_screenshot(path) + end + def reset! # Use instance variable directly so we avoid starting the browser just to reset the session if @browser diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb index 5e2993b5..958a118b 100644 --- a/lib/capybara/session.rb +++ b/lib/capybara/session.rb @@ -41,7 +41,7 @@ module Capybara :body, :html, :current_url, :current_host, :evaluate_script, :source, :visit, :within, :within_fieldset, :within_table, :within_frame, :within_window, :current_path, :save_page, - :save_and_open_page, :reset_session! + :save_and_open_page, :save_screenshot, :reset_session! ] DSL_METHODS = NODE_METHODS + SESSION_METHODS @@ -282,6 +282,16 @@ module Capybara Capybara.save_and_open_page(body, file_name) end + ## + # + # Save a screenshot of page + # + # @param [String] path A string of image path + # @option [Hash] options Options for saving screenshot + def save_screenshot(path, options={}) + driver.save_screenshot(path, options) + end + def document @document ||= Capybara::Node::Document.new(self, driver) end diff --git a/lib/capybara/spec/driver.rb b/lib/capybara/spec/driver.rb index 12e1268e..025e039c 100644 --- a/lib/capybara/spec/driver.rb +++ b/lib/capybara/spec/driver.rb @@ -324,3 +324,19 @@ shared_examples_for "driver with referer support" do @driver.body.should match %r{http://.*/referer_base} end end + +shared_examples_for "driver with screenshot support" do + describe '#save_screenshot' do + let(:image_path) { File.join(Dir.tmpdir, 'capybara-screenshot.png') } + + before do + @driver.visit '/' + @driver.save_screenshot image_path + end + + it "should generate PNG file" do + magic = File.read(image_path, 4) + magic.should eq "\x89PNG" + end + end +end diff --git a/lib/capybara/spec/session/screenshot.rb b/lib/capybara/spec/session/screenshot.rb new file mode 100644 index 00000000..27e1bda9 --- /dev/null +++ b/lib/capybara/spec/session/screenshot.rb @@ -0,0 +1,29 @@ +shared_examples_for "session with screenshot support" do + describe "#save_screenshot" do + let(:image_path) { File.join(Dir.tmpdir, 'capybara-screenshot.png') } + + before do + @session.visit '/' + @session.save_screenshot image_path + end + + it "should generate PNG file" do + magic = File.read(image_path, 4) + magic.should eq "\x89PNG" + end + end +end + +shared_examples_for "session without screenshot support" do + describe "#save_screenshot" do + before do + @session.visit('/') + end + + it "should raise an error" do + running { + @session.save_screenshot 'raise_error.png' + }.should raise_error(Capybara::NotSupportedByDriverError) + end + end +end diff --git a/spec/driver/selenium_driver_spec.rb b/spec/driver/selenium_driver_spec.rb index 8c3744fc..32dbdd69 100644 --- a/spec/driver/selenium_driver_spec.rb +++ b/spec/driver/selenium_driver_spec.rb @@ -13,6 +13,7 @@ describe Capybara::Selenium::Driver do it_should_behave_like "driver without status code support" it_should_behave_like "driver with cookies support" it_should_behave_like "driver with referer support" + it_should_behave_like "driver with screenshot support" unless RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ it "should not interfere with forking child processes" do diff --git a/spec/dsl_spec.rb b/spec/dsl_spec.rb index b0f0eb3a..f0d56ae7 100644 --- a/spec/dsl_spec.rb +++ b/spec/dsl_spec.rb @@ -213,6 +213,7 @@ describe Capybara::DSL do it_should_behave_like "session" it_should_behave_like "session without javascript support" + it_should_behave_like "session without screenshot support" it "should be possible to include it in another class" do klass = Class.new do diff --git a/spec/session/rack_test_session_spec.rb b/spec/session/rack_test_session_spec.rb index 4dd6e99f..807138c0 100644 --- a/spec/session/rack_test_session_spec.rb +++ b/spec/session/rack_test_session_spec.rb @@ -55,6 +55,7 @@ describe Capybara::Session do it_should_behave_like "session" it_should_behave_like "session without javascript support" + it_should_behave_like "session without screenshot support" it_should_behave_like "session with headers support" it_should_behave_like "session with status code support" end diff --git a/spec/session/selenium_session_spec.rb b/spec/session/selenium_session_spec.rb index 19cf0752..5e836206 100644 --- a/spec/session/selenium_session_spec.rb +++ b/spec/session/selenium_session_spec.rb @@ -20,6 +20,7 @@ describe Capybara::Session do it_should_behave_like "session" it_should_behave_like "session with javascript support" + it_should_behave_like "session with screenshot support" it_should_behave_like "session without headers support" it_should_behave_like "session without status code support" end