green_onion 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -4,4 +4,4 @@ rvm:
4
4
  before_script:
5
5
  - "export DISPLAY=:99.0"
6
6
  - "sh -e /etc/init.d/xvfb start"
7
- script: rspec spec
7
+ script: rake spec
data/README.md CHANGED
@@ -11,25 +11,68 @@ GreenOnion is a testing library for the UI only. It alerts you when the appearan
11
11
 
12
12
  Add this line to your application's Gemfile:
13
13
 
14
- gem 'green_onion'
14
+ `gem 'green_onion'`
15
15
 
16
16
  And then execute:
17
17
 
18
- $ bundle
18
+ `bundle`
19
19
 
20
20
  Or install it yourself as:
21
21
 
22
- $ gem install green_onion
22
+ `gem install green_onion`
23
23
 
24
24
  ## Usage
25
25
 
26
- ### Partnering up with RSpec
26
+ ### RSpec
27
27
 
28
+ For RSpec, `require 'green_onion'` in your spec_helper.rb file. Place this block in the file also:
29
+
30
+ `GreenOnion.configure do |c|
31
+ c.skins_dir = 'spec/skins'
32
+ c.threshold = 20
33
+ end`
34
+
35
+ * `skins_dir` is the directory that GreenOnion will store all skins. The namespace for skins is {URI name}.png (original), {URI name}_fresh.png (testing), and {URI name}_diff.png
36
+ * `threshold` is the percentage of acceptable change that the screenshots can take. This number can always be overwritten for an instance.
37
+
38
+ Then use one of the three methods below in a test...
39
+
40
+ ### Percentage of change
41
+
42
+ `GreenOnion.skin_percentage(url, threshold {optional})`
28
43
  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.
29
44
 
45
+ * `url` is the screen you want tested. Must include http://, example - 'http://yourSite.com'
46
+ * `threshold` can be overwritten here, or if not given in the configure block – it will default to a threshold of 100%
47
+
30
48
  ### Viewing screenshot diffs
31
49
 
32
- 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.
50
+ `GreenOnion.skin_visual(url)`
51
+ 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.
52
+
53
+ * `url` is the screen you want tested. Must include http://, example - 'http://yourSite.com'
54
+
55
+ ### Both viewing screenshot diffs and percentage of change
56
+
57
+
58
+
59
+ ## Contributing
60
+
61
+ ### Testing
62
+
63
+ The best way to run the specs is with...
64
+
65
+ `bundle exec rake spec`
66
+
67
+ ...this way a Sinatra WEBrick server will run concurrently with the test suite, and exit on completion. You can see the Sinatra app in spec/sample_app.
68
+
69
+ ## Roadmap
70
+
71
+ * Screenshots can either be viewed as a visual diff, or overlayed newest over oldest and viewed as an onion-skin with sliding transparency.
72
+ * Allow for headless screenshooting
73
+ * More robust tests, especially around the visual diffs themselves
74
+ * More documentation
75
+ * More configuration/customizable settings
33
76
 
34
77
  ## THANK YOU
35
78
 
data/Rakefile CHANGED
@@ -1,2 +1,24 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+ require 'rack'
4
+
5
+ desc "Running server..."
6
+ task :server do
7
+ require File.dirname(__FILE__) + '/spec/sample_app/sample_app.rb'
8
+ Rack::Handler::WEBrick.run SampleApp, :Port => 8070
9
+ end
10
+
11
+ desc "Running specs..."
12
+ task :specs do
13
+ system "rspec spec"
14
+ end
15
+
16
+ desc "Running specs on test server"
17
+ task :spec do
18
+ # have the server run on its own thread so that it doesn't block the spec task
19
+ server = Thread.new do
20
+ task("server").execute
21
+ end
22
+ task("specs").execute
23
+ server.kill
24
+ end
data/green_onion.gemspec CHANGED
@@ -13,9 +13,11 @@ Gem::Specification.new do |gem|
13
13
  gem.add_development_dependency "fileutils"
14
14
  gem.add_development_dependency "pry"
15
15
  gem.add_development_dependency "debugger"
16
+ gem.add_development_dependency "sinatra"
16
17
 
17
18
  gem.add_dependency "capybara"
18
19
  gem.add_dependency "oily_png"
20
+ gem.add_dependency "rainbow"
19
21
 
20
22
  gem.files = `git ls-files`.split($\)
21
23
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -1,4 +1,5 @@
1
1
  require "oily_png"
2
+ require "rainbow"
2
3
 
3
4
  module GreenOnion
4
5
  class Compare
@@ -25,17 +26,24 @@ module GreenOnion
25
26
 
26
27
  def percentage_diff(org, fresh)
27
28
  diff_images(org, fresh)
28
- self.total_px = @images.first.pixels.length
29
- self.changed_px = @diff.length
30
- self.percentage_changed = (@diff.length.to_f / @images.first.pixels.length) * 100
31
-
32
- puts "pixels (total): #{@total_px}"
33
- puts "pixels changed: #{@changed_px}"
34
- puts "pixels changed (%): #{@percentage_changed}%"
29
+ @total_px = @images.first.pixels.length
30
+ @changed_px = @diff.length
31
+ @percentage_changed = ( (@diff.length.to_f / @images.first.pixels.length) * 100 ).round(2)
35
32
  end
36
33
 
37
34
  def visual_diff(org, fresh)
38
35
  diff_images(org, fresh)
36
+ diff_iterating(org, fresh)
37
+ end
38
+
39
+ def percentage_and_visual_diff(org, fresh)
40
+ diff_images(org, fresh)
41
+ @total_px = @images.first.pixels.length
42
+ @changed_px = @diff.length
43
+ @percentage_changed = ( (@diff.length.to_f / @images.first.pixels.length) * 100 ).round(2)
44
+ end
45
+
46
+ def diff_iterating(org, fresh)
39
47
  x, y = @diff.map{ |xy| xy[0] }, @diff.map{ |xy| xy[1] }
40
48
 
41
49
  @diffed_image = org.insert(-5, '_diff')
@@ -43,7 +51,7 @@ module GreenOnion
43
51
  begin
44
52
  @images.last.rect(x.min, y.min, x.max, y.max, ChunkyPNG::Color.rgb(0,255,0))
45
53
  rescue NoMethodError
46
- puts "#{org} and #{fresh} skins are the same."
54
+ puts "#{org} and #{fresh} skins are the same.".color(:yellow)
47
55
  end
48
56
 
49
57
  @images.last.save(@diffed_image)
@@ -1,11 +1,7 @@
1
1
  module GreenOnion
2
2
  class Configuration
3
3
 
4
- attr_accessor :skins_dir
5
-
6
- def skins_dir=(directory)
7
- @skins_dir ||= directory
8
- end
4
+ attr_accessor :skins_dir, :threshold
9
5
 
10
6
  end
11
7
  end
@@ -1,3 +1,3 @@
1
1
  module GreenOnion
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/green_onion.rb CHANGED
@@ -2,11 +2,14 @@ require "green_onion/version"
2
2
  require "green_onion/screenshot"
3
3
  require "green_onion/compare"
4
4
  require "green_onion/configuration"
5
+ require "rainbow"
6
+
5
7
  module GreenOnion
6
8
  class << self
7
9
 
8
10
  attr_reader :compare, :screenshot
9
11
 
12
+ # Pass configure block to set Configuration object
10
13
  def configure
11
14
  yield configuration
12
15
  end
@@ -15,26 +18,56 @@ module GreenOnion
15
18
  @configuration ||= GreenOnion::Configuration.new
16
19
  end
17
20
 
21
+ # Bring the Screenshot and Compare classes together to create a skin
18
22
  def skin(url)
19
23
  @screenshot = Screenshot.new(
20
- :dir => self.configuration.skins_dir
24
+ :dir => @configuration.skins_dir
21
25
  )
22
26
  @compare = GreenOnion::Compare.new
23
27
 
24
28
  @screenshot.test_screenshot(url)
25
29
  end
26
30
 
27
- def skin_percentage(url)
28
- self.skin(url)
31
+ # Finds the percentage of change between skins
32
+ # Threshold can be set in configuration, or as an argument itself, and can be specific to an instance
33
+ def skin_percentage(url, threshold=@configuration.threshold)
34
+ threshold ||= 100
35
+ skin(url)
29
36
  if(@screenshot.paths_hash.length > 1)
30
- self.compare.percentage_diff(@screenshot.paths_hash[:original], @screenshot.paths_hash[:fresh])
37
+ puts "\n" + url.color(:cyan)
38
+ @compare.percentage_diff(@screenshot.paths_hash[:original], @screenshot.paths_hash[:fresh])
39
+ threshold_alert(@compare.percentage_changed, threshold)
31
40
  end
32
41
  end
33
42
 
43
+ # Creates a diffed screenshot between skins
34
44
  def skin_visual(url)
35
- self.skin(url)
45
+ skin(url)
46
+ if(@screenshot.paths_hash.length > 1)
47
+ puts "\n" + url.color(:cyan)
48
+ @compare.visual_diff(@screenshot.paths_hash[:original], @screenshot.paths_hash[:fresh])
49
+ end
50
+ end
51
+
52
+ # Creates a diffed screenshot between skins AND prints percentage changed
53
+ def skin_visual_and_percentage(url, threshold=@configuration.threshold)
54
+ skin(url)
36
55
  if(@screenshot.paths_hash.length > 1)
37
- self.compare.visual_diff(@screenshot.paths_hash[:original], @screenshot.paths_hash[:fresh])
56
+ puts "\n" + url.color(:cyan)
57
+ @compare.percentage_diff(@screenshot.paths_hash[:original], @screenshot.paths_hash[:fresh])
58
+ @compare.visual_diff(@screenshot.paths_hash[:original], @screenshot.paths_hash[:fresh])
59
+ threshold_alert(@compare.percentage_changed, threshold)
60
+ end
61
+ end
62
+
63
+ # This is used in skin_percentage to better alert if a set of skins are ok or not
64
+ def threshold_alert(actual, threshold)
65
+ if actual > threshold
66
+ puts "#{actual - threshold}% above threshold set @ #{threshold}%".color(:red)
67
+ puts "pixels changed (%): #{@compare.percentage_changed}%"
68
+ puts "pixels changed/total: #{@compare.changed_px}/#{@compare.total_px}"
69
+ else
70
+ puts "pixels changed/total: #{@compare.changed_px}/#{@compare.total_px}"
38
71
  end
39
72
  end
40
73
 
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ require 'sinatra'
3
+
4
+ class SampleApp < Sinatra::Base
5
+ set :root, File.dirname(__FILE__)
6
+ set :static, true
7
+ set :logging, false
8
+
9
+ get '/' do
10
+ "<div style='height:200px; width:200px; background-color:rgb(#{rand(266)}, #{rand(266)}, #{rand(266)})'><!-- Big blue box --></div>"
11
+ end
12
+
13
+ get "/fake_uri" do
14
+ "<h2>foo</h2>"
15
+ end
16
+
17
+ end
@@ -6,10 +6,13 @@ describe GreenOnion do
6
6
 
7
7
  before(:each) do
8
8
  @tmp_path = './spec/tmp'
9
+ @url = 'http://localhost:8070'
10
+ @url_w_uri = @url + '/fake_uri'
9
11
  FileUtils.mkdir(@tmp_path)
10
12
 
11
13
  GreenOnion.configure do |c|
12
14
  c.skins_dir = @tmp_path
15
+ c.threshold = 1
13
16
  end
14
17
  end
15
18
 
@@ -23,7 +26,7 @@ describe GreenOnion do
23
26
 
24
27
  it "should get the correct paths_hash" do
25
28
  2.times do
26
- GreenOnion.skin('http://www.google.com')
29
+ GreenOnion.skin(@url)
27
30
  end
28
31
  ( (GreenOnion.screenshot.paths_hash[:original] == "#{@tmp_path}/root.png") &&
29
32
  (GreenOnion.screenshot.paths_hash[:fresh] == "#{@tmp_path}/root_fresh.png") ).should be_true
@@ -31,18 +34,53 @@ describe GreenOnion do
31
34
 
32
35
  it "should measure the percentage of diff between skins" do
33
36
  2.times do
34
- GreenOnion.skin_percentage('http://www.google.com')
37
+ GreenOnion.skin_percentage(@url)
35
38
  end
36
- GreenOnion.compare.percentage_changed.should be <(1)
39
+ GreenOnion.compare.percentage_changed.should be > 0
40
+ end
41
+
42
+ it "should measure the percentage of diff between skins (even if there is no diff)" do
43
+ 2.times do
44
+ GreenOnion.skin_percentage(@url_w_uri)
45
+ end
46
+ GreenOnion.compare.percentage_changed.should be == 0
47
+ end
48
+
49
+ it "should alert when diff percentage threshold is surpassed" do
50
+ $stdout.should_receive(:puts).exactly(4).times
51
+ 2.times do
52
+ GreenOnion.skin_percentage(@url)
53
+ end
54
+ end
55
+
56
+ it "should print just URL and changed/total when diff percentage threshold has not been surpassed" do
57
+ $stdout.should_receive(:puts).exactly(2).times
58
+ 2.times do
59
+ GreenOnion.skin_percentage(@url, 6)
60
+ end
61
+ end
62
+
63
+ it "should create visual diff between skins" do
64
+ 2.times do
65
+ GreenOnion.skin_visual(@url)
66
+ end
67
+ GreenOnion.compare.diffed_image.should eq("#{@tmp_path}/root_diff.png")
37
68
  end
38
69
 
39
- it "should create visual diff between skins"
40
70
 
41
71
  it "should create visual diff between skins (even when there is no change)" do
42
72
  2.times do
43
- GreenOnion.skin_visual('http://www.google.com')
73
+ GreenOnion.skin_visual(@url_w_uri)
74
+ end
75
+ GreenOnion.compare.diffed_image.should eq("#{@tmp_path}/fake_uri_diff.png")
76
+ end
77
+
78
+ it "should measure the percentage of diff between skins AND create visual diff" do
79
+ 2.times do
80
+ GreenOnion.skin_visual_and_percentage(@url)
44
81
  end
45
- GreenOnion.compare.diffed_image.should eq('./spec/tmp/root_diff.png')
82
+ ( (GreenOnion.compare.diffed_image.should eq("#{@tmp_path}/root_diff.png")) &&
83
+ (GreenOnion.compare.percentage_changed.should be > 0) ).should be_true
46
84
  end
47
85
 
48
86
  end
@@ -2,6 +2,11 @@ require 'spec_helper'
2
2
 
3
3
  describe GreenOnion::Screenshot do
4
4
 
5
+ before(:all) do
6
+ @url = 'http://localhost:8070'
7
+ @url_w_uri = @url + '/fake_uri'
8
+ end
9
+
5
10
  describe 'Snap single screenshot' do
6
11
 
7
12
  before(:each) do
@@ -11,8 +16,7 @@ describe GreenOnion::Screenshot do
11
16
  @screenshot = GreenOnion::Screenshot.new(
12
17
  :dir => @tmp_path
13
18
  )
14
- @url = 'http://www.google.com/maps'
15
- @file = "#{@tmp_path}/maps.png"
19
+ @file = "#{@tmp_path}/fake_uri.png"
16
20
  end
17
21
 
18
22
  after(:each) do
@@ -20,24 +24,24 @@ describe GreenOnion::Screenshot do
20
24
  end
21
25
 
22
26
  it 'should build the path from the URI' do
23
- @screenshot.url_to_path(@url).should eq(@file)
27
+ @screenshot.url_to_path(@url_w_uri).should eq(@file)
24
28
  end
25
29
 
26
30
  it 'should build the path from root' do
27
- @screenshot.url_to_path('http://www.google.com').should eq("#{@tmp_path}/root.png")
31
+ @screenshot.url_to_path('http://localhost:8070').should eq("#{@tmp_path}/root.png")
28
32
  end
29
33
 
30
34
  it 'should build the path from root (even with trailing slash)' do
31
- @screenshot.url_to_path('http://www.google.com/').should eq("#{@tmp_path}/root.png")
35
+ @screenshot.url_to_path('http://localhost:8070/').should eq("#{@tmp_path}/root.png")
32
36
  end
33
37
 
34
38
  it 'should snap and save screenshot' do
35
- @screenshot.snap_screenshot(@url, @file)
39
+ @screenshot.snap_screenshot(@url_w_uri, @file)
36
40
  File.exist?(@file).should be_true
37
41
  end
38
42
 
39
43
  it "should destroy a singular screenshot" do
40
- @screenshot.destroy(@url)
44
+ @screenshot.destroy(@url_w_uri)
41
45
  File.exist?(@file).should be_false
42
46
  end
43
47
  end
@@ -51,11 +55,10 @@ describe GreenOnion::Screenshot do
51
55
  @screenshot = GreenOnion::Screenshot.new(
52
56
  :dir => @tmp_path
53
57
  )
54
- @url = 'http://www.google.com/maps'
55
- @file1 = "#{@tmp_path}/maps.png"
56
- @file2 = "#{@tmp_path}/maps_fresh.png"
58
+ @file1 = "#{@tmp_path}/fake_uri.png"
59
+ @file2 = "#{@tmp_path}/fake_uri_fresh.png"
57
60
  2.times do
58
- @screenshot.test_screenshot(@url)
61
+ @screenshot.test_screenshot(@url_w_uri)
59
62
  end
60
63
  end
61
64
 
@@ -74,7 +77,7 @@ describe GreenOnion::Screenshot do
74
77
  end
75
78
 
76
79
  it "should destroy a set of screenshots" do
77
- @screenshot.destroy(@url)
80
+ @screenshot.destroy(@url_w_uri)
78
81
  ( File.exist?(@file1) && File.exist?(@file2) ).should be_false
79
82
  end
80
83
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: green_onion
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.2
5
+ version: 0.0.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ted O'Meara
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-07-26 00:00:00 Z
13
+ date: 2012-07-27 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -68,7 +68,7 @@ dependencies:
68
68
  type: :development
69
69
  version_requirements: *id005
70
70
  - !ruby/object:Gem::Dependency
71
- name: capybara
71
+ name: sinatra
72
72
  prerelease: false
73
73
  requirement: &id006 !ruby/object:Gem::Requirement
74
74
  none: false
@@ -76,10 +76,10 @@ dependencies:
76
76
  - - ">="
77
77
  - !ruby/object:Gem::Version
78
78
  version: "0"
79
- type: :runtime
79
+ type: :development
80
80
  version_requirements: *id006
81
81
  - !ruby/object:Gem::Dependency
82
- name: oily_png
82
+ name: capybara
83
83
  prerelease: false
84
84
  requirement: &id007 !ruby/object:Gem::Requirement
85
85
  none: false
@@ -89,6 +89,28 @@ dependencies:
89
89
  version: "0"
90
90
  type: :runtime
91
91
  version_requirements: *id007
92
+ - !ruby/object:Gem::Dependency
93
+ name: oily_png
94
+ prerelease: false
95
+ requirement: &id008 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: "0"
101
+ type: :runtime
102
+ version_requirements: *id008
103
+ - !ruby/object:Gem::Dependency
104
+ name: rainbow
105
+ prerelease: false
106
+ requirement: &id009 !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: "0"
112
+ type: :runtime
113
+ version_requirements: *id009
92
114
  description: UI testing/screenshot diffing tool
93
115
  email:
94
116
  - ted@intridea.com
@@ -113,6 +135,7 @@ files:
113
135
  - lib/green_onion/configuration.rb
114
136
  - lib/green_onion/screenshot.rb
115
137
  - lib/green_onion/version.rb
138
+ - spec/sample_app/sample_app.rb
116
139
  - spec/skins/spec_shot.png
117
140
  - spec/skins/spec_shot_fresh.png
118
141
  - spec/spec_helper.rb
@@ -147,6 +170,7 @@ signing_key:
147
170
  specification_version: 3
148
171
  summary: Regressions in the view making you cry? Have more confidence with GreenOnion.
149
172
  test_files:
173
+ - spec/sample_app/sample_app.rb
150
174
  - spec/skins/spec_shot.png
151
175
  - spec/skins/spec_shot_fresh.png
152
176
  - spec/spec_helper.rb