capybara-screenshot 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,10 @@
1
+ 1 October 2014 - 1.0.2 -> 1.0.3
2
+ -----------
3
+
4
+ * Added ability to prune screenshots automatically, see https://github.com/mattheworiordan/capybara-screenshot/pull/100
5
+
6
+ Thanks to [Anton Kolomiychuk](https://github.com/akolomiychuk) for his contribution.
7
+
1
8
  27 September 2014 - 1.0.1 -> 1.0.2
2
9
  -----------
3
10
 
data/README.md CHANGED
@@ -162,6 +162,19 @@ Capybara.save_and_open_page_path = "/file/path"
162
162
  ```
163
163
 
164
164
 
165
+ Pruning old screenshots automatically
166
+ --------------------------
167
+ By default screenshots are saved indefinitely into `$APPLICATION_ROOT/tmp/capybara`. If you want screenshots to be automatically pruned on a new failure, then you can specify one of the following prune strategies as follows:
168
+
169
+ ```ruby
170
+ # Keep only the screenshots generated from the last failing test suite
171
+ Capybara::ScreenShot.prune_strategy = :keep_last_run
172
+
173
+ # Keep up to the number of screenshots specified in the hash
174
+ Capybara::ScreenShot.prune_strategy = { keep: 20 }
175
+ ```
176
+
177
+
165
178
  Information about screenshots in RSpec output
166
179
  ---------------------------------------------
167
180
 
@@ -7,6 +7,7 @@ module Capybara
7
7
  attr_accessor :append_timestamp
8
8
  attr_accessor :webkit_options
9
9
  attr_writer :final_session_name
10
+ attr_accessor :prune_strategy
10
11
  end
11
12
 
12
13
  self.autosave_on_failure = true
@@ -14,6 +15,7 @@ module Capybara
14
15
  self.filename_prefix_formatters = {}
15
16
  self.append_timestamp = true
16
17
  self.webkit_options = {}
18
+ self.prune_strategy = :keep_all
17
19
 
18
20
  def self.append_screenshot_path=(value)
19
21
  $stderr.puts "WARNING: Capybara::Screenshot.append_screenshot_path is deprecated. " +
@@ -74,6 +76,19 @@ module Capybara
74
76
  def self.final_session_name
75
77
  @final_session_name || Capybara.session_name || :default
76
78
  end
79
+
80
+ # Prune screenshots based on prune_strategy
81
+ # Will run only once unless force:true
82
+ def self.prune(options = {})
83
+ reset_prune_history if options[:force]
84
+ Capybara::Screenshot::Pruner.new(Capybara::Screenshot.prune_strategy).prune_old_screenshots unless @pruned_previous_screenshots
85
+ @pruned_previous_screenshots = true
86
+ end
87
+
88
+ # Reset prune history allowing further prunining on next failure
89
+ def self.reset_prune_history
90
+ @pruned_previous_screenshots = nil
91
+ end
77
92
  end
78
93
  end
79
94
 
@@ -133,5 +148,4 @@ require 'capybara/util/save_and_open_page' if Capybara::VERSION.match(/^\d+/)[0]
133
148
 
134
149
  require 'capybara-screenshot/saver'
135
150
  require 'capybara-screenshot/capybara'
136
-
137
-
151
+ require 'capybara-screenshot/pruner'
@@ -8,14 +8,15 @@ module Capybara::Screenshot::MiniTestPlugin
8
8
 
9
9
  def after_teardown
10
10
  super
11
- if self.class.ancestors.map(&:to_s).include?('ActionDispatch::IntegrationTest') &&
12
- Capybara::Screenshot.autosave_on_failure && !passed?
13
- Capybara.using_session(Capybara::Screenshot.final_session_name) do
14
- filename_prefix = Capybara::Screenshot.filename_prefix_for(:minitest, self)
11
+ if self.class.ancestors.map(&:to_s).include?('ActionDispatch::IntegrationTest')
12
+ if Capybara::Screenshot.autosave_on_failure && !passed?
13
+ Capybara.using_session(Capybara::Screenshot.final_session_name) do
14
+ filename_prefix = Capybara::Screenshot.filename_prefix_for(:minitest, self)
15
15
 
16
- saver = Capybara::Screenshot::Saver.new(Capybara, Capybara.page, true, filename_prefix)
17
- saver.save
18
- saver.output_screenshot_path
16
+ saver = Capybara::Screenshot::Saver.new(Capybara, Capybara.page, true, filename_prefix)
17
+ saver.save
18
+ saver.output_screenshot_path
19
+ end
19
20
  end
20
21
  end
21
22
  end
@@ -0,0 +1,47 @@
1
+ module Capybara
2
+ module Screenshot
3
+ class Pruner
4
+ attr_reader :strategy
5
+
6
+ def initialize(strategy)
7
+ @strategy = strategy
8
+
9
+ @strategy_proc = case strategy
10
+ when :keep_all
11
+ -> { }
12
+ when :keep_last_run
13
+ -> { prune_with_last_run_strategy }
14
+ when Hash
15
+ raise ArgumentError, ":keep key is required" unless strategy[:keep]
16
+ raise ArgumentError, ":keep value must be number greater than zero" unless strategy[:keep].to_i > 0
17
+ -> { prune_with_numeric_strategy(strategy[:keep].to_i) }
18
+ else
19
+ fail "Invalid prune strategy #{strategy}. `:keep_all`or `{ keep: 10 }` are valid examples."
20
+ end
21
+ end
22
+
23
+ def prune_old_screenshots
24
+ strategy_proc.call
25
+ end
26
+
27
+ private
28
+ attr_reader :strategy_proc
29
+
30
+ def wildcard_path
31
+ File.expand_path('*', Screenshot.capybara_root)
32
+ end
33
+
34
+ def prune_with_last_run_strategy
35
+ FileUtils.rm_rf(Dir.glob(wildcard_path))
36
+ end
37
+
38
+ def prune_with_numeric_strategy(count)
39
+ files = Dir.glob(wildcard_path).sort_by do |file_name|
40
+ File.mtime(File.expand_path(file_name, Screenshot.capybara_root))
41
+ end
42
+
43
+ FileUtils.rm_rf(files[0...-count])
44
+ end
45
+ end
46
+ end
47
+ end
@@ -11,13 +11,14 @@ module Capybara
11
11
  module Screenshot
12
12
  class Saver
13
13
  attr_reader :capybara, :page, :file_base_name
14
-
15
14
  def initialize(capybara, page, html_save=true, filename_prefix='screenshot')
16
15
  @capybara, @page, @html_save = capybara, page, html_save
17
16
  time_now = Time.now
18
17
  timestamp = "#{time_now.strftime('%Y-%m-%d-%H-%M-%S.')}#{'%03d' % (time_now.usec/1000).to_i}"
19
18
  @file_base_name = filename_prefix
20
19
  @file_base_name = "#{@file_base_name}_#{timestamp}" if Capybara::Screenshot.append_timestamp
20
+
21
+ Capybara::Screenshot.prune
21
22
  end
22
23
 
23
24
  def save
@@ -1,5 +1,5 @@
1
1
  module Capybara
2
2
  module Screenshot
3
- VERSION = "1.0.2"
3
+ VERSION = "1.0.3"
4
4
  end
5
5
  end
@@ -1,14 +1,20 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe "Using Capybara::Screenshot with Cucumber" do
4
- include Aruba::Api
5
4
  include CommonSetup
6
5
 
7
6
  before do
8
7
  clean_current_dir
9
8
  end
10
9
 
10
+ let(:cmd) { 'bundle exec cucumber' }
11
+
11
12
  def run_failing_case(failure_message, code)
13
+ run_case code
14
+ expect(output_from(cmd)).to match(failure_message)
15
+ end
16
+
17
+ def run_case(code, options = {})
12
18
  write_file('features/support/env.rb', <<-RUBY)
13
19
  #{ensure_load_paths_valid}
14
20
  require 'cucumber/support/env.rb'
@@ -23,38 +29,65 @@ describe "Using Capybara::Screenshot with Cucumber" do
23
29
  RUBY
24
30
 
25
31
  write_file('features/cucumber.feature', code)
26
- cmd = 'bundle exec cucumber'
32
+
27
33
  run_simple_with_retry cmd, false
28
- expect(output_from(cmd)).to match failure_message
34
+
35
+ expect(output_from(cmd)).to_not include('failed)') if options[:assert_all_passed]
29
36
  end
30
37
 
31
- it "saves a screenshot on failure" do
32
- run_failing_case(%q{Unable to find link or button "you'll never find me"}, <<-CUCUMBER)
38
+ it 'saves a screenshot on failure' do
39
+ run_failing_case %q{Unable to find link or button "you'll never find me"}, <<-CUCUMBER
33
40
  Feature: Failure
34
41
  Scenario: Failure
35
42
  Given I visit "/"
36
43
  And I click on a missing link
37
44
  CUCUMBER
38
- check_file_content('tmp/my_screenshot.html', 'This is the root page', true)
45
+ check_file_content 'tmp/my_screenshot.html', 'This is the root page', true
39
46
  end
40
47
 
41
- it "saves a screenshot on an error" do
42
- run_failing_case(%q{you can't handle me}, <<-CUCUMBER)
48
+ it 'saves a screenshot on an error' do
49
+ run_failing_case %q{you can't handle me}, <<-CUCUMBER
43
50
  Feature: Failure
44
51
  Scenario: Failure
45
52
  Given I visit "/"
46
53
  And I trigger an unhandled exception
47
54
  CUCUMBER
48
- check_file_content('tmp/my_screenshot.html', 'This is the root page', true)
55
+ check_file_content 'tmp/my_screenshot.html', 'This is the root page', true
49
56
  end
50
57
 
51
- it "saves a screenshot for the correct session for failures using_session" do
58
+ it 'saves a screenshot for the correct session for failures using_session' do
52
59
  run_failing_case(%q{Unable to find link or button "you'll never find me"}, <<-CUCUMBER)
53
60
  Feature: Failure
54
61
  Scenario: Failure in different session
55
62
  Given I visit "/"
56
63
  And I click on a missing link on a different page in a different session
57
64
  CUCUMBER
58
- check_file_content('tmp/my_screenshot.html', 'This is a different page', true)
65
+ check_file_content 'tmp/my_screenshot.html', 'This is a different page', true
66
+ end
67
+
68
+ context 'pruning' do
69
+ before do
70
+ create_screenshot_for_pruning
71
+ configure_prune_strategy :last_run
72
+ end
73
+
74
+ it 'on failure it prunes previous screenshots when strategy is set' do
75
+ run_failing_case %q{Unable to find link or button "you'll never find me"}, <<-CUCUMBER
76
+ Feature: Prune
77
+ Scenario: Screenshots are pruned if strategy is set
78
+ Given I visit "/"
79
+ And I click on a missing link
80
+ CUCUMBER
81
+ assert_screenshot_pruned
82
+ end
83
+
84
+ it 'on success it never prunes' do
85
+ run_case <<-CUCUMBER, assert_all_passed: true
86
+ Feature: Prune
87
+ Scenario: Screenshots are pruned if strategy is set
88
+ Given I visit "/"
89
+ CUCUMBER
90
+ assert_screenshot_not_pruned
91
+ end
59
92
  end
60
93
  end
@@ -1,7 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe "Using Capybara::Screenshot with MiniTest" do
4
- include Aruba::Api
5
4
  include CommonSetup
6
5
 
7
6
  before do
@@ -31,7 +30,7 @@ describe "Using Capybara::Screenshot with MiniTest" do
31
30
  expect(output_from(cmd)).to include %q{Unable to find link or button "you'll never find me"}
32
31
  end
33
32
 
34
- it "saves a screenshot on failure" do
33
+ it 'saves a screenshot on failure' do
35
34
  run_failing_case <<-RUBY
36
35
  module ActionDispatch
37
36
  class IntegrationTest < Minitest::Unit::TestCase; end
@@ -47,7 +46,7 @@ describe "Using Capybara::Screenshot with MiniTest" do
47
46
  end
48
47
  end
49
48
  RUBY
50
- check_file_content('tmp/my_screenshot.html', 'This is the root page', true)
49
+ check_file_content 'tmp/my_screenshot.html', 'This is the root page', true
51
50
  end
52
51
 
53
52
  it "does not save a screenshot for tests that don't inherit from ActionDispatch::IntegrationTest" do
@@ -65,7 +64,7 @@ describe "Using Capybara::Screenshot with MiniTest" do
65
64
  check_file_presence(%w{tmp/my_screenshot.html}, false)
66
65
  end
67
66
 
68
- it "saves a screenshot for the correct session for failures using_session" do
67
+ it 'saves a screenshot for the correct session for failures using_session' do
69
68
  run_failing_case <<-RUBY
70
69
  module ActionDispatch
71
70
  class IntegrationTest < Minitest::Unit::TestCase; end
@@ -85,6 +84,27 @@ describe "Using Capybara::Screenshot with MiniTest" do
85
84
  end
86
85
  end
87
86
  RUBY
88
- check_file_content('tmp/my_screenshot.html', 'This is a different page', true)
87
+ check_file_content 'tmp/my_screenshot.html', 'This is a different page', true
88
+ end
89
+
90
+ it 'prunes screenshots on failure' do
91
+ create_screenshot_for_pruning
92
+ configure_prune_strategy :last_run
93
+ run_failing_case <<-RUBY
94
+ module ActionDispatch
95
+ class IntegrationTest < Minitest::Unit::TestCase; end
96
+ end
97
+
98
+ class TestFailure < ActionDispatch::IntegrationTest
99
+ include Capybara::DSL
100
+
101
+ def test_failure
102
+ visit '/'
103
+ assert(page.body.include?('This is the root page'))
104
+ click_on "you'll never find me"
105
+ end
106
+ end
107
+ RUBY
108
+ assert_screenshot_pruned
89
109
  end
90
110
  end
@@ -1,7 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe "Using Capybara::Screenshot with Test::Unit" do
4
- include Aruba::Api
5
4
  include CommonSetup
6
5
 
7
6
  before do
@@ -38,16 +37,16 @@ describe "Using Capybara::Screenshot with Test::Unit" do
38
37
  end
39
38
 
40
39
  it "saves a screenshot on failure for any test in path 'test/integration'" do
41
- run_failing_case(<<-RUBY, 'test/integration')
40
+ run_failing_case <<-RUBY, 'test/integration'
42
41
  visit '/'
43
42
  assert(page.body.include?('This is the root page'))
44
43
  click_on "you'll never find me"
45
44
  RUBY
46
- check_file_content('tmp/my_screenshot.html', 'This is the root page', true)
45
+ check_file_content 'tmp/my_screenshot.html', 'This is the root page', true
47
46
  end
48
47
 
49
48
  it "does not generate a screenshot for tests that are not in 'test/integration'" do
50
- run_failing_case(<<-RUBY, 'test/something-else')
49
+ run_failing_case <<-RUBY, 'test/something-else'
51
50
  visit '/'
52
51
  assert(page.body.include?('This is the root page'))
53
52
  click_on "you'll never find me"
@@ -56,8 +55,8 @@ describe "Using Capybara::Screenshot with Test::Unit" do
56
55
  check_file_presence(%w{tmp/my_screenshot.html}, false)
57
56
  end
58
57
 
59
- it "saves a screenshot for the correct session for failures using_session" do
60
- run_failing_case(<<-RUBY, 'test/integration')
58
+ it 'saves a screenshot for the correct session for failures using_session' do
59
+ run_failing_case <<-RUBY, 'test/integration'
61
60
  visit '/'
62
61
  assert(page.body.include?('This is the root page'))
63
62
  using_session :different_session do
@@ -66,6 +65,17 @@ describe "Using Capybara::Screenshot with Test::Unit" do
66
65
  click_on "you'll never find me"
67
66
  end
68
67
  RUBY
69
- check_file_content('tmp/my_screenshot.html', 'This is a different page', true)
68
+ check_file_content 'tmp/my_screenshot.html', 'This is a different page', true
69
+ end
70
+
71
+ it 'prunes screenshots on failure' do
72
+ create_screenshot_for_pruning
73
+ configure_prune_strategy :last_run
74
+ run_failing_case <<-RUBY, 'test/integration'
75
+ visit '/'
76
+ assert(page.body.include?('This is the root page'))
77
+ click_on "you'll never find me"
78
+ RUBY
79
+ assert_screenshot_pruned
70
80
  end
71
81
  end
@@ -2,7 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe Capybara::Screenshot::RSpec do
4
4
  describe "used with RSpec" do
5
- include Aruba::Api
6
5
  include CommonSetup
7
6
 
8
7
  before do
@@ -10,6 +9,17 @@ describe Capybara::Screenshot::RSpec do
10
9
  end
11
10
 
12
11
  def run_failing_case(code, error_message, format=nil)
12
+ run_case code, format: format
13
+
14
+ cmd = cmd_with_format(format)
15
+ if error_message.kind_of?(Regexp)
16
+ expect(output_from(cmd)).to match(error_message)
17
+ else
18
+ expect(output_from(cmd)).to include(error_message)
19
+ end
20
+ end
21
+
22
+ def run_case(code, options = {})
13
23
  write_file('spec/test_failure.rb', <<-RUBY)
14
24
  #{ensure_load_paths_valid}
15
25
  require 'rspec'
@@ -22,17 +32,17 @@ describe Capybara::Screenshot::RSpec do
22
32
  #{code}
23
33
  RUBY
24
34
 
25
- cmd = "bundle exec rspec #{"--format #{format} " if format}spec/test_failure.rb"
35
+ cmd = cmd_with_format(options[:format])
26
36
  run_simple_with_retry cmd, false
27
37
 
28
- if error_message.kind_of?(Regexp)
29
- expect(output_from(cmd)).to match(error_message)
30
- else
31
- expect(output_from(cmd)).to include(error_message)
32
- end
38
+ expect(output_from(cmd)).to include('0 failures') if options[:assert_all_passed]
39
+ end
40
+
41
+ def cmd_with_format(format)
42
+ "bundle exec rspec #{"--format #{format} " if format}spec/test_failure.rb"
33
43
  end
34
44
 
35
- it "saves a screenshot on failure" do
45
+ it 'saves a screenshot on failure' do
36
46
  run_failing_case <<-RUBY, %q{Unable to find link or button "you'll never find me"}
37
47
  feature 'screenshot with failure' do
38
48
  scenario 'click on a missing link' do
@@ -46,8 +56,8 @@ describe Capybara::Screenshot::RSpec do
46
56
  end
47
57
 
48
58
  formatters = {
49
- progress: "HTML screenshot:",
50
- documentation: "HTML screenshot:",
59
+ progress: 'HTML screenshot:',
60
+ documentation: 'HTML screenshot:',
51
61
  html: %r{<a href="file://\./tmp/screenshot\.html"[^>]*>HTML page</a>}
52
62
  }
53
63
 
@@ -81,7 +91,7 @@ describe Capybara::Screenshot::RSpec do
81
91
  check_file_presence(%w{tmp/screenshot.html}, false)
82
92
  end
83
93
 
84
- it "saves a screenshot for the correct session for failures using_session" do
94
+ it 'saves a screenshot for the correct session for failures using_session' do
85
95
  run_failing_case <<-RUBY, %q{Unable to find link or button "you'll never find me"}
86
96
  feature 'screenshot with failure' do
87
97
  scenario 'click on a missing link' do
@@ -97,5 +107,53 @@ describe Capybara::Screenshot::RSpec do
97
107
  RUBY
98
108
  check_file_content('tmp/screenshot.html', 'This is a different page', true)
99
109
  end
110
+
111
+ context 'pruning' do
112
+ before do
113
+ create_screenshot_for_pruning
114
+ configure_prune_strategy :last_run
115
+ end
116
+
117
+ it 'on failure it prunes previous screenshots when strategy is set' do
118
+ run_failing_case <<-RUBY, 'HTML screenshot:', :progress
119
+ feature 'screenshot with failure' do
120
+ scenario 'click on a missing link' do
121
+ visit '/'
122
+ click_on "you'll never find me"
123
+ end
124
+ end
125
+ RUBY
126
+ assert_screenshot_pruned
127
+ end
128
+
129
+ it 'on success it never prunes' do
130
+ run_case <<-CUCUMBER, assert_all_passed: true
131
+ feature 'screenshot without failure' do
132
+ scenario 'click on a link' do
133
+ visit '/'
134
+ end
135
+ end
136
+ CUCUMBER
137
+ assert_screenshot_not_pruned
138
+ end
139
+ end
140
+
141
+ context 'no pruning by default' do
142
+ before do
143
+ create_screenshot_for_pruning
144
+ end
145
+
146
+ it 'on failure it leaves existing screenshots' do
147
+ run_failing_case <<-RUBY, 'HTML screenshot:', :progress
148
+ feature 'screenshot with failure' do
149
+ scenario 'click on a missing link' do
150
+ visit '/'
151
+ click_on "you'll never find me"
152
+ end
153
+ end
154
+ RUBY
155
+ assert_screenshot_not_pruned
156
+ end
157
+ end
100
158
  end
101
159
  end
@@ -1,7 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe "Using Capybara::Screenshot with Spinach" do
4
- include Aruba::Api
5
4
  include CommonSetup
6
5
 
7
6
  before do
@@ -50,4 +49,16 @@ describe "Using Capybara::Screenshot with Spinach" do
50
49
  GHERKIN
51
50
  check_file_content('tmp/my_screenshot.html', 'This is a different page', true)
52
51
  end
52
+
53
+ it 'on failure it prunes previous screenshots when strategy is set' do
54
+ create_screenshot_for_pruning
55
+ configure_prune_strategy :last_run
56
+ run_failing_case(%q{Unable to find link or button "you'll never find me"}, <<-GHERKIN)
57
+ Feature: Failure
58
+ Scenario: Failure
59
+ Given I visit "/"
60
+ And I click on a missing link
61
+ GHERKIN
62
+ assert_screenshot_pruned
63
+ end
53
64
  end
@@ -1,5 +1,9 @@
1
1
  module CommonSetup
2
2
  def self.included(target)
3
+ target.class_eval do
4
+ include Aruba::Api
5
+ end
6
+
3
7
  target.let(:gem_root) { File.expand_path('../..', File.dirname(__FILE__)) }
4
8
 
5
9
  target.let(:ensure_load_paths_valid) do
@@ -10,12 +14,16 @@ module CommonSetup
10
14
  RUBY
11
15
  end
12
16
 
17
+ target.let(:screenshot_path) { 'tmp' }
18
+ target.let(:screenshot_for_pruning_path) { "#{screenshot_path}/old_screenshot.html" }
19
+
13
20
  target.let(:setup_test_app) do
14
21
  <<-RUBY
15
22
  require 'support/test_app'
16
- Capybara.save_and_open_page_path = 'tmp'
23
+ Capybara.save_and_open_page_path = '#{screenshot_path}'
17
24
  Capybara.app = TestApp
18
25
  Capybara::Screenshot.append_timestamp = false
26
+ #{@additional_setup_steps}
19
27
  RUBY
20
28
  end
21
29
 
@@ -31,5 +39,21 @@ module CommonSetup
31
39
  puts "run_simple(#{args.join(', ')}) failed. Will retry once. `#{e.message}`"
32
40
  run_simple(*args)
33
41
  end
42
+
43
+ def configure_prune_strategy(strategy)
44
+ @additional_setup_steps = "Capybara::Screenshot.prune_strategy = :keep_last_run"
45
+ end
46
+
47
+ def create_screenshot_for_pruning
48
+ write_file screenshot_for_pruning_path, '<html></html>'
49
+ end
50
+
51
+ def assert_screenshot_pruned
52
+ check_file_presence Array(screenshot_for_pruning_path), false
53
+ end
54
+
55
+ def assert_screenshot_not_pruned
56
+ check_file_presence Array(screenshot_for_pruning_path), true
57
+ end
34
58
  end
35
59
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Capybara::Screenshot do
4
- describe ".register_driver" do
4
+ describe '.register_driver' do
5
5
  before(:all) do
6
6
  @original_drivers = Capybara::Screenshot.registered_drivers.dup
7
7
  end
@@ -18,7 +18,7 @@ describe Capybara::Screenshot do
18
18
  end
19
19
  end
20
20
 
21
- describe ".register_filename_prefix_formatter" do
21
+ describe '.register_filename_prefix_formatter' do
22
22
  before(:all) do
23
23
  @original_formatters = Capybara::Screenshot.filename_prefix_formatters.dup
24
24
  end
@@ -35,7 +35,7 @@ describe Capybara::Screenshot do
35
35
  end
36
36
  end
37
37
 
38
- describe ".filename_prefix_for" do
38
+ describe '.filename_prefix_for' do
39
39
  it 'returns "screenshot" for undefined formatter' do
40
40
  expect(Capybara::Screenshot.filename_prefix_for(:foo, double('test'))).to eql('screenshot')
41
41
  end
@@ -57,4 +57,32 @@ describe Capybara::Screenshot do
57
57
  end
58
58
  end
59
59
  end
60
+
61
+ describe '#prune' do
62
+ before do
63
+ Capybara::Screenshot.reset_prune_history
64
+ end
65
+
66
+ it 'prunes once by default' do
67
+ expect(Capybara::Screenshot::Pruner).to receive(:new).and_call_original.once
68
+ 3.times { Capybara::Screenshot.prune }
69
+ end
70
+
71
+ it 'prunes every time if option force: true' do
72
+ expect(Capybara::Screenshot::Pruner).to receive(:new).and_call_original.exactly(3).times
73
+ 3.times { Capybara::Screenshot.prune(force: true) }
74
+ end
75
+
76
+ context 'prune strategy' do
77
+ let(:prune_strategy) { { keep: 100 } }
78
+ before do
79
+ Capybara::Screenshot.prune_strategy = prune_strategy
80
+ end
81
+
82
+ it 'is passed to initializer' do
83
+ expect(Capybara::Screenshot::Pruner).to receive(:new).with(prune_strategy).and_call_original
84
+ Capybara::Screenshot.prune
85
+ end
86
+ end
87
+ end
60
88
  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
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
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}").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
metadata CHANGED
@@ -1,176 +1,200 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara-screenshot
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Matthew O'Riordan
8
- autorequire:
9
+ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2014-09-27 00:00:00.000000000 Z
12
+ date: 2014-10-01 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
15
+ name: capybara
14
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
15
18
  requirements:
16
- - - '>='
19
+ - - ! '>='
17
20
  - !ruby/object:Gem::Version
18
21
  version: '1.0'
19
22
  - - <
20
23
  - !ruby/object:Gem::Version
21
24
  version: '3'
22
- name: capybara
23
- prerelease: false
24
25
  type: :runtime
26
+ prerelease: false
25
27
  version_requirements: !ruby/object:Gem::Requirement
28
+ none: false
26
29
  requirements:
27
- - - '>='
30
+ - - ! '>='
28
31
  - !ruby/object:Gem::Version
29
32
  version: '1.0'
30
33
  - - <
31
34
  - !ruby/object:Gem::Version
32
35
  version: '3'
33
36
  - !ruby/object:Gem::Dependency
37
+ name: launchy
34
38
  requirement: !ruby/object:Gem::Requirement
39
+ none: false
35
40
  requirements:
36
- - - '>='
41
+ - - ! '>='
37
42
  - !ruby/object:Gem::Version
38
43
  version: '0'
39
- name: launchy
40
- prerelease: false
41
44
  type: :runtime
45
+ prerelease: false
42
46
  version_requirements: !ruby/object:Gem::Requirement
47
+ none: false
43
48
  requirements:
44
- - - '>='
49
+ - - ! '>='
45
50
  - !ruby/object:Gem::Version
46
51
  version: '0'
47
52
  - !ruby/object:Gem::Dependency
53
+ name: colored
48
54
  requirement: !ruby/object:Gem::Requirement
55
+ none: false
49
56
  requirements:
50
- - - '>='
57
+ - - ! '>='
51
58
  - !ruby/object:Gem::Version
52
59
  version: '0'
53
- name: colored
54
- prerelease: false
55
60
  type: :runtime
61
+ prerelease: false
56
62
  version_requirements: !ruby/object:Gem::Requirement
63
+ none: false
57
64
  requirements:
58
- - - '>='
65
+ - - ! '>='
59
66
  - !ruby/object:Gem::Version
60
67
  version: '0'
61
68
  - !ruby/object:Gem::Dependency
69
+ name: rspec
62
70
  requirement: !ruby/object:Gem::Requirement
71
+ none: false
63
72
  requirements:
64
- - - '>='
73
+ - - ! '>='
65
74
  - !ruby/object:Gem::Version
66
75
  version: '0'
67
- name: rspec
68
- prerelease: false
69
76
  type: :development
77
+ prerelease: false
70
78
  version_requirements: !ruby/object:Gem::Requirement
79
+ none: false
71
80
  requirements:
72
- - - '>='
81
+ - - ! '>='
73
82
  - !ruby/object:Gem::Version
74
83
  version: '0'
75
84
  - !ruby/object:Gem::Dependency
85
+ name: timecop
76
86
  requirement: !ruby/object:Gem::Requirement
87
+ none: false
77
88
  requirements:
78
- - - '>='
89
+ - - ! '>='
79
90
  - !ruby/object:Gem::Version
80
91
  version: '0'
81
- name: timecop
82
- prerelease: false
83
92
  type: :development
93
+ prerelease: false
84
94
  version_requirements: !ruby/object:Gem::Requirement
95
+ none: false
85
96
  requirements:
86
- - - '>='
97
+ - - ! '>='
87
98
  - !ruby/object:Gem::Version
88
99
  version: '0'
89
100
  - !ruby/object:Gem::Dependency
101
+ name: cucumber
90
102
  requirement: !ruby/object:Gem::Requirement
103
+ none: false
91
104
  requirements:
92
- - - '>='
105
+ - - ! '>='
93
106
  - !ruby/object:Gem::Version
94
107
  version: '0'
95
- name: cucumber
96
- prerelease: false
97
108
  type: :development
109
+ prerelease: false
98
110
  version_requirements: !ruby/object:Gem::Requirement
111
+ none: false
99
112
  requirements:
100
- - - '>='
113
+ - - ! '>='
101
114
  - !ruby/object:Gem::Version
102
115
  version: '0'
103
116
  - !ruby/object:Gem::Dependency
117
+ name: aruba
104
118
  requirement: !ruby/object:Gem::Requirement
119
+ none: false
105
120
  requirements:
106
- - - '>='
121
+ - - ! '>='
107
122
  - !ruby/object:Gem::Version
108
123
  version: '0'
109
- name: aruba
110
- prerelease: false
111
124
  type: :development
125
+ prerelease: false
112
126
  version_requirements: !ruby/object:Gem::Requirement
127
+ none: false
113
128
  requirements:
114
- - - '>='
129
+ - - ! '>='
115
130
  - !ruby/object:Gem::Version
116
131
  version: '0'
117
132
  - !ruby/object:Gem::Dependency
133
+ name: sinatra
118
134
  requirement: !ruby/object:Gem::Requirement
135
+ none: false
119
136
  requirements:
120
- - - '>='
137
+ - - ! '>='
121
138
  - !ruby/object:Gem::Version
122
139
  version: '0'
123
- name: sinatra
124
- prerelease: false
125
140
  type: :development
141
+ prerelease: false
126
142
  version_requirements: !ruby/object:Gem::Requirement
143
+ none: false
127
144
  requirements:
128
- - - '>='
145
+ - - ! '>='
129
146
  - !ruby/object:Gem::Version
130
147
  version: '0'
131
148
  - !ruby/object:Gem::Dependency
149
+ name: test-unit
132
150
  requirement: !ruby/object:Gem::Requirement
151
+ none: false
133
152
  requirements:
134
- - - '>='
153
+ - - ! '>='
135
154
  - !ruby/object:Gem::Version
136
155
  version: '0'
137
- name: test-unit
138
- prerelease: false
139
156
  type: :development
157
+ prerelease: false
140
158
  version_requirements: !ruby/object:Gem::Requirement
159
+ none: false
141
160
  requirements:
142
- - - '>='
161
+ - - ! '>='
143
162
  - !ruby/object:Gem::Version
144
163
  version: '0'
145
164
  - !ruby/object:Gem::Dependency
165
+ name: spinach
146
166
  requirement: !ruby/object:Gem::Requirement
167
+ none: false
147
168
  requirements:
148
- - - '>='
169
+ - - ! '>='
149
170
  - !ruby/object:Gem::Version
150
171
  version: '0'
151
- name: spinach
152
- prerelease: false
153
172
  type: :development
173
+ prerelease: false
154
174
  version_requirements: !ruby/object:Gem::Requirement
175
+ none: false
155
176
  requirements:
156
- - - '>='
177
+ - - ! '>='
157
178
  - !ruby/object:Gem::Version
158
179
  version: '0'
159
180
  - !ruby/object:Gem::Dependency
181
+ name: minitest
160
182
  requirement: !ruby/object:Gem::Requirement
183
+ none: false
161
184
  requirements:
162
- - - '>='
185
+ - - ! '>='
163
186
  - !ruby/object:Gem::Version
164
187
  version: '0'
165
- name: minitest
166
- prerelease: false
167
188
  type: :development
189
+ prerelease: false
168
190
  version_requirements: !ruby/object:Gem::Requirement
191
+ none: false
169
192
  requirements:
170
- - - '>='
193
+ - - ! '>='
171
194
  - !ruby/object:Gem::Version
172
195
  version: '0'
173
- description: When a Cucumber step fails, it is useful to create a screenshot image and HTML file of the current page
196
+ description: When a Cucumber step fails, it is useful to create a screenshot image
197
+ and HTML file of the current page
174
198
  email:
175
199
  - matthew.oriordan@gmail.com
176
200
  executables: []
@@ -199,6 +223,7 @@ files:
199
223
  - lib/capybara-screenshot/capybara.rb
200
224
  - lib/capybara-screenshot/cucumber.rb
201
225
  - lib/capybara-screenshot/minitest.rb
226
+ - lib/capybara-screenshot/pruner.rb
202
227
  - lib/capybara-screenshot/rspec.rb
203
228
  - lib/capybara-screenshot/rspec/base_reporter.rb
204
229
  - lib/capybara-screenshot/rspec/html_embed_reporter.rb
@@ -225,6 +250,7 @@ files:
225
250
  - spec/unit/capybara-screenshot_rspec_spec.rb
226
251
  - spec/unit/capybara-screenshot_spec.rb
227
252
  - spec/unit/capybara_spec.rb
253
+ - spec/unit/pruner_spec.rb
228
254
  - spec/unit/rspec_reporters/html_embed_reporter_spec.rb
229
255
  - spec/unit/rspec_reporters/html_link_reporter_spec.rb
230
256
  - spec/unit/rspec_reporters/text_reporter_spec.rb
@@ -233,27 +259,35 @@ files:
233
259
  homepage: http://github.com/mattheworiordan/capybara-screenshot
234
260
  licenses:
235
261
  - MIT
236
- metadata: {}
237
- post_install_message:
262
+ post_install_message:
238
263
  rdoc_options: []
239
264
  require_paths:
240
265
  - lib
241
266
  required_ruby_version: !ruby/object:Gem::Requirement
267
+ none: false
242
268
  requirements:
243
- - - '>='
269
+ - - ! '>='
244
270
  - !ruby/object:Gem::Version
245
271
  version: '0'
272
+ segments:
273
+ - 0
274
+ hash: 696952700666398309
246
275
  required_rubygems_version: !ruby/object:Gem::Requirement
276
+ none: false
247
277
  requirements:
248
- - - '>='
278
+ - - ! '>='
249
279
  - !ruby/object:Gem::Version
250
280
  version: '0'
281
+ segments:
282
+ - 0
283
+ hash: 696952700666398309
251
284
  requirements: []
252
285
  rubyforge_project: capybara-screenshot
253
- rubygems_version: 2.1.9
254
- signing_key:
255
- specification_version: 4
256
- summary: Automatically create snapshots when Cucumber steps fail with Capybara and Rails
286
+ rubygems_version: 1.8.23.2
287
+ signing_key:
288
+ specification_version: 3
289
+ summary: Automatically create snapshots when Cucumber steps fail with Capybara and
290
+ Rails
257
291
  test_files:
258
292
  - spec/cucumber/cucumber_spec.rb
259
293
  - spec/cucumber/step_definitions/step_definitions.rb
@@ -271,6 +305,7 @@ test_files:
271
305
  - spec/unit/capybara-screenshot_rspec_spec.rb
272
306
  - spec/unit/capybara-screenshot_spec.rb
273
307
  - spec/unit/capybara_spec.rb
308
+ - spec/unit/pruner_spec.rb
274
309
  - spec/unit/rspec_reporters/html_embed_reporter_spec.rb
275
310
  - spec/unit/rspec_reporters/html_link_reporter_spec.rb
276
311
  - spec/unit/rspec_reporters/text_reporter_spec.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: ea0f0f79b26cc47c17432e0d436e6c5c11fe1d01
4
- data.tar.gz: cf7a0fdcf2f73c7dda324ab4f06eeacf0af4b4fd
5
- SHA512:
6
- metadata.gz: 8c9b5f03a37755b78be62e9b5619e23200d6ee7017a7b21d2c33a75dc127632e431707e349572511aba2e900af51597674e47cdf1604312b1b7f6056fda3c600
7
- data.tar.gz: d3c4e74a8b4c7c58a6770695ceb8d5d174253f82cafbb19408f127bda0d1bad9077e16d5cb838fe3bd8ca7a7192f2b27c722bc4258dc8a37b3e95a52ef7ba1e0