Skip to content

Commit

Permalink
Wrapped gist up in an application
Browse files Browse the repository at this point in the history
  • Loading branch information
techbelly committed Jun 26, 2012
0 parents commit f8ad4d3
Show file tree
Hide file tree
Showing 11 changed files with 253 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
@@ -0,0 +1,7 @@
*.gem
.rvmrc
*.tar.gz
rdoc
Gemfile.lock
html
pkg
2 changes: 2 additions & 0 deletions Gemfile
@@ -0,0 +1,2 @@
source :rubygems
gemspec
22 changes: 22 additions & 0 deletions Rakefile
@@ -0,0 +1,22 @@
require 'rubygems'
require 'rubygems/package_task'
require 'rdoc/task'

RDoc::Task.new do |rd|
rd.main = "README.rdoc"
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
rd.title = 'Your application title'
end

spec = eval(File.read('web_regression.gemspec'))

Gem::PackageTask.new(spec) do |pkg|
end

require 'rake/testtask'
Rake::TestTask.new do |t|
t.libs << "test"
t.test_files = FileList['test/**/*_test.rb']
end

task :default => :test
14 changes: 14 additions & 0 deletions bin/web-regression
@@ -0,0 +1,14 @@
#!/usr/bin/env ruby

unless File.respond_to? :realpath
class File #:nodoc:
def self.realpath path
return realpath(File.readlink(path)) if symlink?(path)
path
end
end
end
$: << File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../lib')
require 'web_regression'

WebRegression::Cli.execute($PROGRAM_NAME,ARGV)
8 changes: 8 additions & 0 deletions lib/web_regression.rb
@@ -0,0 +1,8 @@
module WebRegression
end

require 'web_regression/version'
require 'web_regression/application'
require 'web_regression/cli'
require 'web_regression/comparator'

13 changes: 13 additions & 0 deletions lib/web_regression/application.rb
@@ -0,0 +1,13 @@
require 'uri'

class WebRegression::Application
def initialize(options)
@options = options
end

def start
reference_file = @options.reference_file
uri = URI(@options.url)
return WebRegression::Comparator.new(reference_file,"#{uri.scheme}://#{uri.host}:#{uri.port}",uri.path,@options).compare
end
end
59 changes: 59 additions & 0 deletions lib/web_regression/cli.rb
@@ -0,0 +1,59 @@
require 'optparse'
require 'ostruct'

module WebRegression
class Cli
def self.parse_options(program,args)
options = OpenStruct.new
options.fastfail = false
options.nodiff = false
options.opendiff = false
options.reference_file = "/tmp/reference.png"

opts = OptionParser.new do |opts|
executable = File.basename(program)
opts.banner = "Usage: #{executable} [options] URL"
opts.separator ""

opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end

opts.on("-r","--reference_png PNG_FILE","Png file to compare against") do |f|
options.reference_file = f
end

opts.on("-f", "--fastfail","Fail as soon as a difference detected. Implies -n") do
options.fastfail = true
end

opts.on("-n", "--nodiff","Don't create a diff png") do
options.nodiff = true
end

opts.on("-o", "--opendiff","Open the diff file") do
options.opendiff = true
end

opts.on_tail("--version", "Show version") do
puts WebRegression::VERSION
exit
end
end
opts.parse!(args)
if ARGV.length != 1
puts opts
exit
end
options.url = ARGV[0]
options
end

def self.execute(program,args)
options = parse_options(program,args)
app = WebRegression::Application.new(options)
exit app.start
end
end
end
88 changes: 88 additions & 0 deletions lib/web_regression/comparator.rb
@@ -0,0 +1,88 @@
require 'capybara'
require 'capybara/dsl'
require 'capybara/poltergeist'
require 'chunky_png'
require 'tempfile'

Capybara.run_server = false
Capybara.default_driver = :poltergeist
Capybara.javascript_driver = :poltergeist

class WebRegression::Comparator < Struct.new(:reference_file,:host,:path,:options)
include Capybara::DSL

SUCCESS, FAILURE = 0,1

def take_screenshot(name)
Capybara.app_host = self.host
visit(self.path);
page.driver.render(name,:full => true)
end

def ensure_reference_image
unless File.exists?(self.reference_file)
$stderr.puts "Creating a reference screenshot at #{self.reference_file}"
take_screenshot(self.reference_file)
end
end

def screenshot
@screenshot ||= begin
image_name = '/tmp/ss.png'
take_screenshot(image_name)
image_name
end
end

def checksum_match?(file1, file2)
ref_md5 = `md5 #{file1}`
new_md5 = `md5 #{file2}`
ref_md5 == new_md5
end

def reference_image
@reference_image ||= ChunkyPNG::Image.from_file(self.reference_file)
end

def new_image
@new_image ||= ChunkyPNG::Image.from_file(screenshot)
end

def highlight_diffs(new_image,diff)
x, y = diff.map{ |xy| xy[0] }, diff.map{ |xy| xy[1] }

new_image.rect(x.min, y.min, x.max, y.max, ChunkyPNG::Color.rgb(255,0,0))
diff_path = '/tmp/diff.png'
new_image.save(diff_path)

if options.opendiff
`open #{diff_path}`
end
end

def compare
ensure_reference_image

return SUCCESS if checksum_match?(self.reference_file,screenshot)

diff = []

reference_image.height.times do |y|
reference_image.row(y).each_with_index do |pixel, x|
unless pixel == new_image[x,y]
return FAILURE if options.fastfail
diff << [x,y]
end
end
end

return SUCCESS if diff.length == 0

unless options.nodiff
highlight_diffs(new_image,diff)
end

return FAILURE
end

end
3 changes: 3 additions & 0 deletions lib/web_regression/version.rb
@@ -0,0 +1,3 @@
module WebRegression
VERSION = '0.9'
end
14 changes: 14 additions & 0 deletions test/null_test.rb
@@ -0,0 +1,14 @@
require 'test/unit'

class NullTest < Test::Unit::TestCase

def setup
end

def teardown
end

def test_the_truth
assert true
end
end
23 changes: 23 additions & 0 deletions web_regression.gemspec
@@ -0,0 +1,23 @@
require File.join([File.dirname(__FILE__),'lib','web_regression','version.rb'])
spec = Gem::Specification.new do |s|
s.name = 'web_regression'
s.version = WebRegression::VERSION
s.author = 'Ben Griffiths'
s.email = 'bengriffiths@gmail.com'
s.homepage = 'http://techbelly.com'
s.platform = Gem::Platform::RUBY
s.summary = 'Simple guard-friendly utility for diffing web screenshots to make css refactoring easier'
s.files = %w(
bin/web-regression
)
s.require_paths << 'lib'
s.has_rdoc = false
s.bindir = 'bin'
s.executables << 'web-regression'

s.add_dependency('chunky_png')
s.add_dependency('poltergeist')

s.add_development_dependency('rake')
s.add_development_dependency('rdoc')
end

0 comments on commit f8ad4d3

Please sign in to comment.