capybara-screenshot 0.1.10 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -1,3 +1,8 @@
1
+ 15 Feb 2012
2
+ -----------
3
+
4
+ Merged pull request https://github.com/mattheworiordan/capybara-screenshot/pull/14 to limit when capybara-screenshot is fired for RSpec
5
+
1
6
  30 Jan 2012
2
7
  -----------
3
8
 
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in capybara-screenshot.gemspec
4
4
  gemspec
5
+
6
+ gem 'rake'
data/README.md CHANGED
@@ -18,6 +18,28 @@ or update your Gemfile to include:
18
18
 
19
19
  That's it!
20
20
 
21
+ If you require more control, you can generate the screenshot on demand rather than on failure. This is useful
22
+ if the failure occurs at a point where the screen shot is not as useful for debugging a rendering problem.
23
+
24
+ In Cucumber,
25
+
26
+ screen_shot_and_save_page
27
+
28
+ Or for screenshot only, with image automatically opened
29
+
30
+ screen_shot_and_open_image
31
+
32
+ Or anywhere, including specs and tests
33
+
34
+ Capybara::Screenshot.screen_shot_and_save_page
35
+
36
+ Capybara::Screenshot.screen_shot_and_open_image
37
+
38
+ This can be more useful if you disable the auto-generate on failure feature with the following config
39
+
40
+ Capybara::Screenshot.autosave_on_failure = false
41
+
42
+
21
43
  Example application
22
44
  -------------------
23
45
 
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
16
16
 
17
17
  s.add_dependency 'capybara', '>= 1.0'
18
18
  s.add_development_dependency 'rspec', '~> 2.6'
19
+ s.add_development_dependency 'timecop'
19
20
 
20
21
  s.files = `git ls-files`.split("\n")
21
22
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -1,21 +1,69 @@
1
+ module Capybara
2
+ module Screenshot
3
+ class << self
4
+ attr_accessor :autosave_on_failure
5
+ attr_accessor :registered_drivers
6
+ end
7
+
8
+ self.autosave_on_failure = true
9
+ self.registered_drivers = {}
10
+
11
+ def self.screen_shot_and_save_page
12
+ saver = Saver.new(Capybara, Capybara.page)
13
+ saver.save
14
+ {:html => saver.html_path, :image => saver.screenshot_path}
15
+ end
16
+
17
+ def self.screen_shot_and_open_image
18
+ require "launchy"
19
+
20
+ saver = Saver.new(Capybara, Capybara.page, false)
21
+ saver.save
22
+ Launchy.open saver.screenshot_path
23
+ {:html => saver.html_path, :image => saver.screenshot_path}
24
+ end
25
+
26
+ def self.capybara_root
27
+ return @capybara_root if defined?(@capybara_root)
28
+
29
+ capybara_tmp_path = Capybara.save_and_open_page_path.to_s
30
+
31
+ @capybara = if defined?(Rails)
32
+ Rails.root.join capybara_tmp_path
33
+ elsif defined?(Padrino)
34
+ Padrino.root capybara_tmp_path
35
+ elsif defined?(Sinatra)
36
+ # Sinatra support, untested
37
+ File.join(settings.root, capybara_tmp_path)
38
+ else
39
+ capybara_tmp_path
40
+ end.to_s
41
+ end
42
+
43
+ def self.register_driver(driver, &block)
44
+ self.registered_drivers[driver] = block
45
+ end
46
+ end
47
+ end
48
+
49
+ Capybara::Screenshot.register_driver(:selenium) do |driver, path|
50
+ driver.browser.save_screenshot(path)
51
+ end
52
+
53
+ Capybara::Screenshot.register_driver(:poltergeist) do |driver, path|
54
+ driver.render(path, :full => true)
55
+ end
56
+
57
+ Capybara::Screenshot.register_driver(:webkit) do |driver, path|
58
+ driver.render(path)
59
+ end
60
+
61
+ require 'capybara-screenshot/saver'
62
+
1
63
  # do nothing if Cucumber is not being used
2
64
  if defined?(Cucumber::RbSupport::RbDsl)
3
65
  require 'capybara/cucumber'
4
66
  require 'capybara-screenshot/cucumber'
5
-
6
- After do |scenario|
7
- if scenario.failed?
8
- screenshot_path = Capybara::Screenshot::Cucumber.screen_shot_and_save_page[:image]
9
- # Trying to embed the screenshot into our output."
10
- if File.exist?(screenshot_path)
11
- require "base64"
12
- #encode the image into it's base64 representation
13
- encoded_img = Base64.encode64(IO.read(screenshot_path))
14
- #this will embed the image in the HTML report, embed() is defined in cucumber
15
- embed("data:image/png;base64,#{encoded_img}", 'image/png', "Screenshot of the error")
16
- end
17
- end
18
- end
19
67
  end
20
68
 
21
69
  if defined?(RSpec)
@@ -23,11 +71,6 @@ if defined?(RSpec)
23
71
  # RSpec hooks afterwards, and thus executed first
24
72
  require 'capybara/rspec'
25
73
  require 'capybara-screenshot/rspec'
26
- RSpec.configure do |config|
27
- config.after do
28
- Capybara::Screenshot::RSpec.screen_shot_and_save_page if example.exception
29
- end
30
- end
31
74
  end
32
75
 
33
76
  begin
@@ -35,4 +78,4 @@ begin
35
78
  require 'capybara-screenshot/minitest'
36
79
  rescue LoadError
37
80
  # mini test not available
38
- end
81
+ end
@@ -1,11 +1,32 @@
1
- require 'capybara-screenshot/saver'
2
-
3
1
  module Capybara
4
2
  module Screenshot
5
3
  module Cucumber
6
- def self.screen_shot_and_save_page
7
- Capybara::Screenshot::Saver.screen_shot_and_save_page Capybara, Capybara.body
4
+
5
+ def screen_shot_and_save_page
6
+ Capybara::Screenshot.screen_shot_and_save_page
7
+ end
8
+
9
+ def screen_shot_and_open_image
10
+ Capybara::Screenshot.screen_shot_and_open_image
8
11
  end
12
+
13
+ end
14
+ end
15
+ end
16
+ World(Capybara::Screenshot::Cucumber)
17
+
18
+ After do |scenario|
19
+ if Capybara::Screenshot.autosave_on_failure && scenario.failed?
20
+ saver = Capybara::Screenshot::Saver.new(Capybara, Capybara.page)
21
+ saver.save
22
+
23
+ # Trying to embed the screenshot into our output."
24
+ if File.exist?(saver.screenshot_path)
25
+ require "base64"
26
+ #encode the image into it's base64 representation
27
+ encoded_img = Base64.encode64(IO.read(saver.screenshot_path))
28
+ #this will embed the image in the HTML report, embed() is defined in cucumber
29
+ embed("data:image/png;base64,#{encoded_img}", 'image/png', "Screenshot of the error")
9
30
  end
10
31
  end
11
32
  end
@@ -1,5 +1,3 @@
1
- require 'capybara-screenshot/saver'
2
-
3
1
  if defined?(ActionDispatch::IntegrationTest)
4
2
  method = if ActionDispatch::IntegrationTest.respond_to? :teardown
5
3
  :teardown
@@ -13,8 +11,8 @@ if defined?(ActionDispatch::IntegrationTest)
13
11
  # by adding the argument context, MiniTest passes the context of the test
14
12
  # which has an instance variable @passed indicating success / failure
15
13
  context.instance_eval do
16
- if @passed.blank?
17
- Capybara::Screenshot::Saver.screen_shot_and_save_page Capybara, Capybara.body
14
+ if Capybara::Screenshot.autosave_on_failure && @passed.blank?
15
+ Capybara::Screenshot.screen_shot_and_save_page
18
16
  end
19
17
  end
20
18
  end
@@ -1,11 +1,10 @@
1
- require 'capybara-screenshot/saver'
1
+ RSpec.configure do |config|
2
+ config.after(:type => :request) do
3
+ if Capybara::Screenshot.autosave_on_failure && example.exception
4
+ saver = Capybara::Screenshot::Saver.new(Capybara, Capybara.page)
5
+ saver.save
2
6
 
3
- module Capybara
4
- module Screenshot
5
- class RSpec
6
- def self.screen_shot_and_save_page
7
- Capybara::Screenshot::Saver.screen_shot_and_save_page Capybara, Capybara.body
8
- end
7
+ example.metadata[:full_description] += "\n Screenshot: #{saver.screenshot_path}"
9
8
  end
10
9
  end
11
10
  end
@@ -1,49 +1,47 @@
1
1
  module Capybara
2
2
  module Screenshot
3
- module Saver
4
- def self.screen_shot_and_save_page(capybara, body)
5
- #Our default return values
6
- html_path = nil
7
- image_path = nil
3
+ class Saver
4
+ attr_reader :capybara, :page, :file_base_name
8
5
 
6
+ def initialize(capybara, page, html_save=true)
7
+ @capybara, @page, @html_save = capybara, page, html_save
8
+ @file_base_name = "screenshot-#{Time.now.strftime('%Y-%m-%d-%H-%M-%S')}"
9
+ end
10
+
11
+ def save
9
12
  # if current_path empty then nothing to screen shot as browser has not loaded any URL
10
- unless capybara.current_path.to_s.empty?
11
- require 'capybara/util/save_and_open_page'
12
- file_base_name = "#{Time.now.strftime('%Y-%m-%d-%H-%M-%S')}"
13
- #will save to the capybara.save_and_open_page_path
14
- html_path = "{capybara.save_and_open_page_path}#{file_base_name}.html"
15
- capybara.save_page(body, "#{file_base_name}.html")
16
-
17
- #where should we save the screenshot to
18
- if defined?(Rails)
19
- screenshot_path = Rails.root.join "#{capybara.save_and_open_page_path}/#{file_base_name}.png"
20
- elsif defined?(Padrino)
21
- screenshot_path = Padrino.root "#{capybara.save_and_open_page_path}/#{file_base_name}.png"
22
- elsif defined?(Sinatra)
23
- # Sinatra support, untested
24
- screenshot_path = File.join(settings.root, "#{capybara.save_and_open_page_path}/#{file_base_name}.png")
25
- else
26
- screenshot_path = File.join(capybara.save_and_open_page_path.to_s, "#{file_base_name}.png")
27
- end
28
-
29
- #We try to figure out how to call the screenshot method on the current driver
30
- case capybara.current_driver
31
- when :poltergeist
32
- capybara.page.driver.render(screenshot_path, :full => true)
33
- when :selenium
34
- capybara.page.driver.browser.save_screenshot(screenshot_path)
35
- else
36
- #For other drivers that support a plain .render call and only expect the path as a parameter
37
- #This includes e.g. capybara-webkit
38
- if capybara.page.driver.respond_to?(:render)
39
- capybara.page.driver.render(screenshot_path)
40
- end
41
- end
13
+ return if capybara.current_path.to_s.empty?
14
+
15
+ save_html if @html_save
16
+ save_screenshot
17
+ end
18
+
19
+ def save_html
20
+ require 'capybara/util/save_and_open_page'
21
+ capybara.save_page(page.body, "#{file_base_name}.html")
22
+ end
23
+
24
+ def save_screenshot
25
+ if Capybara::Screenshot.registered_drivers.has_key?(capybara.current_driver)
26
+ Capybara::Screenshot.registered_drivers[capybara.current_driver].call(page.driver, screenshot_path)
27
+ else
28
+ warn "capybara-screenshot could not detect a screenshot driver for '#{capybara.current_driver}'. Saving with default with unknown results."
29
+ save_with_default
42
30
  end
43
- #we return the path to the html and the screenshot
44
- {:html => html_path, :image => screenshot_path}
45
31
  end
32
+
33
+ def save_with_default
34
+ page.driver.render(screenshot_path)
35
+ end
36
+
37
+ def html_path
38
+ File.join(Capybara::Screenshot.capybara_root, "#{file_base_name}.html")
39
+ end
40
+
41
+ def screenshot_path
42
+ File.join(Capybara::Screenshot.capybara_root, "#{file_base_name}.png")
43
+ end
44
+
46
45
  end
47
46
  end
48
47
  end
49
-
@@ -1,5 +1,5 @@
1
1
  module Capybara
2
2
  module Screenshot
3
- VERSION = "0.1.10"
3
+ VERSION = "0.2"
4
4
  end
5
5
  end
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capybara::Screenshot::Saver do
4
+ before(:all) do
5
+ @original_drivers = Capybara::Screenshot.registered_drivers
6
+ Capybara::Screenshot.registered_drivers[:default] = lambda {|driver, path| driver.render(path) }
7
+ end
8
+
9
+ after(:all) do
10
+ Capybara::Screenshot.registered_drivers = @original_drivers
11
+ end
12
+
13
+ before do
14
+ Capybara::Screenshot.stub(:capybara_root).and_return(capybara_root)
15
+ Timecop.freeze(Time.local(2012, 6, 7, 8, 9, 10))
16
+ end
17
+
18
+ let(:capybara_root) { '/tmp' }
19
+ let(:file_basename) { "screenshot-2012-06-07-08-09-10" }
20
+ let(:screenshot_path) { "#{capybara_root}/#{file_basename}.png" }
21
+
22
+ let(:driver_mock) { mock('Capybara driver').as_null_object }
23
+ let(:page_mock) { mock('Capybara session page', :body => 'body', :driver => driver_mock).as_null_object }
24
+ let(:capybara_mock) {
25
+ mock(Capybara).as_null_object.tap do |m|
26
+ m.stub(:current_driver).and_return(:default)
27
+ m.stub(:current_path).and_return('/')
28
+ end
29
+ }
30
+
31
+ let(:saver) { Capybara::Screenshot::Saver.new(capybara_mock, page_mock) }
32
+
33
+ it 'should save html file with "screenshot-Y-M-D-H-M-S.html" format' do
34
+ capybara_mock.should_receive(:save_page).with('body', "#{file_basename}.html")
35
+
36
+ saver.save
37
+ end
38
+
39
+ it 'should save screenshot file in capybara root output directory with format "screenshot-Y-M-D-H-M-S.png"' do
40
+ driver_mock.should_receive(:render).with(screenshot_path)
41
+
42
+ saver.save
43
+ end
44
+
45
+ it 'should not save html if false passed as html argument' do
46
+ saver = Capybara::Screenshot::Saver.new(capybara_mock, page_mock, false)
47
+ capybara_mock.should_not_receive(:save_page)
48
+
49
+ saver.save
50
+ end
51
+
52
+ it 'should save if current_path is empty' do
53
+ capybara_mock.stub(:current_path).and_return(nil)
54
+ capybara_mock.should_not_receive(:save_page)
55
+ driver_mock.should_not_receive(:render)
56
+
57
+ saver.save
58
+ end
59
+
60
+ describe "with selenium driver" do
61
+ before do
62
+ capybara_mock.stub(:current_driver).and_return(:selenium)
63
+ end
64
+
65
+ it 'should save via browser' do
66
+ browser_mock = mock('browser')
67
+ driver_mock.should_receive(:browser).and_return(browser_mock)
68
+ browser_mock.should_receive(:save_screenshot).with(screenshot_path)
69
+
70
+ saver.save
71
+ end
72
+ end
73
+
74
+ describe "with poltergeist driver" do
75
+ before do
76
+ capybara_mock.stub(:current_driver).and_return(:poltergeist)
77
+ end
78
+
79
+ it 'should save driver render with :full => true' do
80
+ driver_mock.should_receive(:render).with(screenshot_path, {:full => true})
81
+
82
+ saver.save
83
+ end
84
+ end
85
+
86
+ describe "with webkit driver" do
87
+ before do
88
+ capybara_mock.stub(:current_driver).and_return(:webkit)
89
+ end
90
+
91
+ it 'should save driver render' do
92
+ driver_mock.should_receive(:render).with(screenshot_path)
93
+
94
+ saver.save
95
+ end
96
+ end
97
+
98
+ describe "with unknown driver" do
99
+ before do
100
+ capybara_mock.stub(:current_driver).and_return(:unknown)
101
+ saver.stub(:warn).and_return(nil)
102
+ end
103
+
104
+ it 'should save driver render' do
105
+ driver_mock.should_receive(:render).with(screenshot_path)
106
+
107
+ saver.save
108
+ end
109
+
110
+ it 'should output warning about unknown results' do
111
+ # Not pure mock testing
112
+ saver.should_receive(:warn).with(/screenshot driver for 'unknown'.*unknown results/).and_return(nil)
113
+
114
+ saver.save
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capybara::Screenshot do
4
+ before(:all) do
5
+ @original_drivers = Capybara::Screenshot.registered_drivers
6
+ end
7
+
8
+ after(:all) do
9
+ Capybara::Screenshot.registered_drivers = @original_drivers
10
+ end
11
+
12
+ describe ".register_driver" do
13
+ it 'should store driver with block' do
14
+ block = lambda {}
15
+ Capybara::Screenshot.register_driver :foo, &block
16
+
17
+ Capybara::Screenshot.registered_drivers[:foo].should eq block
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper.rb"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+
8
+ $: << '../lib'
9
+ require 'capybara-screenshot'
10
+ require 'timecop'
11
+
12
+ RSpec.configure do |config|
13
+ config.treat_symbols_as_metadata_keys_with_true_values = true
14
+ config.run_all_when_everything_filtered = true
15
+ config.filter_run :focus
16
+ end
metadata CHANGED
@@ -1,64 +1,74 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: capybara-screenshot
3
- version: !ruby/object:Gem::Version
4
- hash: 15
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 1
9
- - 10
10
- version: 0.1.10
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.2'
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Matthew O'Riordan
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-01-30 00:00:00 +00:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2012-06-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: capybara
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 15
30
- segments:
31
- - 1
32
- - 0
33
- version: "1.0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
34
22
  type: :runtime
35
- version_requirements: *id001
36
- - !ruby/object:Gem::Dependency
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '1.0'
30
+ - !ruby/object:Gem::Dependency
37
31
  name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.6'
38
+ type: :development
38
39
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
40
41
  none: false
41
- requirements:
42
+ requirements:
42
43
  - - ~>
43
- - !ruby/object:Gem::Version
44
- hash: 15
45
- segments:
46
- - 2
47
- - 6
48
- version: "2.6"
44
+ - !ruby/object:Gem::Version
45
+ version: '2.6'
46
+ - !ruby/object:Gem::Dependency
47
+ name: timecop
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
49
54
  type: :development
50
- version_requirements: *id002
51
- description: When a Cucumber step fails, it is useful to create a screenshot image and HTML file of the current page
52
- email:
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: When a Cucumber step fails, it is useful to create a screenshot image
63
+ and HTML file of the current page
64
+ email:
53
65
  - matthew.oriordan@gmail.com
54
66
  executables: []
55
-
56
67
  extensions: []
57
-
58
68
  extra_rdoc_files: []
59
-
60
- files:
69
+ files:
61
70
  - .gitignore
71
+ - .rspec
62
72
  - CHANGELOG.md
63
73
  - Gemfile
64
74
  - LICENSE
@@ -71,39 +81,41 @@ files:
71
81
  - lib/capybara-screenshot/rspec.rb
72
82
  - lib/capybara-screenshot/saver.rb
73
83
  - lib/capybara-screenshot/version.rb
74
- has_rdoc: true
84
+ - spec/capybara-screenshot/saver_spec.rb
85
+ - spec/capybara-screenshot_spec.rb
86
+ - spec/spec_helper.rb
75
87
  homepage: http://github.com/mattheworiordan/capybara-screenshot
76
88
  licenses: []
77
-
78
89
  post_install_message:
79
90
  rdoc_options: []
80
-
81
- require_paths:
91
+ require_paths:
82
92
  - lib
83
- required_ruby_version: !ruby/object:Gem::Requirement
93
+ required_ruby_version: !ruby/object:Gem::Requirement
84
94
  none: false
85
- requirements:
86
- - - ">="
87
- - !ruby/object:Gem::Version
88
- hash: 3
89
- segments:
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ segments:
90
100
  - 0
91
- version: "0"
92
- required_rubygems_version: !ruby/object:Gem::Requirement
101
+ hash: 1087741615674543132
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
103
  none: false
94
- requirements:
95
- - - ">="
96
- - !ruby/object:Gem::Version
97
- hash: 3
98
- segments:
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ segments:
99
109
  - 0
100
- version: "0"
110
+ hash: 1087741615674543132
101
111
  requirements: []
102
-
103
112
  rubyforge_project: capybara-screenshot
104
- rubygems_version: 1.3.7
113
+ rubygems_version: 1.8.24
105
114
  signing_key:
106
115
  specification_version: 3
107
- summary: Automatically create snapshots when Cucumber steps fail with Capybara and Rails
108
- test_files: []
109
-
116
+ summary: Automatically create snapshots when Cucumber steps fail with Capybara and
117
+ Rails
118
+ test_files:
119
+ - spec/capybara-screenshot/saver_spec.rb
120
+ - spec/capybara-screenshot_spec.rb
121
+ - spec/spec_helper.rb