leifcr-capybara-screenshot 1.0.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +13 -0
  5. data/Appraisals +19 -0
  6. data/CHANGELOG.md +256 -0
  7. data/Gemfile +9 -0
  8. data/LICENSE +19 -0
  9. data/README.md +315 -0
  10. data/Rakefile +40 -0
  11. data/capybara-screenshot.gemspec +39 -0
  12. data/gemfiles/cucumber.1.3.gemfile +11 -0
  13. data/gemfiles/cucumber.2.4.gemfile +11 -0
  14. data/gemfiles/latest.gemfile +10 -0
  15. data/gemfiles/rspec.3.0.gemfile +11 -0
  16. data/gemfiles/spinach.0.8.gemfile +11 -0
  17. data/lib/capybara-screenshot/callbacks.rb +44 -0
  18. data/lib/capybara-screenshot/capybara.rb +26 -0
  19. data/lib/capybara-screenshot/cucumber.rb +28 -0
  20. data/lib/capybara-screenshot/helpers.rb +28 -0
  21. data/lib/capybara-screenshot/minitest.rb +36 -0
  22. data/lib/capybara-screenshot/pruner.rb +48 -0
  23. data/lib/capybara-screenshot/rspec/base_reporter.rb +21 -0
  24. data/lib/capybara-screenshot/rspec/html_embed_reporter.rb +25 -0
  25. data/lib/capybara-screenshot/rspec/html_link_reporter.rb +37 -0
  26. data/lib/capybara-screenshot/rspec/json_reporter.rb +19 -0
  27. data/lib/capybara-screenshot/rspec/text_reporter.rb +39 -0
  28. data/lib/capybara-screenshot/rspec/textmate_link_reporter.rb +19 -0
  29. data/lib/capybara-screenshot/rspec.rb +95 -0
  30. data/lib/capybara-screenshot/s3_saver.rb +64 -0
  31. data/lib/capybara-screenshot/saver.rb +131 -0
  32. data/lib/capybara-screenshot/spinach.rb +26 -0
  33. data/lib/capybara-screenshot/testunit.rb +39 -0
  34. data/lib/capybara-screenshot/version.rb +5 -0
  35. data/lib/capybara-screenshot.rb +217 -0
  36. data/spec/cucumber/cucumber_spec.rb +89 -0
  37. data/spec/cucumber/step_definitions/step_definitions.rb +18 -0
  38. data/spec/cucumber/support/env.rb +17 -0
  39. data/spec/feature/minitest_spec.rb +79 -0
  40. data/spec/feature/testunit_spec.rb +77 -0
  41. data/spec/rspec/rspec_spec.rb +158 -0
  42. data/spec/spec_helper.rb +34 -0
  43. data/spec/spinach/spinach_spec.rb +60 -0
  44. data/spec/spinach/support/spinach_failure.rb +41 -0
  45. data/spec/support/aruba.rb +2 -0
  46. data/spec/support/common_setup.rb +67 -0
  47. data/spec/support/html_reporter_context.rb +28 -0
  48. data/spec/support/test_app.rb +13 -0
  49. data/spec/unit/base_reporter_spec.rb +25 -0
  50. data/spec/unit/capybara-screenshot_rspec_spec.rb +48 -0
  51. data/spec/unit/capybara-screenshot_spec.rb +121 -0
  52. data/spec/unit/capybara_spec.rb +50 -0
  53. data/spec/unit/pruner_spec.rb +108 -0
  54. data/spec/unit/rspec_reporters/html_embed_reporter_spec.rb +18 -0
  55. data/spec/unit/rspec_reporters/html_link_reporter_spec.rb +27 -0
  56. data/spec/unit/rspec_reporters/text_reporter_spec.rb +98 -0
  57. data/spec/unit/rspec_reporters/textmate_link_reporter_spec.rb +39 -0
  58. data/spec/unit/s3_saver_spec.rb +132 -0
  59. data/spec/unit/saver_spec.rb +366 -0
  60. metadata +264 -0
@@ -0,0 +1,121 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capybara::Screenshot do
4
+ describe '.register_driver' do
5
+ before(:all) do
6
+ @original_drivers = Capybara::Screenshot.registered_drivers.dup
7
+ end
8
+
9
+ after(:all) do
10
+ Capybara::Screenshot.registered_drivers = @original_drivers
11
+ end
12
+
13
+ it 'stores driver with block' do
14
+ block = lambda {}
15
+ Capybara::Screenshot.register_driver :foo, &block
16
+
17
+ expect(Capybara::Screenshot.registered_drivers[:foo]).to eql(block)
18
+ end
19
+ end
20
+
21
+ describe '.register_filename_prefix_formatter' do
22
+ before(:all) do
23
+ @original_formatters = Capybara::Screenshot.filename_prefix_formatters.dup
24
+ end
25
+
26
+ after(:all) do
27
+ Capybara::Screenshot.filename_prefix_formatters = @original_formatters
28
+ end
29
+
30
+ it 'stores test type with block' do
31
+ block = lambda { |arg| }
32
+ Capybara::Screenshot.register_filename_prefix_formatter :foo, &block
33
+
34
+ expect(Capybara::Screenshot.filename_prefix_formatters[:foo]).to eql(block)
35
+ end
36
+
37
+ describe '.filename_prefix_for' do
38
+ it 'returns "configured formatter" for specified formatter' do
39
+ Capybara::Screenshot.register_filename_prefix_formatter(:foo) { |arg| 'custom_path' }
40
+ expect(Capybara::Screenshot.filename_prefix_for(:foo, double('test'))).to eql('custom_path')
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '.filename_prefix_for' do
46
+ it 'returns "screenshot" for undefined formatter' do
47
+ expect(Capybara::Screenshot.filename_prefix_for(:foo, double('test'))).to eql('screenshot')
48
+ end
49
+ end
50
+
51
+ describe '.append_screenshot_path' do
52
+ it 'prints a deprecation message and delegates to RSpec.add_link_to_screenshot_for_failed_examples' do
53
+ begin
54
+ original_stderr = $stderr
55
+ $stderr = StringIO.new
56
+ expect {
57
+ Capybara::Screenshot.append_screenshot_path = false
58
+ }.to change {
59
+ Capybara::Screenshot::RSpec.add_link_to_screenshot_for_failed_examples
60
+ }.from(true).to(false)
61
+ expect($stderr.string).to include("append_screenshot_path is deprecated")
62
+ ensure
63
+ $stderr = original_stderr
64
+ end
65
+ end
66
+ end
67
+
68
+ describe '.new_saver' do
69
+ it 'passes through to get a new Saver if the user has not configured s3' do
70
+ saver_double = double('saver')
71
+ args = double('args')
72
+ expect(Capybara::Screenshot::Saver).to receive(:new).with(args).and_return(saver_double)
73
+
74
+ expect(Capybara::Screenshot.new_saver(args)).to eq(saver_double)
75
+ end
76
+
77
+ it 'wraps the returned saver in an S3 saver if it has been configured' do
78
+ require 'capybara-screenshot/s3_saver'
79
+
80
+ saver_double = double('saver')
81
+ args = double('args')
82
+ s3_saver_double = double('s3_saver')
83
+ s3_configuration = { hello: 'world' }
84
+
85
+ Capybara::Screenshot.s3_configuration = s3_configuration
86
+
87
+ expect(Capybara::Screenshot::Saver).to receive(:new).with(args).and_return(saver_double)
88
+ expect(Capybara::Screenshot::S3Saver).to receive(:new_with_configuration).with(saver_double, s3_configuration).and_return(s3_saver_double)
89
+
90
+ expect(Capybara::Screenshot.new_saver(args)).to eq(s3_saver_double)
91
+ end
92
+ end
93
+
94
+ describe '#prune' do
95
+ before do
96
+ Capybara::Screenshot.reset_prune_history
97
+ end
98
+
99
+ it 'prunes once by default' do
100
+ expect(Capybara::Screenshot::Pruner).to receive(:new).and_call_original.once
101
+ 3.times { Capybara::Screenshot.prune }
102
+ end
103
+
104
+ it 'prunes every time if option force: true' do
105
+ expect(Capybara::Screenshot::Pruner).to receive(:new).and_call_original.exactly(3).times
106
+ 3.times { Capybara::Screenshot.prune(force: true) }
107
+ end
108
+
109
+ context 'prune strategy' do
110
+ let(:prune_strategy) { { keep: 100 } }
111
+ before do
112
+ Capybara::Screenshot.prune_strategy = prune_strategy
113
+ end
114
+
115
+ it 'is passed to initializer' do
116
+ expect(Capybara::Screenshot::Pruner).to receive(:new).with(prune_strategy).and_call_original
117
+ Capybara::Screenshot.prune
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,50 @@
1
+ require 'capybara-screenshot'
2
+ require 'capybara/dsl'
3
+
4
+ describe Capybara do
5
+ it 'adds screen shot methods to the Capybara module' do
6
+ expect(::Capybara).to respond_to(:screenshot_and_save_page)
7
+ expect(::Capybara).to respond_to(:screenshot_and_open_image)
8
+ end
9
+
10
+ context 'request type example', :type => :request do
11
+ it 'has access to screen shot instance methods' do
12
+ expect(subject).to respond_to(:screenshot_and_save_page)
13
+ expect(subject).to respond_to(:screenshot_and_open_image)
14
+ end
15
+ end
16
+
17
+ describe 'using_session' do
18
+ include Capybara::DSL
19
+
20
+ it 'saves the name of the final session' do
21
+ expect(Capybara::Screenshot).to receive(:final_session_name=).with(:different_session)
22
+ expect {
23
+ using_session :different_session do
24
+ expect(0).to eq 1
25
+ end
26
+ }.to raise_exception ::RSpec::Expectations::ExpectationNotMetError
27
+ end
28
+ end
29
+ end
30
+
31
+ describe 'final_session_name' do
32
+ subject { Capybara::Screenshot.clone }
33
+
34
+ describe 'when the final session name has been set' do
35
+ before do
36
+ subject.final_session_name = 'my-failing-session'
37
+ end
38
+
39
+ it 'returns the name' do
40
+ expect(subject.final_session_name).to eq 'my-failing-session'
41
+ end
42
+ end
43
+
44
+ describe 'when the final session name has not been set' do
45
+ it 'returns the current session name' do
46
+ allow(Capybara).to receive(:session_name).and_return('my-current-session')
47
+ expect(subject.final_session_name).to eq 'my-current-session'
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capybara::Screenshot::Pruner do
4
+ describe '#initialize' do
5
+ let(:pruner) { Capybara::Screenshot::Pruner.new(strategy) }
6
+
7
+ context 'accepts generic strategies:' do
8
+ [:keep_all, :keep_last_run].each do |strategy_sym|
9
+ let(:strategy) { strategy_sym }
10
+
11
+ it ":#{strategy_sym}" do
12
+ expect(pruner.strategy).to eq(strategy)
13
+ end
14
+ end
15
+ end
16
+
17
+ context 'keep:int' do
18
+ let(:strategy) { { keep: 50 } }
19
+
20
+ it 'is a suitable strategy' do
21
+ expect(pruner.strategy).to eq(strategy)
22
+ end
23
+ end
24
+
25
+ context 'invalid strategy' do
26
+ context 'symbol' do
27
+ let(:strategy) { :invalid_strategy }
28
+
29
+ it 'raises an error' do
30
+ expect { pruner }.to raise_error(/Invalid prune strategy/)
31
+ end
32
+ end
33
+
34
+ context 'keep:sym' do
35
+ let(:strategy) { { keep: :symbol } }
36
+
37
+ it 'raises an error' do
38
+ expect { pruner }.to raise_error(/must be a Integer/)
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '#prune_old_screenshots' do
45
+ let(:capybara_root) { Capybara::Screenshot.capybara_root }
46
+ let(:remaining_files) { Dir.glob(File.expand_path('*', capybara_root)).sort }
47
+ let(:files_created) { [] }
48
+ let(:files_count) { 8 }
49
+ let(:pruner) { Capybara::Screenshot::Pruner.new(strategy) }
50
+
51
+ before do
52
+ allow(Capybara::Screenshot).to receive(:capybara_root).and_return(Dir.mktmpdir.to_s)
53
+
54
+ files_count.times do |i|
55
+ files_created << FileUtils.touch("#{capybara_root}/#{i}.#{i % 2 == 0 ? 'png' : 'html'}").first.tap do |file_name|
56
+ File.utime(Time.now, Time.now - files_count + i, file_name)
57
+ end
58
+ end
59
+
60
+ pruner.prune_old_screenshots
61
+ end
62
+
63
+ after do
64
+ FileUtils.rm_rf capybara_root
65
+ end
66
+
67
+ context 'with :keep_all strategy' do
68
+ let(:strategy) { :keep_all }
69
+
70
+ it 'should not remove screens' do
71
+ expect(remaining_files).to eq(files_created)
72
+ end
73
+ end
74
+
75
+ context 'with :keep_last_run strategy' do
76
+ let(:strategy) { :keep_last_run }
77
+
78
+ it 'should remove all screens' do
79
+ expect(remaining_files).to be_empty
80
+ end
81
+
82
+ context 'when dir is missing' do
83
+ before { FileUtils.rm_rf(Capybara::Screenshot.capybara_root) }
84
+
85
+ it 'should not raise error' do
86
+ expect { pruner.prune_old_screenshots }.to_not raise_error
87
+ end
88
+ end
89
+ end
90
+
91
+ context 'with :keep strategy' do
92
+ let(:keep_count) { 3 }
93
+ let(:strategy) { { keep: keep_count } }
94
+
95
+ it 'should keep specified number of screens' do
96
+ expect(remaining_files).to eq(files_created.last(keep_count))
97
+ end
98
+
99
+ context 'when dir is missing' do
100
+ before { FileUtils.rm_rf(Capybara::Screenshot.capybara_root) }
101
+
102
+ it 'should not raise error when dir is missing' do
103
+ expect { pruner.prune_old_screenshots }.to_not raise_error
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capybara::Screenshot::RSpec::HtmlEmbedReporter do
4
+ include_context 'html reporter'
5
+
6
+ context 'when an image was saved' do
7
+ before do
8
+ set_example double("example", metadata: {screenshot: {image: "path/to/image"}})
9
+ end
10
+
11
+ it 'embeds the image base64 encoded into the content' do
12
+ expect(File).to receive(:binread).with("path/to/image").and_return("image data")
13
+ encoded_image_data = Base64.encode64('image data')
14
+ content_without_styles = @reporter.extra_failure_content(nil).gsub(/ ?style='.*?' ?/, "")
15
+ expect(content_without_styles).to eql("original content<img src='data:image/png;base64,#{encoded_image_data}'>")
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capybara::Screenshot::RSpec::HtmlLinkReporter do
4
+ include_context 'html reporter'
5
+
6
+ context 'when a html file was saved' do
7
+ before do
8
+ set_example double("example", metadata: {screenshot: {html: "path/to/a html file"}})
9
+ end
10
+
11
+ it 'appends a link to the html to the original content' do
12
+ content_without_styles = @reporter.extra_failure_content(nil).gsub(/ ?style=".*?" ?/, "")
13
+ expect(content_without_styles).to eql(%{original content<p>Saved files: <a href="file://path/to/a%20html%20file">HTML page</a></p>})
14
+ end
15
+ end
16
+
17
+ context 'when a html file and an image were saved' do
18
+ before do
19
+ set_example double("example", metadata: {screenshot: {html: "path/to/html", image: "path/to/an image"}})
20
+ end
21
+
22
+ it 'appends links to both files to the original content' do
23
+ content_without_styles = @reporter.extra_failure_content(nil).gsub(/ ?style=".*?" ?/, "")
24
+ expect(content_without_styles).to eql(%{original content<p>Saved files: <a href="file://path/to/html">HTML page</a><a href="file://path/to/an%20image">Screenshot</a></p>})
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+ require 'capybara-screenshot/helpers'
3
+
4
+ describe Capybara::Screenshot::RSpec::TextReporter do
5
+ before do
6
+ # Mocking `RSpec::Core::Formatters::ProgressFormatter`, but only implementing the methods that
7
+ # are actually used in `TextReporter#dump_failure_info_with_screenshot`.
8
+ @reporter_class = Class.new do
9
+ attr_reader :output
10
+
11
+ def initialize
12
+ @output = StringIO.new
13
+ end
14
+
15
+ protected
16
+
17
+ def long_padding
18
+ " "
19
+ end
20
+
21
+ def failure_color(str)
22
+ "colorized(#{str})"
23
+ end
24
+
25
+ private
26
+
27
+ def dump_failure_info(example)
28
+ output.puts "original failure info"
29
+ end
30
+ alias_method :example_failed, :dump_failure_info
31
+ end
32
+
33
+ @reporter = @reporter_class.new
34
+ @reporter.singleton_class.send :include, described_class
35
+ end
36
+
37
+ let(:example_failed_method) do
38
+ if ::RSpec::Core::Version::STRING.to_i <= 2
39
+ :dump_failure_info
40
+ else
41
+ :example_failed
42
+ end
43
+ end
44
+
45
+ def example_failed_method_argument_double(metadata = {})
46
+ example_group = Module.new.send(:include, Capybara::DSL)
47
+ example = double("example", metadata: metadata, example_group: example_group)
48
+ if ::RSpec::Core::Version::STRING.to_i <= 2
49
+ example
50
+ else
51
+ double("notification").tap do |notification|
52
+ allow(notification).to receive(:example).and_return(example)
53
+ end
54
+ end
55
+ end
56
+
57
+ context 'when there is no screenshot' do
58
+ let(:example) { example_failed_method_argument_double }
59
+
60
+ it 'doesnt change the original output of the reporter' do
61
+ @reporter.send(example_failed_method, example)
62
+ expect(@reporter.output.string).to eql("original failure info\n")
63
+ end
64
+ end
65
+
66
+ context 'when a html file was saved' do
67
+ let(:example) { example_failed_method_argument_double(screenshot: { html: "path/to/html" }) }
68
+
69
+ it 'appends the html file path to the original output' do
70
+ @reporter.send(example_failed_method, example)
71
+ expect(@reporter.output.string).to eql("original failure info\n #{CapybaraScreenshot::Helpers.yellow("HTML screenshot: file://path/to/html")}\n")
72
+ end
73
+ end
74
+
75
+ context 'when a html file and an image were saved' do
76
+ let(:example) { example_failed_method_argument_double(screenshot: { html: "path/to/html", image: "path/to/image" }) }
77
+
78
+ it 'appends the image path to the original output' do
79
+ @reporter.send(example_failed_method, example)
80
+ expect(@reporter.output.string).to eql("original failure info\n #{CapybaraScreenshot::Helpers.yellow("HTML screenshot: file://path/to/html")}\n #{CapybaraScreenshot::Helpers.yellow("Image screenshot: file://path/to/image")}\n")
81
+ end
82
+ end
83
+
84
+
85
+ it 'works with older RSpec formatters where `#red` is used instead of `#failure_color`' do
86
+ old_reporter_class = Class.new(@reporter_class) do
87
+ undef_method :failure_color
88
+ def red(str)
89
+ "red(#{str})"
90
+ end
91
+ end
92
+ old_reporter = old_reporter_class.new
93
+ old_reporter.singleton_class.send :include, described_class
94
+ example = example_failed_method_argument_double(screenshot: { html: "path/to/html" })
95
+ old_reporter.send(example_failed_method, example)
96
+ expect(old_reporter.output.string).to eql("original failure info\n #{CapybaraScreenshot::Helpers.yellow("HTML screenshot: file://path/to/html")}\n")
97
+ end
98
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capybara::Screenshot::RSpec::TextMateLinkReporter do
4
+ include_context 'html reporter'
5
+
6
+ context 'when a html file was saved' do
7
+ before do
8
+ set_example double("example", metadata: {screenshot: {html: "path/to/a html file"}})
9
+ end
10
+
11
+ it 'appends a link to the html to the original content' do
12
+ content_without_styles = @reporter.extra_failure_content(nil).gsub(/ ?style=".*?"/, "")
13
+ # Single quotes are handled differently by CGI.escape_html in Ruby 1.9 / Ruby 2, so to be
14
+ # compatible with both versions we can't hard code the final escaped string.
15
+ expected_onclick_handler = CGI.escape_html("TextMate.system('open file://path/to/a\\%20html\\%20file'); return false;")
16
+ expect(content_without_styles).to eql(%{original content<p>} +
17
+ %{Saved files: <a href="file://path/to/a%20html%20file" onclick="#{expected_onclick_handler}">HTML page</a></p>}
18
+ )
19
+ end
20
+ end
21
+
22
+ context 'when a html file and an image were saved' do
23
+ before do
24
+ set_example double("example", metadata: {screenshot: {html: "path/to/html", image: "path/to/an image"}})
25
+ end
26
+
27
+ it 'appends links to both files to the original content' do
28
+ content_without_styles = @reporter.extra_failure_content(nil).gsub(/ ?style=".*?"/, "")
29
+ # Single quotes are handled differently by CGI.escape_html in Ruby 1.9 / Ruby 2, so to be
30
+ # compatible with both versions we can't hard code the final escaped string.
31
+ expected_onclick_handler_1 = CGI.escape_html("TextMate.system('open file://path/to/html'); return false;")
32
+ expected_onclick_handler_2 = CGI.escape_html("TextMate.system('open file://path/to/an\\%20image'); return false;")
33
+ expect(content_without_styles).to eql(%{original content<p>} +
34
+ %{Saved files: <a href="file://path/to/html" onclick="#{expected_onclick_handler_1}">HTML page</a>} +
35
+ %{<a href="file://path/to/an%20image" onclick="#{expected_onclick_handler_2}">Screenshot</a></p>}
36
+ )
37
+ end
38
+ end
39
+ end