Class: SnapDiff::Screenshoter

Inherits:
Object
  • Object
show all
Defined in:
lib/snap_diff/screenshoter.rb

Constant Summary collapse

PNG_EXTENSION =
".png"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(capture_options, comparison_options = {}) ⇒ Screenshoter

Returns a new instance of Screenshoter.

Parameters:

  • capture_options (Hash)

    Options for capturing (window_size, wait, etc.)

  • comparison_options (Hash) (defaults to: {})

    Options for image comparison (driver, tolerance, etc.)



14
15
16
17
# File 'lib/snap_diff/screenshoter.rb', line 14

def initialize(capture_options, comparison_options = {})
  @capture_options = capture_options
  @driver = SnapDiff::Drivers.for(comparison_options)
end

Instance Attribute Details

#capture_optionsObject (readonly)

Returns the value of attribute capture_options.



10
11
12
# File 'lib/snap_diff/screenshoter.rb', line 10

def capture_options
  @capture_options
end

#driverObject (readonly)

Returns the value of attribute driver.



10
11
12
# File 'lib/snap_diff/screenshoter.rb', line 10

def driver
  @driver
end

Instance Method Details

#capybara_screenshot_optionsObject



27
28
29
# File 'lib/snap_diff/screenshoter.rb', line 27

def capybara_screenshot_options
  @capture_options[:capybara_screenshot_options] || {}
end

#cropObject



19
20
21
# File 'lib/snap_diff/screenshoter.rb', line 19

def crop
  @capture_options[:crop]
end

#notice_how_to_avoid_thisObject



61
62
63
64
65
66
67
# File 'lib/snap_diff/screenshoter.rb', line 61

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:) ⇒ Object



69
70
71
72
73
74
75
76
77
78
# File 'lib/snap_diff/screenshoter.rb', line 69

def prepare_page_for_screenshot(timeout:)
  wait_images_loaded(timeout: timeout) if timeout

  blurred_input = BrowserHelpers.blur_from_focused_element if SnapDiff.config.blur_active_element

  BrowserHelpers.hide_caret if SnapDiff.config.hide_caret
  BrowserHelpers.disable_animations if SnapDiff.config.disable_animations

  blurred_input
end

#process_screenshot(stored_path, screenshot_path) ⇒ Object



50
51
52
53
54
55
56
57
58
59
# File 'lib/snap_diff/screenshoter.rb', line 50

def process_screenshot(stored_path, screenshot_path)
  screenshot_image = driver.from_file(stored_path)

  # TODO(uwe): Remove when chromedriver takes right size screenshots
  screenshot_image = resize_if_needed(screenshot_image) if selenium_with_retina_screen?

  screenshot_image = driver.crop(crop, screenshot_image) if crop

  driver.save_image_to(screenshot_image, screenshot_path)
end

#take_comparison_screenshot(snapshot) ⇒ Object

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



34
35
36
37
# File 'lib/snap_diff/screenshoter.rb', line 34

def take_comparison_screenshot(snapshot)
  capture_screenshot_at(snapshot)
  snapshot.cleanup_attempts!
end

#take_screenshot(screenshot_path) ⇒ Object



41
42
43
44
45
46
47
48
# File 'lib/snap_diff/screenshoter.rb', line 41

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

#waitObject



23
24
25
# File 'lib/snap_diff/screenshoter.rb', line 23

def wait
  @capture_options[:wait]
end

#wait_images_loaded(timeout:) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/snap_diff/screenshoter.rb', line 80

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 SnapDiff::ExpectationNotMet.new("Images have not been loaded after #{timeout}s: #{pending_image.inspect}", caller)
    end

    sleep 0.025
  end
end