lib/capybara/screenshot/diff/stabilization.rb in capybara-screenshot-diff-1.3.1 vs lib/capybara/screenshot/diff/stabilization.rb in capybara-screenshot-diff-1.4.0
- old
+ new
@@ -1,8 +1,8 @@
# frozen_string_literal: true
-require_relative 'os'
+require_relative "os"
module Capybara
module Screenshot
module Diff
module Stabilization
@@ -18,31 +18,29 @@
}
return false;
}()
JS
- def take_stable_screenshot(comparison, color_distance_limit:, shift_distance_limit:,
- area_size_limit:, skip_area:, stability_time_limit:, wait:)
- blurred_input = prepare_page_for_screenshot(timeout: wait)
+ def take_stable_screenshot(comparison, stability_time_limit:, wait:)
previous_file_name = comparison.old_file_name
screenshot_started_at = last_image_change_at = Time.now
+ clean_stabilization_images(comparison.new_file_name)
+
1.step do |i|
take_right_size_screenshot(comparison)
-
- break unless stability_time_limit
-
if comparison.quick_equal?
clean_stabilization_images(comparison.new_file_name)
break
end
comparison.reset
if previous_file_name
- stabilization_comparison =
- ImageCompare.new(comparison.new_file_name, previous_file_name,
- color_distance_limit: color_distance_limit, shift_distance_limit: shift_distance_limit,
- area_size_limit: area_size_limit, skip_area: skip_area)
+ stabilization_comparison = make_stabilization_comparison_from(
+ comparison,
+ comparison.new_file_name,
+ previous_file_name
+ )
if stabilization_comparison.quick_equal?
if (Time.now - last_image_change_at) > stability_time_limit
clean_stabilization_images(comparison.new_file_name)
break
end
@@ -50,43 +48,58 @@
else
last_image_change_at = Time.now
end
end
- previous_file_name = "#{comparison.new_file_name.chomp('.png')}" \
- "_x#{format('%02i', i)}_#{(Time.now - screenshot_started_at).round(1)}s" \
- "_#{stabilization_comparison.dimensions&.to_s&.gsub(', ', '_') || :initial}.png~"
+ previous_file_name = "#{comparison.new_file_name.chomp(".png")}" \
+ "_x#{format("%02i", i)}_#{(Time.now - screenshot_started_at).round(1)}s" \
+ "_#{stabilization_comparison.difference_region&.to_s&.gsub(", ", "_") || :initial}.png~"
FileUtils.mv comparison.new_file_name, previous_file_name
- check_max_wait_time(comparison, screenshot_started_at,
- wait: wait, shift_distance_limit: shift_distance_limit)
+ check_max_wait_time(
+ comparison,
+ screenshot_started_at,
+ max_wait_time: max_wait_time(comparison.shift_distance_limit, wait)
+ )
end
- ensure
- blurred_input&.click
end
+ def notice_how_to_avoid_this
+ unless @_csd_retina_warned
+ warn "Halving retina screenshot. " \
+ 'You should add "force-device-scale-factor=1" to your Chrome chromeOptions args.'
+ @_csd_retina_warned = true
+ end
+ end
+
private
- def reduce_retina_image_size(file_name)
+ def make_stabilization_comparison_from(comparison, new_file_name, previous_file_name)
+ ImageCompare.new(new_file_name, previous_file_name, **comparison.driver_options)
+ end
+
+ def reduce_retina_image_size(file_name, driver)
return if !ON_MAC || !selenium? || !Capybara::Screenshot.window_size
- saved_image = ChunkyPNG::Image.from_file(file_name)
- width = Capybara::Screenshot.window_size[0]
- return if saved_image.width < width * 2
+ expected_image_width = Capybara::Screenshot.window_size[0]
+ saved_image = driver.from_file(file_name)
+ return if driver.width_for(saved_image) < expected_image_width * 2
- unless @_csd_retina_warned
- warn 'Halving retina screenshot. ' \
- 'You should add "force-device-scale-factor=1" to your Chrome chromeOptions args.'
- @_csd_retina_warned = true
+ notice_how_to_avoid_this
+
+ new_height = expected_image_width * driver.height_for(saved_image) / driver.width_for(saved_image)
+ resized_image = driver.resize_image_to(saved_image, expected_image_width, new_height)
+
+ Dir.mktmpdir do |dir|
+ resized_image_file = "#{dir}/resized.png"
+ driver.save_image_to(resized_image, resized_image_file)
+ FileUtils.mv(resized_image_file, file_name)
end
- height = (width * saved_image.height) / saved_image.width
- resized_image = saved_image.resample_bilinear(width, height)
- resized_image.save(file_name)
end
def stabilization_images(base_file)
- Dir["#{base_file.chomp('.png')}_x*.png~"].sort
+ Dir["#{base_file.chomp(".png")}_x*.png~"].sort
end
def clean_stabilization_images(base_file)
FileUtils.rm stabilization_images(base_file)
end
@@ -102,55 +115,74 @@
}
return null;
JS
blurred_input = page.driver.send :unwrap_script_result, active_element
end
- execute_script("$('*').css('caret-color','transparent')") if Capybara::Screenshot.hide_caret
+ if Capybara::Screenshot.hide_caret && !@hid_caret
+ execute_script(<<~JS)
+ var style = document.createElement('style');
+ document.head.appendChild(style);
+ var styleSheet = style.sheet;
+ styleSheet.insertRule("* { caret-color: transparent !important; }", 0);
+ JS
+ @hid_caret = true
+ end
blurred_input
end
def take_right_size_screenshot(comparison)
save_screenshot(comparison.new_file_name)
# TODO(uwe): Remove when chromedriver takes right size screenshots
- reduce_retina_image_size(comparison.new_file_name)
+ reduce_retina_image_size(comparison.new_file_name, comparison.driver)
# ODOT
end
- def check_max_wait_time(comparison, screenshot_started_at, wait:, shift_distance_limit:)
- shift_factor = shift_distance_limit ? (shift_distance_limit * 2 + 1) ^ 2 : 1
- max_wait_time = wait * shift_factor
+ def check_max_wait_time(comparison, screenshot_started_at, max_wait_time:)
return if (Time.now - screenshot_started_at) < max_wait_time
+ annotate_stabilization_images(comparison)
# FIXME(uwe): Change to store the failure and only report if the test succeeds functionally.
+ fail("Could not get stable screenshot within #{max_wait_time}s\n" \
+ "#{stabilization_images(comparison.new_file_name).join("\n")}")
+ end
+
+ def annotate_stabilization_images(comparison)
previous_file = comparison.old_file_name
stabilization_images(comparison.new_file_name).each do |file_name|
if File.exist? previous_file
- stabilization_comparison =
- ImageCompare.new(file_name, previous_file,
- color_distance_limit: comparison.color_distance_limit,
- shift_distance_limit: comparison.shift_distance_limit,
- area_size_limit: comparison.area_size_limit, skip_area: comparison.skip_area)
- assert stabilization_comparison.different?
- FileUtils.mv stabilization_comparison.annotated_new_file_name, file_name
+ stabilization_comparison = make_stabilization_comparison_from(
+ comparison,
+ file_name,
+ previous_file
+ )
+ if stabilization_comparison.different?
+ FileUtils.mv stabilization_comparison.annotated_new_file_name, file_name
+ end
FileUtils.rm stabilization_comparison.annotated_old_file_name
end
previous_file = file_name
end
- fail("Could not get stable screenshot within #{max_wait_time}s\n" \
- "#{stabilization_images(comparison.new_file_name).join("\n")}")
end
+ def max_wait_time(shift_distance_limit, wait)
+ shift_factor = shift_distance_limit ? (shift_distance_limit * 2 + 1) ^ 2 : 1
+ wait * shift_factor
+ end
+
def assert_images_loaded(timeout:)
return unless respond_to? :evaluate_script
start = Time.now
loop do
pending_image = evaluate_script IMAGE_WAIT_SCRIPT
break unless pending_image
- assert((Time.now - start) < timeout,
- "Images not loaded after #{timeout}s: #{pending_image.inspect}")
+ assert(
+ (Time.now - start) < timeout,
+ "Images not loaded after #{timeout}s: #{pending_image.inspect}"
+ )
+
sleep 0.1
end
end
end
end