Class: SnapDiff::StableScreenshoter

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

Constant Summary collapse

STABILITY_OPTIONS =
[:stability_time_limit, :wait]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Initializes a new instance of StableScreenshoter

This method sets up a new screenshoter with specific capture and comparison options. It validates the presence of :stability_time_limit and :wait in capture options and ensures that :stability_time_limit is less than or equal to :wait.

Parameters:

  • capture_options (Hash)

    The options for capturing screenshots, must include :stability_time_limit and :wait.

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

    The options for comparing screenshots, defaults to {}. Same signature as SnapDiff::Screenshoter#initialize.

Raises:

  • (ArgumentError)

    If :wait or :stability_time_limit are not provided, or if :stability_time_limit is greater than :wait.



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/snap_diff/stable_screenshoter.rb', line 17

def initialize(capture_options, comparison_options = {})
  @stability_time_limit, @wait = capture_options.fetch_values(*STABILITY_OPTIONS)

  raise ArgumentError, "wait should be provided for stable screenshots" unless wait
  raise ArgumentError, "stability_time_limit should be provided for stable screenshots" unless stability_time_limit
  raise ArgumentError, "stability_time_limit (#{stability_time_limit}) should be less or equal than wait (#{wait}) for stable screenshots" unless stability_time_limit <= wait

  @comparison_options = comparison_options

  @screenshoter = SnapDiff.config.screenshoter.new(capture_options.except(:stability_time_limit), @comparison_options)
end

Instance Attribute Details

#stability_time_limitObject (readonly)

Returns the value of attribute stability_time_limit.



7
8
9
# File 'lib/snap_diff/stable_screenshoter.rb', line 7

def stability_time_limit
  @stability_time_limit
end

#waitObject (readonly)

Returns the value of attribute wait.



7
8
9
# File 'lib/snap_diff/stable_screenshoter.rb', line 7

def wait
  @wait
end

Instance Method Details

#take_comparison_screenshot(snapshot) ⇒ void

This method returns an undefined value.

Takes a comparison screenshot ensuring page stability

Attempts to take a stable screenshot of the page by comparing several screenshot attempts until the page stops updating or the :wait limit is reached. If unable to achieve a stable state within the time limit, it annotates the attempts to aid debugging.

Parameters:

  • snapshot

    Snap The snapshot details to take a stable screenshot of.

Raises:



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/snap_diff/stable_screenshoter.rb', line 38

def take_comparison_screenshot(snapshot)
  result = take_stable_screenshot(snapshot)

  # We failed to get stable browser state! Generate difference between attempts to overview moving parts!
  unless result
    # The failed-stability outcome is data (the annotated attempts report); raising is this
    # boundary's decision, not the reporter's.
    # FIXME(uwe): Hand the failure to the verify path so it only reports after the test's own assertions run.
    raise SnapDiff::UnstableImage.new(stability_failure_report(snapshot), caller)
  end

  # store success attempt as actual screenshot
  snapshot.commit_last_attempt

  # cleanup all previous attempts
  snapshot.cleanup_attempts!
end

#take_stable_screenshot(snapshot) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/snap_diff/stable_screenshoter.rb', line 56

def take_stable_screenshot(snapshot)
  # We try to compare first attempt with checkout version, in order to not run next screenshots
  deadline_at = Process.clock_gettime(Process::CLOCK_MONOTONIC) + wait

  # Cleanup all previous attempts for sure
  snapshot.cleanup_attempts!

  loop do
    attempt_next_screenshot(snapshot)

    return true if attempt_successful?(snapshot)
    return false if timeout?(deadline_at)

    sleep(stability_time_limit)
  end
end