capybara-screenshot 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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