Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f8ad4d3
Showing
11 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
*.gem | ||
.rvmrc | ||
*.tar.gz | ||
rdoc | ||
Gemfile.lock | ||
html | ||
pkg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
source :rubygems | ||
gemspec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module WebRegression | ||
end | ||
|
||
require 'web_regression/version' | ||
require 'web_regression/application' | ||
require 'web_regression/cli' | ||
require 'web_regression/comparator' | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module WebRegression | ||
VERSION = '0.9' | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |