leifcr-capybara-screenshot 1.0.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +13 -0
  5. data/Appraisals +19 -0
  6. data/CHANGELOG.md +256 -0
  7. data/Gemfile +9 -0
  8. data/LICENSE +19 -0
  9. data/README.md +315 -0
  10. data/Rakefile +40 -0
  11. data/capybara-screenshot.gemspec +39 -0
  12. data/gemfiles/cucumber.1.3.gemfile +11 -0
  13. data/gemfiles/cucumber.2.4.gemfile +11 -0
  14. data/gemfiles/latest.gemfile +10 -0
  15. data/gemfiles/rspec.3.0.gemfile +11 -0
  16. data/gemfiles/spinach.0.8.gemfile +11 -0
  17. data/lib/capybara-screenshot/callbacks.rb +44 -0
  18. data/lib/capybara-screenshot/capybara.rb +26 -0
  19. data/lib/capybara-screenshot/cucumber.rb +28 -0
  20. data/lib/capybara-screenshot/helpers.rb +28 -0
  21. data/lib/capybara-screenshot/minitest.rb +36 -0
  22. data/lib/capybara-screenshot/pruner.rb +48 -0
  23. data/lib/capybara-screenshot/rspec/base_reporter.rb +21 -0
  24. data/lib/capybara-screenshot/rspec/html_embed_reporter.rb +25 -0
  25. data/lib/capybara-screenshot/rspec/html_link_reporter.rb +37 -0
  26. data/lib/capybara-screenshot/rspec/json_reporter.rb +19 -0
  27. data/lib/capybara-screenshot/rspec/text_reporter.rb +39 -0
  28. data/lib/capybara-screenshot/rspec/textmate_link_reporter.rb +19 -0
  29. data/lib/capybara-screenshot/rspec.rb +95 -0
  30. data/lib/capybara-screenshot/s3_saver.rb +64 -0
  31. data/lib/capybara-screenshot/saver.rb +131 -0
  32. data/lib/capybara-screenshot/spinach.rb +26 -0
  33. data/lib/capybara-screenshot/testunit.rb +39 -0
  34. data/lib/capybara-screenshot/version.rb +5 -0
  35. data/lib/capybara-screenshot.rb +217 -0
  36. data/spec/cucumber/cucumber_spec.rb +89 -0
  37. data/spec/cucumber/step_definitions/step_definitions.rb +18 -0
  38. data/spec/cucumber/support/env.rb +17 -0
  39. data/spec/feature/minitest_spec.rb +79 -0
  40. data/spec/feature/testunit_spec.rb +77 -0
  41. data/spec/rspec/rspec_spec.rb +158 -0
  42. data/spec/spec_helper.rb +34 -0
  43. data/spec/spinach/spinach_spec.rb +60 -0
  44. data/spec/spinach/support/spinach_failure.rb +41 -0
  45. data/spec/support/aruba.rb +2 -0
  46. data/spec/support/common_setup.rb +67 -0
  47. data/spec/support/html_reporter_context.rb +28 -0
  48. data/spec/support/test_app.rb +13 -0
  49. data/spec/unit/base_reporter_spec.rb +25 -0
  50. data/spec/unit/capybara-screenshot_rspec_spec.rb +48 -0
  51. data/spec/unit/capybara-screenshot_spec.rb +121 -0
  52. data/spec/unit/capybara_spec.rb +50 -0
  53. data/spec/unit/pruner_spec.rb +108 -0
  54. data/spec/unit/rspec_reporters/html_embed_reporter_spec.rb +18 -0
  55. data/spec/unit/rspec_reporters/html_link_reporter_spec.rb +27 -0
  56. data/spec/unit/rspec_reporters/text_reporter_spec.rb +98 -0
  57. data/spec/unit/rspec_reporters/textmate_link_reporter_spec.rb +39 -0
  58. data/spec/unit/s3_saver_spec.rb +132 -0
  59. data/spec/unit/saver_spec.rb +366 -0
  60. metadata +264 -0
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