Class: Capybara::Screenshot::Diff::ImageCompare
- Inherits:
-
SimpleDelegator
- Object
- SimpleDelegator
- Capybara::Screenshot::Diff::ImageCompare
- Defined in:
- lib/capybara/screenshot/diff/image_compare.rb
Overview
Compare two images and determine if they are equal, different, or within some comparison range considering color values and difference area size.
Constant Summary collapse
- TMP_FILE_SUFFIX =
"~"
- DIFF_COLOR =
[255, 0, 0, 255].freeze
- SKIP_COLOR =
[255, 192, 0, 255].freeze
Instance Attribute Summary collapse
-
#annotated_new_file_name ⇒ Object
readonly
Returns the value of attribute annotated_new_file_name.
-
#annotated_old_file_name ⇒ Object
readonly
Returns the value of attribute annotated_old_file_name.
-
#area_size_limit ⇒ Object
readonly
Returns the value of attribute area_size_limit.
-
#color_distance_limit ⇒ Object
readonly
Returns the value of attribute color_distance_limit.
-
#driver ⇒ Object
readonly
Returns the value of attribute driver.
-
#driver_options ⇒ Object
readonly
Returns the value of attribute driver_options.
-
#new_file_name ⇒ Object
readonly
Returns the value of attribute new_file_name.
-
#old_file_name ⇒ Object
readonly
Returns the value of attribute old_file_name.
-
#shift_distance_limit ⇒ Object
readonly
Returns the value of attribute shift_distance_limit.
-
#skip_area ⇒ Object
readonly
Returns the value of attribute skip_area.
Instance Method Summary collapse
- #annotate_and_save(images, region = difference_region) ⇒ Object
- #clean_tmp_files ⇒ Object
- #difference_region ⇒ Object
-
#different? ⇒ Boolean
Compare the two images referenced by this object, and return ‘true` if they are different, and `false` if they are the same.
- #error_message ⇒ Object
-
#initialize(new_file_name, old_file_name = nil, options = {}) ⇒ ImageCompare
constructor
A new instance of ImageCompare.
- #old_file_exists? ⇒ Boolean
-
#quick_equal? ⇒ Boolean
Compare the two image files and return ‘true` or `false` as quickly as possible.
- #reset ⇒ Object
- #save(old_img, new_img, annotated_old_file_name, annotated_new_file_name) ⇒ Object
Constructor Details
#initialize(new_file_name, old_file_name = nil, options = {}) ⇒ ImageCompare
Returns a new instance of ImageCompare.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 19 def initialize(new_file_name, old_file_name = nil, = {}) = old_file_name if old_file_name.is_a?(Hash) @new_file_name = new_file_name @old_file_name = old_file_name || "#{new_file_name}#{ImageCompare::TMP_FILE_SUFFIX}" @annotated_old_file_name = "#{new_file_name.chomp(".png")}.committed.png" @annotated_new_file_name = "#{new_file_name.chomp(".png")}.latest.png" @driver_options = @color_distance_limit = [:color_distance_limit] || 0 @area_size_limit = [:area_size_limit] @shift_distance_limit = [:shift_distance_limit] @dimensions = [:dimensions] @skip_area = [:skip_area] @tolerance = [:tolerance] @median_filter_window_size = [:median_filter_window_size] driver_klass = find_driver_class_for(@driver_options.fetch(:driver, :chunky_png)) @driver = driver_klass.new(@new_file_name, @old_file_name, **@driver_options) super(@driver) end |
Instance Attribute Details
#annotated_new_file_name ⇒ Object (readonly)
Returns the value of attribute annotated_new_file_name.
15 16 17 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 15 def annotated_new_file_name @annotated_new_file_name end |
#annotated_old_file_name ⇒ Object (readonly)
Returns the value of attribute annotated_old_file_name.
15 16 17 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 15 def annotated_old_file_name @annotated_old_file_name end |
#area_size_limit ⇒ Object (readonly)
Returns the value of attribute area_size_limit.
15 16 17 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 15 def area_size_limit @area_size_limit end |
#color_distance_limit ⇒ Object (readonly)
Returns the value of attribute color_distance_limit.
15 16 17 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 15 def color_distance_limit @color_distance_limit end |
#driver ⇒ Object (readonly)
Returns the value of attribute driver.
13 14 15 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13 def driver @driver end |
#driver_options ⇒ Object (readonly)
Returns the value of attribute driver_options.
13 14 15 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13 def @driver_options end |
#new_file_name ⇒ Object (readonly)
Returns the value of attribute new_file_name.
15 16 17 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 15 def new_file_name @new_file_name end |
#old_file_name ⇒ Object (readonly)
Returns the value of attribute old_file_name.
15 16 17 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 15 def old_file_name @old_file_name end |
#shift_distance_limit ⇒ Object (readonly)
Returns the value of attribute shift_distance_limit.
15 16 17 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 15 def shift_distance_limit @shift_distance_limit end |
#skip_area ⇒ Object (readonly)
Returns the value of attribute skip_area.
15 16 17 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 15 def skip_area @skip_area end |
Instance Method Details
#annotate_and_save(images, region = difference_region) ⇒ Object
129 130 131 132 133 134 135 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 129 def annotate_and_save(images, region = difference_region) annotated_images = driver.draw_rectangles(images, region, DIFF_COLOR) @skip_area.to_a.flatten.each_slice(4) do |region| annotated_images = driver.draw_rectangles(annotated_images, region, SKIP_COLOR) end save(*annotated_images, @annotated_old_file_name, @annotated_new_file_name) end |
#clean_tmp_files ⇒ Object
119 120 121 122 123 124 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 119 def clean_tmp_files FileUtils.cp @old_file_name, @new_file_name if old_file_exists? File.delete(@old_file_name) if old_file_exists? File.delete(@annotated_old_file_name) if File.exist?(@annotated_old_file_name) File.delete(@annotated_new_file_name) if File.exist?(@annotated_new_file_name) end |
#difference_region ⇒ Object
162 163 164 165 166 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 162 def difference_region return nil unless @left || @top || @right || @bottom [@left, @top, @right, @bottom] end |
#different? ⇒ Boolean
Compare the two images referenced by this object, and return ‘true` if they are different, and `false` if they are the same. Return `nil` if the old file does not exist or if the image dimensions do not match.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 83 def different? return nil unless old_file_exists? images = driver.load_images(@old_file_name, @new_file_name) old_image, new_image = preprocess_images(images, driver) if driver.dimension_changed?(old_image, new_image) save(new_image, old_image, @annotated_new_file_name, @annotated_old_file_name) self.difference_region = 0, 0, driver.width_for(old_image), driver.height_for(old_image) return true end region, = driver.find_difference_region( new_image, old_image, @color_distance_limit, @shift_distance_limit, @area_size_limit ) self.difference_region = region return not_different if difference_region_empty?(old_image, region) return not_different if @area_size_limit && driver.size(region) <= @area_size_limit return not_different if @tolerance && @tolerance > driver.difference_level(, old_image, region) # TODO: Remove this or find similar solution for vips return not_different if @shift_distance_limit && !driver.shift_distance_different? annotate_and_save(images, region) true end |
#error_message ⇒ Object
151 152 153 154 155 156 157 158 159 160 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 151 def result = { area_size: driver.size(difference_region), region: difference_region } driver.adds_error_details_to(result) ["(#{result.to_json})", new_file_name, annotated_old_file_name, annotated_new_file_name].join("\n") end |
#old_file_exists? ⇒ Boolean
142 143 144 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 142 def old_file_exists? @old_file_name && File.exist?(@old_file_name) end |
#quick_equal? ⇒ Boolean
Compare the two image files and return ‘true` or `false` as quickly as possible. Return falsish if the old file does not exist or the image dimensions do not match.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 45 def quick_equal? return false unless old_file_exists? return true if new_file_size == old_file_size # old_bytes, new_bytes = load_image_files(@old_file_name, @new_file_name) # return true if old_bytes == new_bytes images = driver.load_images(@old_file_name, @new_file_name) old_image, new_image = preprocess_images(images, driver) return false if driver.dimension_changed?(old_image, new_image) region, = driver.find_difference_region( new_image, old_image, @color_distance_limit, @shift_distance_limit, @area_size_limit, fast_fail: true ) self.difference_region = region return true if difference_region_empty?(new_image, region) return true if @area_size_limit && driver.size(region) <= @area_size_limit return true if @tolerance && @tolerance >= driver.difference_level(, old_image, region) # TODO: Remove this or find similar solution for vips return true if @shift_distance_limit && driver.shift_distance_equal? false end |
#reset ⇒ Object
146 147 148 149 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 146 def reset self.difference_region = nil driver.reset end |
#save(old_img, new_img, annotated_old_file_name, annotated_new_file_name) ⇒ Object
137 138 139 140 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 137 def save(old_img, new_img, annotated_old_file_name, annotated_new_file_name) driver.save_image_to(old_img, annotated_old_file_name) driver.save_image_to(new_img, annotated_new_file_name) end |