diff --git a/capybara-screenshot-diff.gemspec b/capybara-screenshot-diff.gemspec index ebf37ab9..0fc1eead 100644 --- a/capybara-screenshot-diff.gemspec +++ b/capybara-screenshot-diff.gemspec @@ -15,9 +15,10 @@ Gem::Specification.new do |spec| spec.required_ruby_version = ">= 3.2" spec.license = "MIT" spec.metadata["allowed_push_host"] = "https://rubygems.org/" - spec.files = `git ls-files -z`.split("\x0").reject do |f| - f.match(%r{(^(\.|tmp|bin|test|spec|features|gemfiles|scripts|foo)/)|(^(\.|Dockerfile|CONTRIBUTING|README))}) - end + # Allow-list: everything a consumer needs at runtime plus the shipped docs. + # Build/dev files (gems.rb, Rakefile, the gemspec itself, tests, CI) stay out. + spec.files = `git ls-files -z`.split("\x0") + .grep(%r{\A(lib/|docs/|README\.md\z|LICENSE\.txt\z|CHANGELOG\.md\z)}) spec.bindir = "exe" spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } diff --git a/lib/snap_diff/comparison_result.rb b/lib/snap_diff/comparison_result.rb index 8cb0fcff..b01010a9 100644 --- a/lib/snap_diff/comparison_result.rb +++ b/lib/snap_diff/comparison_result.rb @@ -67,8 +67,10 @@ def ratio meta[:difference_level] end + # Serializable difference metrics. The raw diff mask image is excluded — + # it is an image object, not a metric, and is reachable via #diff_mask. def to_h - {area_size: region_area_size, region: coordinates}.merge!(meta) + {area_size: region_area_size, region: coordinates}.merge!(meta.except(:diff_mask)) end def coordinates diff --git a/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_annotated_both.png b/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_annotated_both.png deleted file mode 100644 index 6b69e577..00000000 Binary files a/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_annotated_both.png and /dev/null differ diff --git a/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_base.png b/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_base.png deleted file mode 100644 index d81375a1..00000000 Binary files a/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_base.png and /dev/null differ diff --git a/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_both.png b/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_both.png deleted file mode 100644 index d6da51e0..00000000 Binary files a/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_both.png and /dev/null differ diff --git a/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_heatmap.png b/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_heatmap.png deleted file mode 100644 index e10e0af6..00000000 Binary files a/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_heatmap.png and /dev/null differ diff --git a/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_new.png b/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_new.png deleted file mode 100644 index 474a40f3..00000000 Binary files a/test/fixtures/app/doc/screenshots/macos/cuprite/html_report/report_new.png and /dev/null differ diff --git a/test/integration/report_screenshot_test.rb b/test/integration/report_screenshot_test.rb deleted file mode 100644 index b79ed8e1..00000000 --- a/test/integration/report_screenshot_test.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -require "system_test_case" - -class ReportScreenshotTest < SystemTestCase - PERCEPTUAL_THRESHOLD = 2.0 - - setup do - screenshot_section "html_report" - - @report_dir = Pathname.new("test/fixtures/app/report") - @report_path = @report_dir / "index.html" - skip "Run with RECORD_SCREENSHOTS=1 to update report fixtures" unless ENV["RECORD_SCREENSHOTS"] - generate_sample_report - visit "/report/index.html" - end - - teardown do - FileUtils.rm_rf(@report_dir) - end - - def test_report_both_view - screenshot "report_both", perceptual_threshold: PERCEPTUAL_THRESHOLD - end - - def test_report_base_view - find("[data-view='base']").click - screenshot "report_base", perceptual_threshold: PERCEPTUAL_THRESHOLD - end - - def test_report_new_view - find("[data-view='new']").click - screenshot "report_new", perceptual_threshold: PERCEPTUAL_THRESHOLD - end - - def test_report_heatmap_view - find("[data-view='heatmap']").click - screenshot "report_heatmap", perceptual_threshold: PERCEPTUAL_THRESHOLD - end - - def test_report_annotated_both - find("#annotate-toggle").click - screenshot "report_annotated_both", perceptual_threshold: PERCEPTUAL_THRESHOLD - end - - private - - def generate_sample_report - img_dir = @report_dir / "images" - img_dir.mkpath - - # Copy fixtures into served directory so browser can load them - fixtures = Pathname.new("test/fixtures/images") - %w[a.png b.png c.png].each { |f| FileUtils.cp(fixtures / f, img_dir / f) } - - # Run real comparisons inside the served directory - assertions = [ - build_assertion("islands-map", img_dir / "a.png", img_dir / "b.png"), - build_assertion("islands-variant", img_dir / "a.png", img_dir / "c.png") - ] - - reporter = SnapDiff::Reporters::HTML.new(output_path: @report_path) - reporter.record(assertions) - reporter.finalize - end - - def build_assertion(name, base_path, new_path) - # Copy to unique files so shared base images don't overwrite each other's annotations - unique_base = @report_dir / "images" / "#{name}_base.png" - unique_new = @report_dir / "images" / "#{name}_new.png" - FileUtils.cp(base_path, unique_base) - FileUtils.cp(new_path, unique_new) - - compare = SnapDiff::Comparison.new(unique_new, unique_base, driver: :vips) - compare.processed - SnapDiff::ScreenshotAssertion.new(name).tap { |a| a.compare = compare } - end -end diff --git a/test/unit/reporters/default_test.rb b/test/unit/reporters/default_test.rb index edd7199d..6dd55129 100644 --- a/test/unit/reporters/default_test.rb +++ b/test/unit/reporters/default_test.rb @@ -41,6 +41,22 @@ class Reporters::DefaultTest < ActiveSupport::TestCase assert_not reporter.heatmap_diff_path.exist?, "heatmap diff should be cleaned" end + test "failure message reports metrics without leaking image objects" do + driver = SnapDiff::Drivers::VipsDriver.new + comparison = build_comparison_for(driver, "a.png", "b.png") + difference = driver.find_difference_region(comparison) + difference.meta[:difference_level] = 0.42 + + message = SnapDiff::Reporters::Default.new(difference).generate + metrics = message.lines.first + + assert_includes metrics, "area_size" + assert_includes metrics, "region" + assert_includes metrics, "difference_level" + assert_not_includes metrics, "Vips::Image" + assert_not_includes metrics, "0x" + end + private def build_comparison_for(driver, *images)