capybara-screenshot-diff 1.6.3 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/lint.yml +1 -1
- data/.github/workflows/test.yml +36 -18
- data/.gitignore +2 -0
- data/CONTRIBUTING.md +3 -1
- data/Dockerfile +2 -3
- data/README.md +39 -27
- data/bin/install-vips +1 -1
- data/capybara-screenshot-diff.gemspec +2 -2
- data/lib/capybara/screenshot/diff/browser_helpers.rb +101 -0
- data/lib/capybara/screenshot/diff/drivers/chunky_png_driver.rb +30 -17
- data/lib/capybara/screenshot/diff/drivers/vips_driver.rb +26 -17
- data/lib/capybara/screenshot/diff/image_compare.rb +85 -72
- data/lib/capybara/screenshot/diff/region.rb +86 -0
- data/lib/capybara/screenshot/diff/stabilization.rb +14 -38
- data/lib/capybara/screenshot/diff/test_methods.rb +68 -35
- data/lib/capybara/screenshot/diff/vcs.rb +6 -5
- data/lib/capybara/screenshot/diff/version.rb +1 -1
- metadata +8 -6
- data/gemfiles/rails52.gemfile +0 -6
@@ -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
|
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,
|
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
|
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
|
-
|
77
|
+
create_output_directory_for(file_name)
|
78
|
+
|
88
79
|
comparison = ImageCompare.new(file_name, nil, driver_options)
|
89
|
-
checkout_vcs(name, comparison)
|
90
|
-
|
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
|
-
|
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
|
-
|
106
|
-
end
|
90
|
+
(@test_screenshots ||= []) << [caller[skip_stack_frames], name, comparison]
|
107
91
|
|
108
|
-
|
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,
|
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,
|
26
|
+
FileUtils.cp committed_file_name, old_file_name
|
26
27
|
else
|
27
|
-
svn_info = `svn info #{
|
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,
|
34
|
+
FileUtils.cp committed_file_name, old_file_name
|
34
35
|
end
|
35
36
|
else
|
36
|
-
restore_git_revision(name,
|
37
|
+
restore_git_revision(name, old_file_name)
|
37
38
|
end
|
38
39
|
end
|
39
40
|
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.
|
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-
|
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: '
|
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: '
|
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.
|
123
|
+
version: 2.7.0
|
122
124
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
125
|
requirements:
|
124
126
|
- - ">="
|