eyes_core 3.10.1 → 3.10.2
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 +30 -15
- data/lib/applitools/core/eyes_base.rb +60 -30
- data/lib/applitools/core/fixed_cut_provider.rb +2 -0
- data/lib/applitools/core/floating_region.rb +10 -1
- data/lib/applitools/core/fluent_interface.rb +13 -3
- data/lib/applitools/core/match_level_setter.rb +45 -0
- data/lib/applitools/core/match_window_data.rb +17 -4
- data/lib/applitools/core/region_provider.rb +4 -0
- data/lib/applitools/utils/utils.rb +5 -0
- data/lib/applitools/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5809ea0c1a4fce9a7233b53c2f93b811cd45e24
|
4
|
+
data.tar.gz: 7297d6577eb1d687fe9fd08954a9accbbd7273b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 224885021816ed5b60ba60c5e07a9469c3e991f1fb10a789935fce33b7119d2605202ea751b23da8bf3291f088e82b0ce71e461736610854b2a7ed03fb53f48a
|
7
|
+
data.tar.gz: 7257faf0af15b39d3d90a0708ee001f2f7aa55ffa9b4134745633af0b342bb56898316494b03da7547278431bcb5c4a6061ced8456475485de093d8ec0445d0a
|
@@ -100,8 +100,11 @@ module Applitools::Connectivity
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def start_session(session_start_info)
|
103
|
-
res = post(
|
104
|
-
|
103
|
+
res = post(
|
104
|
+
endpoint_url, body: Oj.dump(
|
105
|
+
startInfo: Applitools::Utils.camelcase_hash_keys(session_start_info.to_hash)
|
106
|
+
)
|
107
|
+
)
|
105
108
|
raise Applitools::EyesError.new("Request failed: #{res.status} #{res.body}") unless res.success?
|
106
109
|
|
107
110
|
response = Oj.load(res.body)
|
@@ -167,29 +170,41 @@ module Applitools::Connectivity
|
|
167
170
|
def long_request(url, method, request_delay, options = {})
|
168
171
|
delay = request_delay
|
169
172
|
options = { headers: {
|
170
|
-
'Eyes-Expect' => '202+location'
|
171
|
-
|
172
|
-
} }.merge! options
|
173
|
+
'Eyes-Expect' => '202+location'
|
174
|
+
}.merge(eyes_date_header) }.merge! options
|
173
175
|
res = request(url, method, options)
|
174
|
-
|
176
|
+
check_status(res, delay)
|
177
|
+
end
|
175
178
|
|
176
|
-
|
179
|
+
def eyes_date_header
|
180
|
+
{ 'Eyes-Date' => Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT') }
|
181
|
+
end
|
182
|
+
|
183
|
+
def check_status(res, delay)
|
184
|
+
case res.status
|
185
|
+
when HTTP_STATUS_CODES[:ok]
|
186
|
+
res
|
187
|
+
when HTTP_STATUS_CODES[:accepted]
|
177
188
|
second_step_url = res.headers[:location]
|
178
|
-
delay = [MAX_LONG_REQUEST_DELAY, (delay * LONG_REQUEST_DELAY_MULTIPLICATIVE_INCREASE_FACTOR).round].min
|
179
189
|
loop do
|
190
|
+
delay = [MAX_LONG_REQUEST_DELAY, (delay * LONG_REQUEST_DELAY_MULTIPLICATIVE_INCREASE_FACTOR).round].min
|
180
191
|
Applitools::EyesLogger.debug "Still running... retrying in #{delay}s"
|
181
192
|
sleep delay
|
182
|
-
second_step_options = {
|
183
|
-
|
184
|
-
}
|
193
|
+
second_step_options = {
|
194
|
+
headers: {}.merge(eyes_date_header)
|
195
|
+
}
|
185
196
|
res = request(second_step_url, :get, second_step_options)
|
186
197
|
break unless res.status == HTTP_STATUS_CODES[:ok]
|
187
198
|
end
|
199
|
+
check_status(res, delay)
|
200
|
+
when HTTP_STATUS_CODES[:created]
|
201
|
+
last_step_url = res.headers[:location]
|
202
|
+
request(last_step_url, :delete, headers: eyes_date_header)
|
203
|
+
when HTTP_STATUS_CODES[:gone]
|
204
|
+
raise Applitools::EyesError.new('The server task has gone.')
|
205
|
+
else
|
206
|
+
raise Applitools::EyesError.new('Unknown error processing long request')
|
188
207
|
end
|
189
|
-
|
190
|
-
raise Applitools::EyesError.new('The server task has gone.') if res.status == HTTP_STATUS_CODES[:gone]
|
191
|
-
return request(second_step_url, :delete) if res.status == HTTP_STATUS_CODES[:created]
|
192
|
-
raise Applitools::EyesError.new('Unknown error processing long request')
|
193
208
|
end
|
194
209
|
end
|
195
210
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'applitools/core/helpers'
|
2
2
|
require 'applitools/core/eyes_screenshot'
|
3
|
+
require_relative 'match_level_setter'
|
3
4
|
|
4
5
|
module Applitools
|
5
6
|
MATCH_LEVEL = {
|
@@ -12,6 +13,7 @@ module Applitools
|
|
12
13
|
}.freeze
|
13
14
|
|
14
15
|
class EyesBase
|
16
|
+
include Applitools::MatchLevelSetter
|
15
17
|
extend Forwardable
|
16
18
|
extend Applitools::Helpers
|
17
19
|
|
@@ -33,7 +35,7 @@ module Applitools
|
|
33
35
|
attr_accessor :app_name, :baseline_name, :branch_name, :parent_branch_name, :batch, :agent_id, :full_agent_id,
|
34
36
|
:match_timeout, :save_new_tests, :save_failed_tests, :failure_reports, :default_match_settings, :cut_provider,
|
35
37
|
:scale_ratio, :host_os, :host_app, :base_line_name, :position_provider, :viewport_size, :verbose_results,
|
36
|
-
:inferred_environment, :remove_session_if_matching
|
38
|
+
:inferred_environment, :remove_session_if_matching, :server_scale, :server_remainder, :match_level, :exact
|
37
39
|
|
38
40
|
abstract_attr_accessor :base_agent_id
|
39
41
|
abstract_method :capture_screenshot, true
|
@@ -68,14 +70,52 @@ module Applitools
|
|
68
70
|
end
|
69
71
|
end
|
70
72
|
|
73
|
+
self.exact = nil
|
74
|
+
self.match_level = Applitools::MATCH_LEVEL[:strict]
|
75
|
+
self.server_scale = 0
|
76
|
+
self.server_remainder = 0
|
77
|
+
|
71
78
|
@default_match_settings = {
|
72
|
-
match_level:
|
73
|
-
exact:
|
79
|
+
match_level: match_level,
|
80
|
+
exact: exact,
|
74
81
|
scale: server_scale,
|
75
82
|
remainder: server_remainder
|
76
83
|
}
|
77
84
|
end
|
78
85
|
|
86
|
+
# Sets default match_level which will be applied to any test, unless match_level is set for a test explicitly
|
87
|
+
# @param [Symbol] value Can be one of allowed match levels - :none, :layout, :layout2, :content, :strict or :exact
|
88
|
+
# @param [Hash] exact_options exact options are used only for :exact match level
|
89
|
+
# @option exact_options [Integer] :min_diff_intensity
|
90
|
+
# @option exact_options [Integer] :min_diff_width
|
91
|
+
# @option exact_options [Integer] :min_diff_height
|
92
|
+
# @option exact_options [Integer] :match_threshold
|
93
|
+
# @return [Target] Applitools::Selenium::Target or Applitools::Images::target
|
94
|
+
|
95
|
+
def default_match_level(value, exact_options = {})
|
96
|
+
@match_level, self.exact = match_level_with_exact(value, exact_options)
|
97
|
+
end
|
98
|
+
|
99
|
+
# rubocop:disable LineLength
|
100
|
+
# Sets default match settings
|
101
|
+
# @param [Hash] value
|
102
|
+
# @option value [Symbol] match_level
|
103
|
+
# @option value [Hash] exact exact values. Available keys are 'MinDiffIntensity', 'MinDiffWidth', 'MinDiffHeight', 'MatchThreshold'
|
104
|
+
# @option value [Fixnum] scale
|
105
|
+
# @option value [Fixnum] remainder
|
106
|
+
# rubocop:enable LineLength
|
107
|
+
|
108
|
+
def default_match_settings=(value)
|
109
|
+
Applitools::ArgumentGuard.is_a? value, 'value', Hash
|
110
|
+
extra_keys = value.keys - match_level_keys
|
111
|
+
unless extra_keys.empty?
|
112
|
+
raise Applitools::EyesIllegalArgument.new(
|
113
|
+
"Pasiing extra keys is prohibited! Passed extra keys: #{extra_keys}"
|
114
|
+
)
|
115
|
+
end
|
116
|
+
default_match_settings.merge! value
|
117
|
+
end
|
118
|
+
|
79
119
|
def batch
|
80
120
|
if @batch.nil?
|
81
121
|
logger.info 'No batch set'
|
@@ -92,28 +132,6 @@ module Applitools
|
|
92
132
|
end
|
93
133
|
end
|
94
134
|
|
95
|
-
def match_level=(level)
|
96
|
-
@default_match_settings[:match_level] = level
|
97
|
-
end
|
98
|
-
|
99
|
-
def match_level
|
100
|
-
@default_match_settings[:match_level]
|
101
|
-
end
|
102
|
-
|
103
|
-
def server_scale=(ratio)
|
104
|
-
@server_scale = ratio
|
105
|
-
@default_match_settings[:scale] = ratio
|
106
|
-
end
|
107
|
-
|
108
|
-
attr_reader :server_scale
|
109
|
-
|
110
|
-
def server_remainder=(ratio)
|
111
|
-
@server_remainder = ratio
|
112
|
-
@default_match_settings[:remainder] = ratio
|
113
|
-
end
|
114
|
-
|
115
|
-
attr_reader :server_remainder
|
116
|
-
|
117
135
|
def disabled=(value)
|
118
136
|
@disabled = Applitools::Utils.boolean_value value
|
119
137
|
end
|
@@ -137,7 +155,7 @@ module Applitools
|
|
137
155
|
def abort_if_not_closed
|
138
156
|
if disabled?
|
139
157
|
logger.info "#{__method__} Ignored"
|
140
|
-
return
|
158
|
+
return false
|
141
159
|
end
|
142
160
|
|
143
161
|
self.open = false
|
@@ -146,7 +164,7 @@ module Applitools
|
|
146
164
|
|
147
165
|
if running_session.nil?
|
148
166
|
logger.info 'Closed'
|
149
|
-
return
|
167
|
+
return false
|
150
168
|
end
|
151
169
|
|
152
170
|
logger.info 'Aborting server session...'
|
@@ -154,7 +172,7 @@ module Applitools
|
|
154
172
|
logger.info '---Test aborted'
|
155
173
|
|
156
174
|
rescue Applitools::EyesError => e
|
157
|
-
logger.error e.
|
175
|
+
logger.error e.message
|
158
176
|
|
159
177
|
ensure
|
160
178
|
self.running_session = nil
|
@@ -163,7 +181,7 @@ module Applitools
|
|
163
181
|
def open_base(options)
|
164
182
|
if disabled?
|
165
183
|
logger.info "#{__method__} Ignored"
|
166
|
-
return
|
184
|
+
return false
|
167
185
|
end
|
168
186
|
|
169
187
|
Applitools::ArgumentGuard.hash options, 'open_base parameter', [:test_name]
|
@@ -230,6 +248,8 @@ module Applitools
|
|
230
248
|
)
|
231
249
|
end
|
232
250
|
|
251
|
+
match_window_data.user_inputs = user_inputs
|
252
|
+
|
233
253
|
logger.info 'Calling match_window...'
|
234
254
|
result = @match_window_task.match_window(
|
235
255
|
match_window_data,
|
@@ -349,7 +369,7 @@ module Applitools
|
|
349
369
|
def close(throw_exception = true)
|
350
370
|
if disabled?
|
351
371
|
logger.info "#{__method__} Ignored"
|
352
|
-
return
|
372
|
+
return false
|
353
373
|
end
|
354
374
|
|
355
375
|
logger.info "close(#{throw_exception})"
|
@@ -416,6 +436,16 @@ module Applitools
|
|
416
436
|
|
417
437
|
private :full_agent_id, :full_agent_id=
|
418
438
|
|
439
|
+
def match_level_keys
|
440
|
+
%w(match_level exact scale remainder).map(&:to_sym)
|
441
|
+
end
|
442
|
+
|
443
|
+
def update_default_settings(match_data)
|
444
|
+
match_level_keys.each do |k|
|
445
|
+
match_data.send("#{k}=", default_match_settings[k])
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
419
449
|
def app_environment
|
420
450
|
Applitools::AppEnvironment.new os: host_os, hosting_app: host_app,
|
421
451
|
display_size: @viewport_size, inferred: inferred_environment
|
@@ -11,6 +11,8 @@ module Applitools
|
|
11
11
|
# Applitools::FixedCutProvider.new Applitools::Region.new(20,20, 300, 300)
|
12
12
|
# @example Creates cut provider by a set of fields
|
13
13
|
# Applitools::FixedCutProvider.new 20, 20, 300, 300
|
14
|
+
# @!parse def initialize(crop_region, header, left, right, footer); end
|
15
|
+
|
14
16
|
def initialize(*args)
|
15
17
|
self.region = nil
|
16
18
|
self.left = 0
|
@@ -2,11 +2,20 @@ require_relative 'region'
|
|
2
2
|
module Applitools
|
3
3
|
class FloatingRegion < Region
|
4
4
|
class << self
|
5
|
+
def any(element, max_left_offset, max_top_offset, max_right_offset, max_bottom_offset)
|
6
|
+
case element
|
7
|
+
when Applitools::Selenium::Element, ::Selenium::WebDriver::Element, Applitools::Region
|
8
|
+
for_element(element, max_left_offset, max_top_offset, max_right_offset, max_bottom_offset)
|
9
|
+
else
|
10
|
+
raise Applitools::EyesIllegalArgument.new "Unsupported element - #{element.class}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
5
14
|
def for_element(element, max_left_offset, max_top_offset, max_right_offset, max_bottom_offset)
|
6
|
-
Applitools::ArgumentGuard.is_a? element, 'element', Applitools::Selenium::Element
|
7
15
|
new element.location.x, element.location.y, element.size.width, element.size.height, max_left_offset,
|
8
16
|
max_top_offset, max_right_offset, max_bottom_offset
|
9
17
|
end
|
18
|
+
private :for_element
|
10
19
|
end
|
11
20
|
|
12
21
|
attr_accessor :max_top_offset, :max_right_offset, :max_bottom_offset, :max_left_offset
|
@@ -1,4 +1,6 @@
|
|
1
|
+
require_relative 'match_level_setter'
|
1
2
|
module Applitools::FluentInterface
|
3
|
+
include Applitools::MatchLevelSetter
|
2
4
|
def ignore_caret(value = false)
|
3
5
|
options[:ignore_caret] = value ? true : false
|
4
6
|
self
|
@@ -19,9 +21,17 @@ module Applitools::FluentInterface
|
|
19
21
|
self
|
20
22
|
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
# Sets match_level for current test
|
25
|
+
# @param [Symbol] value Can be one of allowed match levels - :none, :layout, :layout2, :content, :strict or :exact
|
26
|
+
# @param [Hash] exact_options exact options are used only for :exact match level
|
27
|
+
# @option exact_options [Integer] :min_diff_intensity
|
28
|
+
# @option exact_options [Integer] :min_diff_width
|
29
|
+
# @option exact_options [Integer] :min_diff_height
|
30
|
+
# @option exact_options [Integer] :match_threshold
|
31
|
+
# @return [Target] Applitools::Selenium::Target or Applitools::Images::target
|
32
|
+
|
33
|
+
def match_level(value, exact_options = {})
|
34
|
+
options[:match_level], options[:exact] = match_level_with_exact(value, exact_options)
|
25
35
|
self
|
26
36
|
end
|
27
37
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Applitools::MatchLevelSetter
|
2
|
+
def match_level_with_exact(value, exact_options = {})
|
3
|
+
raise Applitools::EyesError unless Applitools::MATCH_LEVEL.keys.include? value
|
4
|
+
if value != :exact && (exact_options && !exact_options.empty?)
|
5
|
+
raise Applitools::EyesError.new(
|
6
|
+
'Exact options are accepted only for EXACT match level'
|
7
|
+
)
|
8
|
+
end
|
9
|
+
[Applitools::MATCH_LEVEL[value], value == :exact ? convert_exact_options(exact_options) : nil]
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
EXACT_KEYS = {
|
15
|
+
:min_diff_intensity => 'MinDiffIntensity',
|
16
|
+
:min_diff_width => 'MinDiffWidth',
|
17
|
+
:min_diff_height => 'MinDiffHeight',
|
18
|
+
:match_threshold => 'MatchThreshold',
|
19
|
+
'MinDiffIntensity' => 'MinDiffIntensity',
|
20
|
+
'MinDiffWidth' => 'MinDiffWidth',
|
21
|
+
'MinDiffHeight' => 'MinDiffHeight',
|
22
|
+
'MatchThreshold' => 'MatchThreshold'
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
def convert_exact_options(options)
|
26
|
+
allowed_keys = EXACT_KEYS.keys
|
27
|
+
extra_keys = options.keys - allowed_keys
|
28
|
+
result = {
|
29
|
+
'MinDiffIntensity' => 0,
|
30
|
+
'MinDiffWidth' => 0,
|
31
|
+
'MinDiffHeight' => 0,
|
32
|
+
'MatchThreshold' => 0
|
33
|
+
}
|
34
|
+
unless extra_keys.empty?
|
35
|
+
raise Applitools::EyesIllegalArgument.new(
|
36
|
+
"Extra exact keys passed - [#{extra_keys.join(', ')}]"
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
allowed_keys.each do |k|
|
41
|
+
result[EXACT_KEYS[k]] = options[k] unless options[k].nil?
|
42
|
+
end
|
43
|
+
result
|
44
|
+
end
|
45
|
+
end
|
@@ -89,9 +89,8 @@ module Applitools
|
|
89
89
|
|
90
90
|
def user_inputs=(value)
|
91
91
|
Applitools::ArgumentGuard.is_a? value, 'value', Array
|
92
|
-
value.
|
93
|
-
|
94
|
-
end
|
92
|
+
current_data['UserInputs'] += value.select { |i| i.respond_to? :to_hash }
|
93
|
+
.select { |i| self.class.valid_input(i) }.map(&:to_hash)
|
95
94
|
current_data['Options']['UserInputs'] = current_data['UserInputs']
|
96
95
|
end
|
97
96
|
|
@@ -142,6 +141,20 @@ module Applitools
|
|
142
141
|
current_data['Options']['ImageMatchSettings']['remainder']
|
143
142
|
end
|
144
143
|
|
144
|
+
def exact
|
145
|
+
current_data['Options']['ImageMatchSettings']['Exact']
|
146
|
+
end
|
147
|
+
|
148
|
+
def exact=(value)
|
149
|
+
raise Applitools::EyesError.new('You should pass a hash as a value!') unless value.nil? || value.is_a?(Hash)
|
150
|
+
return current_data['Options']['ImageMatchSettings']['Exact'] = nil if value.nil?
|
151
|
+
current_value = exact || {}
|
152
|
+
%w(MinDiffIntensity MinDiffWidth MinDiffHeight MatchThreshold).each do |k|
|
153
|
+
current_value[k] = value[k]
|
154
|
+
end
|
155
|
+
current_data['Options']['ImageMatchSettings']['Exact'] = current_value
|
156
|
+
end
|
157
|
+
|
145
158
|
def read_target(target, driver)
|
146
159
|
# options
|
147
160
|
target_options_to_read.each do |field|
|
@@ -181,7 +194,7 @@ module Applitools
|
|
181
194
|
end
|
182
195
|
|
183
196
|
def target_options_to_read
|
184
|
-
%w(trim ignore_caret match_level ignore_mismatch)
|
197
|
+
%w(trim ignore_caret match_level ignore_mismatch exact)
|
185
198
|
end
|
186
199
|
|
187
200
|
private :target_options_to_read
|
@@ -16,6 +16,11 @@ module Applitools::Utils
|
|
16
16
|
uncapitalize(tokens.shift) + tokens.map(&:capitalize).join
|
17
17
|
end
|
18
18
|
|
19
|
+
def to_method_name(str)
|
20
|
+
str = str.to_s if !str.is_a?(String) && str.respond_to?(:to_s)
|
21
|
+
underscore(str).gsub(%r{\/}, '__')
|
22
|
+
end
|
23
|
+
|
19
24
|
def wrap(object)
|
20
25
|
if object.nil?
|
21
26
|
[]
|
data/lib/applitools/version.rb
CHANGED
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.2
|
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-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oily_png
|
@@ -222,6 +222,7 @@ files:
|
|
222
222
|
- lib/applitools/core/hash_extension.rb
|
223
223
|
- lib/applitools/core/helpers.rb
|
224
224
|
- lib/applitools/core/location.rb
|
225
|
+
- lib/applitools/core/match_level_setter.rb
|
225
226
|
- lib/applitools/core/match_result.rb
|
226
227
|
- lib/applitools/core/match_results.rb
|
227
228
|
- lib/applitools/core/match_single_check_data.rb
|
@@ -271,7 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
271
272
|
version: '0'
|
272
273
|
requirements: []
|
273
274
|
rubyforge_project:
|
274
|
-
rubygems_version: 2.
|
275
|
+
rubygems_version: 2.6.8
|
275
276
|
signing_key:
|
276
277
|
specification_version: 4
|
277
278
|
summary: Applitools Ruby SDK
|