Class: Capybara::Screenshot::Diff::StableScreenshoter

Inherits:
Object
  • Object
show all
Defined in:
lib/capybara/screenshot/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, nil) (defaults to: {})

    The options for comparing screenshots, defaults to ‘nil` which uses `Diff.default_options`.

Raises:

  • (ArgumentError)

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



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/capybara/screenshot/diff/stable_screenshoter.rb', line 19

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

  driver = Diff::Drivers.for(@comparison_options)
  @screenshoter = Diff.screenshoter.new(capture_options.except(:stability_time_limit), driver)
end

Instance Attribute Details

#stability_time_limitObject (readonly)

Returns the value of attribute stability_time_limit.



9
10
11
# File 'lib/capybara/screenshot/diff/stable_screenshoter.rb', line 9

def stability_time_limit
  @stability_time_limit
end

#waitObject (readonly)

Returns the value of attribute wait.



9
10
11
# File 'lib/capybara/screenshot/diff/stable_screenshoter.rb', line 9

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:

  • (RuntimeError)

    If a stable screenshot cannot be obtained within the specified ‘:wait` time.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/capybara/screenshot/diff/stable_screenshoter.rb', line 41

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
    # FIXME(uwe): Change to store the failure and only report if the test succeeds functionally.
    annotate_attempts_and_fail!(snapshot)
  end

  # store success attempt as actual screenshot
  snapshot.commit_last_attempt

  # cleanup all previous attempts
  snapshot.cleanup_attempts
end

#take_stable_screenshot(snapshot) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/capybara/screenshot/diff/stable_screenshoter.rb', line 57

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

  0.step do |i|
    # FIXME: it should be wait, and wait should be replaced with stability_time_limit
    sleep(stability_time_limit) unless i == 0 # test prev_attempt_path is nil

    attempt_next_screenshot(snapshot)

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