eyes_core 3.10.0 → 3.10.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/lib/applitools/connectivity/server_connector.rb +4 -1
- data/lib/applitools/core/eyes_base.rb +8 -10
- data/lib/applitools/core/fluent_interface.rb +27 -0
- data/lib/applitools/core/match_single_check_data.rb +3 -47
- data/lib/applitools/core/match_window_data.rb +17 -12
- data/lib/applitools/core/region_provider.rb +10 -0
- data/lib/applitools/sauce.rb +1 -1
- data/lib/applitools/version.rb +1 -1
- data/lib/eyes_core.rb +5 -9
- data/lib/require_utils.rb +10 -0
- metadata +5 -5
- data/lib/applitools/images/eyes.rb +0 -288
- data/lib/applitools/images/eyes_images_screenshot.rb +0 -106
- data/lib/applitools/images/target.rb +0 -104
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 69da25c3d4e67d9f44a708e6b0c0da5382374285
|
|
4
|
+
data.tar.gz: 45358e7a6182c7185b00cfeda8034423fcce5178
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 00ace03b98a2b76511a79bba56c9fe0c2299f80e935c46fbaeeb368a87b4059394f1881b25d38236ff905e13259305e1ddd849c83082c8c9186d65771da2e2b0
|
|
7
|
+
data.tar.gz: a328ecd8c09fb95c31ee1d3833ab9d6456f56caf3f8df484083104a65ee9e8473c68fefe148d7493cf466205896affae4ff44cb50d0e6dd64c0bb7919f5e84a5
|
|
@@ -179,7 +179,10 @@ module Applitools::Connectivity
|
|
|
179
179
|
loop do
|
|
180
180
|
Applitools::EyesLogger.debug "Still running... retrying in #{delay}s"
|
|
181
181
|
sleep delay
|
|
182
|
-
|
|
182
|
+
second_step_options = { headers: {
|
|
183
|
+
'Eyes-Date' => Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')
|
|
184
|
+
} }
|
|
185
|
+
res = request(second_step_url, :get, second_step_options)
|
|
183
186
|
break unless res.status == HTTP_STATUS_CODES[:ok]
|
|
184
187
|
end
|
|
185
188
|
end
|
|
@@ -68,10 +68,12 @@ module Applitools
|
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
@default_match_settings = {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
@default_match_settings = {
|
|
72
|
+
match_level: Applitools::MATCH_LEVEL[:strict],
|
|
73
|
+
exact: nil,
|
|
74
|
+
scale: server_scale,
|
|
75
|
+
remainder: server_remainder
|
|
76
|
+
}
|
|
75
77
|
end
|
|
76
78
|
|
|
77
79
|
def batch
|
|
@@ -103,18 +105,14 @@ module Applitools
|
|
|
103
105
|
@default_match_settings[:scale] = ratio
|
|
104
106
|
end
|
|
105
107
|
|
|
106
|
-
|
|
107
|
-
@server_scale
|
|
108
|
-
end
|
|
108
|
+
attr_reader :server_scale
|
|
109
109
|
|
|
110
110
|
def server_remainder=(ratio)
|
|
111
111
|
@server_remainder = ratio
|
|
112
112
|
@default_match_settings[:remainder] = ratio
|
|
113
113
|
end
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
@server_remainder
|
|
117
|
-
end
|
|
115
|
+
attr_reader :server_remainder
|
|
118
116
|
|
|
119
117
|
def disabled=(value)
|
|
120
118
|
@disabled = Applitools::Utils.boolean_value value
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Applitools::FluentInterface
|
|
2
|
+
def ignore_caret(value = false)
|
|
3
|
+
options[:ignore_caret] = value ? true : false
|
|
4
|
+
self
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def timeout(value)
|
|
8
|
+
options[:timeout] = value.to_i
|
|
9
|
+
self
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def trim(value = true)
|
|
13
|
+
options[:trim] = value ? true : false
|
|
14
|
+
self
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def ignore_mismatch(value)
|
|
18
|
+
options[:ignore_mismatch] = value ? true : false
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def match_level(value)
|
|
23
|
+
raise Applitools::EyesError unless Applitools::MATCH_LEVEL.keys.include? value
|
|
24
|
+
options[:match_level] = Applitools::MATCH_LEVEL[value]
|
|
25
|
+
self
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -3,7 +3,7 @@ module Applitools
|
|
|
3
3
|
class MatchSingleCheckData < MatchWindowData
|
|
4
4
|
class << self
|
|
5
5
|
def default_data
|
|
6
|
-
|
|
6
|
+
super.merge!(
|
|
7
7
|
'startInfo' => {
|
|
8
8
|
'agentId' => nil,
|
|
9
9
|
'appIdOrName' => nil,
|
|
@@ -16,52 +16,8 @@ module Applitools
|
|
|
16
16
|
'branchName' => nil,
|
|
17
17
|
'parentBranchName' => nil,
|
|
18
18
|
'properties' => nil
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
'MismatchWait' => 0,
|
|
22
|
-
'Options' => {
|
|
23
|
-
'Name' => nil,
|
|
24
|
-
'UserInputs' => [],
|
|
25
|
-
'ImageMatchSettings' => {
|
|
26
|
-
'MatchLevel' => 'None',
|
|
27
|
-
'SplitTopHeight' => 0,
|
|
28
|
-
'SplitBottomHeight' => 0,
|
|
29
|
-
'IgnoreCaret' => false,
|
|
30
|
-
'Ignore' => [],
|
|
31
|
-
'Exact' => {
|
|
32
|
-
'MinDiffIntensity' => 0,
|
|
33
|
-
'MinDiffWidth' => 0,
|
|
34
|
-
'MinDiffHeight' => 0,
|
|
35
|
-
'MatchThreshold' => 0
|
|
36
|
-
},
|
|
37
|
-
'scale' => 0,
|
|
38
|
-
'remainder' => 0
|
|
39
|
-
},
|
|
40
|
-
'IgnoreExpectedOutputSettings' => false,
|
|
41
|
-
'ForceMatch' => false,
|
|
42
|
-
'ForceMismatch' => false,
|
|
43
|
-
'IgnoreMatch' => false,
|
|
44
|
-
'IgnoreMismatch' => false,
|
|
45
|
-
'Trim' => {
|
|
46
|
-
'Enabled' => false,
|
|
47
|
-
'ForegroundIntensity' => 0,
|
|
48
|
-
'MinEdgeLength' => 0
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
'Id' => nil,
|
|
52
|
-
'UserInputs' => [],
|
|
53
|
-
'AppOutput' => {
|
|
54
|
-
'Screenshot64' => nil,
|
|
55
|
-
'ScreenshotUrl' => nil,
|
|
56
|
-
'Title' => nil,
|
|
57
|
-
'IsPrimary' => false,
|
|
58
|
-
'Elapsed' => 0
|
|
59
|
-
},
|
|
60
|
-
'Tag' => nil,
|
|
61
|
-
'updateBaselineIfDifferent' => false,
|
|
62
|
-
'updateBaselineIfNew' => false,
|
|
63
|
-
'removeSessionIfMatching' => false
|
|
64
|
-
}
|
|
19
|
+
}
|
|
20
|
+
)
|
|
65
21
|
end
|
|
66
22
|
end
|
|
67
23
|
|
|
@@ -17,7 +17,7 @@ module Applitools
|
|
|
17
17
|
'Name' => nil,
|
|
18
18
|
'UserInputs' => [],
|
|
19
19
|
'ImageMatchSettings' => {
|
|
20
|
-
'MatchLevel' => '
|
|
20
|
+
'MatchLevel' => 'Strict',
|
|
21
21
|
'SplitTopHeight' => 0,
|
|
22
22
|
'SplitBottomHeight' => 0,
|
|
23
23
|
'IgnoreCaret' => false,
|
|
@@ -145,21 +145,26 @@ module Applitools
|
|
|
145
145
|
def read_target(target, driver)
|
|
146
146
|
# options
|
|
147
147
|
target_options_to_read.each do |field|
|
|
148
|
-
|
|
148
|
+
a_value = target.options[field.to_sym]
|
|
149
|
+
send("#{field}=", a_value) unless a_value.nil?
|
|
149
150
|
end
|
|
150
151
|
# ignored regions
|
|
151
|
-
target.ignored_regions
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
152
|
+
if target.respond_to? :ignored_regions
|
|
153
|
+
target.ignored_regions.each do |r|
|
|
154
|
+
case r
|
|
155
|
+
when Proc
|
|
156
|
+
region = r.call(driver)
|
|
157
|
+
@ignored_regions << Applitools::Region.from_location_size(region.location, region.size)
|
|
158
|
+
@need_convert_ignored_regions_coordinates = true
|
|
159
|
+
when Applitools::Region
|
|
160
|
+
@ignored_regions << r
|
|
161
|
+
@need_convert_ignored_regions_coordinates = true
|
|
162
|
+
end
|
|
160
163
|
end
|
|
161
164
|
end
|
|
165
|
+
|
|
162
166
|
# floating regions
|
|
167
|
+
return unless target.respond_to? :floating_regions
|
|
163
168
|
target.floating_regions.each do |r|
|
|
164
169
|
case r
|
|
165
170
|
when Proc
|
|
@@ -176,7 +181,7 @@ module Applitools
|
|
|
176
181
|
end
|
|
177
182
|
|
|
178
183
|
def target_options_to_read
|
|
179
|
-
%w(trim ignore_caret)
|
|
184
|
+
%w(trim ignore_caret match_level ignore_mismatch)
|
|
180
185
|
end
|
|
181
186
|
|
|
182
187
|
private :target_options_to_read
|
data/lib/applitools/sauce.rb
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
require_relative 'capybara' if defined? Capybara
|
|
2
|
-
Applitools.require_dir 'selenium/sauce'
|
|
2
|
+
Applitools::Selenium.require_dir 'selenium/sauce'
|
data/lib/applitools/version.rb
CHANGED
data/lib/eyes_core.rb
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
require 'forwardable'
|
|
2
2
|
require 'delegate'
|
|
3
3
|
require 'time'
|
|
4
|
+
require_relative 'require_utils'
|
|
4
5
|
|
|
5
6
|
module Applitools
|
|
6
|
-
|
|
7
|
-
class << self
|
|
8
|
-
# @!visibility private
|
|
9
|
-
def require_dir(dir)
|
|
10
|
-
Dir[File.join(File.dirname(File.expand_path(__FILE__)), 'applitools', dir, '*.rb')].sort.each do |f|
|
|
11
|
-
require f
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
7
|
+
extend Applitools::RequireUtils
|
|
15
8
|
|
|
9
|
+
def self.load_dir
|
|
10
|
+
File.dirname(File.expand_path(__FILE__))
|
|
11
|
+
end
|
|
16
12
|
# @!visibility private
|
|
17
13
|
class EyesError < StandardError; end
|
|
18
14
|
# @!visibility private
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: eyes_core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.10.
|
|
4
|
+
version: 3.10.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Applitools Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-06-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: oily_png
|
|
@@ -218,6 +218,7 @@ files:
|
|
|
218
218
|
- lib/applitools/core/fixed_cut_provider.rb
|
|
219
219
|
- lib/applitools/core/fixed_scale_provider.rb
|
|
220
220
|
- lib/applitools/core/floating_region.rb
|
|
221
|
+
- lib/applitools/core/fluent_interface.rb
|
|
221
222
|
- lib/applitools/core/hash_extension.rb
|
|
222
223
|
- lib/applitools/core/helpers.rb
|
|
223
224
|
- lib/applitools/core/location.rb
|
|
@@ -230,6 +231,7 @@ files:
|
|
|
230
231
|
- lib/applitools/core/mouse_trigger.rb
|
|
231
232
|
- lib/applitools/core/rectangle_size.rb
|
|
232
233
|
- lib/applitools/core/region.rb
|
|
234
|
+
- lib/applitools/core/region_provider.rb
|
|
233
235
|
- lib/applitools/core/screenshot.rb
|
|
234
236
|
- lib/applitools/core/session.rb
|
|
235
237
|
- lib/applitools/core/session_start_info.rb
|
|
@@ -238,9 +240,6 @@ files:
|
|
|
238
240
|
- lib/applitools/core/trigger.rb
|
|
239
241
|
- lib/applitools/extensions.rb
|
|
240
242
|
- lib/applitools/eyes_logger.rb
|
|
241
|
-
- lib/applitools/images/eyes.rb
|
|
242
|
-
- lib/applitools/images/eyes_images_screenshot.rb
|
|
243
|
-
- lib/applitools/images/target.rb
|
|
244
243
|
- lib/applitools/method_tracer.rb
|
|
245
244
|
- lib/applitools/sauce.rb
|
|
246
245
|
- lib/applitools/utils/eyes_selenium_utils.rb
|
|
@@ -249,6 +248,7 @@ files:
|
|
|
249
248
|
- lib/applitools/utils/utils.rb
|
|
250
249
|
- lib/applitools/version.rb
|
|
251
250
|
- lib/eyes_core.rb
|
|
251
|
+
- lib/require_utils.rb
|
|
252
252
|
homepage: https://www.applitools.com
|
|
253
253
|
licenses:
|
|
254
254
|
- Apache License, Version 2.0
|
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
require 'applitools/core/eyes_base'
|
|
2
|
-
|
|
3
|
-
# Eyes Images SDK
|
|
4
|
-
#
|
|
5
|
-
module Applitools::Images
|
|
6
|
-
# A class to perform visual validation on images. Allows to handle user data like +Mouse trigger+ and +Text trigger+
|
|
7
|
-
# @example
|
|
8
|
-
# eyes = Applitools::Images::Eyes.new
|
|
9
|
-
# eyes.open(app_name: 'App name', test_name: 'Test name')
|
|
10
|
-
# eyes.check_image(eyes.check_image(image_path: '~/test/some_screenshot.png', tag: 'My Test')
|
|
11
|
-
# eyes.close(true)
|
|
12
|
-
class Eyes < Applitools::EyesBase
|
|
13
|
-
# @!visibility private
|
|
14
|
-
attr_accessor :base_agent_id, :screenshot, :inferred_environment, :title
|
|
15
|
-
|
|
16
|
-
# @!visibility private
|
|
17
|
-
def capture_screenshot
|
|
18
|
-
@screenshot
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# Creates a new eyes object
|
|
22
|
-
# @example
|
|
23
|
-
# eyes = Applitools::Images::Eyes.new
|
|
24
|
-
# @param server_url The Eyes Server URL
|
|
25
|
-
def initialize(server_url = Applitools::Connectivity::ServerConnector::DEFAULT_SERVER_URL)
|
|
26
|
-
super
|
|
27
|
-
self.base_agent_id = "eyes.images.ruby/#{Applitools::VERSION}".freeze
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Starts a test.
|
|
31
|
-
# @param [Hash] options
|
|
32
|
-
# @option options [String] :app_name the name of the application under trest. Required.
|
|
33
|
-
# @option options [String] :test_name the test name. Required
|
|
34
|
-
# @option options [String | Hash] :viewport_size viewport size for the baseline, may be passed as a
|
|
35
|
-
# string (<tt>'800x600'</tt>) or as a hash (<tt>{width: 800, height: 600}</tt>).
|
|
36
|
-
# If ommited, the viewport size will be grabbed from the actual image size
|
|
37
|
-
# @example
|
|
38
|
-
# eyes.open app_name: 'my app', test_name: 'my test'
|
|
39
|
-
def open(options = {})
|
|
40
|
-
Applitools::ArgumentGuard.hash options, 'open(options)', [:app_name, :test_name]
|
|
41
|
-
options[:viewport_size] = Applitools::RectangleSize.from_any_argument options[:viewport_size]
|
|
42
|
-
open_base options
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Opens eyes using passed options, yields the block and then closes eyes session.
|
|
46
|
-
# Use Applitools::Images::Eyes method inside the block to perform the test. If the block throws an exception,
|
|
47
|
-
# eyes session will be closed correctly.
|
|
48
|
-
# @example
|
|
49
|
-
# eyes.test(app_name: 'Eyes.Java', test_name: 'home2') do
|
|
50
|
-
# eyes.check_image(image_path: './images/viber-home.png')
|
|
51
|
-
# eyes.check_image(image_path: './images/viber-bada.png')
|
|
52
|
-
# end
|
|
53
|
-
def test(options = {}, &_block)
|
|
54
|
-
open(options)
|
|
55
|
-
yield
|
|
56
|
-
close
|
|
57
|
-
ensure
|
|
58
|
-
abort_if_not_closed
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def check(name, target)
|
|
62
|
-
Applitools::ArgumentGuard.not_nil(name, 'name')
|
|
63
|
-
region_provider = get_region_provider(target)
|
|
64
|
-
|
|
65
|
-
match_window_data = Applitools::MatchWindowData.new
|
|
66
|
-
match_window_data.tag = name
|
|
67
|
-
match_window_data.match_level = default_match_settings[:match_level]
|
|
68
|
-
match_window_data.read_target(target, nil)
|
|
69
|
-
|
|
70
|
-
image = target.image
|
|
71
|
-
self.viewport_size = Applitools::RectangleSize.new image.width, image.height if viewport_size.nil?
|
|
72
|
-
self.screenshot = EyesImagesScreenshot.new image
|
|
73
|
-
|
|
74
|
-
mr = check_window_base(
|
|
75
|
-
region_provider,
|
|
76
|
-
target.options[:timeout] || Applitools::EyesBase::USE_DEFAULT_TIMEOUT,
|
|
77
|
-
match_window_data
|
|
78
|
-
)
|
|
79
|
-
mr.as_expected?
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def check_single(name, target, options = {})
|
|
83
|
-
open_base(options) unless options.empty?
|
|
84
|
-
Applitools::ArgumentGuard.not_nil(name, 'name')
|
|
85
|
-
region_provider = get_region_provider(target)
|
|
86
|
-
|
|
87
|
-
match_window_data = Applitools::MatchSingleCheckData.new
|
|
88
|
-
match_window_data.tag = name
|
|
89
|
-
|
|
90
|
-
match_window_data.ignore_mismatch = options[:ignore_mismatch] ? true : false
|
|
91
|
-
match_window_data.match_level = default_match_settings[:match_level]
|
|
92
|
-
|
|
93
|
-
match_window_data.read_target(target, nil)
|
|
94
|
-
|
|
95
|
-
image = target.image
|
|
96
|
-
self.viewport_size = Applitools::RectangleSize.new image.width, image.height if viewport_size.nil?
|
|
97
|
-
self.screenshot = EyesImagesScreenshot.new image
|
|
98
|
-
|
|
99
|
-
mr = check_single_base(
|
|
100
|
-
region_provider,
|
|
101
|
-
target.options[:timeout] || Applitools::EyesBase::USE_DEFAULT_TIMEOUT,
|
|
102
|
-
match_window_data
|
|
103
|
-
)
|
|
104
|
-
mr
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def get_region_provider(target)
|
|
108
|
-
if (region_to_check = target.region_to_check).nil?
|
|
109
|
-
Object.new.tap do |prov|
|
|
110
|
-
prov.instance_eval do
|
|
111
|
-
define_singleton_method :region do
|
|
112
|
-
Applitools::Region::EMPTY
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
define_singleton_method :coordinate_type do
|
|
116
|
-
nil
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
else
|
|
121
|
-
Object.new.tap do |prov|
|
|
122
|
-
prov.instance_eval do
|
|
123
|
-
define_singleton_method :region do
|
|
124
|
-
region_to_check
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
define_singleton_method :coordinate_type do
|
|
128
|
-
Applitools::EyesScreenshot::COORDINATE_TYPES[:context_relative]
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# Matches the input image with the next expected image. Takes a hash as an argument. Returns +boolean+
|
|
136
|
-
# as result of matching.
|
|
137
|
-
# @param [Hash] options
|
|
138
|
-
# @option options [Applitools::Screenshot] :image
|
|
139
|
-
# @option options [String] :image_bytes image in PNG format. Can be obtained as ChunkyPNG::Image.to_blob()
|
|
140
|
-
# @option options [String] :image_path
|
|
141
|
-
# @option options [String] :tag An optional tag to be associated with the validation checkpoint.
|
|
142
|
-
# @option options [Boolean] :ignore_mismatch If set to +true+ the server should ignore a negative
|
|
143
|
-
# result for the visual validation. (+false+ by default)
|
|
144
|
-
# @example Image is a file
|
|
145
|
-
# eyes.check_image(image_path: '~/test/some_screenshot.png', tag: 'My Test')
|
|
146
|
-
# @example Image is a +Applitools::Screenshot+ instance
|
|
147
|
-
# eyes.check_image(image: my_image, tag: 'My Test')
|
|
148
|
-
# @example Image is a +String+
|
|
149
|
-
# eyes.check_image(image_bytes: string_represents_image, tag: 'My Test')
|
|
150
|
-
# @example Ignore mismatch
|
|
151
|
-
# eyes.check_image(image: my_image, tag: 'My Test', ignore_mismatch: true)
|
|
152
|
-
def check_image(options)
|
|
153
|
-
options = { tag: nil, ignore_mismatch: false }.merge options
|
|
154
|
-
match_data = Applitools::MatchWindowData.new
|
|
155
|
-
match_data.tag = options[:tag]
|
|
156
|
-
match_data.ignore_mismatch = options[:ignore_mismatch]
|
|
157
|
-
match_data.match_level = default_match_settings[:match_level]
|
|
158
|
-
|
|
159
|
-
if disabled?
|
|
160
|
-
logger.info "check_image(image, #{options[:tag]}, #{options[:ignore_mismatch]}): Ignored"
|
|
161
|
-
return false
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
image = get_image_from_options options
|
|
165
|
-
|
|
166
|
-
logger.info "check_image(image, #{options[:tag]}, #{options[:ignore_mismatch]})"
|
|
167
|
-
if image.is_a? Applitools::Screenshot
|
|
168
|
-
self.viewport_size = Applitools::RectangleSize.new image.width, image.height if viewport_size.nil?
|
|
169
|
-
self.screenshot = EyesImagesScreenshot.new image
|
|
170
|
-
end
|
|
171
|
-
self.title = options[:tag] || ''
|
|
172
|
-
region_provider = Object.new
|
|
173
|
-
region_provider.instance_eval do
|
|
174
|
-
define_singleton_method :region do
|
|
175
|
-
Applitools::Region::EMPTY
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
define_singleton_method :coordinate_type do
|
|
179
|
-
nil
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
mr = check_window_base region_provider, Applitools::EyesBase::USE_DEFAULT_TIMEOUT, match_data
|
|
183
|
-
mr.as_expected?
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
# Performs visual validation for the current image.
|
|
187
|
-
# @param [Hash] options
|
|
188
|
-
# @option options [Applitools::Region] :region A region to validate within the image
|
|
189
|
-
# @option options [Applitools::Screenshot] :image Image to validate
|
|
190
|
-
# @option options [String] :image_bytes Image in +PNG+ format. Can be obtained as ChunkyPNG::Image.to_blob()
|
|
191
|
-
# @option options [String] :image_path Path to image file
|
|
192
|
-
# @option options [String] :tag An optional tag to be associated with the validation checkpoint.
|
|
193
|
-
# @option options [Boolean] :ignore_mismatch If set to +true+ the server would ignore a negative
|
|
194
|
-
# result for the visual validation
|
|
195
|
-
# @example Image is a file
|
|
196
|
-
# eyes.check_region(image_path: '~/test/some_screenshot.png', region: my_region, tag: 'My Test')
|
|
197
|
-
# @example Image is a Applitools::Screenshot instance
|
|
198
|
-
# eyes.check_region(image: my_image, tag: 'My Test', region: my_region)
|
|
199
|
-
# @example Image is a +String+
|
|
200
|
-
# eyes.check_region(image_bytes: string_represents_image, tag: 'My Test', region: my_region)
|
|
201
|
-
def check_region(options)
|
|
202
|
-
options = { tag: nil, ignore_mismatch: false }.merge options
|
|
203
|
-
match_data = Applitools::MatchWindowData.new
|
|
204
|
-
match_data.tag = options[:tag]
|
|
205
|
-
match_data.ignore_mismatch = options[:ignore_mismatch]
|
|
206
|
-
match_data.match_level = default_match_settings[:match_level]
|
|
207
|
-
|
|
208
|
-
if disabled?
|
|
209
|
-
logger.info "check_region(image, #{options[:tag]}, #{options[:ignore_mismatch]}): Ignored"
|
|
210
|
-
return false
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
Applitools::ArgumentGuard.not_nil options[:region], 'options[:region] can\'t be nil!'
|
|
214
|
-
image = get_image_from_options options
|
|
215
|
-
|
|
216
|
-
logger.info "check_region(image, #{options[:region]}, #{options[:tag]}, #{options[:ignore_mismatch]})"
|
|
217
|
-
|
|
218
|
-
if image.is_a? Applitools::Screenshot
|
|
219
|
-
self.viewport_size = Applitools::RectangleSize.new image.width, image.height if viewport_size.nil?
|
|
220
|
-
self.screenshot = EyesImagesScreenshot.new image
|
|
221
|
-
end
|
|
222
|
-
self.title = options[:tag] || ''
|
|
223
|
-
|
|
224
|
-
region_provider = Object.new
|
|
225
|
-
region_provider.instance_eval do
|
|
226
|
-
define_singleton_method :region do
|
|
227
|
-
options[:region]
|
|
228
|
-
end
|
|
229
|
-
define_singleton_method :coordinate_type do
|
|
230
|
-
Applitools::EyesScreenshot::COORDINATE_TYPES[:screenshot_as_is]
|
|
231
|
-
end
|
|
232
|
-
end
|
|
233
|
-
# mr = check_window_base region_provider, options[:tag], options[:ignore_mismatch],
|
|
234
|
-
# Applitools::EyesBase::USE_DEFAULT_TIMEOUT, options.merge(match_level: default_match_settings[:match_level])
|
|
235
|
-
mr = check_window_base region_provider, Applitools::EyesBase::USE_DEFAULT_TIMEOUT, match_data
|
|
236
|
-
mr.as_expected?
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
# Adds a mouse trigger
|
|
240
|
-
# @param [Symbol] action A mouse action. Can be one of +:click+, +:right_click+, +:double_click+, +:move+,
|
|
241
|
-
# +:down+, +:up+
|
|
242
|
-
# @param [Applitools::Region] control The control on which the trigger is activated
|
|
243
|
-
# (context relative coordinates).
|
|
244
|
-
# @param [Applitools::Location] cursor The cursor's position relative to the control.
|
|
245
|
-
def add_mouse_trigger(action, control, cursor)
|
|
246
|
-
add_mouse_trigger_base action, control, cursor
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
# Adds a keyboard trigger
|
|
250
|
-
# @param [Applitools::Region] control the control's context-relative region.
|
|
251
|
-
# @param text The trigger's text.
|
|
252
|
-
def add_text_trigger(control, text)
|
|
253
|
-
add_text_trigger_base control, text
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
private
|
|
257
|
-
|
|
258
|
-
def vp_size
|
|
259
|
-
viewport_size
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
def vp_size=(value)
|
|
263
|
-
Applitools::ArgumentGuard.not_nil 'value', value
|
|
264
|
-
@viewport_size = Applitools::RectangleSize.for value
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
alias get_viewport_size vp_size
|
|
268
|
-
alias set_viewport_size vp_size=
|
|
269
|
-
|
|
270
|
-
def get_image_from_options(options)
|
|
271
|
-
image = if options[:image].nil? || !options[:image].is_a?(Applitools::Screenshot)
|
|
272
|
-
if options[:image].is_a? ChunkyPNG::Image
|
|
273
|
-
Applitools::Screenshot.from_image options[:image]
|
|
274
|
-
elsif !options[:image_path].nil? && !options[:image_path].empty?
|
|
275
|
-
Applitools::Screenshot.from_datastream ChunkyPNG::Datastream.from_file(options[:image_path]).to_s
|
|
276
|
-
elsif !options[:image_bytes].nil? && !options[:image_bytes].empty?
|
|
277
|
-
Applitools::Screenshot.from_datastream options[:image_bytes]
|
|
278
|
-
end
|
|
279
|
-
else
|
|
280
|
-
options[:image]
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
Applitools::ArgumentGuard.not_nil image, 'options[:image] can\'t be nil!'
|
|
284
|
-
|
|
285
|
-
image
|
|
286
|
-
end
|
|
287
|
-
end
|
|
288
|
-
end
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
module Applitools::Images
|
|
2
|
-
# @!visibility private
|
|
3
|
-
class EyesImagesScreenshot < ::Applitools::EyesScreenshot
|
|
4
|
-
SCREENSHOT_AS_IS = Applitools::EyesScreenshot::COORDINATE_TYPES[:screenshot_as_is].freeze
|
|
5
|
-
CONTEXT_RELATIVE = Applitools::EyesScreenshot::COORDINATE_TYPES[:context_relative].freeze
|
|
6
|
-
|
|
7
|
-
def initialize(image, options = {})
|
|
8
|
-
super image
|
|
9
|
-
return if (location = options[:location]).nil?
|
|
10
|
-
Applitools::ArgumentGuard.is_a? location, 'options[:location]', Applitools::Location
|
|
11
|
-
@bounds = Applitools::Region.new location.x, location.y, image.width, image.height
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def convert_location(location, from, to)
|
|
15
|
-
Applitools::ArgumentGuard.not_nil location, 'location'
|
|
16
|
-
Applitools::ArgumentGuard.not_nil from, 'from'
|
|
17
|
-
Applitools::ArgumentGuard.not_nil to, 'to'
|
|
18
|
-
|
|
19
|
-
Applitools::ArgumentGuard.is_a? location, 'location', Applitools::Location
|
|
20
|
-
|
|
21
|
-
result = Applitools::Location.new location.x, location.y
|
|
22
|
-
return result if from == to
|
|
23
|
-
|
|
24
|
-
case from
|
|
25
|
-
when SCREENSHOT_AS_IS
|
|
26
|
-
raise "Coordinate type conversation error: #{from} -> #{to}" unless to == CONTEXT_RELATIVE
|
|
27
|
-
result.offset bounds
|
|
28
|
-
return result
|
|
29
|
-
when CONTEXT_RELATIVE
|
|
30
|
-
raise "Coordinate type conversation error: #{from} -> #{to}" unless to == SCREENSHOT_AS_IS
|
|
31
|
-
result.offset(Applitools::Location.new(-bounds.x, -bounds.y))
|
|
32
|
-
return result
|
|
33
|
-
else
|
|
34
|
-
raise "Coordinate type conversation error: #{from} -> #{to}"
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def convert_region_location(region, from, to)
|
|
39
|
-
Applitools::ArgumentGuard.not_nil region, 'region'
|
|
40
|
-
return Core::Region.new(0, 0, 0, 0) if region.empty?
|
|
41
|
-
|
|
42
|
-
Applitools::ArgumentGuard.not_nil from, 'from'
|
|
43
|
-
Applitools::ArgumentGuard.not_nil to, 'to'
|
|
44
|
-
|
|
45
|
-
updated_location = convert_location region.location, from, to
|
|
46
|
-
|
|
47
|
-
Applitools::Region.new updated_location.x, updated_location.y, region.width, region.height
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def intersected_region(region, from, to = CONTEXT_RELATIVE)
|
|
51
|
-
Applitools::ArgumentGuard.not_nil region, 'region'
|
|
52
|
-
Applitools::ArgumentGuard.not_nil from, 'coordinates Type (from)'
|
|
53
|
-
|
|
54
|
-
return Applitools::Region.new(0, 0, 0, 0) if region.empty?
|
|
55
|
-
|
|
56
|
-
intersected_region = convert_region_location region, from, to
|
|
57
|
-
intersected_region.intersect bounds
|
|
58
|
-
return intersected_region if intersected_region.empty?
|
|
59
|
-
|
|
60
|
-
intersected_region.location = convert_location intersected_region.location, to, from
|
|
61
|
-
intersected_region
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def location_in_screenshot(location, coordinates_type)
|
|
65
|
-
Applitools::ArgumentGuard.not_nil location, 'location'
|
|
66
|
-
Applitools::ArgumentGuard.not_nil coordinates_type, 'coordinates_type'
|
|
67
|
-
location = convert_location(location, coordinates_type, CONTEXT_RELATIVE)
|
|
68
|
-
|
|
69
|
-
unless bounds.contains? location.left, location.top
|
|
70
|
-
raise Applitools::OutOfBoundsException.new "Location #{location} is not available in screenshot!"
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
convert_location location, CONTEXT_RELATIVE, SCREENSHOT_AS_IS
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def sub_screenshot(region, coordinates_type, throw_if_clipped = false, force_nil_if_clipped = false)
|
|
77
|
-
Applitools::ArgumentGuard.not_nil region, 'region'
|
|
78
|
-
Applitools::ArgumentGuard.not_nil coordinates_type, 'coordinates_type'
|
|
79
|
-
|
|
80
|
-
sub_screen_region = intersected_region region, coordinates_type, SCREENSHOT_AS_IS
|
|
81
|
-
|
|
82
|
-
if sub_screen_region.empty? || (throw_if_clipped && !region.size_equals?(sub_screen_region))
|
|
83
|
-
return nil if force_nil_if_clipped
|
|
84
|
-
Applitools::OutOfBoundsException.new "Region #{sub_screen_region} (#{coordinates_type}) is out of " \
|
|
85
|
-
" screenshot bounds #{bounds}"
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
sub_screenshot_image = Applitools::Screenshot.from_any_image(
|
|
89
|
-
image.crop(
|
|
90
|
-
sub_screen_region.left, sub_screen_region.top, sub_screen_region.width, sub_screen_region.height
|
|
91
|
-
).to_datastream.to_blob
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
relative_sub_screenshot_region = convert_region_location(sub_screen_region, SCREENSHOT_AS_IS, CONTEXT_RELATIVE)
|
|
95
|
-
|
|
96
|
-
Applitools::Images::EyesImagesScreenshot.new sub_screenshot_image,
|
|
97
|
-
location: relative_sub_screenshot_region.location
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
private
|
|
101
|
-
|
|
102
|
-
def bounds
|
|
103
|
-
@bounds ||= Applitools::Region.new(0, 0, image.width, image.height)
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
end
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
module Applitools::Images
|
|
2
|
-
class Target
|
|
3
|
-
class << self
|
|
4
|
-
def path(path)
|
|
5
|
-
raise Applitools::EyesIllegalArgument unless File.exist?(path)
|
|
6
|
-
new Applitools::Screenshot.from_image(ChunkyPNG::Image.from_file(path))
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def blob(blob_image)
|
|
10
|
-
Applitools::ArgumentGuard.not_nil blob_image, 'blob_image'
|
|
11
|
-
Applitools::ArgumentGuard.is_a? blob_image, 'blob_image', String
|
|
12
|
-
new Applitools::Screenshot.from_datastream(blob_image)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def image(image)
|
|
16
|
-
Applitools::ArgumentGuard.not_nil image, 'image'
|
|
17
|
-
Applitools::ArgumentGuard.is_a? image, 'image', ChunkyPNG::Image
|
|
18
|
-
new Applitools::Screenshot.from_image(image)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def screenshot(screenshot)
|
|
22
|
-
Applitools::ArgumentGuard.not_nil screenshot, 'screenshot'
|
|
23
|
-
Applitools::ArgumentGuard.is_a? screenshot, 'screenshot', Applitools::Screenshot
|
|
24
|
-
new screenshot
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def any(screenshot)
|
|
28
|
-
case screenshot
|
|
29
|
-
when Applitools::Screenshot
|
|
30
|
-
screenshot(screenshot)
|
|
31
|
-
when ChunkyPNG::Image
|
|
32
|
-
image(screenshot)
|
|
33
|
-
when String
|
|
34
|
-
begin
|
|
35
|
-
blob(screenshot)
|
|
36
|
-
rescue ChunkyPNG::SignatureMismatch
|
|
37
|
-
path(screenshot)
|
|
38
|
-
end
|
|
39
|
-
else
|
|
40
|
-
raise Applitools::EyesIllegalArgument.new "Passed screenshot is not image type (#{screenshot.class})"
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
attr_accessor :image, :options, :ignored_regions, :region_to_check, :floating_regions
|
|
46
|
-
|
|
47
|
-
def initialize(image)
|
|
48
|
-
Applitools::ArgumentGuard.not_nil(image, 'image')
|
|
49
|
-
Applitools::ArgumentGuard.is_a? image, 'image', Applitools::Screenshot
|
|
50
|
-
self.image = image
|
|
51
|
-
self.ignored_regions = []
|
|
52
|
-
self.floating_regions = []
|
|
53
|
-
self.options = {
|
|
54
|
-
trim: false
|
|
55
|
-
}
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def ignore(region = nil)
|
|
59
|
-
if region
|
|
60
|
-
Applitools::ArgumentGuard.is_a? region, 'region', Applitools::Region
|
|
61
|
-
ignored_regions << region
|
|
62
|
-
else
|
|
63
|
-
self.ignored_regions = []
|
|
64
|
-
end
|
|
65
|
-
self
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def floating(*args)
|
|
69
|
-
value = case args.first
|
|
70
|
-
when Applitools::FloatingRegion
|
|
71
|
-
proc { args.first }
|
|
72
|
-
when Applitools::Region
|
|
73
|
-
proc do
|
|
74
|
-
region = args.shift
|
|
75
|
-
Applitools::FloatingRegion.new region.left, region.top, region.width, region.height, *args
|
|
76
|
-
end
|
|
77
|
-
else
|
|
78
|
-
self.floating_regions = []
|
|
79
|
-
end
|
|
80
|
-
floating_regions << value
|
|
81
|
-
self
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def region(region = nil)
|
|
85
|
-
if region
|
|
86
|
-
Applitools::ArgumentGuard.is_a? region, 'region', Applitools::Region
|
|
87
|
-
self.region_to_check = region
|
|
88
|
-
else
|
|
89
|
-
self.region_to_check = nil
|
|
90
|
-
end
|
|
91
|
-
self
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def trim(value = true)
|
|
95
|
-
options[:trim] = value ? true : false
|
|
96
|
-
self
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def timeout(value = nil)
|
|
100
|
-
options[:timeout] = value ? value : nil
|
|
101
|
-
self
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
end
|