capybara-screenshot-diff 1.6.3 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,8 @@ require "active_support/core_ext/string/strip"
8
8
  require_relative "image_compare"
9
9
  require_relative "stabilization"
10
10
  require_relative "vcs"
11
+ require_relative "browser_helpers"
12
+ require_relative "region"
11
13
 
12
14
  # Add the `screenshot` method to ActionDispatch::IntegrationTest
13
15
  module Capybara
@@ -16,6 +18,7 @@ module Capybara
16
18
  module TestMethods
17
19
  include Stabilization
18
20
  include Vcs
21
+ include BrowserHelpers
19
22
 
20
23
  def initialize(*)
21
24
  super
@@ -34,21 +37,13 @@ module Capybara
34
37
  end
35
38
 
36
39
  def full_name(name)
37
- File.join group_parts.<<(name).map(&:to_s)
40
+ File.join group_parts.push(name).map(&:to_s)
38
41
  end
39
42
 
40
43
  def screenshot_dir
41
44
  File.join [Screenshot.screenshot_area] + group_parts
42
45
  end
43
46
 
44
- def current_capybara_driver_class
45
- Capybara.current_session.driver.class
46
- end
47
-
48
- def selenium?
49
- current_capybara_driver_class <= Capybara::Selenium::Driver
50
- end
51
-
52
47
  def screenshot_section(name)
53
48
  @screenshot_section = name.to_s
54
49
  end
@@ -62,7 +57,7 @@ module Capybara
62
57
  end
63
58
 
64
59
  # @return [Boolean] whether a screenshot was taken
65
- def screenshot(name, options = {})
60
+ def screenshot(name, skip_stack_frames: 0, **options)
66
61
  return false unless Screenshot.active?
67
62
  return false if window_size_is_wrong?
68
63
 
@@ -70,12 +65,7 @@ module Capybara
70
65
 
71
66
  stability_time_limit = driver_options[:stability_time_limit]
72
67
  wait = driver_options[:wait]
73
- crop = driver_options.delete(:crop)
74
-
75
- # Allow nil or single or multiple areas
76
- if driver_options[:skip_area]
77
- driver_options[:skip_area] = driver_options[:skip_area].compact.flatten&.each_slice(4)&.to_a
78
- end
68
+ crop = calculate_crop_region(driver_options)
79
69
 
80
70
  if @screenshot_counter
81
71
  name = "#{format("%02i", @screenshot_counter)}_#{name}"
@@ -84,31 +74,22 @@ module Capybara
84
74
  name = full_name(name)
85
75
  file_name = "#{Screenshot.screenshot_area_abs}/#{name}.png"
86
76
 
87
- FileUtils.mkdir_p File.dirname(file_name)
77
+ create_output_directory_for(file_name)
78
+
88
79
  comparison = ImageCompare.new(file_name, nil, driver_options)
89
- checkout_vcs(name, comparison)
90
- begin
91
- blurred_input = prepare_page_for_screenshot(timeout: wait)
92
- if stability_time_limit
93
- take_stable_screenshot(comparison, stability_time_limit: stability_time_limit, wait: wait, crop: crop)
94
- else
95
- take_right_size_screenshot(comparison, crop: crop)
96
- end
97
- ensure
98
- blurred_input&.click
99
- end
80
+ checkout_vcs(name, comparison.old_file_name, comparison.new_file_name)
81
+ take_screenshot(comparison, crop, stability_time_limit, wait)
100
82
 
101
83
  return false unless comparison.old_file_exists?
102
84
 
103
- (@test_screenshots ||= []) << [caller(1..1).first, name, comparison]
85
+ # Allow nil or single or multiple areas
86
+ if driver_options[:skip_area]
87
+ comparison.skip_area = calculate_skip_area(driver_options[:skip_area], crop)
88
+ end
104
89
 
105
- true
106
- end
90
+ (@test_screenshots ||= []) << [caller[skip_stack_frames], name, comparison]
107
91
 
108
- def window_size_is_wrong?
109
- selenium? && Screenshot.window_size &&
110
- page.driver.browser.manage.window.size !=
111
- ::Selenium::WebDriver::Dimension.new(*Screenshot.window_size)
92
+ true
112
93
  end
113
94
 
114
95
  def assert_image_not_changed(caller, name, comparison)
@@ -116,6 +97,58 @@ module Capybara
116
97
 
117
98
  "Screenshot does not match for '#{name}' #{comparison.error_message}\nat #{caller}"
118
99
  end
100
+
101
+ private
102
+
103
+ def calculate_crop_region(driver_options)
104
+ crop_coordinates = driver_options.delete(:crop)
105
+ return nil unless crop_coordinates
106
+
107
+ crop_coordinates = bounds_for_css(crop_coordinates).first if crop_coordinates.is_a?(String)
108
+ Region.from_edge_coordinates(*crop_coordinates)
109
+ end
110
+
111
+ def create_output_directory_for(file_name)
112
+ FileUtils.mkdir_p File.dirname(file_name)
113
+ end
114
+
115
+ def take_screenshot(comparison, crop, stability_time_limit, wait)
116
+ blurred_input = prepare_page_for_screenshot(timeout: wait)
117
+ if stability_time_limit
118
+ take_stable_screenshot(
119
+ comparison,
120
+ crop: crop,
121
+ stability_time_limit: stability_time_limit,
122
+ wait: wait
123
+ )
124
+ else
125
+ take_right_size_screenshot(comparison, crop: crop)
126
+ end
127
+ ensure
128
+ blurred_input&.click
129
+ end
130
+
131
+ def calculate_skip_area(skip_area, crop)
132
+ crop_region = crop && Region.new(*crop)
133
+ skip_area = Array(skip_area)
134
+
135
+ css_selectors, regions = skip_area.compact.partition { |region| region.is_a? String }
136
+
137
+ result = []
138
+ result.concat(build_regions_for(bounds_for_css(*css_selectors))) unless css_selectors.empty?
139
+ result.concat(build_regions_for(regions.flatten&.each_slice(4))) unless regions.empty?
140
+ result.compact!
141
+
142
+ result.map! { |region| crop_region.find_relative_intersect(region) } if crop_region
143
+
144
+ result
145
+ end
146
+
147
+ def build_regions_for(coordinates)
148
+ coordinates.map do |region_coordinates|
149
+ Region.from_edge_coordinates(*region_coordinates)
150
+ end
151
+ end
119
152
  end
120
153
  end
121
154
  end
@@ -18,22 +18,23 @@ module Capybara
18
18
  FileUtils.rm_f(target_file_name) unless $CHILD_STATUS == 0
19
19
  end
20
20
 
21
- def checkout_vcs(name, comparison)
21
+ def checkout_vcs(name, old_file_name, new_file_name)
22
22
  svn_file_name = "#{Capybara::Screenshot.screenshot_area_abs}/.svn/text-base/#{name}.png.svn-base"
23
+
23
24
  if File.exist?(svn_file_name)
24
25
  committed_file_name = svn_file_name
25
- FileUtils.cp committed_file_name, comparison.old_file_name
26
+ FileUtils.cp committed_file_name, old_file_name
26
27
  else
27
- svn_info = `svn info #{comparison.new_file_name} #{SILENCE_ERRORS}`
28
+ svn_info = `svn info #{new_file_name} #{SILENCE_ERRORS}`
28
29
  if svn_info.present?
29
30
  wc_root = svn_info.slice(/(?<=Working Copy Root Path: ).*$/)
30
31
  checksum = svn_info.slice(/(?<=Checksum: ).*$/)
31
32
  if checksum
32
33
  committed_file_name = "#{wc_root}/.svn/pristine/#{checksum[0..1]}/#{checksum}.svn-base"
33
- FileUtils.cp committed_file_name, comparison.old_file_name
34
+ FileUtils.cp committed_file_name, old_file_name
34
35
  end
35
36
  else
36
- restore_git_revision(name, comparison.old_file_name)
37
+ restore_git_revision(name, old_file_name)
37
38
  end
38
39
  end
39
40
  end
@@ -3,7 +3,7 @@
3
3
  module Capybara
4
4
  module Screenshot
5
5
  module Diff
6
- VERSION = "1.6.3"
6
+ VERSION = "1.7.0"
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara-screenshot-diff
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.3
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uwe Kubosch
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-21 00:00:00.000000000 Z
11
+ date: 2022-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '6.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '8'
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '4.2'
29
+ version: '6.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '8'
@@ -72,6 +72,7 @@ extensions: []
72
72
  extra_rdoc_files: []
73
73
  files:
74
74
  - ".gitattributes"
75
+ - ".github/dependabot.yml"
75
76
  - ".github/workflows/lint.yml"
76
77
  - ".github/workflows/test.yml"
77
78
  - ".gitignore"
@@ -88,18 +89,19 @@ files:
88
89
  - bin/setup
89
90
  - bin/standardrb
90
91
  - capybara-screenshot-diff.gemspec
91
- - gemfiles/rails52.gemfile
92
92
  - gemfiles/rails60_gems.rb
93
93
  - gemfiles/rails61_gems.rb
94
94
  - gemfiles/rails70_gems.rb
95
95
  - gems.rb
96
96
  - lib/capybara-screenshot-diff.rb
97
97
  - lib/capybara/screenshot/diff.rb
98
+ - lib/capybara/screenshot/diff/browser_helpers.rb
98
99
  - lib/capybara/screenshot/diff/drivers/chunky_png_driver.rb
99
100
  - lib/capybara/screenshot/diff/drivers/utils.rb
100
101
  - lib/capybara/screenshot/diff/drivers/vips_driver.rb
101
102
  - lib/capybara/screenshot/diff/image_compare.rb
102
103
  - lib/capybara/screenshot/diff/os.rb
104
+ - lib/capybara/screenshot/diff/region.rb
103
105
  - lib/capybara/screenshot/diff/stabilization.rb
104
106
  - lib/capybara/screenshot/diff/test_methods.rb
105
107
  - lib/capybara/screenshot/diff/vcs.rb
@@ -118,7 +120,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
118
120
  requirements:
119
121
  - - ">="
120
122
  - !ruby/object:Gem::Version
121
- version: 2.5.0
123
+ version: 2.7.0
122
124
  required_rubygems_version: !ruby/object:Gem::Requirement
123
125
  requirements:
124
126
  - - ">="
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- gems = "#{File.dirname __dir__}/gems.rb"
4
- eval File.read(gems), binding, gems
5
-
6
- gem "actionpack", "~>5.2.1"