capybara-screenshot-diff 1.7.1 → 1.8.1
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.
- checksums.yaml +4 -4
- data/Rakefile +29 -0
- data/capybara-screenshot-diff.gemspec +6 -3
- data/gems.rb +8 -2
- data/lib/capybara/screenshot/diff/browser_helpers.rb +29 -28
- data/lib/capybara/screenshot/diff/cucumber.rb +11 -0
- data/lib/capybara/screenshot/diff/difference.rb +63 -0
- data/lib/capybara/screenshot/diff/drivers/base_driver.rb +42 -0
- data/lib/capybara/screenshot/diff/drivers/chunky_png_driver.rb +188 -260
- data/lib/capybara/screenshot/diff/drivers/utils.rb +18 -0
- data/lib/capybara/screenshot/diff/drivers/vips_driver.rb +54 -104
- data/lib/capybara/screenshot/diff/drivers.rb +16 -0
- data/lib/capybara/screenshot/diff/image_compare.rb +125 -154
- data/lib/capybara/screenshot/diff/os.rb +1 -1
- data/lib/capybara/screenshot/diff/screenshot_matcher.rb +128 -0
- data/lib/capybara/screenshot/diff/screenshoter.rb +136 -0
- data/lib/capybara/screenshot/diff/stabilization.rb +0 -184
- data/lib/capybara/screenshot/diff/stable_screenshoter.rb +106 -0
- data/lib/capybara/screenshot/diff/test_methods.rb +51 -90
- data/lib/capybara/screenshot/diff/vcs.rb +44 -22
- data/lib/capybara/screenshot/diff/version.rb +1 -1
- data/lib/capybara/screenshot/diff.rb +13 -17
- data/sig/capybara/screenshot/diff/diff.rbs +28 -0
- data/sig/capybara/screenshot/diff/difference.rbs +33 -0
- data/sig/capybara/screenshot/diff/drivers/base_driver.rbs +63 -0
- data/sig/capybara/screenshot/diff/drivers/browser_helpers.rbs +36 -0
- data/sig/capybara/screenshot/diff/drivers/chunky_png_driver.rbs +89 -0
- data/sig/capybara/screenshot/diff/drivers/utils.rbs +13 -0
- data/sig/capybara/screenshot/diff/drivers/vips_driver.rbs +25 -0
- data/sig/capybara/screenshot/diff/image_compare.rbs +93 -0
- data/sig/capybara/screenshot/diff/os.rbs +11 -0
- data/sig/capybara/screenshot/diff/region.rbs +43 -0
- data/sig/capybara/screenshot/diff/screenshot_matcher.rbs +60 -0
- data/sig/capybara/screenshot/diff/screenshoter.rbs +48 -0
- data/sig/capybara/screenshot/diff/stable_screenshoter.rbs +29 -0
- data/sig/capybara/screenshot/diff/test_methods.rbs +39 -0
- data/sig/capybara/screenshot/diff/vcs.rbs +17 -0
- metadata +28 -25
- data/.gitattributes +0 -4
- data/.github/dependabot.yml +0 -8
- data/.github/workflows/lint.yml +0 -25
- data/.github/workflows/test.yml +0 -138
- data/.gitignore +0 -14
- data/.standard.yml +0 -12
- data/CONTRIBUTING.md +0 -24
- data/Dockerfile +0 -59
- data/README.md +0 -567
- data/bin/bundle +0 -114
- data/bin/console +0 -15
- data/bin/install-vips +0 -11
- data/bin/rake +0 -27
- data/bin/setup +0 -8
- data/bin/standardrb +0 -29
- data/gemfiles/rails60_gems.rb +0 -8
- data/gemfiles/rails61_gems.rb +0 -7
- data/gemfiles/rails70_gems.rb +0 -7
- data/tmp/.keep +0 -0
@@ -5,43 +5,41 @@ require "capybara"
|
|
5
5
|
require "action_controller"
|
6
6
|
require "action_dispatch"
|
7
7
|
require "active_support/core_ext/string/strip"
|
8
|
+
require "pathname"
|
9
|
+
|
10
|
+
require_relative "drivers"
|
8
11
|
require_relative "image_compare"
|
9
|
-
require_relative "stabilization"
|
10
12
|
require_relative "vcs"
|
11
13
|
require_relative "browser_helpers"
|
12
14
|
require_relative "region"
|
13
15
|
|
16
|
+
require_relative "screenshot_matcher"
|
17
|
+
|
14
18
|
# Add the `screenshot` method to ActionDispatch::IntegrationTest
|
15
19
|
module Capybara
|
16
20
|
module Screenshot
|
17
21
|
module Diff
|
18
22
|
module TestMethods
|
19
|
-
include Stabilization
|
20
|
-
include Vcs
|
21
|
-
include BrowserHelpers
|
22
|
-
|
23
23
|
def initialize(*)
|
24
24
|
super
|
25
25
|
@screenshot_counter = nil
|
26
26
|
@screenshot_group = nil
|
27
27
|
@screenshot_section = nil
|
28
28
|
@test_screenshot_errors = nil
|
29
|
-
@test_screenshots =
|
29
|
+
@test_screenshots = []
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
32
|
+
def build_full_name(name)
|
33
|
+
if @screenshot_counter
|
34
|
+
name = format("%02i_#{name}", @screenshot_counter)
|
35
|
+
@screenshot_counter += 1
|
36
|
+
end
|
38
37
|
|
39
|
-
|
40
|
-
File.join group_parts.push(name).map(&:to_s)
|
38
|
+
File.join(*group_parts.push(name.to_s))
|
41
39
|
end
|
42
40
|
|
43
41
|
def screenshot_dir
|
44
|
-
File.join
|
42
|
+
File.join(*([Screenshot.screenshot_area] + group_parts))
|
45
43
|
end
|
46
44
|
|
47
45
|
def screenshot_section(name)
|
@@ -50,104 +48,67 @@ module Capybara
|
|
50
48
|
|
51
49
|
def screenshot_group(name)
|
52
50
|
@screenshot_group = name.to_s
|
53
|
-
@screenshot_counter = 0
|
51
|
+
@screenshot_counter = @screenshot_group.present? ? 0 : nil
|
54
52
|
return unless Screenshot.active? && name.present?
|
55
53
|
|
56
54
|
FileUtils.rm_rf screenshot_dir
|
57
55
|
end
|
58
56
|
|
59
|
-
|
60
|
-
|
61
|
-
return false unless Screenshot.active?
|
62
|
-
return false if window_size_is_wrong?
|
63
|
-
|
64
|
-
driver_options = Diff.default_options.merge(options)
|
65
|
-
|
66
|
-
stability_time_limit = driver_options[:stability_time_limit]
|
67
|
-
wait = driver_options[:wait]
|
68
|
-
crop = calculate_crop_region(driver_options)
|
69
|
-
|
70
|
-
if @screenshot_counter
|
71
|
-
name = "#{format("%02i", @screenshot_counter)}_#{name}"
|
72
|
-
@screenshot_counter += 1
|
73
|
-
end
|
74
|
-
name = full_name(name)
|
75
|
-
file_name = "#{Screenshot.screenshot_area_abs}/#{name}.png"
|
76
|
-
|
77
|
-
create_output_directory_for(file_name)
|
78
|
-
|
79
|
-
comparison = ImageCompare.new(file_name, nil, driver_options)
|
80
|
-
checkout_vcs(name, comparison.old_file_name, comparison.new_file_name)
|
81
|
-
take_comparison_screenshot(comparison, crop, stability_time_limit, wait)
|
82
|
-
|
83
|
-
return false unless comparison.old_file_exists?
|
84
|
-
|
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
|
89
|
-
|
90
|
-
(@test_screenshots ||= []) << [caller[skip_stack_frames], name, comparison]
|
91
|
-
|
57
|
+
def schedule_match_job(job)
|
58
|
+
(@test_screenshots ||= []) << job
|
92
59
|
true
|
93
60
|
end
|
94
61
|
|
95
|
-
def
|
96
|
-
|
97
|
-
|
98
|
-
|
62
|
+
def group_parts
|
63
|
+
parts = []
|
64
|
+
parts << @screenshot_section if @screenshot_section.present?
|
65
|
+
parts << @screenshot_group if @screenshot_group.present?
|
66
|
+
parts
|
99
67
|
end
|
100
68
|
|
101
|
-
|
69
|
+
def screenshot(name, skip_stack_frames: 0, **options)
|
70
|
+
return false unless Screenshot.active?
|
102
71
|
|
103
|
-
|
104
|
-
|
105
|
-
return nil unless crop_coordinates
|
72
|
+
screenshot_full_name = build_full_name(name)
|
73
|
+
job = build_screenshot_matches_job(screenshot_full_name, options)
|
106
74
|
|
107
|
-
|
108
|
-
Region.from_edge_coordinates(*crop_coordinates)
|
109
|
-
end
|
75
|
+
return false unless job
|
110
76
|
|
111
|
-
|
112
|
-
FileUtils.mkdir_p File.dirname(file_name)
|
113
|
-
end
|
77
|
+
test_caller = caller(skip_stack_frames)
|
114
78
|
|
115
|
-
|
116
|
-
|
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
|
-
)
|
79
|
+
if Screenshot::Diff.delayed
|
80
|
+
schedule_match_job([test_caller] + job)
|
124
81
|
else
|
125
|
-
|
82
|
+
error_msg = assert_image_not_changed(job.first, job.last)
|
83
|
+
if error_msg
|
84
|
+
error = ASSERTION.new(error_msg)
|
85
|
+
error.set_backtrace(caller(2))
|
86
|
+
raise error
|
87
|
+
end
|
126
88
|
end
|
127
|
-
ensure
|
128
|
-
blurred_input&.click
|
129
89
|
end
|
130
90
|
|
131
|
-
def
|
132
|
-
|
133
|
-
skip_area = Array(skip_area)
|
134
|
-
|
135
|
-
css_selectors, regions = skip_area.compact.partition { |region| region.is_a? String }
|
91
|
+
def assert_image_not_changed(name, comparison)
|
92
|
+
result = comparison.different?
|
136
93
|
|
137
|
-
|
138
|
-
result
|
139
|
-
|
140
|
-
|
94
|
+
# Cleanup after comparisons
|
95
|
+
if !result && comparison.base_image_path.exist?
|
96
|
+
FileUtils.mv(comparison.base_image_path, comparison.image_path, force: true)
|
97
|
+
else
|
98
|
+
FileUtils.rm_rf(comparison.base_image_path)
|
99
|
+
end
|
141
100
|
|
142
|
-
|
101
|
+
return unless result
|
143
102
|
|
144
|
-
|
103
|
+
"Screenshot does not match for '#{name}' #{comparison.error_message}"
|
145
104
|
end
|
146
105
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
106
|
+
private
|
107
|
+
|
108
|
+
def build_screenshot_matches_job(screenshot_full_name, options)
|
109
|
+
ScreenshotMatcher
|
110
|
+
.new(screenshot_full_name, options)
|
111
|
+
.build_screenshot_matches_job
|
151
112
|
end
|
152
113
|
end
|
153
114
|
end
|
@@ -1,42 +1,64 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "os"
|
4
|
+
|
4
5
|
module Capybara
|
5
6
|
module Screenshot
|
6
7
|
module Diff
|
7
8
|
module Vcs
|
8
9
|
SILENCE_ERRORS = Os::ON_WINDOWS ? "2>nul" : "2>/dev/null"
|
9
10
|
|
10
|
-
def restore_git_revision(
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
def self.restore_git_revision(screenshot_path, checkout_path)
|
12
|
+
vcs_file_path = screenshot_path.relative_path_from(Screenshot.root)
|
13
|
+
|
14
|
+
redirect_target = "#{checkout_path} #{SILENCE_ERRORS}"
|
15
|
+
show_command = "git show HEAD~0:./#{vcs_file_path}"
|
16
|
+
if Screenshot.use_lfs
|
17
|
+
`#{show_command} | git lfs smudge > #{redirect_target} ; exit ${PIPESTATUS[0]}`
|
15
18
|
else
|
16
19
|
`#{show_command} > #{redirect_target}`
|
17
20
|
end
|
18
|
-
FileUtils.rm_f(target_file_name) unless $CHILD_STATUS == 0
|
19
|
-
end
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
if $CHILD_STATUS != 0
|
23
|
+
FileUtils.rm_f(checkout_path)
|
24
|
+
false
|
25
|
+
else
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
23
29
|
|
24
|
-
|
25
|
-
|
26
|
-
|
30
|
+
def self.checkout_vcs(screenshot_path, checkout_path)
|
31
|
+
if svn?
|
32
|
+
restore_svn_revision(screenshot_path, checkout_path)
|
27
33
|
else
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
restore_git_revision(screenshot_path, checkout_path)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.restore_svn_revision(screenshot_path, checkout_path)
|
39
|
+
committed_file_name = screenshot_path + "../.svn/text-base/" + "#{screenshot_path.basename}.svn-base"
|
40
|
+
if committed_file_name.exist?
|
41
|
+
FileUtils.cp(committed_file_name, checkout_path)
|
42
|
+
return true
|
43
|
+
end
|
44
|
+
|
45
|
+
svn_info = `svn info #{screenshot_path} #{SILENCE_ERRORS}`
|
46
|
+
if svn_info.present?
|
47
|
+
wc_root = svn_info.slice(/(?<=Working Copy Root Path: ).*$/)
|
48
|
+
checksum = svn_info.slice(/(?<=Checksum: ).*$/)
|
49
|
+
|
50
|
+
if checksum
|
51
|
+
committed_file_name = "#{wc_root}/.svn/pristine/#{checksum[0..1]}/#{checksum}.svn-base"
|
52
|
+
FileUtils.cp(committed_file_name, checkout_path)
|
53
|
+
return true
|
38
54
|
end
|
39
55
|
end
|
56
|
+
|
57
|
+
false
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.svn?
|
61
|
+
(Screenshot.screenshot_area_abs / ".svn").exist?
|
40
62
|
end
|
41
63
|
end
|
42
64
|
end
|
@@ -5,10 +5,10 @@ require "capybara/screenshot/diff/version"
|
|
5
5
|
require "capybara/screenshot/diff/drivers/utils"
|
6
6
|
require "capybara/screenshot/diff/image_compare"
|
7
7
|
require "capybara/screenshot/diff/test_methods"
|
8
|
+
require "capybara/screenshot/diff/screenshoter"
|
8
9
|
|
9
10
|
module Capybara
|
10
11
|
module Screenshot
|
11
|
-
extend Os
|
12
12
|
mattr_accessor :add_driver_path
|
13
13
|
mattr_accessor :add_os_path
|
14
14
|
mattr_accessor :blur_active_element
|
@@ -30,10 +30,10 @@ module Capybara
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def screenshot_area
|
33
|
-
parts = [
|
34
|
-
parts << Capybara.current_driver.to_s if
|
35
|
-
parts <<
|
36
|
-
File.join
|
33
|
+
parts = [Screenshot.save_path]
|
34
|
+
parts << Capybara.current_driver.to_s if Screenshot.add_driver_path
|
35
|
+
parts << Os.name if Screenshot.add_os_path
|
36
|
+
File.join(*parts)
|
37
37
|
end
|
38
38
|
|
39
39
|
def screenshot_area_abs
|
@@ -44,8 +44,8 @@ module Capybara
|
|
44
44
|
# Module to track screen shot changes
|
45
45
|
module Diff
|
46
46
|
include Capybara::DSL
|
47
|
-
include Capybara::Screenshot::Os
|
48
47
|
|
48
|
+
mattr_accessor(:delayed) { true }
|
49
49
|
mattr_accessor :area_size_limit
|
50
50
|
mattr_accessor :color_distance_limit
|
51
51
|
mattr_accessor(:enabled) { true }
|
@@ -54,6 +54,8 @@ module Capybara
|
|
54
54
|
mattr_accessor(:driver) { :auto }
|
55
55
|
mattr_accessor :tolerance
|
56
56
|
|
57
|
+
mattr_accessor(:screenshoter) { Screenshoter }
|
58
|
+
|
57
59
|
AVAILABLE_DRIVERS = Utils.detect_available_drivers.freeze
|
58
60
|
ASSERTION = Utils.detect_test_framework_assert
|
59
61
|
|
@@ -65,7 +67,7 @@ module Capybara
|
|
65
67
|
shift_distance_limit: shift_distance_limit,
|
66
68
|
skip_area: skip_area,
|
67
69
|
stability_time_limit: Screenshot.stability_time_limit,
|
68
|
-
tolerance: tolerance || (driver == :vips ? 0.001 : nil),
|
70
|
+
tolerance: tolerance || ((driver == :vips) ? 0.001 : nil),
|
69
71
|
wait: Capybara.default_max_wait_time
|
70
72
|
}
|
71
73
|
end
|
@@ -73,19 +75,13 @@ module Capybara
|
|
73
75
|
def self.included(klass)
|
74
76
|
klass.include TestMethods
|
75
77
|
klass.setup do
|
76
|
-
if
|
77
|
-
if page.driver.respond_to?(:resize)
|
78
|
-
page.driver.resize(*Capybara::Screenshot.window_size)
|
79
|
-
elsif selenium?
|
80
|
-
page.driver.browser.manage.window.resize_to(*Capybara::Screenshot.window_size)
|
81
|
-
end
|
82
|
-
end
|
78
|
+
BrowserHelpers.resize_to(Screenshot.window_size) if Screenshot.window_size
|
83
79
|
end
|
84
80
|
|
85
81
|
klass.teardown do
|
86
|
-
if
|
82
|
+
if Screenshot.active? && @test_screenshots.present?
|
87
83
|
track_failures(@test_screenshots, caller)
|
88
|
-
@test_screenshots
|
84
|
+
@test_screenshots.clear
|
89
85
|
end
|
90
86
|
end
|
91
87
|
end
|
@@ -96,7 +92,7 @@ module Capybara
|
|
96
92
|
|
97
93
|
def track_failures(screenshots, original_caller)
|
98
94
|
test_screenshot_errors = screenshots.map do |caller, name, compare|
|
99
|
-
assert_image_not_changed(
|
95
|
+
assert_image_not_changed(name, compare)
|
100
96
|
end
|
101
97
|
|
102
98
|
test_screenshot_errors.compact!
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Capybara
|
2
|
+
module Screenshot
|
3
|
+
def self.root=: ((String | Pathname) path) -> Pathname
|
4
|
+
|
5
|
+
def self.root: -> Pathname
|
6
|
+
|
7
|
+
def self.active?: () -> boolish
|
8
|
+
|
9
|
+
def self.screenshot_area: () -> String
|
10
|
+
|
11
|
+
def self.screenshot_area_abs: () -> Pathname
|
12
|
+
|
13
|
+
# Module to track screen shot changes
|
14
|
+
module Diff
|
15
|
+
AVAILABLE_DRIVERS: Array[(:vips | :chunky_png)]
|
16
|
+
|
17
|
+
ASSERTION: (top | RuntimeError)
|
18
|
+
|
19
|
+
def self.default_options: () -> ScreenshotMatcher::input_options
|
20
|
+
|
21
|
+
def self.included: (top klass) -> void
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def track_failures: (Array[untyped] screenshots, (Array[String] | String) original_caller) -> void
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Capybara
|
2
|
+
module Screenshot
|
3
|
+
module Diff
|
4
|
+
class Difference
|
5
|
+
attr_reader comparison: ImageCompare::Comparison
|
6
|
+
|
7
|
+
def different?: () -> bool
|
8
|
+
|
9
|
+
def base_image: () -> top
|
10
|
+
|
11
|
+
def options: () -> Drivers::BaseDriver::options_entity
|
12
|
+
|
13
|
+
def tolerance: () -> Numeric?
|
14
|
+
|
15
|
+
def area_size_limit: () -> Numeric?
|
16
|
+
|
17
|
+
def blank?: () -> bool
|
18
|
+
|
19
|
+
def region_area_size: () -> Numeric
|
20
|
+
|
21
|
+
def ratio: () -> Numeric?
|
22
|
+
|
23
|
+
def to_h: () -> Hash[Symbol, untyped]
|
24
|
+
|
25
|
+
def coordinates: () -> Region::raw_region_entity
|
26
|
+
|
27
|
+
def inspect: () -> String
|
28
|
+
|
29
|
+
def tolerable?: () -> bool
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Capybara
|
2
|
+
module Screenshot
|
3
|
+
module Diff
|
4
|
+
module Drivers
|
5
|
+
class BaseDriver[ImageEntity]
|
6
|
+
|
7
|
+
type images_entity[out T] = [T, T]
|
8
|
+
type dimension_entity = [Numeric, Numeric]
|
9
|
+
|
10
|
+
type options_entity = {
|
11
|
+
area_size_limit?: Numeric?,
|
12
|
+
color_distance_limit?: Numeric?,
|
13
|
+
driver: (:auto | :vips | :chunky_png | VipsDriver | ChunkyPNGDriver)?,
|
14
|
+
dimensions: dimension_entity?,
|
15
|
+
median_filter_window_size: Numeric?,
|
16
|
+
shift_distance_limit?: Numeric?,
|
17
|
+
skip_area?: Array[Region]?,
|
18
|
+
stability_time_limit?: Numeric?,
|
19
|
+
tolerance?: Numeric?,
|
20
|
+
wait?: Numeric?
|
21
|
+
}
|
22
|
+
|
23
|
+
type color = [Integer, Integer, Integer, Integer]
|
24
|
+
|
25
|
+
def find_difference_region: (ImageEntity new_image, ImageEntity old_image, Numeric color_distance_limit, Numeric _shift_distance_limit, Integer _area_size_limit, ?fast_fail: bool) -> Difference
|
26
|
+
|
27
|
+
def inscribed?: (dimension_entity dimensions, ImageEntity i) -> boolish
|
28
|
+
|
29
|
+
def crop: (Region region, ImageEntity i) -> ImageEntity
|
30
|
+
|
31
|
+
def filter_image_with_median: (ImageEntity image, Numeric median_filter_window_size) -> ImageEntity
|
32
|
+
|
33
|
+
def add_black_box: (ImageEntity memo, Region region) -> void
|
34
|
+
|
35
|
+
def difference_level: (ImageEntity diff_mask, ImageEntity old_img, Region _region) -> Float
|
36
|
+
|
37
|
+
def image_area_size: (ImageEntity old_img) -> Integer
|
38
|
+
|
39
|
+
def height_for: (ImageEntity image) -> Integer
|
40
|
+
|
41
|
+
def width_for: (ImageEntity image) -> Integer
|
42
|
+
|
43
|
+
# Vips could not work with the same file. Per each process we require to create new file
|
44
|
+
def save_image_to: (ImageEntity image, String filename) -> void
|
45
|
+
|
46
|
+
def resize_image_to: (ImageEntity image, Integer new_width, Integer new_height) -> ImageEntity
|
47
|
+
|
48
|
+
def load_images: (String old_file_name, String new_file_name) -> images_entity[ImageEntity]
|
49
|
+
|
50
|
+
def from_file: (TestMethods::path_entity filename) -> ImageEntity
|
51
|
+
|
52
|
+
def dimension: (ImageEntity image) -> dimension_entity
|
53
|
+
|
54
|
+
def draw_rectangles: (images_entity[ImageEntity] images, Region region, color rgba, Integer offset) -> void
|
55
|
+
|
56
|
+
def same_pixels?: () -> boolish
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.for: (ScreenshotMatcher::input_options) -> (VipsDriver | ChunkyPNGDriver)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Capybara
|
2
|
+
class Result
|
3
|
+
def map: () -> Result
|
4
|
+
end
|
5
|
+
module Screenshot
|
6
|
+
module BrowserHelpers
|
7
|
+
def self.current_capybara_driver_class: () -> top
|
8
|
+
|
9
|
+
def self.selenium?: () -> boolish?
|
10
|
+
|
11
|
+
def self.window_size_is_wrong?: () -> boolish
|
12
|
+
|
13
|
+
def self.bounds_for_css: (*String css_selectors) -> Array[Region::raw_region_entity]
|
14
|
+
|
15
|
+
IMAGE_WAIT_SCRIPT: String
|
16
|
+
|
17
|
+
def self.pending_image_to_load: () -> top?
|
18
|
+
|
19
|
+
HIDE_CARET_SCRIPT: String
|
20
|
+
|
21
|
+
def self.hide_caret: () -> void
|
22
|
+
|
23
|
+
FIND_ACTIVE_ELEMENT_SCRIPT: String
|
24
|
+
|
25
|
+
type capybara_element = top
|
26
|
+
|
27
|
+
def self.blur_from_focused_element: () -> capybara_element?
|
28
|
+
|
29
|
+
GET_BOUNDING_CLIENT_RECT_SCRIPT: String
|
30
|
+
|
31
|
+
def self.all_visible_regions_for: (String selector) -> Array[Region::raw_region_entity]
|
32
|
+
|
33
|
+
def self.region_for: (Result element) -> Region::raw_region_entity
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module ChunkyPNG
|
2
|
+
class Canvas
|
3
|
+
end
|
4
|
+
|
5
|
+
class Image
|
6
|
+
def self.from_blob: (String str) -> Image
|
7
|
+
|
8
|
+
def self.from_file: (String filename) -> Image
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Capybara
|
13
|
+
module Screenshot
|
14
|
+
module Diff
|
15
|
+
module Drivers
|
16
|
+
class ChunkyPNGDriver < BaseDriver[ChunkyPNG::Canvas]
|
17
|
+
|
18
|
+
def _load_images: (String old_file, String new_file) -> [ChunkyPNG::Image, ChunkyPNG::Image]
|
19
|
+
|
20
|
+
class DifferenceRegionFinder
|
21
|
+
def find_diff_rectangle: (
|
22
|
+
ChunkyPNG::Image org_img,
|
23
|
+
ChunkyPNG::Image new_img,
|
24
|
+
(Region | Region::raw_region_entity) area_coordinates,
|
25
|
+
cache: ImageCompare::cache_entity
|
26
|
+
) -> Region?
|
27
|
+
|
28
|
+
def find_top: (
|
29
|
+
ChunkyPNG::Image old_img,
|
30
|
+
ChunkyPNG::Image new_img,
|
31
|
+
cache: ImageCompare::cache_entity
|
32
|
+
) -> Region::raw_region_entity?
|
33
|
+
|
34
|
+
def find_left_right_and_top: (
|
35
|
+
ChunkyPNG::Image old_img,
|
36
|
+
ChunkyPNG::Image new_img,
|
37
|
+
(Region | Region::raw_region_entity) region,
|
38
|
+
cache: ImageCompare::cache_entity
|
39
|
+
) -> Region::raw_region_entity
|
40
|
+
|
41
|
+
def find_bottom: (
|
42
|
+
ChunkyPNG::Image old_img,
|
43
|
+
ChunkyPNG::Image new_img,
|
44
|
+
Integer left,
|
45
|
+
Integer right,
|
46
|
+
Integer bottom,
|
47
|
+
cache: ImageCompare::cache_entity
|
48
|
+
) -> Integer
|
49
|
+
|
50
|
+
def same_color?: (
|
51
|
+
ChunkyPNG::Image old_img,
|
52
|
+
ChunkyPNG::Image new_img,
|
53
|
+
Integer x,
|
54
|
+
Integer y,
|
55
|
+
?cache: ImageCompare::cache_entity
|
56
|
+
) -> boolish
|
57
|
+
|
58
|
+
def skipped_region?: (Integer x, Integer y) -> boolish
|
59
|
+
|
60
|
+
def color_distance_at: (
|
61
|
+
ChunkyPNG::Image new_img,
|
62
|
+
ChunkyPNG::Image old_img,
|
63
|
+
Integer x,
|
64
|
+
Integer y,
|
65
|
+
shift_distance_limit: Numeric?
|
66
|
+
) -> Float
|
67
|
+
|
68
|
+
def shift_distance_at: (
|
69
|
+
ChunkyPNG::Image new_img,
|
70
|
+
ChunkyPNG::Image old_img,
|
71
|
+
Integer x,
|
72
|
+
Integer y,
|
73
|
+
color_distance_limit: Numeric?
|
74
|
+
) -> Numeric
|
75
|
+
|
76
|
+
def color_matches: (
|
77
|
+
ChunkyPNG::Image new_img,
|
78
|
+
Integer org_color,
|
79
|
+
Integer x,
|
80
|
+
Integer y,
|
81
|
+
Numeric? color_distance_limit
|
82
|
+
) -> boolish
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Capybara
|
2
|
+
module Screenshot
|
3
|
+
module Diff
|
4
|
+
module Utils
|
5
|
+
def self.detect_available_drivers: () -> Array[(:vips | :chunky_png)]
|
6
|
+
|
7
|
+
def self.find_driver_class_for: [T] (Symbol driver) -> T
|
8
|
+
|
9
|
+
def self.detect_test_framework_assert: [T < Exception] () -> T
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module ::Vips
|
2
|
+
class Image
|
3
|
+
def self.new_from_file: (String filename) -> Image
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
module Capybara
|
8
|
+
module Screenshot
|
9
|
+
module Diff
|
10
|
+
module Drivers
|
11
|
+
class VipsDriver < BaseDriver[Vips::Image]
|
12
|
+
class VipsUtil
|
13
|
+
def self.difference_area: (Vips::Image old_image, Vips::Image new_image, ?color_distance: ::Integer) -> Numeric
|
14
|
+
|
15
|
+
def self.difference_area_size_by: (Vips::Image difference_mask) -> Numeric
|
16
|
+
|
17
|
+
def self.difference_mask: (Vips::Image, Vips::Image, ?Numeric? color_distance) -> Vips::Image
|
18
|
+
|
19
|
+
def self.difference_region_by: (Vips::Image diff_mask) -> Region?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|