eyes_core 3.10.1 → 3.10.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|