class Capybara::Screenshot::Screenshoter
Constants
- PNG_EXTENSION
Attributes
capture_options[R]
comparison_options[R]
driver[R]
Public Class Methods
attempts_screenshot_paths(base_file)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 33 def self.attempts_screenshot_paths(base_file) extname = Pathname.new(base_file).extname Dir["#{base_file.to_s.chomp(extname)}.attempt_*#{extname}"].sort end
cleanup_attempts_screenshots(base_file)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 38 def self.cleanup_attempts_screenshots(base_file) FileUtils.rm_rf attempts_screenshot_paths(base_file) end
gen_next_attempt_path(screenshot_path, iteration)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 51 def self.gen_next_attempt_path(screenshot_path, iteration) screenshot_path.sub_ext(format(".attempt_%02i#{screenshot_path.extname}", iteration)) end
new(capture_options, driver)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 11 def initialize(capture_options, driver) @capture_options = capture_options @comparison_options = comparison_options @driver = driver end
Public Instance Methods
capybara_screenshot_options()
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 29 def capybara_screenshot_options @capture_options[:capybara_screenshot_options] || {} end
crop()
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 17 def crop @capture_options[:crop] end
notice_how_to_avoid_this()
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 79 def notice_how_to_avoid_this unless defined?(@_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
prepare_page_for_screenshot(timeout:)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 87 def prepare_page_for_screenshot(timeout:) wait_images_loaded(timeout: timeout) if timeout blurred_input = BrowserHelpers.blur_from_focused_element if Screenshot.blur_active_element if Screenshot.hide_caret BrowserHelpers.hide_caret end blurred_input end
process_screenshot(stored_path, screenshot_path)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 66 def process_screenshot(stored_path, screenshot_path) screenshot_image = driver.from_file(stored_path) # TODO(uwe): Remove when chromedriver takes right size screenshots # TODO: Adds tests when this case is true screenshot_image = resize_if_needed(screenshot_image) if selenium_with_retina_screen? # ODOT screenshot_image = driver.crop(crop, screenshot_image) if crop driver.save_image_to(screenshot_image, screenshot_path) end
screenshot_format()
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 25 def screenshot_format @capture_options[:screenshot_format] || "png" end
take_comparison_screenshot(screenshot_path)
click to toggle source
Try to get screenshot from browser. On ‘stability_time_limit` it checks that page stop updating by comparison several screenshot attempts On reaching `wait` limit then it has been failed. On failing we annotate screenshot attempts to help to debug
# File lib/capybara/screenshot/diff/screenshoter.rb, line 45 def take_comparison_screenshot(screenshot_path) capture_screenshot_at(screenshot_path) Screenshoter.cleanup_attempts_screenshots(screenshot_path) end
take_screenshot(screenshot_path)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 57 def take_screenshot(screenshot_path) blurred_input = prepare_page_for_screenshot(timeout: wait) # Take browser screenshot and save save_and_process_screenshot(screenshot_path) blurred_input&.click end
wait()
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 21 def wait @capture_options[:wait] end
wait_images_loaded(timeout:)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 99 def wait_images_loaded(timeout:) return unless timeout deadline_at = Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout loop do pending_image = BrowserHelpers.pending_image_to_load break unless pending_image if Process.clock_gettime(Process::CLOCK_MONOTONIC) > deadline_at raise CapybaraScreenshotDiff::ExpectationNotMet, "Images have not been loaded after #{timeout}s: #{pending_image.inspect}" end sleep 0.025 end end
Private Instance Methods
capture_screenshot_at(screenshot_path)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 126 def capture_screenshot_at(screenshot_path) new_screenshot_path = Screenshoter.gen_next_attempt_path(screenshot_path, 0) take_and_process_screenshot(new_screenshot_path, screenshot_path) end
move_screenshot_to(new_screenshot_path, screenshot_path)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 136 def move_screenshot_to(new_screenshot_path, screenshot_path) FileUtils.mv(new_screenshot_path, screenshot_path, force: true) end
resize_if_needed(saved_image)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 140 def resize_if_needed(saved_image) expected_image_width = Screenshot.window_size[0] return saved_image if driver.width_for(saved_image) < expected_image_width * 2 notice_how_to_avoid_this new_height = expected_image_width * driver.height_for(saved_image) / driver.width_for(saved_image) driver.resize_image_to(saved_image, expected_image_width, new_height) end
save_and_process_screenshot(screenshot_path)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 117 def save_and_process_screenshot(screenshot_path) tmpfile = Tempfile.new([screenshot_path.basename.to_s, PNG_EXTENSION]) BrowserHelpers.session.save_screenshot(tmpfile.path, **capybara_screenshot_options) # Load saved screenshot and pre-process it process_screenshot(tmpfile.path, screenshot_path) ensure File.unlink(tmpfile) if tmpfile end
selenium_with_retina_screen?()
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 150 def selenium_with_retina_screen? Os::ON_MAC && BrowserHelpers.selenium? && Screenshot.window_size end
take_and_process_screenshot(new_screenshot_path, screenshot_path)
click to toggle source
# File lib/capybara/screenshot/diff/screenshoter.rb, line 131 def take_and_process_screenshot(new_screenshot_path, screenshot_path) take_screenshot(new_screenshot_path) move_screenshot_to(new_screenshot_path, screenshot_path) end