Module: SnapDiff

Defined in:
lib/snap_diff.rb,
lib/snap_diff.rb,
lib/snap_diff/os.rb,
lib/snap_diff/dsl.rb,
lib/snap_diff/vcs.rb,
lib/snap_diff/snap.rb,
lib/snap_diff/utils.rb,
lib/snap_diff/config.rb,
lib/snap_diff/driver.rb,
lib/snap_diff/errors.rb,
lib/snap_diff/region.rb,
lib/snap_diff/static.rb,
lib/snap_diff/drivers.rb,
lib/snap_diff/removal.rb,
lib/snap_diff/version.rb,
lib/snap_diff/reporting.rb,
lib/snap_diff/comparison.rb,
lib/snap_diff/deprecation.rb,
lib/snap_diff/legacy_shims.rb,
lib/snap_diff/legacy_shims.rb,
lib/snap_diff/screenshoter.rb,
lib/snap_diff/snap_manager.rb,
lib/snap_diff/reporters/html.rb,
lib/snap_diff/area_calculator.rb,
lib/snap_diff/browser_helpers.rb,
lib/snap_diff/capture/viewport.rb,
lib/snap_diff/screenshot_namer.rb,
lib/snap_diff/attempts_reporter.rb,
lib/snap_diff/comparison_result.rb,
lib/snap_diff/reporters/default.rb,
lib/snap_diff/annotation_service.rb,
lib/snap_diff/image_preprocessor.rb,
lib/snap_diff/screenshot_matcher.rb,
lib/snap_diff/drivers/vips_driver.rb,
lib/snap_diff/stable_screenshoter.rb,
lib/snap_diff/screenshot_assertion.rb,
lib/snap_diff/integrations/minitest.rb,
lib/snap_diff/drivers/chunky_png_driver.rb,
lib/snap_diff/error_with_filtered_backtrace.rb

Overview

ADR-008 step 2: the gem's error classes live under SnapDiff. The old CapybaraScreenshotDiff names (capybara_screenshot_diff.rb) are EAGER same-object aliases of these classes -- deliberately not const_missing shims, because rescue clauses and defined?/const_defined? feature detection in adopter code must keep behaving exactly as before (const_defined? never triggers const_missing).

Error is the catch-all docs/snapdiff.md advertises: EVERY error this gem raises inherits it, so rescue SnapDiff::Error really does catch them all (pinned by test/unit/errors_alias_test.rb, which discovers the classes rather than listing them). ErrorWithFilteredBacktrace is plumbing, not a second root.

Defined Under Namespace

Modules: BrowserHelpers, Capture, DSL, Deprecation, Driver, Drivers, LegacyShims, Minitest, Os, Removal, Reporters, Reporting, Utils, Vcs Classes: AnnotationService, AreaCalculator, AssertionRegistry, AttemptsReporter, BacktraceFilter, Comparison, ComparisonResult, Config, Error, ErrorWithFilteredBacktrace, ExpectationNotMet, ImagePreprocessor, Region, ScreenshotAssertion, ScreenshotMatcher, ScreenshotNamer, Screenshoter, Snap, SnapManager, StableScreenshoter, UnstableImage, WindowSizeMismatchError

Constant Summary collapse

DualInstallError =
Class.new(Error)
VERSION =
"2.0.0.beta4"
RED_RGBA =

Annotation colors, defined here (not in the capybara_screenshot_diff umbrella) so they resolve in processes that only require "snap_diff".

[255, 0, 0, 255].freeze
ORANGE_RGBA =
[255, 192, 0, 255].freeze

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.silence_deprecationsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



142
143
144
# File 'lib/snap_diff/removal.rb', line 142

def silence_deprecations
  @silence_deprecations
end

Class Method Details

.assert_single_gem!(loaded_specs = Gem.loaded_specs) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Raises:



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

def self.assert_single_gem!(loaded_specs = Gem.loaded_specs)
  return unless loaded_specs.key?("capybara-screenshot-diff") && loaded_specs.key?("snap_diff-capybara")

  raise DualInstallError,
    "Both `capybara-screenshot-diff` and `snap_diff-capybara` gems are installed. " \
    "They ship identical files, so files load from whichever gem activated first " \
    "and versions can silently diverge. Remove one of them from your Gemfile."
end

.compare(baseline_path, current_path, **options) ⇒ Object

Compare two images on disk with the configured defaults. Canonical home; Capybara::Screenshot::Diff.compare forwards here.

Note the argument order swap: callers pass baseline first (reading "compare baseline against current"), Comparison takes current first.



67
68
69
70
71
72
73
# File 'lib/snap_diff.rb', line 67

def self.compare(baseline_path, current_path, **options)
  # BEFORE the merge, which is the last moment `driver:` still means "the
  # caller asked for a backend" rather than "config.default_options
  # carries the key for everyone".
  Removal.warn_once(:driver_setting, Removal::DRIVER_REMOVED) if options.key?(:driver)
  Comparison.new(current_path, baseline_path, config.default_options.merge(options))
end

.configObject

The single consolidated settings object -- and the single storage. See Config.



293
294
295
# File 'lib/snap_diff/config.rb', line 293

def self.config
  @config
end

.configure {|config| ... } ⇒ Object

Forward-looking configuration: yields the single consolidated Config object instead of the two old holders. Same underlying storage as start / the old mattr_accessors -- this is a different shape of the same settings, not a second source of truth.

SnapDiff.configure do |config|
config.window_size = [1280, 1024]
config.tolerance = 0.0005
end

Yields:



88
89
90
# File 'lib/snap_diff.rb', line 88

def self.configure
  yield config
end

.pending_screenshots_messageString?

Message to skip the test with when a new screenshot has no baseline yet and pending_if_new is enabled. Adapters call this after verifying screenshots, and skip the test with the returned message when present.

Returns:

  • (String, nil)

    the pending message, or nil when there is nothing to report



35
36
37
38
39
# File 'lib/snap_diff/screenshot_assertion.rb', line 35

def self.pending_screenshots_message
  return unless SnapDiff.config.pending_if_new && session.new_screenshots_present?

  "No baseline for: #{session.new_screenshots.join(", ")}. Commit the captured screenshots to record them."
end

.resetObject

Ends a test: hands the finished session's assertions to the reporters, then clears it. The one deliberate bridge between the process-global reporter lifecycle (SnapDiff::Reporting) and the per-test session.



25
26
27
28
# File 'lib/snap_diff/screenshot_assertion.rb', line 25

def self.reset
  Reporting.notify(session.assertions)
  session.reset
end

.serve(directory, root: Dir.pwd) ⇒ Object



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

def self.serve(directory, root: Dir.pwd)
  Capybara.app = Rack::Files.new(directory)
  SnapDiff.config.root = root
end

.sessionObject

--- Session lifecycle (per-test) ---

The canonical home of the per-test session: the AssertionRegistry holding the assertions and new-screenshot names of the test running here. CapybaraScreenshotDiff.registry / .reset / .pending_screenshots_message are thin forwarders over these.

Note: Thread.current is fiber-local, so a session is per fiber, not per thread. That is pre-existing, documented behaviour (issue #217); ADR-008 step 6 relocates the accessor without touching the semantics.



18
19
20
# File 'lib/snap_diff/screenshot_assertion.rb', line 18

def self.session
  Thread.current[:capybara_screenshot_diff_registry] ||= AssertionRegistry.new
end

.silence_deprecations?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns true if deprecation warnings should be suppressed, either via the silence_deprecations accessor or the SNAP_DIFF_SILENCE_DEPRECATIONS env var (truthy = "1"/"true").

Returns:

  • (Boolean)

    true if deprecation warnings should be suppressed, either via the silence_deprecations accessor or the SNAP_DIFF_SILENCE_DEPRECATIONS env var (truthy = "1"/"true").



149
150
151
# File 'lib/snap_diff/removal.rb', line 149

def silence_deprecations?
  !!silence_deprecations || truthy_env?(ENV["SNAP_DIFF_SILENCE_DEPRECATIONS"])
end

.start {|Capybara::Screenshot, Capybara::Screenshot::Diff| ... } ⇒ Object

v1-style configuration: yields the two legacy accessor holders (+Capybara::Screenshot+, Capybara::Screenshot::Diff) exactly as Capybara::Screenshot::Diff.configure always has -- and, since ADR-008 step 7b, this is where that yield actually happens; Diff.configure forwards here. Both names stay identical in call shape.

SnapDiff.start do |screenshot, diff|
screenshot.window_size = [1280, 1024]
diff.tolerance = 0.0005
end

Defined in this file, not snap_diff.rb, because the two holders it yields ARE the v1 surface: it cannot outlive them. The consolidated shape, SnapDiff.configure, is the canonical one and lives in the core.



241
242
243
# File 'lib/snap_diff/legacy_shims.rb', line 241

def self.start
  yield Capybara::Screenshot, Capybara::Screenshot::Diff
end