green_onion 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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