capybara-screenshot-diff 1.6.2 → 1.7.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/.github/dependabot.yml +8 -0
- data/.github/workflows/lint.yml +1 -1
- data/.github/workflows/test.yml +38 -20
- data/.gitignore +2 -0
- data/CONTRIBUTING.md +3 -1
- data/Dockerfile +2 -3
- data/README.md +39 -27
- data/bin/install-vips +1 -1
- data/capybara-screenshot-diff.gemspec +2 -2
- data/lib/capybara/screenshot/diff/browser_helpers.rb +101 -0
- data/lib/capybara/screenshot/diff/drivers/chunky_png_driver.rb +30 -17
- data/lib/capybara/screenshot/diff/drivers/utils.rb +7 -0
- data/lib/capybara/screenshot/diff/drivers/vips_driver.rb +33 -18
- data/lib/capybara/screenshot/diff/image_compare.rb +85 -72
- data/lib/capybara/screenshot/diff/region.rb +86 -0
- data/lib/capybara/screenshot/diff/stabilization.rb +18 -44
- data/lib/capybara/screenshot/diff/test_methods.rb +68 -35
- data/lib/capybara/screenshot/diff/vcs.rb +6 -5
- data/lib/capybara/screenshot/diff/version.rb +1 -1
- data/lib/capybara/screenshot/diff.rb +28 -21
- metadata +8 -6
- data/gemfiles/rails52.gemfile +0 -6
@@ -29,6 +29,10 @@ module Capybara
|
|
29
29
|
reset
|
30
30
|
end
|
31
31
|
|
32
|
+
def skip_area=(new_skip_area)
|
33
|
+
# noop
|
34
|
+
end
|
35
|
+
|
32
36
|
# Resets the calculated data about the comparison with regard to the "new_image".
|
33
37
|
# Data about the original image is kept.
|
34
38
|
def reset
|
@@ -53,12 +57,6 @@ module Capybara
|
|
53
57
|
[region, diff_mask]
|
54
58
|
end
|
55
59
|
|
56
|
-
def size(region)
|
57
|
-
return 0 unless region
|
58
|
-
|
59
|
-
(region[2] - region[0]) * (region[3] - region[1])
|
60
|
-
end
|
61
|
-
|
62
60
|
def adds_error_details_to(_log)
|
63
61
|
end
|
64
62
|
|
@@ -68,8 +66,16 @@ module Capybara
|
|
68
66
|
dimension(i) == dimensions || i.width < dimensions[0] || i.height < dimensions[1]
|
69
67
|
end
|
70
68
|
|
71
|
-
def crop(
|
72
|
-
i.crop(
|
69
|
+
def crop(region, i)
|
70
|
+
result = i.crop(*region.to_top_left_corner_coordinates)
|
71
|
+
|
72
|
+
# FIXME: Vips is caching operations, and if we ware going to read the same file, he will use cached version for this
|
73
|
+
# so after we cropped files and stored in the same file, the next load will recover old version instead of cropped
|
74
|
+
# Workaround to make vips works with cropped versions
|
75
|
+
Vips.cache_set_max(0)
|
76
|
+
Vips.vips_cache_set_max(1000)
|
77
|
+
|
78
|
+
result
|
73
79
|
end
|
74
80
|
|
75
81
|
def filter_image_with_median(image, median_filter_window_size)
|
@@ -77,7 +83,7 @@ module Capybara
|
|
77
83
|
end
|
78
84
|
|
79
85
|
def add_black_box(memo, region)
|
80
|
-
memo.draw_rect([0, 0, 0, 0], *region, fill: true)
|
86
|
+
memo.draw_rect([0, 0, 0, 0], *region.to_top_left_corner_coordinates, fill: true)
|
81
87
|
end
|
82
88
|
|
83
89
|
def chunky_png_comparator
|
@@ -104,8 +110,14 @@ module Capybara
|
|
104
110
|
image.width
|
105
111
|
end
|
106
112
|
|
113
|
+
PNG_EXTENSION = ".png"
|
114
|
+
|
115
|
+
# Vips could not work with the same file. Per each process we require to create new file
|
107
116
|
def save_image_to(image, filename)
|
108
|
-
|
117
|
+
::Dir::Tmpname.create([filename, PNG_EXTENSION]) do |tmp_image_filename|
|
118
|
+
image.write_to_file(tmp_image_filename)
|
119
|
+
FileUtils.mv(tmp_image_filename, filename)
|
120
|
+
end
|
109
121
|
end
|
110
122
|
|
111
123
|
def resize_image_to(image, new_width, new_height)
|
@@ -125,10 +137,10 @@ module Capybara
|
|
125
137
|
result
|
126
138
|
end
|
127
139
|
|
128
|
-
def dimension_changed?(
|
129
|
-
return false if dimension(
|
140
|
+
def dimension_changed?(old_image, new_image)
|
141
|
+
return false if dimension(old_image) == dimension(new_image)
|
130
142
|
|
131
|
-
change_msg = [
|
143
|
+
change_msg = [old_image, new_image].map { |i| "#{i.width}x#{i.height}" }.join(" => ")
|
132
144
|
warn "Image size has changed for #{@new_file_name}: #{change_msg}"
|
133
145
|
|
134
146
|
true
|
@@ -138,16 +150,16 @@ module Capybara
|
|
138
150
|
[image.width, image.height]
|
139
151
|
end
|
140
152
|
|
141
|
-
def draw_rectangles(images,
|
153
|
+
def draw_rectangles(images, region, rgba)
|
142
154
|
images.map do |image|
|
143
|
-
image.draw_rect(rgba, left - 1, top - 1,
|
155
|
+
image.draw_rect(rgba, region.left - 1, region.top - 1, region.width + 2, region.height + 2)
|
144
156
|
end
|
145
157
|
end
|
146
158
|
|
147
159
|
class VipsUtil
|
148
160
|
def self.difference(old_image, new_image, color_distance: 0)
|
149
161
|
diff_mask = difference_mask(color_distance, new_image, old_image)
|
150
|
-
difference_region_by(diff_mask)
|
162
|
+
difference_region_by(diff_mask).to_edge_coordinates
|
151
163
|
end
|
152
164
|
|
153
165
|
def self.difference_area(old_image, new_image, color_distance: 0)
|
@@ -165,14 +177,17 @@ module Capybara
|
|
165
177
|
end
|
166
178
|
|
167
179
|
def self.difference_region_by(diff_mask)
|
168
|
-
columns, rows = diff_mask.project
|
180
|
+
columns, rows = diff_mask.bandor.project
|
169
181
|
|
170
182
|
left = columns.profile[1].min
|
171
183
|
right = columns.width - columns.flip("horizontal").profile[1].min
|
184
|
+
|
172
185
|
top = rows.profile[0].min
|
173
186
|
bottom = rows.height - rows.flip("vertical").profile[0].min
|
174
187
|
|
175
|
-
|
188
|
+
return nil if right < left || bottom < top
|
189
|
+
|
190
|
+
Region.from_edge_coordinates(left, top, right, bottom)
|
176
191
|
end
|
177
192
|
end
|
178
193
|
end
|
@@ -12,9 +12,8 @@ module Capybara
|
|
12
12
|
|
13
13
|
attr_reader :driver, :driver_options
|
14
14
|
|
15
|
-
attr_reader :annotated_new_file_name, :annotated_old_file_name, :
|
16
|
-
|
17
|
-
:skip_area
|
15
|
+
attr_reader :annotated_new_file_name, :annotated_old_file_name, :new_file_name, :old_file_name, :skip_area
|
16
|
+
attr_accessor :shift_distance_limit, :area_size_limit, :color_distance_limit
|
18
17
|
|
19
18
|
def initialize(new_file_name, old_file_name = nil, options = {})
|
20
19
|
options = old_file_name if old_file_name.is_a?(Hash)
|
@@ -40,21 +39,23 @@ module Capybara
|
|
40
39
|
super(@driver)
|
41
40
|
end
|
42
41
|
|
42
|
+
def skip_area=(new_skip_area)
|
43
|
+
@skip_area = new_skip_area
|
44
|
+
driver.skip_area = @skip_area
|
45
|
+
end
|
46
|
+
|
43
47
|
# Compare the two image files and return `true` or `false` as quickly as possible.
|
44
|
-
# Return
|
48
|
+
# Return falsely if the old file does not exist or the image dimensions do not match.
|
45
49
|
def quick_equal?
|
46
50
|
return false unless old_file_exists?
|
47
51
|
return true if new_file_size == old_file_size
|
48
52
|
|
49
|
-
# old_bytes, new_bytes = load_image_files(@old_file_name, @new_file_name)
|
50
|
-
# return true if old_bytes == new_bytes
|
51
|
-
|
52
53
|
images = driver.load_images(@old_file_name, @new_file_name)
|
53
54
|
old_image, new_image = preprocess_images(images, driver)
|
54
55
|
|
55
56
|
return false if driver.dimension_changed?(old_image, new_image)
|
56
57
|
|
57
|
-
|
58
|
+
self.difference_region, meta = driver.find_difference_region(
|
58
59
|
new_image,
|
59
60
|
old_image,
|
60
61
|
@color_distance_limit,
|
@@ -63,14 +64,9 @@ module Capybara
|
|
63
64
|
fast_fail: true
|
64
65
|
)
|
65
66
|
|
66
|
-
|
67
|
-
|
68
|
-
return true if
|
69
|
-
|
70
|
-
return true if @area_size_limit && driver.size(region) <= @area_size_limit
|
71
|
-
|
72
|
-
return true if @tolerance && @tolerance >= driver.difference_level(meta, old_image, region)
|
73
|
-
|
67
|
+
return true if difference_region_area_size.zero? || difference_region_empty?(new_image, difference_region)
|
68
|
+
return true if @area_size_limit && difference_region_area_size <= @area_size_limit
|
69
|
+
return true if @tolerance && @tolerance >= driver.difference_level(meta, old_image, difference_region)
|
74
70
|
# TODO: Remove this or find similar solution for vips
|
75
71
|
return true if @shift_distance_limit && driver.shift_distance_equal?
|
76
72
|
|
@@ -79,41 +75,38 @@ module Capybara
|
|
79
75
|
|
80
76
|
# Compare the two images referenced by this object, and return `true` if they are different,
|
81
77
|
# and `false` if they are the same.
|
82
|
-
# Return `nil` if the old file does not exist or if the image dimensions do not match.
|
83
78
|
def different?
|
84
|
-
return
|
79
|
+
return false unless old_file_exists?
|
85
80
|
|
86
81
|
images = driver.load_images(@old_file_name, @new_file_name)
|
87
|
-
|
88
82
|
old_image, new_image = preprocess_images(images, driver)
|
89
83
|
|
90
84
|
if driver.dimension_changed?(old_image, new_image)
|
91
|
-
|
92
|
-
|
93
|
-
|
85
|
+
self.difference_region = Region.from_edge_coordinates(
|
86
|
+
0,
|
87
|
+
0,
|
88
|
+
[driver.width_for(old_image), driver.width_for(new_image)].min,
|
89
|
+
[driver.height_for(old_image), driver.height_for(new_image)].min
|
90
|
+
)
|
94
91
|
|
95
|
-
return
|
92
|
+
return different(*images)
|
96
93
|
end
|
97
94
|
|
98
|
-
|
95
|
+
self.difference_region, meta = driver.find_difference_region(
|
99
96
|
new_image,
|
100
97
|
old_image,
|
101
98
|
@color_distance_limit,
|
102
99
|
@shift_distance_limit,
|
103
100
|
@area_size_limit
|
104
101
|
)
|
105
|
-
self.difference_region = region
|
106
|
-
|
107
|
-
return not_different if difference_region_empty?(old_image, region)
|
108
|
-
return not_different if @area_size_limit && driver.size(region) <= @area_size_limit
|
109
|
-
return not_different if @tolerance && @tolerance > driver.difference_level(meta, old_image, region)
|
110
102
|
|
103
|
+
return not_different if difference_region_area_size.zero? || difference_region_empty?(old_image, difference_region)
|
104
|
+
return not_different if @area_size_limit && difference_region_area_size <= @area_size_limit
|
105
|
+
return not_different if @tolerance && @tolerance > driver.difference_level(meta, old_image, difference_region)
|
111
106
|
# TODO: Remove this or find similar solution for vips
|
112
107
|
return not_different if @shift_distance_limit && !driver.shift_distance_different?
|
113
108
|
|
114
|
-
|
115
|
-
|
116
|
-
true
|
109
|
+
different(*images)
|
117
110
|
end
|
118
111
|
|
119
112
|
def clean_tmp_files
|
@@ -123,17 +116,6 @@ module Capybara
|
|
123
116
|
File.delete(@annotated_new_file_name) if File.exist?(@annotated_new_file_name)
|
124
117
|
end
|
125
118
|
|
126
|
-
DIFF_COLOR = [255, 0, 0, 255].freeze
|
127
|
-
SKIP_COLOR = [255, 192, 0, 255].freeze
|
128
|
-
|
129
|
-
def annotate_and_save(images, region = difference_region)
|
130
|
-
annotated_images = driver.draw_rectangles(images, region, DIFF_COLOR)
|
131
|
-
@skip_area.to_a.flatten.each_slice(4) do |region|
|
132
|
-
annotated_images = driver.draw_rectangles(annotated_images, region, SKIP_COLOR)
|
133
|
-
end
|
134
|
-
save(*annotated_images, @annotated_old_file_name, @annotated_new_file_name)
|
135
|
-
end
|
136
|
-
|
137
119
|
def save(old_img, new_img, annotated_old_file_name, annotated_new_file_name)
|
138
120
|
driver.save_image_to(old_img, annotated_old_file_name)
|
139
121
|
driver.save_image_to(new_img, annotated_new_file_name)
|
@@ -148,25 +130,43 @@ module Capybara
|
|
148
130
|
driver.reset
|
149
131
|
end
|
150
132
|
|
133
|
+
NEW_LINE = "\n"
|
134
|
+
|
151
135
|
def error_message
|
152
136
|
result = {
|
153
|
-
area_size:
|
154
|
-
region:
|
137
|
+
area_size: difference_region_area_size,
|
138
|
+
region: difference_coordinates
|
155
139
|
}
|
156
140
|
|
157
141
|
driver.adds_error_details_to(result)
|
158
142
|
|
159
|
-
[
|
143
|
+
[
|
144
|
+
"(#{result.to_json})",
|
145
|
+
new_file_name,
|
146
|
+
annotated_old_file_name,
|
147
|
+
annotated_new_file_name
|
148
|
+
].join(NEW_LINE)
|
160
149
|
end
|
161
150
|
|
162
|
-
def
|
163
|
-
|
151
|
+
def difference_coordinates
|
152
|
+
difference_region&.to_edge_coordinates
|
153
|
+
end
|
154
|
+
|
155
|
+
def difference_region_area_size
|
156
|
+
return 0 unless difference_region
|
164
157
|
|
165
|
-
|
158
|
+
difference_region.size
|
166
159
|
end
|
167
160
|
|
168
161
|
private
|
169
162
|
|
163
|
+
attr_accessor :difference_region
|
164
|
+
|
165
|
+
def different(old_image, new_image)
|
166
|
+
annotate_and_save([old_image, new_image], difference_region)
|
167
|
+
true
|
168
|
+
end
|
169
|
+
|
170
170
|
def find_driver_class_for(driver)
|
171
171
|
driver = AVAILABLE_DRIVERS.first if driver == :auto
|
172
172
|
|
@@ -183,23 +183,6 @@ module Capybara
|
|
183
183
|
end
|
184
184
|
end
|
185
185
|
|
186
|
-
def old_file_size
|
187
|
-
@old_file_size ||= old_file_exists? && File.size(@old_file_name)
|
188
|
-
end
|
189
|
-
|
190
|
-
def new_file_size
|
191
|
-
File.size(@new_file_name)
|
192
|
-
end
|
193
|
-
|
194
|
-
def not_different
|
195
|
-
clean_tmp_files
|
196
|
-
false
|
197
|
-
end
|
198
|
-
|
199
|
-
def load_images(old_file_name, new_file_name, driver = self)
|
200
|
-
[driver.from_file(old_file_name), driver.from_file(new_file_name)]
|
201
|
-
end
|
202
|
-
|
203
186
|
def preprocess_images(images, driver = self)
|
204
187
|
old_img = preprocess_image(images.first, driver)
|
205
188
|
new_img = preprocess_image(images.last, driver)
|
@@ -225,19 +208,49 @@ module Capybara
|
|
225
208
|
result
|
226
209
|
end
|
227
210
|
|
228
|
-
def
|
229
|
-
@
|
211
|
+
def old_file_size
|
212
|
+
@old_file_size ||= old_file_exists? && File.size(@old_file_name)
|
213
|
+
end
|
214
|
+
|
215
|
+
def new_file_size
|
216
|
+
File.size(@new_file_name)
|
217
|
+
end
|
218
|
+
|
219
|
+
def not_different
|
220
|
+
clean_tmp_files
|
221
|
+
false
|
230
222
|
end
|
231
223
|
|
232
224
|
def difference_region_empty?(new_image, region)
|
233
225
|
region.nil? ||
|
234
226
|
(
|
235
|
-
region
|
236
|
-
region
|
237
|
-
region
|
238
|
-
region
|
227
|
+
region.height == height_for(new_image) &&
|
228
|
+
region.width == width_for(new_image) &&
|
229
|
+
region.x.zero? &&
|
230
|
+
region.y.zero?
|
239
231
|
)
|
240
232
|
end
|
233
|
+
|
234
|
+
def annotate_and_save(images, region)
|
235
|
+
annotated_images = annotate_difference(images, region)
|
236
|
+
annotated_images = annotate_skip_areas(annotated_images, @skip_area) if @skip_area
|
237
|
+
|
238
|
+
save(*annotated_images, @annotated_old_file_name, @annotated_new_file_name)
|
239
|
+
end
|
240
|
+
|
241
|
+
DIFF_COLOR = [255, 0, 0, 255].freeze
|
242
|
+
|
243
|
+
def annotate_difference(images, region)
|
244
|
+
driver.draw_rectangles(images, region, DIFF_COLOR)
|
245
|
+
end
|
246
|
+
|
247
|
+
SKIP_COLOR = [255, 192, 0, 255].freeze
|
248
|
+
|
249
|
+
def annotate_skip_areas(annotated_images, skip_areas)
|
250
|
+
skip_areas.reduce(annotated_images) do |annotated_images, region|
|
251
|
+
driver.draw_rectangles(annotated_images, region, SKIP_COLOR)
|
252
|
+
end
|
253
|
+
end
|
241
254
|
end
|
242
255
|
end
|
243
256
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Region
|
4
|
+
attr_accessor :x, :y, :width, :height
|
5
|
+
|
6
|
+
def initialize(x, y, width, height)
|
7
|
+
@x, @y, @width, @height = x, y, width, height
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.from_top_left_corner_coordinates(x, y, width, height)
|
11
|
+
return nil unless x && y && width && height
|
12
|
+
return nil if width < 0 || height < 0
|
13
|
+
|
14
|
+
Region.new(x, y, width, height)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.from_edge_coordinates(left, top, right, bottom)
|
18
|
+
return nil unless left && top && right && bottom
|
19
|
+
return nil if right < left || bottom < top
|
20
|
+
|
21
|
+
Region.new(left, top, right - left, bottom - top)
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_edge_coordinates
|
25
|
+
[left, top, right, bottom]
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_top_left_corner_coordinates
|
29
|
+
[x, y, width, height]
|
30
|
+
end
|
31
|
+
|
32
|
+
def top
|
33
|
+
y
|
34
|
+
end
|
35
|
+
|
36
|
+
def bottom
|
37
|
+
y + height
|
38
|
+
end
|
39
|
+
|
40
|
+
def left
|
41
|
+
x
|
42
|
+
end
|
43
|
+
|
44
|
+
def right
|
45
|
+
x + width
|
46
|
+
end
|
47
|
+
|
48
|
+
def size
|
49
|
+
return 0 if width < 0 || height < 0
|
50
|
+
|
51
|
+
result = width * height
|
52
|
+
result.zero? ? 1 : result
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_a
|
56
|
+
[@x, @y, @width, @height]
|
57
|
+
end
|
58
|
+
|
59
|
+
def find_intersect_with(region)
|
60
|
+
return nil unless intersect?(region)
|
61
|
+
|
62
|
+
new_left = [x, region.x].max
|
63
|
+
new_top = [y, region.y].max
|
64
|
+
|
65
|
+
Region.new(new_left, new_top, [right, region.right].min - new_left, [bottom, region.bottom].min - new_top)
|
66
|
+
end
|
67
|
+
|
68
|
+
def intersect?(region)
|
69
|
+
left <= region.right && right >= region.left && top <= region.bottom && bottom >= region.top
|
70
|
+
end
|
71
|
+
|
72
|
+
def move_by(right_by, down_by)
|
73
|
+
Region.new(x + right_by, y + down_by, width, height)
|
74
|
+
end
|
75
|
+
|
76
|
+
def find_relative_intersect(region)
|
77
|
+
intersect = find_intersect_with(region)
|
78
|
+
return nil unless intersect
|
79
|
+
|
80
|
+
intersect.move_by(-x, -y)
|
81
|
+
end
|
82
|
+
|
83
|
+
def cover?(x, y)
|
84
|
+
left <= x && x <= right && top <= y && y <= bottom
|
85
|
+
end
|
86
|
+
end
|
@@ -8,28 +8,6 @@ module Capybara
|
|
8
8
|
module Stabilization
|
9
9
|
include Os
|
10
10
|
|
11
|
-
IMAGE_WAIT_SCRIPT = <<-JS.strip_heredoc.freeze
|
12
|
-
function pending_image() {
|
13
|
-
var images = document.images;
|
14
|
-
for (var i = 0; i < images.length; i++) {
|
15
|
-
if (!images[i].complete) {
|
16
|
-
return images[i].src;
|
17
|
-
}
|
18
|
-
}
|
19
|
-
return false;
|
20
|
-
}()
|
21
|
-
JS
|
22
|
-
|
23
|
-
HIDE_CARET_SCRIPT = <<~JS
|
24
|
-
if (!document.getElementById('csdHideCaretStyle')) {
|
25
|
-
let style = document.createElement('style');
|
26
|
-
style.setAttribute('id', 'csdHideCaretStyle');
|
27
|
-
document.head.appendChild(style);
|
28
|
-
let styleSheet = style.sheet;
|
29
|
-
styleSheet.insertRule("* { caret-color: transparent !important; }", 0);
|
30
|
-
}
|
31
|
-
JS
|
32
|
-
|
33
11
|
def take_stable_screenshot(comparison, stability_time_limit:, wait:, crop:)
|
34
12
|
previous_file_name = comparison.old_file_name
|
35
13
|
screenshot_started_at = last_image_change_at = Time.now
|
@@ -41,6 +19,7 @@ module Capybara
|
|
41
19
|
clean_stabilization_images(comparison.new_file_name)
|
42
20
|
break
|
43
21
|
end
|
22
|
+
|
44
23
|
comparison.reset
|
45
24
|
|
46
25
|
if previous_file_name
|
@@ -78,7 +57,7 @@ module Capybara
|
|
78
57
|
end
|
79
58
|
|
80
59
|
def notice_how_to_avoid_this
|
81
|
-
unless @_csd_retina_warned
|
60
|
+
unless defined?(@_csd_retina_warned)
|
82
61
|
warn "Halving retina screenshot. " \
|
83
62
|
'You should add "force-device-scale-factor=1" to your Chrome chromeOptions args.'
|
84
63
|
@_csd_retina_warned = true
|
@@ -90,7 +69,7 @@ module Capybara
|
|
90
69
|
def build_snapshot_version_file_name(comparison, iteration, screenshot_started_at, stabilization_comparison)
|
91
70
|
"#{comparison.new_file_name.chomp(".png")}" \
|
92
71
|
"_x#{format("%02i", iteration)}_#{(Time.now - screenshot_started_at).round(1)}s" \
|
93
|
-
"_#{stabilization_comparison.
|
72
|
+
"_#{stabilization_comparison.difference_coordinates&.to_s&.gsub(", ", "_") || :initial}.png" \
|
94
73
|
"#{ImageCompare::TMP_FILE_SUFFIX}"
|
95
74
|
end
|
96
75
|
|
@@ -110,11 +89,7 @@ module Capybara
|
|
110
89
|
new_height = expected_image_width * driver.height_for(saved_image) / driver.width_for(saved_image)
|
111
90
|
resized_image = driver.resize_image_to(saved_image, expected_image_width, new_height)
|
112
91
|
|
113
|
-
|
114
|
-
resized_image_file = "#{dir}/resized.png"
|
115
|
-
driver.save_image_to(resized_image, resized_image_file)
|
116
|
-
FileUtils.mv(resized_image_file, file_name)
|
117
|
-
end
|
92
|
+
driver.save_image_to(resized_image, file_name)
|
118
93
|
end
|
119
94
|
|
120
95
|
def stabilization_images(base_file)
|
@@ -127,32 +102,31 @@ module Capybara
|
|
127
102
|
|
128
103
|
def prepare_page_for_screenshot(timeout:)
|
129
104
|
assert_images_loaded(timeout: timeout)
|
105
|
+
|
130
106
|
if Capybara::Screenshot.blur_active_element
|
131
|
-
|
132
|
-
ae = document.activeElement;
|
133
|
-
if (ae.nodeName === "INPUT" || ae.nodeName === "TEXTAREA") {
|
134
|
-
ae.blur();
|
135
|
-
return ae;
|
136
|
-
}
|
137
|
-
return null;
|
138
|
-
JS
|
139
|
-
blurred_input = page.driver.send :unwrap_script_result, active_element
|
107
|
+
blurred_input = blur_from_focused_element
|
140
108
|
end
|
141
|
-
|
109
|
+
|
110
|
+
if Capybara::Screenshot.hide_caret
|
111
|
+
hide_caret
|
112
|
+
end
|
113
|
+
|
142
114
|
blurred_input
|
143
115
|
end
|
144
116
|
|
145
117
|
def take_right_size_screenshot(comparison, crop:)
|
118
|
+
driver = comparison.driver
|
119
|
+
|
146
120
|
save_screenshot(comparison.new_file_name)
|
147
121
|
|
148
122
|
# TODO(uwe): Remove when chromedriver takes right size screenshots
|
149
|
-
reduce_retina_image_size(comparison.new_file_name,
|
123
|
+
reduce_retina_image_size(comparison.new_file_name, driver)
|
150
124
|
# ODOT
|
151
125
|
|
152
126
|
if crop
|
153
|
-
|
154
|
-
|
155
|
-
|
127
|
+
image = driver.from_file(comparison.new_file_name)
|
128
|
+
cropped_image = driver.crop(crop, image)
|
129
|
+
driver.save_image_to(cropped_image, comparison.new_file_name)
|
156
130
|
end
|
157
131
|
end
|
158
132
|
|
@@ -193,7 +167,7 @@ module Capybara
|
|
193
167
|
|
194
168
|
start = Time.now
|
195
169
|
loop do
|
196
|
-
pending_image =
|
170
|
+
pending_image = pending_image_to_load
|
197
171
|
break unless pending_image
|
198
172
|
|
199
173
|
assert(
|