Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Basic cucumber_screenshot

  • Loading branch information...
commit 38422b499707f341dd397a80acf2e3da2d5a9cf4 1 parent b84e7e8
Joel Chippindale authored
30 Rakefile
View
@@ -0,0 +1,30 @@
+begin
+ require 'jeweler'
+ Jeweler::Tasks.new do |gemspec|
+ gemspec.name = "cucumber-screenshot"
+ gemspec.summary = "Cucumber formatter that outputs PNG screenshots of your app"
+ gemspec.description = "Cucumber (http://cukes.info/) formatter that uses Webkit to capture PNG screenshots of your web application during tests"
+ gemspec.platform = "universal-darwin"
+ gemspec.requirements << "Mac OS X 10.5 or later"
+ gemspec.requirements << "RubyCocoa"
+ gemspec.requirements << "Cucumber"
+ gemspec.requirements << "Webrat"
+ gemspec.requirements << "SnapUrl"
+ gemspec.email = 'joel.chippindale@gmail.com'
+ gemspec.authors = ['Joel Chippindale']
+ end
+ Jeweler::GemcutterTasks.new
+rescue LoadError
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
+end
+
+begin
+ require 'spec/rake/spectask'
+ desc "Run the cucumber-screenshot specs"
+ Spec::Rake::SpecTask.new('spec') do |t|
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ t.spec_opts = ['--options', 'spec/spec.opts']
+ end
+rescue LoadError
+ puts 'Rspec not available, install it with: sudo gem install rspec'
+end
4 VERSION.yml
View
@@ -0,0 +1,4 @@
+---
+:patch: 0
+:major: 0
+:minor: 1
17 lib/cucumber_screenshot.rb
View
@@ -0,0 +1,17 @@
+require 'cucumber'
+require 'webrat'
+
+require 'cucumber_screenshot/formatter'
+require 'cucumber_screenshot/webrat/session'
+
+# Add formatter to Cucumber's built in list so you can use
+#
+# --format screenshot
+#
+# as well as
+#
+# --format Cucumber::Format::Screenshot
+Cucumber::Cli::Configuration::BUILTIN_FORMATS['screenshot'] = 'CucumberScreenshot::Formatter'
+
+# Make screenshot method available to steps
+Webrat::Methods.delegate_to_session :screenshot
62 lib/cucumber_screenshot/formatter.rb
View
@@ -0,0 +1,62 @@
+module CucumberScreenshot
+ class Formatter < Cucumber::Ast::Visitor
+
+ attr_accessor :response_body_for_last_screenshot, :screenshot_index, :screenshot_directory, :current_feature_segment, :current_scenario_segment
+
+ # Currently ignores io and options arguments
+ def initialize(step_mother, io, options)
+ super(step_mother)
+ @io = io
+ @options = options
+ end
+
+ def visit_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
+ if screenshot_due?
+ self.screenshot_index = screenshot_index.next
+ exit unless session.screenshot(screenshot_directory_name, "screenshot-#{format('%03d', screenshot_index)}")
+ self.response_body_for_last_screenshot = current_response_body
+ end
+ super
+ end
+
+ def visit_scenario_name(keyword, name, file_colon_line, source_indent)
+ puts "Scenario #{name}"
+ self.response_body_for_last_screenshot = nil
+ self.screenshot_index = 0
+ self.current_scenario_segment = segment_for_scenario_named(name)
+ end
+
+ def visit_feature(feature)
+ self.current_feature_segment = segment_for_feature(feature)
+ super
+ end
+
+ def visit_feature_name(name)
+ puts(name)
+ end
+
+ protected
+ def screenshot_directory_name
+ File.join(session.base_screenshot_directory_name, current_feature_segment, current_scenario_segment)
+ end
+
+ def segment_for_feature(feature)
+ feature.file.gsub(/^features\//, '').gsub(/\.feature$/, '')
+ end
+
+ def segment_for_scenario_named(name)
+ name.downcase.gsub(' ', '_')
+ end
+ def session
+ step_mother.current_world.webrat_session
+ end
+
+ def current_response_body
+ session.send(:response) && session.response_body
+ end
+
+ def screenshot_due?
+ current_response_body && current_response_body != response_body_for_last_screenshot && !session.redirect?
+ end
+ end
+end
53 lib/cucumber_screenshot/webrat/session.rb
View
@@ -0,0 +1,53 @@
+module CucumberScreenshot
+ module Webrat
+ module Session #:nodoc:
+
+ def base_screenshot_directory_name
+ # TODO: Make this configurable
+ # TODO: Make this work for other frameworks e.g. sinatra
+ "#{RAILS_ROOT}/features/screenshots"
+ end
+
+ def screenshot(directory_name = base_screenshot_directory_name, file_name = "screenshot-#{Time.now.to_i}")
+ File.makedirs("#{directory_name}/html")
+
+ html_file_name = "#{directory_name}/html/#{file_name}.html"
+ File.open(html_file_name, "w") do |f|
+ f.write rewrite_javascript_and_css_and_image_references(response_body)
+ end
+
+ command = "snapurl file://#{html_file_name} --no-thumbnail --no-clip --filename #{file_name} --output-dir #{directory_name}"
+ `#{command}`
+ if $? == 0
+ puts "- Screenshot saved to #{directory_name}/#{file_name}.png\n"
+ true
+ else
+ report_error_running_screenshot_command(command)
+ false
+ end
+ end
+
+ protected
+ def rewrite_javascript_and_css_and_image_references(response_html) # :nodoc:
+ return response_html unless doc_root
+ rewrite_css_and_image_references(response_html).gsub(/"\/(javascript)/, doc_root + '/\1')
+ end
+
+ def report_error_running_screenshot_command(command)
+ STDERR.puts "
+Unable to make screenshot, to find out what went wrong try the following from the command line
+
+ #{command}
+
+Please remember need to have installed the gem mocoso-SnapshotUrl to take screenshots
+
+ gem install mocoso-SnapshotUrl
+
+"
+ end
+ end
+ end
+end
+
+Webrat::Session.send(:include, CucumberScreenshot::Webrat::Session)
+
30 spec/cucumber_screenshot/webrat/session_spec.rb
View
@@ -0,0 +1,30 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module CucumberScreenshot
+ module Webrat
+ describe Session do
+ describe '#base_screenshot_directory_name' do
+ it "add features/screenshots to rails root" do
+ ::RAILS_ROOT = 'tmp'
+ ::Webrat::Session.new.base_screenshot_directory_name.should == 'tmp/features/screenshots'
+ end
+ end
+
+ describe '#screenshot' do
+ before(:each) do
+ @html_file = stub('html_file', :write => true)
+ File.stub!(:makedirs => true, :open => @html_file)
+ @session = ::Webrat::Session.new
+ @session.stub!(:base_screenshot_directory_name => 'tmp/features/screenshots', :response_body => 'foo')
+ @session.stub!(:` => 'foo')
+ @session.stub!(:report_error_running_screenshot_command => true) # While $? is not being set by the backtick stub
+ end
+
+ it 'should call File.makedirs' do
+ File.should_receive(:makedirs).with('1/2/html').and_return(true)
+ @session.screenshot('1/2', 'snapshot-001')
+ end
+ end
+ end
+ end
+end
2  spec/spec.opts
View
@@ -0,0 +1,2 @@
+--colour
+--format progress
4 spec/spec_helper.rb
View
@@ -0,0 +1,4 @@
+SPEC_DIR = File.dirname(__FILE__)
+
+require 'rubygems'
+require 'cucumber_screenshot'
Please sign in to comment.
Something went wrong with that request. Please try again.