green_onion 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.2@green_onion --create
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in green_onion.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ted O'Meara
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # GreenOnion
2
+
3
+ Regression issues make you cry.
4
+
5
+ GreenOnion is a testing library for the UI only. It alerts you when the appearance of a view has changed, let's you know the percentage of total change, and allows you to visualize the areas that have been changed. It fits right into your test suite, and is dependent on familiar tools like Capybara.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'green_onion'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install green_onion
20
+
21
+ ## Usage
22
+
23
+ ### Partnering up with RSpec
24
+
25
+ The primary feature of GreenOnion is seeing how much (if at all) a view has changed from one instance to the next, and being alerted when a view has surpassed into an unacceptable threshold.
26
+
27
+ ### Viewing screenshot diffs
28
+
29
+ Once you are aware of a issue in the UI, you can also rip open your spec/skins directory and manually see what the differences are from one screenshot to the next. Screenshots can either be viewed as a visual diff, or overlayed newest over oldest and viewed as an green_onion-skin with sliding transparency.
30
+
31
+ ## THANK YOU
32
+
33
+ Much of this work could not be completed without these people and projects
34
+
35
+ ### Jeff Kreeftmeijer
36
+ This is the post that got the wheels in motion: http://jeffkreeftmeijer.com/2011/comparing-images-and-creating-image-diffs/. Most of the GreenOnion::Compare class is based on this work alone. Great job Jeff!
37
+
38
+ ### Compatriot
39
+ Carol Nichols saw the same post, and worked on an excellent gem for cross-browser testing. That gem greatly influenced design decisions with GreenOnion.
40
+
41
+ ### Capybara and ChunkyPNG
42
+ The land on which we sow our bulbs.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/green_onion/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ted O'Meara"]
6
+ gem.email = ["ted@intridea.com"]
7
+ gem.description = %q{UI testing/screenshot diffing tool}
8
+ gem.summary = %q{Regressions in the view making you cry? Have more confidence with GreenOnion.}
9
+ gem.homepage = ""
10
+
11
+ gem.add_development_dependency "rake"
12
+ gem.add_development_dependency "rspec"
13
+ gem.add_development_dependency "fileutils"
14
+ gem.add_development_dependency "pry"
15
+
16
+ gem.add_dependency "capybara"
17
+ gem.add_dependency "chunky_png"
18
+
19
+ gem.files = `git ls-files`.split($\)
20
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
21
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
22
+ gem.name = "green_onion"
23
+ gem.require_paths = ["lib"]
24
+ gem.version = GreenOnion::VERSION
25
+ end
@@ -0,0 +1,45 @@
1
+ require "chunky_png"
2
+
3
+ module GreenOnion
4
+ class Compare
5
+
6
+ attr_accessor :percentage_changed, :total_px, :changed_px
7
+
8
+ # Pulled from Jeff Kreeftmeijer's post here: http://jeffkreeftmeijer.com/2011/comparing-images-and-creating-image-diffs/
9
+ # Thanks Jeff!
10
+ def diff_images(org, fresh)
11
+ @images = [
12
+ ChunkyPNG::Image.from_file(org),
13
+ ChunkyPNG::Image.from_file(fresh)
14
+ ]
15
+
16
+ @diff = []
17
+
18
+ @images.first.height.times do |y|
19
+ @images.first.row(y).each_with_index do |pixel, x|
20
+ @diff << [x,y] unless pixel == @images.last[x,y]
21
+ end
22
+ end
23
+ end
24
+
25
+ def percentage_diff(org, fresh)
26
+ diff_images(org, fresh)
27
+ self.total_px = @images.first.pixels.length
28
+ self.changed_px = @diff.length
29
+ self.percentage_changed = (@diff.length.to_f / @images.first.pixels.length) * 100
30
+
31
+ puts "pixels (total): #{@total_px}"
32
+ puts "pixels changed: #{@changed_px}"
33
+ puts "pixels changed (%): #{@percentage_changed}%"
34
+ end
35
+
36
+ def visual_diff(org, fresh)
37
+ diff_images(org, fresh)
38
+ x, y = diff.map{ |xy| xy[0] }, diff.map{ |xy| xy[1] }
39
+
40
+ images.last.rect(x.min, y.min, x.max, y.max, ChunkyPNG::Color.rgb(0,255,0))
41
+ images.last.save('diff.png')
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,58 @@
1
+ require 'capybara/dsl'
2
+ require "fileutils"
3
+
4
+ module GreenOnion
5
+ class Screenshot
6
+ include Capybara::DSL
7
+
8
+ attr_accessor :dir
9
+
10
+ def initialize(params = {})
11
+ Capybara.default_driver = :selenium
12
+ @dir = params[:dir]
13
+ end
14
+
15
+ def snap_screenshot(url, path)
16
+ visit url
17
+ Capybara.page.driver.browser.save_screenshot(path)
18
+ end
19
+
20
+ def test_screenshot(url)
21
+ url_to_path(url)
22
+ snap_screenshot(url, @path)
23
+ end
24
+
25
+ def url_to_path(url)
26
+ @filename = url.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/)[5]
27
+ if @filename.empty?
28
+ @path = "#{@dir}/root.png"
29
+ else
30
+ @filename = @filename.gsub(/[\/]/, '')
31
+ @path = "#{@dir}/#{@filename}.png"
32
+ end
33
+ accepted?(@path)
34
+ return @path
35
+ end
36
+
37
+ def accepted?(path)
38
+ if File.exist?(path)
39
+ return path.insert(-5, '_fresh')
40
+ else
41
+ return path
42
+ end
43
+ end
44
+
45
+ def destroy(url)
46
+ url_to_path(url)
47
+ fresh_path = @path.insert(-5, '_fresh')
48
+
49
+ if File.exist?(fresh_path)
50
+ FileUtils.rm(fresh_path)
51
+ end
52
+ if File.exist?(@path)
53
+ FileUtils.rm(@path)
54
+ end
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module GreenOnion
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ require "green_onion/version"
2
+ require "green_onion/screenshot"
3
+ require "green_onion/compare"
4
+
5
+ module GreenOnion
6
+ class << self
7
+
8
+ end
9
+ end
Binary file
Binary file
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'fileutils'
4
+
5
+ require 'green_onion'
6
+
7
+ RSpec.configure do |config|
8
+ # some (optional) config here
9
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe GreenOnion::Compare do
4
+
5
+ describe 'Comparing Screenshots' do
6
+
7
+ before(:each) do
8
+ @comparison = GreenOnion::Compare.new
9
+ @spec_shot1 = './spec/skins/spec_shot.png'
10
+ @spec_shot2 = './spec/skins/spec_shot_fresh.png'
11
+ end
12
+
13
+ it 'should get a percentage of difference between two shots' do
14
+ @comparison.percentage_diff(@spec_shot1, @spec_shot2)
15
+ @comparison.percentage_changed.should eq(66.0)
16
+ end
17
+
18
+ it 'should create a new file with a visual diff between two shots' do
19
+ @comparison.visual_diff(@spec_shot1, @spec_shot2)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe GreenOnion::Screenshot do
4
+
5
+ describe 'Snap single screenshot' do
6
+
7
+ before(:each) do
8
+ @tmp_path = './spec/tmp'
9
+ FileUtils.mkdir(@tmp_path)
10
+
11
+ @screenshot = GreenOnion::Screenshot.new(
12
+ :dir => @tmp_path
13
+ )
14
+ @url = 'http://www.google.com/maps'
15
+ @file = "#{@tmp_path}/maps.png"
16
+ end
17
+
18
+ after(:each) do
19
+ FileUtils.rm_r(@tmp_path, :force => true)
20
+ end
21
+
22
+ it 'should build the path from the URI' do
23
+ @screenshot.url_to_path(@url).should eq(@file)
24
+ end
25
+
26
+ it 'should build the path from root' do
27
+ @screenshot.url_to_path('http://www.google.com').should eq("#{@tmp_path}/root.png")
28
+ end
29
+
30
+ it 'should snap and save screenshot' do
31
+ @screenshot.snap_screenshot(@url, @file)
32
+ File.exist?(@file).should be_true
33
+ end
34
+
35
+ it "should destroy a singular screenshot" do
36
+ @screenshot.destroy(@url)
37
+ File.exist?(@file).should be_false
38
+ end
39
+ end
40
+
41
+ describe 'Snap two screenshots' do
42
+
43
+ before(:each) do
44
+ @tmp_path = './spec/tmp'
45
+ FileUtils.mkdir(@tmp_path)
46
+
47
+ @screenshot = GreenOnion::Screenshot.new(
48
+ :dir => @tmp_path
49
+ )
50
+ @url = 'http://www.google.com/maps'
51
+ @file1 = "#{@tmp_path}/maps.png"
52
+ @file2 = "#{@tmp_path}/maps_fresh.png"
53
+ 2.times do
54
+ @screenshot.test_screenshot(@url)
55
+ end
56
+ end
57
+
58
+ after(:each) do
59
+ FileUtils.rm_r(@tmp_path, :force => true)
60
+ end
61
+
62
+ it "should snap and save another screenshot if a screenshot already exists" do
63
+ if File.exist?(@file1)
64
+ File.exist?(@file2).should be_true
65
+ end
66
+ end
67
+
68
+ it "should destroy a set of screenshots" do
69
+ @screenshot.destroy(@url)
70
+ File.exist?(@file1).should be_false
71
+ end
72
+ end
73
+ end
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: green_onion
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Ted O'Meara
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-07-18 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: fileutils
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: pry
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: capybara
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :runtime
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: chunky_png
72
+ prerelease: false
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ type: :runtime
80
+ version_requirements: *id006
81
+ description: UI testing/screenshot diffing tool
82
+ email:
83
+ - ted@intridea.com
84
+ executables: []
85
+
86
+ extensions: []
87
+
88
+ extra_rdoc_files: []
89
+
90
+ files:
91
+ - .gitignore
92
+ - .rspec
93
+ - .rvmrc
94
+ - Gemfile
95
+ - LICENSE
96
+ - README.md
97
+ - Rakefile
98
+ - green_onion.gemspec
99
+ - lib/green_onion.rb
100
+ - lib/green_onion/compare.rb
101
+ - lib/green_onion/screenshot.rb
102
+ - lib/green_onion/version.rb
103
+ - spec/skins/spec_shot.png
104
+ - spec/skins/spec_shot_fresh.png
105
+ - spec/spec_helper.rb
106
+ - spec/unit/compare_spec.rb
107
+ - spec/unit/screenshot_spec.rb
108
+ homepage: ""
109
+ licenses: []
110
+
111
+ post_install_message:
112
+ rdoc_options: []
113
+
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: "0"
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: "0"
128
+ requirements: []
129
+
130
+ rubyforge_project:
131
+ rubygems_version: 1.8.5
132
+ signing_key:
133
+ specification_version: 3
134
+ summary: Regressions in the view making you cry? Have more confidence with GreenOnion.
135
+ test_files:
136
+ - spec/skins/spec_shot.png
137
+ - spec/skins/spec_shot_fresh.png
138
+ - spec/spec_helper.rb
139
+ - spec/unit/compare_spec.rb
140
+ - spec/unit/screenshot_spec.rb