leifcr-capybara-screenshot 1.0.14

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.
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
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ require 'rspec/core/rake_task'
7
+
8
+ rspec_rake_task = RSpec::Core::RakeTask.new(:spec)
9
+
10
+ task default: [:spec]
11
+
12
+ def target_gem
13
+ gem_file = ENV['BUNDLE_GEMFILE'] || ''
14
+ targets = %w(cucumber spinach rspec)
15
+
16
+ target = gem_file.match(/(#{targets.join('|')})/)
17
+ if target && targets.include?(target[1])
18
+ target[1].to_sym
19
+ else
20
+ []
21
+ end
22
+ end
23
+
24
+ namespace :travis do
25
+ task :ci => target_gem do
26
+ Rake::Task['spec'].invoke
27
+ end
28
+
29
+ task :cucumber do
30
+ rspec_rake_task.pattern = 'spec/cucumber'
31
+ end
32
+
33
+ task :spinach do
34
+ rspec_rake_task.pattern = 'spec/spinach'
35
+ end
36
+
37
+ task :rspec do
38
+ rspec_rake_task.pattern = 'spec/rspec'
39
+ end
40
+ end
@@ -0,0 +1,39 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "capybara-screenshot/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "leifcr-capybara-screenshot"
7
+ s.version = Capybara::Screenshot::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Matthew O'Riordan"]
10
+ s.email = ["matthew.oriordan@gmail.com"]
11
+ s.homepage = "http://github.com/mattheworiordan/capybara-screenshot"
12
+ s.summary = %q{Automatically create snapshots when Cucumber steps fail with Capybara and Rails}
13
+ s.description = %q{When a Cucumber step fails, it is useful to create a screenshot image and HTML file of the current page}
14
+ s.license = 'MIT'
15
+
16
+ s.rubyforge_project = "capybara-screenshot"
17
+
18
+ if RUBY_VERSION < "1.9"
19
+ s.add_dependency 'capybara', ['>= 1.0', '< 2']
20
+ else
21
+ s.add_dependency 'capybara', ['>= 1.0', '< 3']
22
+ end
23
+ s.add_dependency 'launchy'
24
+
25
+ s.add_development_dependency 'rspec'
26
+ s.add_development_dependency 'timecop'
27
+ s.add_development_dependency 'cucumber'
28
+ s.add_development_dependency 'aruba'
29
+ s.add_development_dependency 'sinatra'
30
+ s.add_development_dependency 'test-unit'
31
+ s.add_development_dependency 'spinach'
32
+ s.add_development_dependency 'minitest'
33
+ s.add_development_dependency 'aws-sdk'
34
+
35
+ s.files = `git ls-files`.split("\n")
36
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
37
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
38
+ s.require_paths = ["lib"]
39
+ end
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rack", "~> 1.0"
6
+ gem "rake", "~> 10.0"
7
+ gem "appraisal", "~> 2.0"
8
+ gem "aruba", "~> 0.14.0"
9
+ gem "cucumber", "~>1.3.0"
10
+
11
+ gemspec :path => "../"
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rack", "~> 1.0"
6
+ gem "rake", "~> 10.0"
7
+ gem "appraisal", "~> 2.0"
8
+ gem "aruba", "~> 0.14.0"
9
+ gem "cucumber", "~>2.4.0"
10
+
11
+ gemspec :path => "../"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rack", "~> 1.0"
6
+ gem "rake", "~> 10.0"
7
+ gem "appraisal", "~> 2.0"
8
+ gem "aruba", "~> 0.14.0"
9
+
10
+ gemspec :path => "../"
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rack", "~> 1.0"
6
+ gem "rake", "~> 10.0"
7
+ gem "appraisal", "~> 2.0"
8
+ gem "aruba", "~> 0.14.0"
9
+ gem "rspec", "3.0"
10
+
11
+ gemspec :path => "../"
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rack", "~> 1.0"
6
+ gem "rake", "~> 10.0"
7
+ gem "appraisal", "~> 2.0"
8
+ gem "aruba", "~> 0.14.0"
9
+ gem "spinach", "~>0.8.0"
10
+
11
+ gemspec :path => "../"
@@ -0,0 +1,44 @@
1
+ module Capybara
2
+ module Screenshot
3
+ module Callbacks
4
+ class CallbackSet < Array
5
+ def call *args
6
+ each do |callback|
7
+ callback.call *args
8
+ end
9
+ end
10
+ end
11
+
12
+ module ClassMethods
13
+ def callbacks
14
+ @callbacks ||= {}
15
+ end
16
+
17
+ def define_callback name
18
+ callbacks[name] ||= CallbackSet.new
19
+
20
+ define_singleton_method name do |&block|
21
+ callbacks[name] << block
22
+ end
23
+ end
24
+
25
+ def run_callbacks name, *args
26
+ if cb_set = callbacks[name]
27
+ cb_set.call *args
28
+ end
29
+ end
30
+ end
31
+
32
+ module InstanceMethods
33
+ def run_callbacks name, *args
34
+ self.class.run_callbacks name, *args
35
+ end
36
+ end
37
+
38
+ def self.included receiver
39
+ receiver.extend ClassMethods
40
+ receiver.send :include, InstanceMethods
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,26 @@
1
+ require "capybara-screenshot"
2
+
3
+ module Capybara
4
+ module DSL
5
+ # Adds class methods to Capybara module and gets mixed into
6
+ # the current scope during Cucumber and RSpec tests
7
+
8
+ def screenshot_and_save_page
9
+ Capybara::Screenshot.screenshot_and_save_page
10
+ end
11
+
12
+ def screenshot_and_open_image
13
+ Capybara::Screenshot.screenshot_and_open_image
14
+ end
15
+
16
+ def using_session_with_screenshot(name,&blk)
17
+ original_session_name = Capybara.session_name
18
+ Capybara::Screenshot.final_session_name = name
19
+ using_session_without_screenshot(name,&blk)
20
+ Capybara::Screenshot.final_session_name = original_session_name
21
+ end
22
+
23
+ alias_method :using_session_without_screenshot, :using_session
24
+ alias_method :using_session, :using_session_with_screenshot
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ require "capybara-screenshot"
2
+
3
+ Before do |scenario|
4
+ Capybara::Screenshot.final_session_name = nil
5
+ end
6
+
7
+ After do |scenario|
8
+ if Capybara::Screenshot.autosave_on_failure && scenario.failed?
9
+ Capybara.using_session(Capybara::Screenshot.final_session_name) do
10
+ filename_prefix = Capybara::Screenshot.filename_prefix_for(:cucumber, scenario)
11
+
12
+ saver = Capybara::Screenshot.new_saver(Capybara, Capybara.page, true, filename_prefix)
13
+ saver.save
14
+ saver.output_screenshot_path
15
+
16
+ # Trying to embed the screenshot into our output."
17
+ if File.exist?(saver.screenshot_path)
18
+ require "base64"
19
+ #encode the image into it's base64 representation
20
+ image = open(saver.screenshot_path, 'rb') {|io|io.read}
21
+ saver.display_image
22
+ #this will embed the image in the HTML report, embed() is defined in cucumber
23
+ encoded_img = Base64.encode64(image)
24
+ embed(encoded_img, 'image/png;base64', "Screenshot of the error")
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ class CapybaraScreenshot
2
+ module Helpers
3
+ extend self
4
+
5
+ COLORS =
6
+ {
7
+ "black" => 0,
8
+ "red" => 1,
9
+ "green" => 2,
10
+ "yellow" => 3,
11
+ "blue" => 4,
12
+ "purple" => 5,
13
+ "magenta" => 5,
14
+ "cyan" => 6,
15
+ "white" => 7
16
+ }
17
+
18
+ COLORS.each_pair do |color, value|
19
+ define_method color do |text|
20
+ "\033[0;#{30+value}m#{text}\033[0m"
21
+ end
22
+
23
+ define_method "bright_#{color}" do |text|
24
+ "\033[1;#{30+value}m#{text}\033[0m"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,36 @@
1
+ require "capybara-screenshot"
2
+
3
+ module Capybara::Screenshot::MiniTestPlugin
4
+ def before_setup
5
+ super
6
+ Capybara::Screenshot.final_session_name = nil
7
+ end
8
+
9
+ def before_teardown
10
+ super
11
+ if self.class.ancestors.map(&:to_s).include?('Capybara::DSL')
12
+ if Capybara::Screenshot.autosave_on_failure && !passed? && !skipped?
13
+ Capybara.using_session(Capybara::Screenshot.final_session_name) do
14
+ filename_prefix = Capybara::Screenshot.filename_prefix_for(:minitest, self)
15
+
16
+ saver = Capybara::Screenshot.new_saver(Capybara, Capybara.page, true, filename_prefix)
17
+ saver.save
18
+ saver.output_screenshot_path
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ begin
26
+ Minitest.const_get('Test')
27
+ class Minitest::Test
28
+ include Capybara::Screenshot::MiniTestPlugin
29
+ end
30
+ rescue NameError => e
31
+ class MiniTest::Unit::TestCase
32
+ include Capybara::Screenshot::MiniTestPlugin
33
+ end
34
+ end
35
+
36
+
@@ -0,0 +1,48 @@
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
+ lambda { }
12
+ when :keep_last_run
13
+ lambda { prune_with_last_run_strategy }
14
+ when Hash
15
+ raise ArgumentError, ":keep key is required" unless strategy[:keep]
16
+ raise ArgumentError, ":keep must be a Integer" unless strategy[:keep].kind_of?(Integer)
17
+ raise ArgumentError, ":keep value must be number greater than zero" unless strategy[:keep].to_i > 0
18
+ lambda { prune_with_numeric_strategy(strategy[:keep].to_i) }
19
+ else
20
+ fail "Invalid prune strategy #{strategy}. `:keep_all`or `{ keep: 10 }` are valid examples."
21
+ end
22
+ end
23
+
24
+ def prune_old_screenshots
25
+ strategy_proc.call
26
+ end
27
+
28
+ private
29
+ attr_reader :strategy_proc
30
+
31
+ def wildcard_path
32
+ File.expand_path('*.{html,png}', Screenshot.capybara_root)
33
+ end
34
+
35
+ def prune_with_last_run_strategy
36
+ FileUtils.rm_rf(Dir.glob(wildcard_path))
37
+ end
38
+
39
+ def prune_with_numeric_strategy(count)
40
+ files = Dir.glob(wildcard_path).sort_by do |file_name|
41
+ File.mtime(File.expand_path(file_name, Screenshot.capybara_root))
42
+ end
43
+
44
+ FileUtils.rm_rf(files[0...-count])
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,21 @@
1
+ module Capybara
2
+ module Screenshot
3
+ module RSpec
4
+ module BaseReporter
5
+
6
+ # Automatically set up method aliases (very much like ActiveSupport's `alias_method_chain`)
7
+ # when the module gets included.
8
+ def enhance_with_screenshot(method)
9
+ with_method, without_method = "#{method}_with_screenshot", "#{method}_without_screenshot"
10
+ define_singleton_method :included do |mod|
11
+ if mod.method_defined?(method) || mod.private_method_defined?(method)
12
+ mod.send :alias_method, without_method, method
13
+ mod.send :alias_method, method, with_method
14
+ end
15
+ end
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ require 'capybara-screenshot/rspec/base_reporter'
2
+ require 'base64'
3
+
4
+ module Capybara
5
+ module Screenshot
6
+ module RSpec
7
+ module HtmlEmbedReporter
8
+ extend BaseReporter
9
+ enhance_with_screenshot :extra_failure_content
10
+
11
+ def extra_failure_content_with_screenshot(exception)
12
+ result = extra_failure_content_without_screenshot(exception)
13
+ example = @failed_examples.last
14
+ # Ignores saved html file, only saved image will be embedded (if present)
15
+ if (screenshot = example.metadata[:screenshot]) && screenshot[:image]
16
+ image = File.binread(screenshot[:image])
17
+ encoded_img = Base64.encode64(image)
18
+ result += "<img src='data:image/png;base64,#{encoded_img}' style='display: block'>"
19
+ end
20
+ result
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,37 @@
1
+ require 'capybara-screenshot/rspec/base_reporter'
2
+ require 'cgi'
3
+ require 'uri'
4
+
5
+ module Capybara
6
+ module Screenshot
7
+ module RSpec
8
+ module HtmlLinkReporter
9
+ extend BaseReporter
10
+ enhance_with_screenshot :extra_failure_content
11
+
12
+ def extra_failure_content_with_screenshot(exception)
13
+ result = extra_failure_content_without_screenshot(exception)
14
+ example = @failed_examples.last
15
+ if (screenshot = example.metadata[:screenshot])
16
+ result << "<p>Saved files: "
17
+ result << link_to_screenshot("HTML page", screenshot[:html]) if screenshot[:html]
18
+ result << link_to_screenshot("Screenshot", screenshot[:image]) if screenshot[:image]
19
+ result << "</p>"
20
+ end
21
+ result
22
+ end
23
+
24
+ def link_to_screenshot(title, path)
25
+ url = URI.escape("file://#{path}")
26
+ title = CGI.escape_html(title)
27
+ attributes = attributes_for_screenshot_link(url).map { |name, val| %{#{name}="#{CGI.escape_html(val)}"} }.join(" ")
28
+ "<a #{attributes}>#{title}</a>"
29
+ end
30
+
31
+ def attributes_for_screenshot_link(url)
32
+ {"href" => url, "style" => "margin-right: 10px; font-weight: bold"}
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end