green_onion 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- [<img src="https://secure.travis-ci.org/tomeara/green_onion.png" />](http://travis-ci.org/#!/tomeara/green_onion)
2
+ [<img src="https://secure.travis-ci.org/tomeara/green_onion.png" />](http://travis-ci.org/#!/tomeara/green_onion) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/tomeara/green_onion)
3
3
 
4
4
  # GreenOnion
5
5
 
@@ -7,6 +7,10 @@ Regression issues in the view make you cry.
7
7
 
8
8
  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.
9
9
 
10
+ ## Documentation
11
+
12
+ [RDoc](http://rdoc.info/gems/green_onion/frames)
13
+
10
14
  ## Installation
11
15
 
12
16
  You'll need to get Qt built in your testing environment. [Follow these steps](https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit) to get it up and running.
@@ -45,7 +49,7 @@ Options
45
49
 
46
50
  To generate a "skinner" file, which will test a Rails application with the routes without params included (this is an area that could be worked on a lot more :) ); use the command below:
47
51
 
48
- green_onion generate [options]
52
+ green_onion generate [options]
49
53
 
50
54
  * `--url=URL` - the domain that you will be testing your Rails app. The default is "http://localhost:3000".
51
55
  * `--dir=DIR` - the directory in which you would like to generate the skinner. The default is "spec/skinner.rb"
@@ -101,6 +105,7 @@ The best way to run the specs is with...
101
105
  * Screenshots can either be viewed as a visual diff, or overlayed newest over oldest and viewed as an onion-skin with sliding transparency.
102
106
  * Allow for flexibility in picking browsers
103
107
  * Skinner generator needs love <3
108
+ ** Should allow for testing using fixtures/factories
104
109
  * More robust tests, especially around the visual diffs themselves
105
110
  * More documentation
106
111
  * More configuration/customizable settings
@@ -116,4 +121,13 @@ This is the post that got the wheels in motion: http://jeffkreeftmeijer.com/2011
116
121
  Carol Nichols saw the same post, and worked on an excellent gem for cross-browser testing. That gem greatly influenced design decisions with GreenOnion.
117
122
 
118
123
  ### Capybara, ChunkyPNG, Thor, and OilyPNG
119
- The land on which we sow our bulbs.
124
+ The land on which we sow our bulbs.
125
+
126
+ ## Contributor
127
+ [Ted O'Meara](http://www.intridea.com/about/team/ted-o-meara)
128
+
129
+ ## License
130
+ MIT License. See LICENSE for details.
131
+
132
+ ## Copyright
133
+ Copyright (c) 2012 Intridea, Inc.
@@ -5,7 +5,7 @@ module GreenOnion
5
5
  class CLI < Thor
6
6
  include Thor::Actions
7
7
 
8
- self.source_root("lib/green_onion/generators")
8
+ source_root File.expand_path('../generators', __FILE__)
9
9
 
10
10
  class_option :dir, :aliases => "-d", :type => :string
11
11
 
@@ -30,12 +30,12 @@ module GreenOnion
30
30
  end
31
31
  end
32
32
 
33
- desc "generate", "Generates a 'skinner' file to test a Rails app at <url> with routes without params"
33
+ desc "generate", "Generates a 'skinner' file to test only Rails routes without params"
34
34
  method_option :url, :aliases => "-u", :type => :string
35
35
  def generate_skinner
36
36
  options[:dir] ? dir = options[:dir] : dir = "spec"
37
- options[:url] ? url = options[:url] : url = "http://localhost:3000"
38
- template('skinner.erb', "#{dir}/skinner.rb")
37
+ options[:url] ? config = { :url => options[:url] } : config = { :url => "http://localhost:3000" }
38
+ template('skinner.erb', "#{dir}/skinner.rb", config)
39
39
  end
40
40
  end
41
41
  end
@@ -19,7 +19,7 @@ module GreenOnion
19
19
  begin
20
20
  diff_iterator
21
21
  rescue ChunkyPNG::OutOfBounds
22
- puts "Skins are different sizes. Please delete #{org} and/or #{fresh}.".color(:yellow)
22
+ warn "Skins are different sizes. Please delete #{org} and/or #{fresh}.".color(:yellow)
23
23
  end
24
24
  end
25
25
 
@@ -28,16 +28,24 @@ module GreenOnion
28
28
  @images.first.row(y).each_with_index do |pixel, x|
29
29
  unless pixel == @images.last[x,y]
30
30
  @diff_index << [x,y]
31
- @images.last[x,y] = ChunkyPNG::Color.rgb(
32
- ChunkyPNG::Color.r(pixel) + ChunkyPNG::Color.r(@images.last[x,y]) - 2 * [ChunkyPNG::Color.r(pixel), ChunkyPNG::Color.r(@images.last[x,y])].min,
33
- ChunkyPNG::Color.g(pixel) + ChunkyPNG::Color.g(@images.last[x,y]) - 2 * [ChunkyPNG::Color.g(pixel), ChunkyPNG::Color.g(@images.last[x,y])].min,
34
- ChunkyPNG::Color.b(pixel) + ChunkyPNG::Color.b(@images.last[x,y]) - 2 * [ChunkyPNG::Color.b(pixel), ChunkyPNG::Color.b(@images.last[x,y])].min
35
- )
31
+ pixel_difference_filter(pixel, x, y)
36
32
  end
37
33
  end
38
34
  end
39
35
  end
40
36
 
37
+ def pixel_difference_filter(pixel, x, y)
38
+ chans = []
39
+ [:r, :b, :g].each do |chan|
40
+ chans << channel_difference(chan, pixel, x, y)
41
+ end
42
+ @images.last[x,y] = ChunkyPNG::Color.rgb(chans[0], chans[1], chans[2])
43
+ end
44
+
45
+ def channel_difference(chan, pixel, x, y)
46
+ ChunkyPNG::Color.send(chan, pixel) + ChunkyPNG::Color.send(chan, @images.last[x,y]) - 2 * [ChunkyPNG::Color.send(chan, pixel), ChunkyPNG::Color.send(chan, @images.last[x,y])].min
47
+ end
48
+
41
49
  def percentage_diff(org, fresh)
42
50
  diff_images(org, fresh)
43
51
  @total_px = @images.first.pixels.length
@@ -47,19 +55,11 @@ module GreenOnion
47
55
 
48
56
  def visual_diff(org, fresh)
49
57
  diff_images(org, fresh)
50
- diff_iterating(org, fresh)
51
- end
52
-
53
- def percentage_and_visual_diff(org, fresh)
54
- diff_images(org, fresh)
55
- @total_px = @images.first.pixels.length
56
- @changed_px = @diff_index.length
57
- @percentage_changed = ( (@diff_index.length.to_f / @images.first.pixels.length) * 100 ).round(2)
58
+ save_visual_diff(org, fresh)
58
59
  end
59
60
 
60
- def diff_iterating(org, fresh)
61
+ def save_visual_diff(org, fresh)
61
62
  x, y = @diff_index.map{ |xy| xy[0] }, @diff_index.map{ |xy| xy[1] }
62
-
63
63
  @diffed_image = org.insert(-5, '_diff')
64
64
 
65
65
  begin
@@ -0,0 +1,10 @@
1
+ module GreenOnion
2
+ class Errors
3
+ #Base class for all errors
4
+ class Error < StandardError; end
5
+
6
+ class IllformattedURL < Error; end
7
+
8
+ class ThresholdOutOfRange < Error; end
9
+ end
10
+ end
@@ -17,5 +17,5 @@ all_routes = Rails.application.routes.routes
17
17
  routes = all_routes.collect { |r| r.path.spec.to_s.gsub(/\/*(\(\.)*:(\w*)(\))*\/*/, "") }.delete_if(&:empty?)
18
18
 
19
19
  routes.each do |route|
20
- GreenOnion.skin_percentage(url + route)
20
+ GreenOnion.skin_visual_and_percentage("<%= config[:url] %>" + route)
21
21
  end
@@ -36,8 +36,17 @@ module GreenOnion
36
36
  end
37
37
  end
38
38
 
39
+ def url_matcher(url)
40
+ url_match = url.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/).to_a.compact
41
+ if url_match.length >= 5
42
+ @filename = url_match[5]
43
+ else
44
+ raise Errors::IllformattedURL.new "Your URL is incorrectly formatted. Please make sure to use http://"
45
+ end
46
+ end
47
+
39
48
  def get_path(url)
40
- @filename = url.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/)[5]
49
+ url_matcher(url)
41
50
  if @filename.empty? || @filename == '/'
42
51
  @paths_hash[:original] = "#{@dir}/root.png"
43
52
  else
@@ -1,3 +1,3 @@
1
1
  module GreenOnion
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/green_onion.rb CHANGED
@@ -2,6 +2,7 @@ require "green_onion/version"
2
2
  require "green_onion/screenshot"
3
3
  require "green_onion/compare"
4
4
  require "green_onion/configuration"
5
+ require "green_onion/errors"
5
6
  require "rainbow"
6
7
 
7
8
  module GreenOnion
@@ -32,35 +33,34 @@ module GreenOnion
32
33
  # Finds the percentage of change between skins
33
34
  # Threshold can be set in configuration, or as an argument itself, and can be specific to an instance
34
35
  def skin_percentage(url, threshold=@configuration.threshold)
36
+ raise Errors::ThresholdOutOfRange.new "The threshold need to be a number between 1 and 100" if threshold > 100
35
37
  skin(url)
36
- if(@screenshot.paths_hash.length > 1)
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)
40
- else
41
- puts "\n#{url}".color(:cyan) + " has been saved to #{@screenshot.paths_hash[:original]}".color(:yellow)
42
- end
38
+ skin_picker(url, { :percentage => true }, threshold)
43
39
  end
44
40
 
45
41
  # Creates a diffed screenshot between skins
46
42
  def skin_visual(url)
47
43
  skin(url)
48
- if(@screenshot.paths_hash.length > 1)
49
- puts "\n" + url.color(:cyan)
50
- @compare.visual_diff(@screenshot.paths_hash[:original], @screenshot.paths_hash[:fresh])
51
- else
52
- puts "\n#{url}".color(:cyan) + " has been saved to #{@screenshot.paths_hash[:original]}".color(:yellow)
53
- end
44
+ skin_picker(url, { :visual => true })
54
45
  end
55
46
 
56
47
  # Creates a diffed screenshot between skins AND prints percentage changed
57
48
  def skin_visual_and_percentage(url, threshold=@configuration.threshold)
49
+ raise Errors::ThresholdOutOfRange.new "The threshold need to be a number between 1 and 100" if threshold > 100
58
50
  skin(url)
51
+ skin_picker(url, { :percentage => true, :visual => true }, threshold)
52
+ end
53
+
54
+ def skin_picker(url, type, threshold=100)
59
55
  if(@screenshot.paths_hash.length > 1)
60
56
  puts "\n" + url.color(:cyan)
61
- @compare.percentage_diff(@screenshot.paths_hash[:original], @screenshot.paths_hash[:fresh])
62
- @compare.visual_diff(@screenshot.paths_hash[:original], @screenshot.paths_hash[:fresh])
63
- threshold_alert(@compare.percentage_changed, threshold)
57
+ if type[:percentage]
58
+ @compare.percentage_diff(@screenshot.paths_hash[:original], @screenshot.paths_hash[:fresh])
59
+ threshold_alert(@compare.percentage_changed, threshold)
60
+ end
61
+ if type[:visual]
62
+ @compare.visual_diff(@screenshot.paths_hash[:original], @screenshot.paths_hash[:fresh])
63
+ end
64
64
  else
65
65
  puts "\n#{url}".color(:cyan) + " has been saved to #{@screenshot.paths_hash[:original]}".color(:yellow)
66
66
  end
@@ -11,10 +11,6 @@ describe "bin/green_onion" do
11
11
 
12
12
  describe "Skin Utility" do
13
13
 
14
- before(:each) do
15
- FileUtils.mkdir(@tmp_path)
16
- end
17
-
18
14
  after(:each) do
19
15
  FileUtils.rm_r(@tmp_path, :force => true)
20
16
  end
@@ -24,22 +20,30 @@ describe "bin/green_onion" do
24
20
  File.exist?(@file1).should be_true
25
21
  end
26
22
 
23
+ it "should run the skin task w/ --method=p flag to run only percentage diff" do
24
+ stdin, stdout, stderr = Open3.popen3("bin/green_onion skin #{@url} --dir=#{@tmp_path} --method=p --threshold=1 &&
25
+ bin/green_onion skin #{@url} --dir=#{@tmp_path} --method=p --threshold=1")
26
+ stderr.readlines.to_s.should include("above threshold set @")
27
+ end
28
+
27
29
  end
28
30
 
29
31
  describe "Generator" do
30
32
 
31
- before(:each) do
32
- FileUtils.mkdir(@tmp_path)
33
- end
34
-
35
33
  after(:each) do
36
34
  FileUtils.rm_r(@tmp_path, :force => true)
37
35
  end
38
36
 
39
37
  it "should build the skinner file" do
40
- `bin/green_onion generate --url=#{@url} --dir=#{@tmp_path}`
38
+ `bin/green_onion generate --dir=#{@tmp_path}`
41
39
  File.exist?(@skinner_file).should be_true
42
40
  end
41
+
42
+ it "should build the skinner file with the url included correctly" do
43
+ `bin/green_onion generate --url=#{@url} --dir=#{@tmp_path}`
44
+ skinner = IO.read(@skinner_file)
45
+ skinner.should include("GreenOnion.skin_visual_and_percentage(\"http://localhost:8070\" + route)")
46
+ end
43
47
 
44
48
  end
45
49
  end
@@ -10,8 +10,6 @@ describe GreenOnion do
10
10
 
11
11
  describe "Skins" do
12
12
  before(:each) do
13
- FileUtils.mkdir(@tmp_path)
14
-
15
13
  GreenOnion.configure do |c|
16
14
  c.skins_dir = @tmp_path
17
15
  end
@@ -84,8 +82,6 @@ describe GreenOnion do
84
82
 
85
83
  describe "Skins with custom dimensions" do
86
84
  before(:each) do
87
- FileUtils.mkdir(@tmp_path)
88
-
89
85
  GreenOnion.configure do |c|
90
86
  c.skins_dir = @tmp_path
91
87
  c.dimensions = { :width => 1440, :height => 900 }
@@ -104,8 +100,6 @@ describe GreenOnion do
104
100
 
105
101
  describe "Skins with custom threshold" do
106
102
  before(:each) do
107
- FileUtils.mkdir(@tmp_path)
108
-
109
103
  GreenOnion.configure do |c|
110
104
  c.skins_dir = @tmp_path
111
105
  c.threshold = 1
@@ -123,4 +117,28 @@ describe GreenOnion do
123
117
  end
124
118
  end
125
119
  end
120
+
121
+ describe "Errors" do
122
+ before(:each) do
123
+ GreenOnion.configure do |c|
124
+ c.skins_dir = @tmp_path
125
+ end
126
+ end
127
+
128
+ after(:each) do
129
+ FileUtils.rm_r(@tmp_path, :force => true)
130
+ end
131
+
132
+ it "should raise error for when ill-formatted URL is used" do
133
+ expect { GreenOnion.skin_percentage("localhost") }.to raise_error(GreenOnion::Errors::IllformattedURL)
134
+ end
135
+
136
+ it "should raise error for when threshold is out of range for skin_percentage" do
137
+ expect { GreenOnion.skin_percentage(@url, 101) }.to raise_error(GreenOnion::Errors::ThresholdOutOfRange)
138
+ end
139
+
140
+ it "should raise error for when threshold is out of range for skin_visual_and_percentage" do
141
+ expect { GreenOnion.skin_visual_and_percentage(@url, 101) }.to raise_error(GreenOnion::Errors::ThresholdOutOfRange)
142
+ end
143
+ end
126
144
  end
@@ -12,8 +12,6 @@ describe GreenOnion::Screenshot do
12
12
  describe 'Snap single screenshot' do
13
13
 
14
14
  before(:each) do
15
- FileUtils.mkdir(@tmp_path)
16
-
17
15
  @screenshot = GreenOnion::Screenshot.new(
18
16
  :dir => @tmp_path,
19
17
  :dimensions => @dimensions
@@ -51,8 +49,6 @@ describe GreenOnion::Screenshot do
51
49
  describe 'Snap two screenshots' do
52
50
 
53
51
  before(:each) do
54
- FileUtils.mkdir(@tmp_path)
55
-
56
52
  @screenshot = GreenOnion::Screenshot.new(
57
53
  :dir => @tmp_path,
58
54
  :dimensions => @dimensions
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: green_onion
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.0
5
+ version: 0.1.1
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-08-02 00:00:00 Z
13
+ date: 2012-08-06 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -157,6 +157,7 @@ files:
157
157
  - lib/green_onion/cli.rb
158
158
  - lib/green_onion/compare.rb
159
159
  - lib/green_onion/configuration.rb
160
+ - lib/green_onion/errors.rb
160
161
  - lib/green_onion/generators/skinner.erb
161
162
  - lib/green_onion/screenshot.rb
162
163
  - lib/green_onion/version.rb