module Capybara::Screenshot::Diff::TestMethods
Public Class Methods
@!attribute [rw] test_screenshots
@return [Array(Array(Array(String), String, ImageCompare))] An array where each element is an array containing the caller context, the name of the screenshot, and the comparison object. This attribute stores information about each screenshot scheduled for comparison to ensure they do not show any unintended differences.
# File lib/capybara/screenshot/diff/test_methods.rb, line 32 def initialize(*) super @screenshot_counter = nil @screenshot_group = nil @screenshot_section = nil @test_screenshot_errors = nil @test_screenshots = [] end
Public Instance Methods
Asserts that an image has not changed compared to its baseline.
@param caller [Array] The caller context, used for error reporting. @param name [String] The name of the screenshot being verified. @param comparison [Object] The comparison object containing the result and details of the comparison. @return [String, nil] Returns an error message if the screenshot differs from the baseline, otherwise nil. @note This method is used internally to verify individual screenshots.
# File lib/capybara/screenshot/diff/test_methods.rb, line 154 def assert_image_not_changed(caller, name, comparison) result = comparison.different? # Cleanup after comparisons if !result && comparison.base_image_path.exist? FileUtils.mv(comparison.base_image_path, comparison.image_path, force: true) else FileUtils.rm_rf(comparison.base_image_path) end return unless result "Screenshot does not match for '#{name}' #{comparison.error_message}\n#{caller}" end
Builds the full name for a screenshot, incorporating counters and group names for uniqueness.
@param name [String] The base name for the screenshot. @return [String] The full, unique name for the screenshot.
# File lib/capybara/screenshot/diff/test_methods.rb, line 64 def build_full_name(name) if @screenshot_counter name = format("%02i_#{name}", @screenshot_counter) @screenshot_counter += 1 end File.join(*group_parts.push(name.to_s)) end
# File lib/capybara/screenshot/diff/test_methods.rb, line 104 def group_parts parts = [] parts << @screenshot_section if @screenshot_section.present? parts << @screenshot_group if @screenshot_group.present? parts end
Schedules a screenshot comparison job for later execution.
This method adds a job to the queue of screenshots to be matched. It’s used when ‘Capybara::Screenshot::Diff.delayed` is set to true, allowing for batch processing of screenshot comparisons at a later point, typically at the end of a test.
@param job [Array(Array(String), String, ImageCompare
)] The job to be scheduled, consisting of the caller context, screenshot name, and comparison object. @return [Boolean] Always returns true, indicating the job was successfully scheduled.
# File lib/capybara/screenshot/diff/test_methods.rb, line 99 def schedule_match_job(job) (@test_screenshots ||= []) << job true end
Takes a screenshot and optionally compares it against a baseline image.
@param name [String] The name of the screenshot, used to generate the filename. @param skip_stack_frames [Integer] The number of stack frames to skip when reporting errors, for cleaner error messages. @param options [Hash] Additional options for taking the screenshot, such as custom dimensions or selectors. @return [Boolean] Returns true if the screenshot was successfully captured and matches the baseline, false otherwise. @raise [CapybaraScreenshotDiff::ExpectationNotMet] If the screenshot does not match the baseline image and fail_if_new is set to true. @example Capture a full-page screenshot named ‘login_page’
screenshot('login_page', skip_stack_frames: 1, full: true)
# File lib/capybara/screenshot/diff/test_methods.rb, line 120 def screenshot(name, skip_stack_frames: 0, **options) return false unless Screenshot.active? screenshot_full_name = build_full_name(name) job = build_screenshot_matches_job(screenshot_full_name, options) unless job if Screenshot::Diff.fail_if_new raise_error(<<-ERROR.strip_heredoc, caller(2)) No existing screenshot found for #{screenshot_full_name}! To stop seeing this error disable by `Capybara::Screenshot::Diff.fail_if_new=false` ERROR end return false end job.prepend(caller(skip_stack_frames)) if Screenshot::Diff.delayed schedule_match_job(job) else error_msg = assert_image_not_changed(*job) raise_error(error_msg, caller(2)) if error_msg end end
Determines the directory path for saving screenshots.
@return [String] The full path to the directory where screenshots are saved.
# File lib/capybara/screenshot/diff/test_methods.rb, line 76 def screenshot_dir File.join(*([Screenshot.screenshot_area] + group_parts)) end
# File lib/capybara/screenshot/diff/test_methods.rb, line 84 def screenshot_group(name) @screenshot_group = name.to_s @screenshot_counter = @screenshot_group.present? ? 0 : nil return unless Screenshot.active? && name.present? FileUtils.rm_rf screenshot_dir end
# File lib/capybara/screenshot/diff/test_methods.rb, line 80 def screenshot_section(name) @screenshot_section = name.to_s end
Verifies that all scheduled screenshots do not show any unintended differences.
@param screenshots [Array(Array(Array(String), String, ImageCompare
))] The list of match screenshots jobs. Defaults to all screenshots taken during the test. @return [Array, nil] Returns an array of error messages if there are screenshot differences, otherwise nil. @note This method is typically called at the end of a test to assert all screenshots are as expected.
# File lib/capybara/screenshot/diff/test_methods.rb, line 46 def verify_screenshots!(screenshots = @test_screenshots) return unless ::Capybara::Screenshot.active? && ::Capybara::Screenshot::Diff.fail_on_difference test_screenshot_errors = screenshots.map do |caller, name, compare| assert_image_not_changed(caller, name, compare) end test_screenshot_errors.compact! test_screenshot_errors.presence ensure screenshots.clear end
Private Instance Methods
# File lib/capybara/screenshot/diff/test_methods.rb, line 175 def build_screenshot_matches_job(screenshot_full_name, options) ScreenshotMatcher .new(screenshot_full_name, options) .build_screenshot_matches_job end
# File lib/capybara/screenshot/diff/test_methods.rb, line 171 def raise_error(error_msg, backtrace) raise CapybaraScreenshotDiff::ExpectationNotMet.new(error_msg).tap { _1.set_backtrace(backtrace) } end