capybara-screenshot-nocolor 1.0.5
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.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/.travis.yml +17 -0
- data/Appraisals +31 -0
- data/CHANGELOG.md +198 -0
- data/Gemfile +7 -0
- data/LICENSE +19 -0
- data/README.md +240 -0
- data/Rakefile +40 -0
- data/capybara-screenshot.gemspec +38 -0
- data/gemfiles/cucumber.1.2.gemfile +9 -0
- data/gemfiles/cucumber.1.3.0.gemfile +9 -0
- data/gemfiles/latest.gemfile +8 -0
- data/gemfiles/rspec.2.14.gemfile +9 -0
- data/gemfiles/rspec.2.99.gemfile +9 -0
- data/gemfiles/rspec.3.0.gemfile +9 -0
- data/gemfiles/spinach.0.7.gemfile +9 -0
- data/gemfiles/spinach.0.8.0.gemfile +9 -0
- data/lib/capybara-screenshot.rb +157 -0
- data/lib/capybara-screenshot/capybara.rb +28 -0
- data/lib/capybara-screenshot/cucumber.rb +27 -0
- data/lib/capybara-screenshot/minitest.rb +27 -0
- data/lib/capybara-screenshot/pruner.rb +47 -0
- data/lib/capybara-screenshot/rspec.rb +92 -0
- data/lib/capybara-screenshot/rspec/base_reporter.rb +21 -0
- data/lib/capybara-screenshot/rspec/html_embed_reporter.rb +25 -0
- data/lib/capybara-screenshot/rspec/html_link_reporter.rb +37 -0
- data/lib/capybara-screenshot/rspec/text_reporter.rb +38 -0
- data/lib/capybara-screenshot/rspec/textmate_link_reporter.rb +19 -0
- data/lib/capybara-screenshot/saver.rb +87 -0
- data/lib/capybara-screenshot/spinach.rb +26 -0
- data/lib/capybara-screenshot/testunit.rb +39 -0
- data/lib/capybara-screenshot/version.rb +5 -0
- data/spec/cucumber/cucumber_spec.rb +93 -0
- data/spec/cucumber/step_definitions/step_definitions.rb +18 -0
- data/spec/cucumber/support/env.rb +17 -0
- data/spec/feature/minitest_spec.rb +110 -0
- data/spec/feature/testunit_spec.rb +81 -0
- data/spec/rspec/rspec_spec.rb +159 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/spinach/spinach_spec.rb +64 -0
- data/spec/spinach/support/spinach_failure.rb +41 -0
- data/spec/support/common_setup.rb +59 -0
- data/spec/support/html_reporter_context.rb +28 -0
- data/spec/support/test_app.rb +13 -0
- data/spec/unit/base_reporter_spec.rb +25 -0
- data/spec/unit/capybara-screenshot_rspec_spec.rb +48 -0
- data/spec/unit/capybara-screenshot_spec.rb +88 -0
- data/spec/unit/capybara_spec.rb +50 -0
- data/spec/unit/pruner_spec.rb +108 -0
- data/spec/unit/rspec_reporters/html_embed_reporter_spec.rb +18 -0
- data/spec/unit/rspec_reporters/html_link_reporter_spec.rb +27 -0
- data/spec/unit/rspec_reporters/text_reporter_spec.rb +97 -0
- data/spec/unit/rspec_reporters/textmate_link_reporter_spec.rb +39 -0
- data/spec/unit/saver_spec.rb +282 -0
- metadata +247 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'capybara'
|
2
|
+
require 'capybara/rspec'
|
3
|
+
require 'capybara-screenshot'
|
4
|
+
require 'capybara-screenshot/spinach'
|
5
|
+
require 'spinach/capybara'
|
6
|
+
require 'support/test_app'
|
7
|
+
|
8
|
+
Spinach.config.failure_exceptions = [Capybara::ElementNotFound]
|
9
|
+
|
10
|
+
class Spinach::Features::Failure < Spinach::FeatureSteps
|
11
|
+
include ::Capybara::DSL
|
12
|
+
|
13
|
+
before do
|
14
|
+
::Capybara::Screenshot.register_filename_prefix_formatter(:spinach) do |failed_step|
|
15
|
+
raise 'expected failing step' if !@expected_failed_step.nil? && !failed_step.name.include?(@expected_failed_step)
|
16
|
+
'my_screenshot'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
step 'I visit "/"' do
|
21
|
+
visit '/'
|
22
|
+
end
|
23
|
+
|
24
|
+
step 'I click on a missing link' do
|
25
|
+
@expected_failed_step = 'I click on a missing link'
|
26
|
+
click_on "you'll never find me"
|
27
|
+
end
|
28
|
+
|
29
|
+
step 'I trigger an unhandled exception' do
|
30
|
+
@expected_failed_step = "I trigger an unhandled exception"
|
31
|
+
raise "you can't handle me"
|
32
|
+
end
|
33
|
+
|
34
|
+
step 'I click on a missing link on a different page in a different session' do
|
35
|
+
using_session :different_session do
|
36
|
+
visit '/different_page'
|
37
|
+
@expected_failed_step = 'I click on a missing link on a different page in a different session'
|
38
|
+
click_on "you'll never find me"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module CommonSetup
|
2
|
+
def self.included(target)
|
3
|
+
target.class_eval do
|
4
|
+
include Aruba::Api
|
5
|
+
end
|
6
|
+
|
7
|
+
target.let(:gem_root) { File.expand_path('../..', File.dirname(__FILE__)) }
|
8
|
+
|
9
|
+
target.let(:ensure_load_paths_valid) do
|
10
|
+
<<-RUBY
|
11
|
+
%w(lib spec).each do |include_folder|
|
12
|
+
$LOAD_PATH.unshift(File.join('#{gem_root}', include_folder))
|
13
|
+
end
|
14
|
+
RUBY
|
15
|
+
end
|
16
|
+
|
17
|
+
target.let(:screenshot_path) { 'tmp' }
|
18
|
+
target.let(:screenshot_for_pruning_path) { "#{screenshot_path}/old_screenshot.html" }
|
19
|
+
|
20
|
+
target.let(:setup_test_app) do
|
21
|
+
<<-RUBY
|
22
|
+
require 'support/test_app'
|
23
|
+
Capybara.save_and_open_page_path = '#{screenshot_path}'
|
24
|
+
Capybara.app = TestApp
|
25
|
+
Capybara::Screenshot.append_timestamp = false
|
26
|
+
#{@additional_setup_steps}
|
27
|
+
RUBY
|
28
|
+
end
|
29
|
+
|
30
|
+
target.before do
|
31
|
+
if ENV['BUNDLE_GEMFILE'] && ENV['BUNDLE_GEMFILE'].match(/^\.|^[^\/\.]/)
|
32
|
+
ENV['BUNDLE_GEMFILE'] = File.join(gem_root, ENV['BUNDLE_GEMFILE'])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def run_simple_with_retry(*args)
|
37
|
+
run_simple(*args)
|
38
|
+
rescue ChildProcess::TimeoutError => e
|
39
|
+
puts "run_simple(#{args.join(', ')}) failed. Will retry once. `#{e.message}`"
|
40
|
+
run_simple(*args)
|
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
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
shared_context 'html reporter' do
|
2
|
+
def set_example(example)
|
3
|
+
@reporter.instance_variable_set :@failed_examples, [example]
|
4
|
+
end
|
5
|
+
|
6
|
+
before do
|
7
|
+
# Mocking `RSpec::Core::Formatters::HtmlFormatter`, but only implementing the things that
|
8
|
+
# are actually used in `HtmlLinkReporter#extra_failure_content_with_screenshot`.
|
9
|
+
@reporter_class = Class.new do
|
10
|
+
def extra_failure_content(exception)
|
11
|
+
"original content"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
@reporter = @reporter_class.new
|
16
|
+
@reporter.singleton_class.send :include, described_class
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when there is no screenshot' do
|
20
|
+
before do
|
21
|
+
set_example double("example", metadata: {})
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'doesnt change the original content of the reporter' do
|
25
|
+
expect(@reporter.extra_failure_content(nil)).to eql("original content")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Capybara::Screenshot::RSpec::BaseReporter do
|
4
|
+
describe '#enhance_with_screenshot' do
|
5
|
+
it 'makes the original method available under an alias and replaces it with the enhanced method' do
|
6
|
+
reporter_module = Module.new do
|
7
|
+
extend Capybara::Screenshot::RSpec::BaseReporter
|
8
|
+
enhance_with_screenshot :foo
|
9
|
+
def foo_with_screenshot
|
10
|
+
[foo_without_screenshot, :enhanced]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
klass = Class.new do
|
15
|
+
def foo
|
16
|
+
:original
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
expect(klass.new.foo).to eql(:original)
|
21
|
+
klass.send :include, reporter_module
|
22
|
+
expect(klass.new.foo).to eql([:original, :enhanced])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Capybara::Screenshot::RSpec do
|
4
|
+
describe '.after_failed_example' do
|
5
|
+
context 'for a failed example in a feature that can be snapshotted' do
|
6
|
+
before do
|
7
|
+
allow(Capybara.page).to receive(:current_url).and_return("http://test.local")
|
8
|
+
allow(Capybara::Screenshot::Saver).to receive(:new).and_return(mock_saver)
|
9
|
+
end
|
10
|
+
let(:example_group) { Module.new.include(Capybara::DSL) }
|
11
|
+
let(:example) { double("example", exception: Exception.new, example_group: example_group, metadata: {}) }
|
12
|
+
let(:mock_saver) do
|
13
|
+
Capybara::Screenshot::Saver.new(Capybara, Capybara.page).tap do |saver|
|
14
|
+
allow(saver).to receive(:save)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'instantiates a saver and calls `save` on it' do
|
19
|
+
expect(mock_saver).to receive(:save)
|
20
|
+
described_class.after_failed_example(example)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'extends the metadata with an empty hash for screenshot metadata' do
|
24
|
+
described_class.after_failed_example(example)
|
25
|
+
expect(example.metadata).to have_key(:screenshot)
|
26
|
+
expect(example.metadata[:screenshot]).to eql({})
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when a html file gets saved' do
|
30
|
+
before { allow(mock_saver).to receive(:html_saved?).and_return(true) }
|
31
|
+
|
32
|
+
it 'adds the html file path to the screenshot metadata' do
|
33
|
+
described_class.after_failed_example(example)
|
34
|
+
expect(example.metadata[:screenshot][:html]).to match("./screenshot")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when an image gets saved' do
|
39
|
+
before { allow(mock_saver).to receive(:screenshot_saved?).and_return(true) }
|
40
|
+
|
41
|
+
it 'adds the image path to the screenshot metadata' do
|
42
|
+
described_class.after_failed_example(example)
|
43
|
+
expect(example.metadata[:screenshot][:image]).to match("./screenshot")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,88 @@
|
|
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
|
+
end
|
37
|
+
|
38
|
+
describe '.filename_prefix_for' do
|
39
|
+
it 'returns "screenshot" for undefined formatter' do
|
40
|
+
expect(Capybara::Screenshot.filename_prefix_for(:foo, double('test'))).to eql('screenshot')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.append_screenshot_path' do
|
45
|
+
it 'prints a deprecation message and delegates to RSpec.add_link_to_screenshot_for_failed_examples' do
|
46
|
+
begin
|
47
|
+
original_stderr = $stderr
|
48
|
+
$stderr = StringIO.new
|
49
|
+
expect {
|
50
|
+
Capybara::Screenshot.append_screenshot_path = false
|
51
|
+
}.to change {
|
52
|
+
Capybara::Screenshot::RSpec.add_link_to_screenshot_for_failed_examples
|
53
|
+
}.from(true).to(false)
|
54
|
+
expect($stderr.string).to include("append_screenshot_path is deprecated")
|
55
|
+
ensure
|
56
|
+
$stderr = original_stderr
|
57
|
+
end
|
58
|
+
end
|
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
|
88
|
+
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
|
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
|