looks_good 1.0.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 33bfb614a176498eb6a13180459e40aff96fc328673ab0edd6cbcb2b4b28345f
4
- data.tar.gz: 97b7efc3432c0b51b052bad9201e87a900791e57afdc9d2d9ef6444d654891bf
3
+ metadata.gz: 453e5498b4740e2fe1c415307921f1acaf410c7d6f6395ea531916249c30792a
4
+ data.tar.gz: 3f08a7bb2ccb8d860072783bc7dc3fd96fa528a8826d8d1a2f2e401bdb94cb99
5
5
  SHA512:
6
- metadata.gz: 629f66d456631f91b36200dd03266c2de827dd6313ded03a49c01f0021b303f93b98f8c9f5525e831ba9412412ed908800fd831fc89282c16c155804ae8d0b79
7
- data.tar.gz: 63c9fc8f12c8e25f4230e39298ab623b7b85e5b491679ae0a9c59f4bf6da9122cf1991a750df8376d81e482c8bb3063a7fce8f22b3812ee3fd97e83c3dcd97d7
6
+ metadata.gz: f9b731e277ff3015ef89693bb4595e7c4d1346bd244615e989e57ea4395a055d73239ec16cd88721052d8154b5edc38720f5ecff18a64d055dbf2408d8f92d9d
7
+ data.tar.gz: 58cd545954d8d637f5577184f2d2c39c57716c48ecf86237df7c86ba96b86b70a52d29a9978ab390714db1182cc1b75fb68ab5b3a8829ebdb4b60e22e3c68954
data/.DS_Store CHANGED
Binary file
data/README.md CHANGED
@@ -63,6 +63,7 @@ you can override any of the defaults with a config block.
63
63
  c.sleep_between_tries = 0.5
64
64
  c.browser_folders = false
65
65
  c.scale_amount = 0.5
66
+ c.fuzz = "10%"
66
67
  end
67
68
 
68
69
 
@@ -77,10 +78,13 @@ Also created are subfolders:
77
78
  - tmp/diff/ - will hold the visual diff images for inspection when comparison fails
78
79
 
79
80
  #### max_no_tries
80
- - sets how many times looks_good will try and match the element against the reference image. Handy to reduce fragility of tests due to animations and load times. Defaults to 1.
81
+ - sets how many times looks_good will try and match the element against the reference image. Handy to reduce fragility of tests due to animations and load times. Defaults to 2.
81
82
 
82
83
  #### default_within
83
- - a float between 0 and 1 that sets the default tolerance for visual differences. default is 0.01 (1%)
84
+ - a float between 0 and 1 that sets the default tolerance for visual differences. default is 0.0001, which is strict but not absolute 0. Larger screenshots will be less sensitive to subtle differences as a percentage.
85
+
86
+ #### fuzz
87
+ - allows pixels to not need to match exactly. a string percentage value, provided to imagemagick as fuzz value for comparison. default is "10%"
84
88
 
85
89
  #### scale_amount
86
90
  - Retina mac screenshots are 2x actual size, so this scales them to be 1:1. default is 0.5, set to 1 to disable.
@@ -16,7 +16,7 @@ module LooksGood
16
16
  end
17
17
 
18
18
  def self.take_screenshot
19
- temp_dir = LooksGood::Configuration.path(:temp)
19
+ temp_dir = LooksGood::Configuration.path(:tmp)
20
20
  FileUtils.mkdir_p(temp_dir) unless File.exists?(temp_dir)
21
21
  #captures the uncropped full screen
22
22
  begin
@@ -39,7 +39,7 @@ module LooksGood
39
39
  end
40
40
 
41
41
  def self.crop_element(image, element_to_crop, position)
42
- cropped_element = image.scale(LooksGood::Configuration.scale_amount).crop(position[:x], position[:y], position[:width], position[:height])
42
+ cropped_element = image.scale!(LooksGood::Configuration.scale_amount).crop!(position[:x], position[:y], position[:width], position[:height])
43
43
  end
44
44
 
45
45
  end
@@ -1,7 +1,8 @@
1
+ require 'mini_magick'
1
2
  module LooksGood
2
3
  class Comparison
3
4
 
4
- attr_accessor :diff_image, :actual_image, :expected_image
5
+ attr_accessor :diff_image, :diff_image_file, :actual_image, :expected_image
5
6
 
6
7
  def initialize(actual_image, expected_image, within=LooksGood::Configuration.default_within)
7
8
  @actual_image = actual_image
@@ -9,8 +10,8 @@ module LooksGood
9
10
  @comparison = compare_image
10
11
  @within = within
11
12
  # within is a float of % image difference between the two images
12
- @match = @comparison[1] <= @within
13
- @diff_image =LooksGood::Image.new(@comparison.first, @expected_image.file_name) unless @matches
13
+ @match = @comparison <= @within
14
+ @diff_image =LooksGood::Image.new(@diff_image_file, @expected_image.file_name)
14
15
  end
15
16
 
16
17
  def matches?
@@ -22,7 +23,7 @@ module LooksGood
22
23
  end
23
24
 
24
25
  def percent_difference
25
- @comparison[1]
26
+ @comparison
26
27
  end
27
28
 
28
29
  def compare_image
@@ -31,10 +32,7 @@ module LooksGood
31
32
 
32
33
  def compare_images_with_same_size
33
34
  images_to_compare = prep_images_for_comparison
34
- images_to_compare.first.compare_channel(images_to_compare.last, Magick::PeakAbsoluteErrorMetric, Magick::AllChannels) do
35
- self.highlight_color = Magick::Pixel.new(65300,100,0,38000)
36
- self.lowlight_color = Magick::Pixel.new(0,65300,1000,60000)
37
- end
35
+ mini_compare(images_to_compare)
38
36
  end
39
37
 
40
38
  def compare_images_with_different_size
@@ -46,16 +44,36 @@ module LooksGood
46
44
  expanded_image.background_color = 'white'
47
45
  expanded_image
48
46
  end
49
- images_to_compare.first.compare_channel(images_to_compare.last, Magick::PeakAbsoluteErrorMetric) do |img|
50
- img.highlight_color = Magick::Pixel.new(65300,100,0,38000)
51
- img.lowlight_color = Magick::Pixel.new(0,65300,1000,60000)
52
- end
47
+ mini_compare(images_to_compare)
53
48
  end
54
49
 
55
50
  def compare_images_with_same_size?
56
51
  @actual_image.image.rows == @expected_image.image.rows && @actual_image.image.columns == @expected_image.image.columns
57
52
  end
58
53
 
54
+ # drop in refactor to utilize mini_magick.
55
+ # returns a float % of difference
56
+ # TODO: remove rmagick
57
+ def mini_compare(images)
58
+ actual_image, expected_image = images
59
+ actual_image.write(actual_image.filename)
60
+ pixel_difference_count = nil
61
+ MiniMagick::Tool::Compare.new(whiny: false) do |comp|
62
+ comp.fuzz(LooksGood::Configuration.fuzz)
63
+ comp.metric("AE")
64
+ comp << actual_image.filename
65
+ comp << expected_image.filename
66
+ diff_file_name = File.join(LooksGood::Configuration.path(:diff), @actual_image.file_name)
67
+ FileUtils::mkdir_p(File.dirname(diff_file_name)) unless File.exists?(diff_file_name)
68
+ comp << diff_file_name
69
+ comp.call do |stdout, stderr, status|
70
+ pixel_difference_count = stderr
71
+ end
72
+ @diff_image_file = Magick::Image.read(diff_file_name).first
73
+ end
74
+ pixel_difference_count.to_f / (expected_image.rows * expected_image.columns)
75
+ end
76
+
59
77
  def prep_images_for_comparison
60
78
  [
61
79
  @actual_image,
@@ -5,7 +5,7 @@ module LooksGood
5
5
 
6
6
  class << self
7
7
 
8
- attr_accessor :reference_image_path, :max_no_tries, :sleep_between_tries, :browser_folders, :default_within
8
+ attr_accessor :fuzz, :reference_image_path, :max_no_tries, :sleep_between_tries, :browser_folders, :default_within
9
9
 
10
10
  attr_reader :paths
11
11
 
@@ -15,7 +15,7 @@ module LooksGood
15
15
  end
16
16
 
17
17
  def default_within
18
- @default_within ||= 0.01 # 1%
18
+ @default_within ||= 0.0001
19
19
  end
20
20
 
21
21
  # allows retina mac screenshots to be scaled to expected size
@@ -24,7 +24,11 @@ module LooksGood
24
24
  end
25
25
 
26
26
  def max_no_tries
27
- @max_no_tries ||= 1
27
+ @max_no_tries ||= 2
28
+ end
29
+
30
+ def fuzz
31
+ @fuzz ||= "10%"
28
32
  end
29
33
 
30
34
  def sleep_between_tries
@@ -33,9 +37,9 @@ module LooksGood
33
37
 
34
38
  def path(type)
35
39
  paths = {:reference => reference_image_path,
36
- :temp => File.join(reference_image_path, 'tmp', 'tmp'),
37
- :candidate => File.join(reference_image_path, 'temp', 'candidate'),
38
- :diff => File.join(reference_image_path, 'temp', 'diff')
40
+ :tmp => File.join(reference_image_path, 'tmp', 'tmp'),
41
+ :candidate => File.join(reference_image_path, 'tmp', 'candidate'),
42
+ :diff => File.join(reference_image_path, 'tmp', 'diff')
39
43
  }
40
44
  paths[type]
41
45
  end
@@ -29,6 +29,8 @@ module LooksGood
29
29
 
30
30
  class ImageFromElement < Image
31
31
 
32
+ attr_accessor :image
33
+
32
34
  def initialize(element, file_name)
33
35
  super(image, file_name)
34
36
  @element = element
@@ -1,6 +1,6 @@
1
1
  require 'looks_good'
2
2
 
3
- RSpec::Matchers.define :look_like do |expected|
3
+ RSpec::Matchers.define :look_like do |expected, within: LooksGood::Configuration.default_within|
4
4
  result = nil
5
5
  match do |actual|
6
6
  if expected.is_a?(Symbol)
@@ -8,7 +8,7 @@ RSpec::Matchers.define :look_like do |expected|
8
8
  path_to = called_by_file.split("_spec.rb").first.split("spec/").last
9
9
  expected = File.join(path_to, "#{expected}.png")
10
10
  end
11
- result = LooksGood.check(expected, actual)
11
+ result = LooksGood.check(expected, actual, within: within)
12
12
  result[:result]
13
13
  end
14
14
 
@@ -1,3 +1,3 @@
1
1
  module LooksGood
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.1"
3
3
  end
data/lib/looks_good.rb CHANGED
@@ -35,7 +35,6 @@ module LooksGood
35
35
  matches = comparison.matches?
36
36
  if !matches
37
37
  comparison.actual_image.save(:candidate)
38
- save_image_as_diff(comparison.diff_image)
39
38
  result_hash[:message] = %Q[view a visual diff image: open #{comparison.diff_image.path(:diff)}\n
40
39
  HOW TO FIX:\n
41
40
  - cp #{comparison.diff_image.path(:candidate)} #{@expected_reference_file}
@@ -67,11 +66,6 @@ or
67
66
  @comparison
68
67
  end
69
68
 
70
- def save_image_as_diff(image)
71
- image.save(:diff)
72
-
73
- end
74
-
75
69
  def save_image_as_candidate(image)
76
70
  image.save(:candidate)
77
71
  raise "The design reference #{image.file_name} does not exist, #{image.path(:candidate)} " +
@@ -79,11 +73,12 @@ or
79
73
  end
80
74
 
81
75
  def save_reference
76
+ sleep 0.5 # ensures page/browser stability of focus effects etc inherent in browsers
82
77
  ImageFromElement.new(@actual_element,@expected_reference_filename).verify_and_save
83
78
  end
84
79
 
85
80
  def cleanup
86
- FileUtils.remove_dir(LooksGood::Configuration.path(:temp)) if File.directory?(LooksGood::Configuration.path(:temp))
81
+ FileUtils.remove_dir(LooksGood::Configuration.path(:tmp)) if File.directory?(LooksGood::Configuration.path(:tmp))
87
82
  FileUtils.remove_dir(LooksGood::Configuration.path(:diff)) if File.directory?(LooksGood::Configuration.path(:diff))
88
83
  FileUtils.remove_dir(LooksGood::Configuration.path(:candidate)) if File.directory?(LooksGood::Configuration.path(:candidate))
89
84
  end
data/looks_good.gemspec CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ["lib"]
20
20
 
21
21
  s.add_runtime_dependency('rmagick', ['>=2.15.4'])
22
+ s.add_runtime_dependency('mini_magick', ['>=4.11.0'])
22
23
  s.add_runtime_dependency('capybara',['>=2.6.0'])
23
24
 
24
25
  s.add_development_dependency('rake',['>=0.9.2'])
@@ -41,7 +41,7 @@ describe LooksGood::Configuration do
41
41
 
42
42
  it 'should return the directory for a type of image' do
43
43
  subject.reference_image_path = "a_path"
44
- subject.path(:temp).should == 'a_path/temp'
44
+ subject.path(:tmp).should == 'a_path/tmp'
45
45
  end
46
46
 
47
47
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: looks_good
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Russell Jennings
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-08 00:00:00.000000000 Z
11
+ date: 2022-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rmagick
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 2.15.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: mini_magick
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 4.11.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 4.11.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: capybara
29
43
  requirement: !ruby/object:Gem::Requirement