capybara-screenshot-diff 0.5.3 → 0.6.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -3
- data/.rubocop_todo.yml +18 -10
- data/README.md +21 -0
- data/lib/capybara/screenshot/diff.rb +2 -2
- data/lib/capybara/screenshot/diff/capybara_setup.rb +45 -34
- data/lib/capybara/screenshot/diff/image_compare.rb +157 -44
- data/lib/capybara/screenshot/diff/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3417ac0f41265b198a6807b0ae2ea3fe24d4fcae
|
4
|
+
data.tar.gz: efcc110c396d89cf8ed51e982c57cc1a6c3e9b4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d1aecff95b1e1eb031397488bec689f4f1410de71a093914fc2601932237abfb8de30dce236ececb641c0b85dae350d012b6881a5e69c01b1f0eafea300fae9
|
7
|
+
data.tar.gz: 19bb7deb896fe5de11c94ca2d1c4309dba6a774603b859050ff1a6c31a3cc07c5b5e1cdac4355b35b154cea3db5bbf108cd3572e6b32a75845104b4935922d89
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -1,28 +1,36 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2017-06
|
3
|
+
# on 2017-07-06 16:03:55 +0200 using RuboCop version 0.49.1.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
-
# Offense count:
|
9
|
+
# Offense count: 1
|
10
|
+
# Cop supports --auto-correct.
|
11
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
12
|
+
# SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent
|
13
|
+
Layout/IndentHeredoc:
|
14
|
+
Exclude:
|
15
|
+
- 'lib/capybara/screenshot/diff/capybara_setup.rb'
|
16
|
+
|
17
|
+
# Offense count: 7
|
10
18
|
Metrics/AbcSize:
|
11
|
-
Max:
|
19
|
+
Max: 26
|
20
|
+
|
21
|
+
# Offense count: 1
|
22
|
+
# Configuration parameters: CountComments.
|
23
|
+
Metrics/ClassLength:
|
24
|
+
Max: 186
|
12
25
|
|
13
26
|
# Offense count: 2
|
14
27
|
Metrics/CyclomaticComplexity:
|
15
28
|
Max: 8
|
16
29
|
|
17
|
-
# Offense count:
|
30
|
+
# Offense count: 8
|
18
31
|
# Configuration parameters: CountComments.
|
19
32
|
Metrics/MethodLength:
|
20
|
-
Max:
|
21
|
-
|
22
|
-
# Offense count: 1
|
23
|
-
# Configuration parameters: CountKeywordArgs.
|
24
|
-
Metrics/ParameterLists:
|
25
|
-
Max: 6
|
33
|
+
Max: 24
|
26
34
|
|
27
35
|
# Offense count: 1
|
28
36
|
Metrics/PerceivedComplexity:
|
data/README.md
CHANGED
@@ -101,6 +101,7 @@ that test will get the same prefix:
|
|
101
101
|
setup do
|
102
102
|
screenshot_section 'my_feature'
|
103
103
|
end
|
104
|
+
|
104
105
|
test 'my subfeature' do
|
105
106
|
screenshot_group 'subfeature'
|
106
107
|
visit '/feature'
|
@@ -241,6 +242,26 @@ Capybara::Screenshot.stability_time_limit = 0.5
|
|
241
242
|
```
|
242
243
|
|
243
244
|
|
245
|
+
|
246
|
+
### Allowed color distance
|
247
|
+
|
248
|
+
Sometimes you want to allow small differences in the images. You can set set the difference
|
249
|
+
threshold for the comparison using the `color_distance_limit` option to the `screenshot` method:
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
test 'color threshold' do
|
253
|
+
visit '/'
|
254
|
+
screenshot 'index', color_distance_limit: 30
|
255
|
+
end
|
256
|
+
```
|
257
|
+
|
258
|
+
The difference is calculated as the eucledian distance. You can also set this globally:
|
259
|
+
|
260
|
+
```ruby
|
261
|
+
Capybara::Screenshot::Diff.color_distance_limit = 42
|
262
|
+
```
|
263
|
+
|
264
|
+
|
244
265
|
## Development
|
245
266
|
|
246
267
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -97,8 +97,8 @@ module ActionDispatch
|
|
97
97
|
|
98
98
|
teardown do
|
99
99
|
if Capybara::Screenshot::Diff.enabled && @test_screenshots
|
100
|
-
test_screenshot_errors =
|
101
|
-
|
100
|
+
test_screenshot_errors = @test_screenshots
|
101
|
+
.map { |caller, name, compare| assert_image_not_changed(caller, name, compare) }.compact
|
102
102
|
fail(test_screenshot_errors.join("\n\n")) if test_screenshot_errors.any?
|
103
103
|
end
|
104
104
|
end
|
@@ -114,7 +114,8 @@ module ActionDispatch
|
|
114
114
|
FileUtils.rm_rf screenshot_dir
|
115
115
|
end
|
116
116
|
|
117
|
-
def screenshot(name
|
117
|
+
def screenshot(name, color_distance_limit: Capybara::Screenshot::Diff.color_distance_limit,
|
118
|
+
area_size_limit: nil)
|
118
119
|
return unless Capybara::Screenshot.active?
|
119
120
|
return if window_size_is_wrong?
|
120
121
|
if @screenshot_counter
|
@@ -123,16 +124,15 @@ module ActionDispatch
|
|
123
124
|
end
|
124
125
|
name = full_name(name)
|
125
126
|
file_name = "#{self.class.screenshot_area_abs}/#{name}.png"
|
126
|
-
org_name = "#{self.class.screenshot_area_abs}/#{name}_0.png~"
|
127
|
-
new_name = "#{self.class.screenshot_area_abs}/#{name}_1.png~"
|
128
127
|
|
129
128
|
FileUtils.mkdir_p File.dirname(file_name)
|
130
|
-
committed_file_name = check_vcs(name, file_name
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
129
|
+
committed_file_name = check_vcs(name, file_name)
|
130
|
+
comparison = Capybara::Screenshot::Diff::ImageCompare.new(committed_file_name, file_name,
|
131
|
+
dimensions: Capybara::Screenshot.window_size, color_distance_limit: color_distance_limit,
|
132
|
+
area_size_limit: area_size_limit)
|
133
|
+
take_stable_screenshot(comparison)
|
134
|
+
return unless comparison.old_file_exists?
|
135
|
+
(@test_screenshots ||= []) << [caller[0], name, comparison]
|
136
136
|
end
|
137
137
|
|
138
138
|
private def window_size_is_wrong?
|
@@ -142,7 +142,7 @@ module ActionDispatch
|
|
142
142
|
Selenium::WebDriver::Dimension.new(*Capybara::Screenshot.window_size)
|
143
143
|
end
|
144
144
|
|
145
|
-
def check_vcs(name, file_name
|
145
|
+
private def check_vcs(name, file_name)
|
146
146
|
svn_file_name = "#{self.class.screenshot_area_abs}/.svn/text-base/#{name}.png.svn-base"
|
147
147
|
if File.exist?(svn_file_name)
|
148
148
|
committed_file_name = svn_file_name
|
@@ -155,17 +155,21 @@ module ActionDispatch
|
|
155
155
|
committed_file_name = "#{wc_root}/.svn/pristine/#{checksum[0..1]}/#{checksum}.svn-base"
|
156
156
|
end
|
157
157
|
else
|
158
|
-
committed_file_name =
|
159
|
-
|
160
|
-
`git show HEAD~0:./#{self.class.screenshot_area}/#{name}.png > #{redirect_target}`
|
161
|
-
if File.size(committed_file_name) == 0
|
162
|
-
FileUtils.rm_f committed_file_name
|
163
|
-
end
|
158
|
+
committed_file_name = restore_git_revision(name,
|
159
|
+
Capybara::Screenshot::Diff::ImageCompare.annotated_old_file_name(file_name))
|
164
160
|
end
|
165
161
|
end
|
166
162
|
committed_file_name
|
167
163
|
end
|
168
164
|
|
165
|
+
private def restore_git_revision(name, org_name)
|
166
|
+
committed_file_name = org_name
|
167
|
+
redirect_target = "#{committed_file_name} #{SILENCE_ERRORS}"
|
168
|
+
`git show HEAD~0:./#{self.class.screenshot_area}/#{name}.png > #{redirect_target}`
|
169
|
+
FileUtils.rm_f(committed_file_name) if File.size(committed_file_name) == 0
|
170
|
+
committed_file_name
|
171
|
+
end
|
172
|
+
|
169
173
|
IMAGE_WAIT_SCRIPT = <<EOF.freeze
|
170
174
|
function pending_image() {
|
171
175
|
var images = document.images;
|
@@ -190,28 +194,33 @@ EOF
|
|
190
194
|
end
|
191
195
|
end
|
192
196
|
|
193
|
-
def take_stable_screenshot(
|
197
|
+
private def take_stable_screenshot(comparison)
|
194
198
|
assert_images_loaded
|
195
|
-
|
199
|
+
previous_file_size = comparison.old_file_size
|
196
200
|
screeenshot_started_at = last_image_change_at = Time.now
|
197
201
|
loop do
|
198
|
-
save_screenshot(
|
202
|
+
save_screenshot(comparison.new_file_name)
|
199
203
|
|
200
204
|
# TODO(uwe): Remove when chromedriver take right size screenshots
|
201
|
-
reduce_retina_image_size(
|
205
|
+
reduce_retina_image_size(comparison.new_file_name)
|
202
206
|
# EMXIF
|
203
207
|
|
204
208
|
break unless Capybara::Screenshot.stability_time_limit
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
209
|
+
break if comparison.quick_equal?
|
210
|
+
|
211
|
+
if comparison.new_file_size == previous_file_size
|
212
|
+
if (Time.now - last_image_change_at) > Capybara::Screenshot.stability_time_limit
|
213
|
+
break
|
214
|
+
end
|
215
|
+
else
|
216
|
+
last_image_change_at = Time.now
|
217
|
+
end
|
212
218
|
|
213
219
|
assert (Time.now - screeenshot_started_at) < Capybara.default_max_wait_time,
|
214
220
|
"Could not get stable screenshot within #{Capybara.default_max_wait_time}s"
|
221
|
+
|
222
|
+
previous_file_size = comparison.new_file_size
|
223
|
+
comparison.reset
|
215
224
|
end
|
216
225
|
end
|
217
226
|
|
@@ -225,11 +234,13 @@ EOF
|
|
225
234
|
resized_image.save(file_name)
|
226
235
|
end
|
227
236
|
|
228
|
-
def assert_image_not_changed(caller, name,
|
229
|
-
|
230
|
-
|
231
|
-
"
|
232
|
-
|
237
|
+
def assert_image_not_changed(caller, name, comparison)
|
238
|
+
return unless comparison.different?
|
239
|
+
"Screenshot does not match for '#{name}' (area: #{comparison.size} #{comparison.dimensions}" \
|
240
|
+
", max_color_distance: #{comparison.max_color_distance.round(1)})\n" \
|
241
|
+
"#{comparison.new_file_name}\n#{comparison.annotated_old_file_name}\n" \
|
242
|
+
"#{comparison.annotated_new_file_name}\n" \
|
243
|
+
"at #{caller}"
|
233
244
|
end
|
234
245
|
end
|
235
246
|
end
|
@@ -6,53 +6,130 @@ module Capybara
|
|
6
6
|
class ImageCompare
|
7
7
|
include ChunkyPNG::Color
|
8
8
|
|
9
|
+
attr_reader :annotated_new_file_name, :annotated_old_file_name, :new_file_name
|
10
|
+
|
9
11
|
def self.compare(*args)
|
10
|
-
new(*args).
|
12
|
+
new(*args).different?
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.annotated_old_file_name(new_file_name)
|
16
|
+
"#{new_file_name.chomp('.png')}_0.png~"
|
11
17
|
end
|
12
18
|
|
13
|
-
def initialize(old_file_name, new_file_name, dimensions
|
19
|
+
def initialize(old_file_name, new_file_name, dimensions: nil, color_distance_limit: nil,
|
20
|
+
area_size_limit: nil)
|
14
21
|
@old_file_name = old_file_name
|
15
|
-
@
|
22
|
+
@new_file_name = new_file_name
|
23
|
+
@color_distance_limit = color_distance_limit
|
24
|
+
@area_size_limit = area_size_limit
|
16
25
|
@dimensions = dimensions
|
26
|
+
@annotated_old_file_name = self.class.annotated_old_file_name(new_file_name)
|
27
|
+
@annotated_new_file_name = "#{new_file_name.chomp('.png')}_1.png~"
|
28
|
+
reset
|
17
29
|
end
|
18
30
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
|
31
|
+
def reset
|
32
|
+
@max_color_distance = 0 if @color_distance_limit
|
33
|
+
@left = @top = @right = @bottom = nil
|
34
|
+
end
|
35
|
+
|
36
|
+
# Compare the two image files and return `true` or `false` as quickly as possible.
|
37
|
+
# Return falsish if the old file does not exist or the image dimensions do not match.
|
38
|
+
def quick_equal?
|
39
|
+
return nil unless old_file_exists?
|
40
|
+
return true if new_file_size == old_file_size
|
41
|
+
old_file, new_file = load_image_files(@old_file_name, @new_file_name)
|
42
|
+
return true if old_file == new_file
|
43
|
+
images = load_images(old_file, new_file)
|
44
|
+
crop_images(images, @dimensions) if @dimensions
|
45
|
+
|
46
|
+
old_img = images.first
|
47
|
+
new_img = images.last
|
48
|
+
|
49
|
+
return false if sizes_changed?(old_img, new_img)
|
50
|
+
|
51
|
+
return true if old_img.pixels == new_img.pixels
|
52
|
+
|
53
|
+
@left, @top, @right, @bottom = find_top(old_img, new_img)
|
54
|
+
|
55
|
+
return true if @top.nil?
|
56
|
+
|
57
|
+
false
|
58
|
+
end
|
23
59
|
|
24
|
-
|
60
|
+
# Compare the two images referenced by this object, and return `true` if they are different,
|
61
|
+
# and `false` if they are the same.
|
62
|
+
# Return `nil` if the old file does not exist or if the image dimensions do not match.
|
63
|
+
def different?
|
64
|
+
return nil unless old_file_exists?
|
25
65
|
|
26
|
-
|
66
|
+
old_file, new_file = load_image_files(@old_file_name, @new_file_name)
|
27
67
|
|
28
|
-
|
29
|
-
clean_tmp_files(
|
68
|
+
if old_file == new_file
|
69
|
+
clean_tmp_files(@annotated_old_file_name, @annotated_new_file_name)
|
30
70
|
return false
|
31
71
|
end
|
32
72
|
|
73
|
+
images = load_images(old_file, new_file)
|
74
|
+
|
33
75
|
crop_images(images, @dimensions) if @dimensions
|
34
|
-
|
76
|
+
|
77
|
+
old_img = images.first
|
35
78
|
new_img = images.last
|
36
|
-
|
37
|
-
|
79
|
+
|
80
|
+
if sizes_changed?(old_img, new_img)
|
81
|
+
save_images(@annotated_new_file_name, new_img, @annotated_old_file_name, old_img)
|
38
82
|
return true
|
39
83
|
end
|
40
84
|
|
41
|
-
if
|
42
|
-
clean_tmp_files(
|
85
|
+
if old_img.pixels == new_img.pixels
|
86
|
+
clean_tmp_files(@annotated_new_file_name, @annotated_old_file_name)
|
43
87
|
return false
|
44
88
|
end
|
45
89
|
|
46
|
-
@left, @top, @right, @bottom = find_diff_rectangle(
|
47
|
-
|
48
|
-
|
90
|
+
@left, @top, @right, @bottom = find_diff_rectangle(old_img, new_img)
|
91
|
+
|
92
|
+
return false if @top.nil?
|
93
|
+
annotated_old_img, annotated_new_img = draw_rectangles(images, @bottom, @left, @right, @top)
|
94
|
+
save_images(@annotated_new_file_name, annotated_new_img,
|
95
|
+
@annotated_old_file_name, annotated_old_img)
|
49
96
|
true
|
50
97
|
end
|
51
98
|
|
99
|
+
def old_file_exists?
|
100
|
+
@old_file_name && File.exist?(@old_file_name)
|
101
|
+
end
|
102
|
+
|
103
|
+
def old_file_size
|
104
|
+
@_old_filesize ||= old_file_exists? && File.size(@old_file_name)
|
105
|
+
end
|
106
|
+
|
107
|
+
def new_file_size
|
108
|
+
File.size(@new_file_name)
|
109
|
+
end
|
110
|
+
|
52
111
|
def dimensions
|
53
112
|
[@left, @top, @right, @bottom]
|
54
113
|
end
|
55
114
|
|
115
|
+
def size
|
116
|
+
(@right - @left + 1) * (@bottom - @top + 1)
|
117
|
+
end
|
118
|
+
|
119
|
+
def max_color_distance
|
120
|
+
return @max_color_distance if @max_color_distance
|
121
|
+
old_file, new_file = load_image_files(@old_file_name, @new_file_name)
|
122
|
+
return @max_color_distance = 0 if old_file == new_file
|
123
|
+
|
124
|
+
old_image, new_image = load_images(old_file, new_file)
|
125
|
+
|
126
|
+
pixel_pairs = old_image.pixels.zip(new_image.pixels)
|
127
|
+
@max_color_distance = pixel_pairs.inject(0) do |max, (p1, p2)|
|
128
|
+
d = ChunkyPNG::Color.euclidean_distance_rgba(p1, p2)
|
129
|
+
[max, d].max
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
56
133
|
private
|
57
134
|
|
58
135
|
def save_images(new_file_name, new_img, org_file_name, org_img)
|
@@ -60,28 +137,29 @@ module Capybara
|
|
60
137
|
new_img.save(new_file_name)
|
61
138
|
end
|
62
139
|
|
63
|
-
def clean_tmp_files(
|
64
|
-
File.delete(
|
140
|
+
def clean_tmp_files(old_file_name, new_file_name)
|
141
|
+
File.delete(old_file_name) if File.exist?(old_file_name)
|
65
142
|
File.delete(new_file_name) if File.exist?(new_file_name)
|
66
143
|
end
|
67
144
|
|
68
|
-
def load_images(
|
145
|
+
def load_images(old_file, new_file)
|
146
|
+
[ChunkyPNG::Image.from_blob(old_file), ChunkyPNG::Image.from_blob(new_file)]
|
147
|
+
end
|
148
|
+
|
149
|
+
def load_image_files(old_file_name, file_name)
|
69
150
|
old_file = File.binread(old_file_name)
|
70
151
|
new_file = File.binread(file_name)
|
71
|
-
|
72
|
-
return false if old_file == new_file
|
73
|
-
|
74
|
-
[ChunkyPNG::Image.from_blob(old_file), ChunkyPNG::Image.from_blob(new_file)]
|
152
|
+
[old_file, new_file]
|
75
153
|
end
|
76
154
|
|
77
|
-
def sizes_changed?(org_image, new_image
|
155
|
+
def sizes_changed?(org_image, new_image)
|
78
156
|
return unless org_image.dimension != new_image.dimension
|
79
157
|
change_msg = [org_image, new_image].map { |i| "#{i.width}x#{i.height}" }.join(' => ')
|
80
|
-
puts "Image size has changed for #{
|
158
|
+
puts "Image size has changed for #{@new_file_name}: #{change_msg}"
|
81
159
|
true
|
82
160
|
end
|
83
161
|
|
84
|
-
def crop_images(images, dimensions)
|
162
|
+
private def crop_images(images, dimensions)
|
85
163
|
images.map! do |i|
|
86
164
|
if i.dimension.to_a == dimensions || i.width < dimensions[0] || i.height < dimensions[1]
|
87
165
|
i
|
@@ -91,38 +169,73 @@ module Capybara
|
|
91
169
|
end
|
92
170
|
end
|
93
171
|
|
94
|
-
def draw_rectangles(images, bottom, left, right, top)
|
95
|
-
images.
|
96
|
-
|
172
|
+
private def draw_rectangles(images, bottom, left, right, top)
|
173
|
+
images.map do |image|
|
174
|
+
new_img = image.dup
|
175
|
+
new_img.rect(left - 1, top - 1, right + 1, bottom + 1, ChunkyPNG::Color.rgb(255, 0, 0))
|
176
|
+
new_img
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
private def find_diff_rectangle(org_img, new_img)
|
181
|
+
left, top, right, bottom = find_left_right_and_top(org_img, new_img)
|
182
|
+
bottom = find_bottom(org_img, new_img, left, right, bottom)
|
183
|
+
[left, top, right, bottom]
|
184
|
+
end
|
185
|
+
|
186
|
+
private def find_top(old_img, new_img)
|
187
|
+
old_img.height.times do |y|
|
188
|
+
old_img.width.times do |x|
|
189
|
+
return [x, y, x, y] unless same_color?(old_img, new_img, x, y)
|
190
|
+
end
|
97
191
|
end
|
98
192
|
end
|
99
193
|
|
100
|
-
def
|
101
|
-
top =
|
102
|
-
|
103
|
-
|
104
|
-
|
194
|
+
private def find_left_right_and_top(old_img, new_img)
|
195
|
+
top = @top
|
196
|
+
bottom = @bottom
|
197
|
+
left = @left || old_img.width - 1
|
198
|
+
right = @right || 0
|
199
|
+
old_img.height.times do |y|
|
105
200
|
(0...left).find do |x|
|
106
|
-
next if
|
201
|
+
next if same_color?(old_img, new_img, x, y)
|
107
202
|
top ||= y
|
108
203
|
bottom = y
|
109
204
|
left = x
|
110
205
|
right = x if x > right
|
111
206
|
x
|
112
207
|
end
|
113
|
-
(
|
114
|
-
|
208
|
+
(old_img.width - 1).step(right + 1, -1).find do |x|
|
209
|
+
unless same_color?(old_img, new_img, x, y)
|
115
210
|
bottom = y
|
116
211
|
right = x
|
117
212
|
end
|
118
213
|
end
|
119
214
|
end
|
120
|
-
|
121
|
-
|
122
|
-
|
215
|
+
[left, top, right, bottom]
|
216
|
+
end
|
217
|
+
|
218
|
+
private def find_bottom(old_img, new_img, left, right, bottom)
|
219
|
+
if bottom
|
220
|
+
(old_img.height - 1).step(bottom + 1, -1).find do |y|
|
221
|
+
(left..right).find do |x|
|
222
|
+
bottom = y unless same_color?(old_img, new_img, x, y)
|
223
|
+
end
|
123
224
|
end
|
124
225
|
end
|
125
|
-
|
226
|
+
bottom
|
227
|
+
end
|
228
|
+
|
229
|
+
private def same_color?(old_img, new_img, x, y)
|
230
|
+
org_color = old_img[x, y]
|
231
|
+
new_color = new_img[x, y]
|
232
|
+
if @color_distance_limit && @color_distance_limit > 0
|
233
|
+
distance = ChunkyPNG::Color.euclidean_distance_rgba(org_color, new_color)
|
234
|
+
@max_color_distance = distance if distance > @max_color_distance
|
235
|
+
distance <= @color_distance_limit
|
236
|
+
else
|
237
|
+
org_color == new_color
|
238
|
+
end
|
126
239
|
end
|
127
240
|
end
|
128
241
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capybara-screenshot-diff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Uwe Kubosch
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06
|
11
|
+
date: 2017-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|