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
- 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, **driver_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, **driver_options) ⇒ ImageCompare
Returns a new instance of ImageCompare.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 17 def initialize(new_file_name, old_file_name = nil, **) @new_file_name = new_file_name @old_file_name = old_file_name || "#{new_file_name}~" @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.
13 14 15 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13 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.
13 14 15 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13 def annotated_old_file_name @annotated_old_file_name end |
#area_size_limit ⇒ Object (readonly)
Returns the value of attribute area_size_limit.
13 14 15 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13 def area_size_limit @area_size_limit end |
#color_distance_limit ⇒ Object (readonly)
Returns the value of attribute color_distance_limit.
13 14 15 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13 def color_distance_limit @color_distance_limit end |
#driver ⇒ Object (readonly)
Returns the value of attribute driver.
11 12 13 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 11 def driver @driver end |
#driver_options ⇒ Object (readonly)
Returns the value of attribute driver_options.
11 12 13 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 11 def @driver_options end |
#new_file_name ⇒ Object (readonly)
Returns the value of attribute new_file_name.
13 14 15 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13 def new_file_name @new_file_name end |
#old_file_name ⇒ Object (readonly)
Returns the value of attribute old_file_name.
13 14 15 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13 def old_file_name @old_file_name end |
#shift_distance_limit ⇒ Object (readonly)
Returns the value of attribute shift_distance_limit.
13 14 15 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13 def shift_distance_limit @shift_distance_limit end |
#skip_area ⇒ Object (readonly)
Returns the value of attribute skip_area.
13 14 15 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13 def skip_area @skip_area end |
Instance Method Details
#annotate_and_save(images, region = difference_region) ⇒ Object
125 126 127 128 129 130 131 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 125 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
115 116 117 118 119 120 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 115 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
158 159 160 161 162 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 158 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.
79 80 81 82 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 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 79 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
147 148 149 150 151 152 153 154 155 156 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 147 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
138 139 140 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 138 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.
41 42 43 44 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 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 41 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
142 143 144 145 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 142 def reset self.difference_region = nil driver.reset end |
#save(old_img, new_img, annotated_old_file_name, annotated_new_file_name) ⇒ Object
133 134 135 136 |
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 133 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 |