eyes_core 3.18.1 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/applitools/appium/eyes.rb +2 -1
- data/lib/applitools/appium/target.rb +218 -193
- data/lib/applitools/connectivity/proxy.rb +11 -3
- data/lib/applitools/connectivity/server_connector.rb +4 -2
- data/lib/applitools/core/accessibility_level.rb +11 -0
- data/lib/applitools/core/batch_info.rb +24 -2
- data/lib/applitools/core/classic_runner.rb +8 -1
- data/lib/applitools/core/eyes_base.rb +82 -29
- data/lib/applitools/core/eyes_base_configuration.rb +34 -2
- data/lib/applitools/core/eyes_runner.rb +12 -0
- data/lib/applitools/core/floating_region.rb +17 -8
- data/lib/applitools/core/image_match_settings.rb +54 -0
- data/lib/applitools/core/match_level.rb +3 -1
- data/lib/applitools/core/match_window_data.rb +4 -0
- data/lib/applitools/core/session_start_info.rb +2 -1
- data/lib/applitools/core/test_results.rb +2 -2
- data/lib/applitools/core/universal_eyes_checks.rb +66 -0
- data/lib/applitools/core/universal_eyes_open.rb +100 -0
- data/lib/applitools/core/universal_new_api.rb +43 -0
- data/lib/applitools/universal_sdk/universal_check_settings.rb +184 -0
- data/lib/applitools/universal_sdk/universal_client.rb +142 -0
- data/lib/applitools/universal_sdk/universal_client_socket.rb +110 -0
- data/lib/applitools/universal_sdk/universal_eyes.rb +45 -0
- data/lib/applitools/universal_sdk/universal_eyes_config.rb +203 -0
- data/lib/applitools/universal_sdk/universal_eyes_manager.rb +40 -0
- data/lib/applitools/universal_sdk/universal_eyes_manager_config.rb +62 -0
- data/lib/applitools/universal_sdk/universal_server.rb +81 -0
- data/lib/applitools/utils/utils.rb +13 -0
- data/lib/applitools/version.rb +2 -1
- data/lib/eyes_core.rb +3 -0
- metadata +69 -2
@@ -0,0 +1,184 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Applitools
|
4
|
+
class UniversalCheckSettings
|
5
|
+
include Applitools::Jsonable
|
6
|
+
|
7
|
+
# export type CheckSettings<TElement, TSelector> = MatchSettings<RegionReference<TElement, TSelector>> &
|
8
|
+
# ScreenshotSettings<TElement, TSelector> & {
|
9
|
+
# name?: string
|
10
|
+
# disableBrowserFetching?: boolean
|
11
|
+
# layoutBreakpoints?: boolean | number[]
|
12
|
+
# visualGridOptions?: {[key: string]: any}
|
13
|
+
# hooks?: {beforeCaptureScreenshot: string}
|
14
|
+
# renderId?: string
|
15
|
+
# variationGroupId?: string
|
16
|
+
# timeout?: number
|
17
|
+
# }
|
18
|
+
json_fields :name,
|
19
|
+
:disableBrowserFetching,
|
20
|
+
:layoutBreakpoints,
|
21
|
+
:visualGridOptions,
|
22
|
+
:hooks,
|
23
|
+
:renderId,
|
24
|
+
:variationGroupId,
|
25
|
+
:timeout
|
26
|
+
|
27
|
+
# export type MatchSettings<TRegion> = {
|
28
|
+
# exact?: {
|
29
|
+
# minDiffIntensity: number
|
30
|
+
# minDiffWidth: number
|
31
|
+
# minDiffHeight: number
|
32
|
+
# matchThreshold: number
|
33
|
+
# }
|
34
|
+
# matchLevel?: MatchLevel
|
35
|
+
# sendDom?: boolean
|
36
|
+
# useDom?: boolean
|
37
|
+
# enablePatterns?: boolean
|
38
|
+
# ignoreCaret?: boolean
|
39
|
+
# ignoreDisplacements?: boolean
|
40
|
+
# accessibilitySettings?: {
|
41
|
+
# level?: AccessibilityLevel
|
42
|
+
# guidelinesVersion?: AccessibilityGuidelinesVersion
|
43
|
+
# }
|
44
|
+
# ignoreRegions?: TRegion[]
|
45
|
+
# layoutRegions?: TRegion[]
|
46
|
+
# strictRegions?: TRegion[]
|
47
|
+
# contentRegions?: TRegion[]
|
48
|
+
# floatingRegions?: (TRegion | FloatingRegion<TRegion>)[]
|
49
|
+
# accessibilityRegions?: (TRegion | AccessibilityRegion<TRegion>)[]
|
50
|
+
# }
|
51
|
+
json_fields :exact,
|
52
|
+
:matchLevel,
|
53
|
+
:sendDom,
|
54
|
+
:useDom,
|
55
|
+
:enablePatterns,
|
56
|
+
:ignoreCaret,
|
57
|
+
:ignoreDisplacements,
|
58
|
+
:accessibilitySettings,
|
59
|
+
:ignoreRegions,
|
60
|
+
:layoutRegions,
|
61
|
+
:strictRegions,
|
62
|
+
:contentRegions,
|
63
|
+
:floatingRegions,
|
64
|
+
:accessibilityRegions
|
65
|
+
|
66
|
+
# export type ScreenshotSettings<TElement, TSelector> = {
|
67
|
+
# region?: RegionReference<TElement, TSelector>
|
68
|
+
# frames?: (ContextReference<TElement, TSelector> | FrameReference<TElement, TSelector>)[]
|
69
|
+
# scrollRootElement?: ElementReference<TElement, TSelector>
|
70
|
+
# fully?: boolean
|
71
|
+
# }
|
72
|
+
json_fields :region,
|
73
|
+
:frames,
|
74
|
+
:scrollRootElement,
|
75
|
+
:fully
|
76
|
+
|
77
|
+
def initialize(*args)
|
78
|
+
options = Applitools::Utils.extract_options! args
|
79
|
+
options.keys.select {|k| options[k] && respond_to?("#{k}=") }.each {|k| send("#{k}=", options[k]) }
|
80
|
+
|
81
|
+
# self.timeout = Applitools::Connectivity::ServerConnector::DEFAULT_TIMEOUT
|
82
|
+
end
|
83
|
+
|
84
|
+
def normalize_element_selector(element)
|
85
|
+
if element.is_a?(::Selenium::WebDriver::Element) || element.is_a?(Applitools::Selenium::Element)
|
86
|
+
ref = element.ref
|
87
|
+
ref = element.ref[1] if ref.is_a?(Array) && ref[0] === :element
|
88
|
+
return { elementId: ref }
|
89
|
+
else
|
90
|
+
element
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def from_original_target(target, eyes)
|
95
|
+
# require('pry')
|
96
|
+
# binding.pry
|
97
|
+
|
98
|
+
self.accessibility_settings = eyes.accessibility_validation
|
99
|
+
self.disable_browser_fetching = eyes.dont_fetch_resources
|
100
|
+
|
101
|
+
self.accessibility_regions = target.accessibility_regions
|
102
|
+
self.content_regions = target.content_regions
|
103
|
+
self.floating_regions = target.floating_regions
|
104
|
+
|
105
|
+
if target.respond_to?(:frames)
|
106
|
+
self.frames = target.frames.map do |f|
|
107
|
+
f = f.call(eyes.driver) if f.is_a?(Proc)
|
108
|
+
normalize_element_selector(f)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
self.fully = target.options[:stitch_content]
|
113
|
+
self.hooks = target.options[:script_hooks]
|
114
|
+
|
115
|
+
# require('pry')
|
116
|
+
# binding.pry
|
117
|
+
|
118
|
+
self.ignore_regions = target.ignored_regions.map do |ir|
|
119
|
+
ir.is_a?(Proc) ? normalize_element_selector(ir.call(eyes.driver)) : ir
|
120
|
+
end
|
121
|
+
# self.ignore_regions = target.ignored_regions
|
122
|
+
self.layout_regions = target.layout_regions.map do |lr|
|
123
|
+
lr.is_a?(Proc) ? normalize_element_selector(lr.call(eyes.driver)) : lr
|
124
|
+
end
|
125
|
+
|
126
|
+
if target.region_to_check.is_a?(Hash)
|
127
|
+
self.region = target.region_to_check
|
128
|
+
elsif target.region_to_check.is_a?(String)
|
129
|
+
self.region = target.region_to_check
|
130
|
+
elsif target.region_to_check.is_a?(Proc)
|
131
|
+
# require('pry')
|
132
|
+
# binding.pry
|
133
|
+
el = target.region_to_check.call(eyes.driver)
|
134
|
+
self.region = normalize_element_selector(el) unless el.respond_to?(:empty?) && el.empty?
|
135
|
+
end
|
136
|
+
# self.region = normalize_element_selector(target.region_to_check.call(eyes.driver))
|
137
|
+
# self.region = nil if region.empty?
|
138
|
+
|
139
|
+
self.strict_regions = target.strict_regions
|
140
|
+
self.timeout = target.options[:timeout]
|
141
|
+
self.variation_group_id = target.options[:variation_group_id]
|
142
|
+
|
143
|
+
self.scroll_root_element = target.options[:scroll_root_element] || eyes.scroll_root_element
|
144
|
+
self.layout_breakpoints = target.options[:layout_breakpoints] || eyes.layout_breakpoints
|
145
|
+
|
146
|
+
self.exact = (target.options[:exact] && target.options[:exact].to_hash) || (eyes.exact && eyes.exact.to_hash)
|
147
|
+
self.enable_patterns = from_target_options_or_eyes(:enable_patterns, target.options, eyes)
|
148
|
+
self.ignore_caret = from_target_options_or_eyes(:ignore_caret, target.options, eyes)
|
149
|
+
self.ignore_displacements = from_target_options_or_eyes(:ignore_displacements, target.options, eyes)
|
150
|
+
self.match_level = from_target_options_or_eyes(:match_level, target.options, eyes)
|
151
|
+
self.send_dom = from_target_options_or_eyes(:send_dom, target.options, eyes)
|
152
|
+
self.use_dom = from_target_options_or_eyes(:use_dom, target.options, eyes)
|
153
|
+
self.visual_grid_options = from_target_options_or_eyes(:visual_grid_options, target.options, eyes)
|
154
|
+
# rescue => e
|
155
|
+
# require('pry')
|
156
|
+
# binding.pry
|
157
|
+
end
|
158
|
+
|
159
|
+
def to_hash
|
160
|
+
json_data.compact.reject do |_, v|
|
161
|
+
case v
|
162
|
+
when Array, Hash
|
163
|
+
v.empty?
|
164
|
+
when Numeric
|
165
|
+
v.zero?
|
166
|
+
# when FalseClass
|
167
|
+
# true
|
168
|
+
else
|
169
|
+
false
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
def from_target_options_or_eyes(what, options, eyes)
|
177
|
+
return options[what] unless options[what].nil?
|
178
|
+
return eyes.send(what) if eyes.respond_to?(what)
|
179
|
+
nil
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
end
|
184
|
+
# U-Notes : Added internal Applitools::UniversalCheckSettings
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eventmachine'
|
4
|
+
|
5
|
+
# require_relative 'universal_client_socket'
|
6
|
+
# require_relative 'universal_eyes_manager'
|
7
|
+
|
8
|
+
module Applitools::Connectivity
|
9
|
+
class UniversalClient
|
10
|
+
|
11
|
+
extend Forwardable
|
12
|
+
def_delegators 'Applitools::EyesLogger', :logger
|
13
|
+
|
14
|
+
SESSION_INIT = 'Core.makeSDK'
|
15
|
+
|
16
|
+
CORE_MAKE_MANAGER = 'Core.makeManager'
|
17
|
+
CORE_GET_VIEWPORT_SIZE = 'Core.getViewportSize'
|
18
|
+
CORE_SET_VIEWPORT_SIZE = 'Core.setViewportSize'
|
19
|
+
CORE_CLOSE_BATCHES = 'Core.closeBatches'
|
20
|
+
CORE_DELETE_TEST = 'Core.deleteTest'
|
21
|
+
|
22
|
+
EYES_MANAGER_MAKE_EYES = 'EyesManager.openEyes'
|
23
|
+
EYES_MANAGER_CLOSE_ALL_EYES = 'EyesManager.closeAllEyes'
|
24
|
+
EYES_CHECK = 'Eyes.check'
|
25
|
+
EYES_LOCATE = 'Eyes.locate'
|
26
|
+
EYES_EXTRACT_TEXT_REGIONS = 'Eyes.extractTextRegions'
|
27
|
+
EYES_EXTRACT_TEXT = 'Eyes.extractText'
|
28
|
+
EYES_CLOSE = 'Eyes.close'
|
29
|
+
EYES_ABORT = 'Eyes.abort'
|
30
|
+
|
31
|
+
|
32
|
+
def initialize(queue = EM::Queue.new)
|
33
|
+
@socket = Applitools::Connectivity::UniversalClientSocket.new
|
34
|
+
@queue = queue
|
35
|
+
prepare_socket
|
36
|
+
# store on open for next check calls
|
37
|
+
@open_config = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def make_manager(eyes_manager_config)
|
41
|
+
Applitools::EyesLogger.logger.debug "EyesManager config: #{eyes_manager_config}"
|
42
|
+
eyes_manager = core_make_manager(eyes_manager_config)
|
43
|
+
Applitools::EyesLogger.logger.debug "EyesManager applitools-ref-id: #{eyes_manager[:"applitools-ref-id"]}"
|
44
|
+
Applitools::UniversalEyesManager.new(eyes_manager, self)
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def core_make_manager(eyes_manager_config)
|
49
|
+
await(->(cb) { @socket.request(CORE_MAKE_MANAGER, eyes_manager_config, cb) })
|
50
|
+
end
|
51
|
+
|
52
|
+
def eyes_manager_make_eyes(manager, driver_config, config)
|
53
|
+
@open_config = config
|
54
|
+
|
55
|
+
await(->(cb) {
|
56
|
+
@socket.request(EYES_MANAGER_MAKE_EYES, {manager: manager, driver: driver_config, config: config}, cb)
|
57
|
+
})
|
58
|
+
end
|
59
|
+
|
60
|
+
def eyes_manager_close_all_eyes(manager)
|
61
|
+
await(->(cb) { @socket.request(EYES_MANAGER_CLOSE_ALL_EYES, {manager: manager}, cb) })
|
62
|
+
end
|
63
|
+
|
64
|
+
def eyes_check(eyes, settings)
|
65
|
+
await(->(cb) { @socket.request(EYES_CHECK, {eyes: eyes, settings: settings, config: @open_config}, cb) })
|
66
|
+
end
|
67
|
+
|
68
|
+
def eyes_locate(eyes, settings)
|
69
|
+
await(->(cb) { @socket.request(EYES_LOCATE, {eyes: eyes, settings: settings, config: @open_config}, cb) })
|
70
|
+
end
|
71
|
+
|
72
|
+
def eyes_extract_text_regions(eyes, settings)
|
73
|
+
await(->(cb) { @socket.request(EYES_EXTRACT_TEXT_REGIONS, {eyes: eyes, settings: settings, config: @open_config}, cb) })
|
74
|
+
end
|
75
|
+
|
76
|
+
def eyes_extract_text(eyes, regions)
|
77
|
+
await(->(cb) { @socket.request(EYES_EXTRACT_TEXT, {eyes: eyes, regions: regions, config: @open_config}, cb) })
|
78
|
+
end
|
79
|
+
|
80
|
+
def eyes_close(eyes)
|
81
|
+
await(->(cb) { @socket.request(EYES_CLOSE, {eyes: eyes}, cb) })
|
82
|
+
end
|
83
|
+
|
84
|
+
def eyes_abort(eyes)
|
85
|
+
await(->(cb) { @socket.request(EYES_ABORT, {eyes: eyes}, cb) })
|
86
|
+
end
|
87
|
+
|
88
|
+
def core_get_viewport_size(driver)
|
89
|
+
await(->(cb) { @socket.request(CORE_GET_VIEWPORT_SIZE, {driver: driver}, cb) })
|
90
|
+
end
|
91
|
+
|
92
|
+
def core_set_viewport_size(driver, size)
|
93
|
+
await(->(cb) { @socket.request(CORE_SET_VIEWPORT_SIZE, {driver: driver, size: size}, cb) })
|
94
|
+
end
|
95
|
+
|
96
|
+
def core_close_batches(close_batch_settings)
|
97
|
+
# batchIds, serverUrl?, apiKey?, proxy?
|
98
|
+
await(->(cb) { @socket.request(CORE_CLOSE_BATCHES, close_batch_settings, cb) })
|
99
|
+
end
|
100
|
+
|
101
|
+
def core_delete_test(delete_test_settings)
|
102
|
+
# testId, batchId, secretToken, serverUrl, apiKey?, proxy?
|
103
|
+
await(->(cb) { @socket.request(CORE_DELETE_TEST, delete_test_settings, cb) })
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
|
110
|
+
def prepare_socket
|
111
|
+
socket_uri = ::Applitools::Connectivity::UniversalServer.check_or_run
|
112
|
+
connect_and_configure_socket(socket_uri)
|
113
|
+
end
|
114
|
+
|
115
|
+
def connect_and_configure_socket(uri)
|
116
|
+
Thread.new do
|
117
|
+
EM.run do
|
118
|
+
@socket.connect(uri)
|
119
|
+
@socket.emit(SESSION_INIT, {
|
120
|
+
name: :rb,
|
121
|
+
version: ::Applitools::VERSION,
|
122
|
+
protocol: :webdriver,
|
123
|
+
cwd: Dir.pwd
|
124
|
+
})
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def await(function)
|
130
|
+
resolved = false
|
131
|
+
cb = ->(result) {
|
132
|
+
resolved = result
|
133
|
+
}
|
134
|
+
@queue.push(function)
|
135
|
+
@queue.pop {|fn| fn.call(cb)}
|
136
|
+
sleep 1 until !!resolved
|
137
|
+
resolved
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
142
|
+
# U-Notes : Added internal Applitools::Connectivity::UniversalClient
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faye/websocket'
|
4
|
+
require 'json'
|
5
|
+
require 'securerandom'
|
6
|
+
require 'colorize'
|
7
|
+
|
8
|
+
module Applitools::Connectivity
|
9
|
+
class UniversalClientSocket
|
10
|
+
attr_reader :listeners, :queue
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@listeners = {}
|
14
|
+
@queue = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def connect(uri, ws = ::Faye::WebSocket::Client.new(uri))
|
18
|
+
@socket = ws
|
19
|
+
|
20
|
+
queue.each {|command| command.call}
|
21
|
+
queue.clear
|
22
|
+
|
23
|
+
ws.on :message do |event|
|
24
|
+
message = JSON.parse(event.data, {:symbolize_names => true})
|
25
|
+
params = [message[:payload], message[:key]]
|
26
|
+
find_and_execute_listeners(message[:name], message[:key], params)
|
27
|
+
end
|
28
|
+
|
29
|
+
ws.on :close do |event|
|
30
|
+
find_and_execute_listeners('close')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def emit(message, payload)
|
35
|
+
command = ->() {@socket.send(serialize(message, payload))}
|
36
|
+
@socket ? command.call : queue.push(command)
|
37
|
+
end
|
38
|
+
|
39
|
+
def command(name, fn)
|
40
|
+
on(name, ->(payload, key) {
|
41
|
+
begin
|
42
|
+
log("[#{'COMMAND'.yellow}] #{name}, #{key}, #{JSON.pretty_generate(payload)}")
|
43
|
+
result = fn.call(payload)
|
44
|
+
emit({name: name, key: key}, {result: result})
|
45
|
+
rescue => error
|
46
|
+
log("[#{'COMMAND ERROR'.red}] #{error}")
|
47
|
+
emit({name: name, key: key}, error.message || error)
|
48
|
+
end
|
49
|
+
})
|
50
|
+
end
|
51
|
+
|
52
|
+
def request(name, payload, cb = nil, key = SecureRandom.uuid)
|
53
|
+
log("[#{'REQUEST'.blue}] #{name}, #{key}, #{JSON.pretty_generate(payload)}")
|
54
|
+
emit({name: name, key: key}, payload)
|
55
|
+
once({name: name, key: key}, Proc.new {|result|
|
56
|
+
cb.call(result[:result] || result[:error] || true) if cb
|
57
|
+
})
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def find_and_execute_listeners(name, key = nil, params = [])
|
63
|
+
name_with_key = "#{name}/#{key}"
|
64
|
+
fns = listeners[name.to_sym]
|
65
|
+
fns = listeners[name_with_key.to_sym] if (!fns)
|
66
|
+
return if (!fns)
|
67
|
+
fns.each {|fn| fn.call(*params)}
|
68
|
+
end
|
69
|
+
|
70
|
+
def serialize(type, payload)
|
71
|
+
message = type.is_a?(String) ?
|
72
|
+
{:name => type, :payload => payload} : {:name => type[:name], key: type[:key], :payload => payload}
|
73
|
+
JSON.generate(message)
|
74
|
+
end
|
75
|
+
|
76
|
+
def get_name_from_type(type)
|
77
|
+
type.is_a?(String) ? type : "#{type[:name]}/#{type[:key]}"
|
78
|
+
end
|
79
|
+
|
80
|
+
def on(type, fn)
|
81
|
+
name = get_name_from_type(type)
|
82
|
+
fns = listeners[name.to_sym]
|
83
|
+
if (!fns)
|
84
|
+
fns = []
|
85
|
+
listeners[name.to_sym] = fns
|
86
|
+
end
|
87
|
+
fns.push(fn)
|
88
|
+
end
|
89
|
+
|
90
|
+
def off(type)
|
91
|
+
name = get_name_from_type(type)
|
92
|
+
listeners.delete(name.to_sym)
|
93
|
+
end
|
94
|
+
|
95
|
+
def once(type, fn)
|
96
|
+
on(type, ->(*args) {
|
97
|
+
fn.call(*args)
|
98
|
+
off(type)
|
99
|
+
})
|
100
|
+
end
|
101
|
+
|
102
|
+
def log(message)
|
103
|
+
if ENV['APPLITOOLS_SHOW_UNIVERSAL_LOGS']
|
104
|
+
Applitools::EyesLogger.logger.debug message
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
110
|
+
# U-Notes : Added internal Applitools::Connectivity::UniversalClientSocket
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Applitools
|
4
|
+
class UniversalEyes
|
5
|
+
|
6
|
+
extend Forwardable
|
7
|
+
def_delegators 'Applitools::EyesLogger', :logger
|
8
|
+
|
9
|
+
def initialize(eyes, universal_client)
|
10
|
+
@eyes = eyes
|
11
|
+
@universal_client = universal_client
|
12
|
+
end
|
13
|
+
|
14
|
+
def check(settings)
|
15
|
+
elapsed_time_start = Time.now
|
16
|
+
# Applitools::EyesLogger.logger.debug "check settings: #{settings}"
|
17
|
+
check_result = @universal_client.eyes_check(@eyes, settings)
|
18
|
+
# Applitools::EyesLogger.logger.debug "check_result: #{check_result}"
|
19
|
+
Applitools::EyesLogger.logger.info "Completed in #{format('%.2f', Time.now - elapsed_time_start)} seconds"
|
20
|
+
check_result
|
21
|
+
end
|
22
|
+
|
23
|
+
def close
|
24
|
+
@universal_client.eyes_close(@eyes)
|
25
|
+
end
|
26
|
+
|
27
|
+
def abort
|
28
|
+
@universal_client.eyes_abort(@eyes)
|
29
|
+
end
|
30
|
+
|
31
|
+
def locate(settings)
|
32
|
+
@universal_client.eyes_locate(@eyes, settings)
|
33
|
+
end
|
34
|
+
|
35
|
+
def extract_text_regions(patterns_array)
|
36
|
+
@universal_client.eyes_extract_text_regions(@eyes, patterns_array)
|
37
|
+
end
|
38
|
+
|
39
|
+
def extract_text(targets_array)
|
40
|
+
@universal_client.eyes_extract_text(@eyes, targets_array)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
# U-Notes : Added internal Applitools::UniversalEyes
|
@@ -0,0 +1,203 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Applitools
|
4
|
+
class UniversalEyesConfig
|
5
|
+
include Applitools::Jsonable
|
6
|
+
|
7
|
+
# export type EyesBaseConfig = {
|
8
|
+
# logs?: LogHandler
|
9
|
+
# debugScreenshots?: DebugScreenshotHandler
|
10
|
+
# agentId?: string
|
11
|
+
# apiKey?: string
|
12
|
+
# serverUrl?: string
|
13
|
+
# proxy?: Proxy
|
14
|
+
# isDisabled?: boolean
|
15
|
+
# connectionTimeout?: number
|
16
|
+
# removeSession?: boolean
|
17
|
+
# remoteEvents?: {serverUrl: string; accessKey?: string; timeout?: number}
|
18
|
+
# }
|
19
|
+
json_fields :logs,
|
20
|
+
:debugScreenshots,
|
21
|
+
:agentId,
|
22
|
+
:apiKey,
|
23
|
+
:serverUrl,
|
24
|
+
:proxy,
|
25
|
+
:isDisabled,
|
26
|
+
:connectionTimeout,
|
27
|
+
:removeSession,
|
28
|
+
:remoteEvents
|
29
|
+
|
30
|
+
# export type EyesOpenConfig = {
|
31
|
+
# appName?: string
|
32
|
+
# testName?: string
|
33
|
+
# displayName?: string
|
34
|
+
# viewportSize?: Size
|
35
|
+
# sessionType?: SessionType
|
36
|
+
# properties?: CustomProperty[]
|
37
|
+
# batch?: Batch
|
38
|
+
# defaultMatchSettings?: MatchSettings<Region>
|
39
|
+
# hostApp?: string
|
40
|
+
# hostOS?: string
|
41
|
+
# hostAppInfo?: string
|
42
|
+
# hostOSInfo?: string
|
43
|
+
# deviceInfo?: string
|
44
|
+
# baselineEnvName?: string
|
45
|
+
# environmentName?: string
|
46
|
+
# branchName?: string
|
47
|
+
# parentBranchName?: string
|
48
|
+
# baselineBranchName?: string
|
49
|
+
# compareWithParentBranch?: boolean
|
50
|
+
# ignoreBaseline?: boolean
|
51
|
+
# saveFailedTests?: boolean
|
52
|
+
# saveNewTests?: boolean
|
53
|
+
# saveDiffs?: boolean
|
54
|
+
# dontCloseBatches?: boolean
|
55
|
+
# }
|
56
|
+
json_fields :appName,
|
57
|
+
:testName,
|
58
|
+
:displayName,
|
59
|
+
:viewportSize,
|
60
|
+
:sessionType,
|
61
|
+
:properties,
|
62
|
+
:batch,
|
63
|
+
:defaultMatchSettings,
|
64
|
+
:hostApp,
|
65
|
+
:hostOS,
|
66
|
+
:hostAppInfo,
|
67
|
+
:hostOSInfo,
|
68
|
+
:deviceInfo,
|
69
|
+
:baselineEnvName,
|
70
|
+
:environmentName,
|
71
|
+
:branchName,
|
72
|
+
:parentBranchName,
|
73
|
+
:baselineBranchName,
|
74
|
+
:compareWithParentBranch,
|
75
|
+
:ignoreBaseline,
|
76
|
+
:saveFailedTests,
|
77
|
+
:saveNewTests,
|
78
|
+
:saveDiffs,
|
79
|
+
:dontCloseBatches
|
80
|
+
|
81
|
+
# export type EyesCheckConfig = {
|
82
|
+
# sendDom?: boolean
|
83
|
+
# matchTimeout?: number
|
84
|
+
# forceFullPageScreenshot?: boolean
|
85
|
+
# }
|
86
|
+
json_fields :sendDom,
|
87
|
+
:matchTimeout,
|
88
|
+
:forceFullPageScreenshot
|
89
|
+
|
90
|
+
# export type EyesClassicConfig<TElement = unknown, TSelector = unknown> = {
|
91
|
+
# waitBeforeScreenshots?: number
|
92
|
+
# stitchMode?: StitchMode
|
93
|
+
# hideScrollbars?: boolean
|
94
|
+
# hideCaret?: boolean
|
95
|
+
# stitchOverlap?: number
|
96
|
+
# scrollRootElement?: TElement | TSelector
|
97
|
+
# cut?: ImageCropRect | ImageCropRegion
|
98
|
+
# rotation?: ImageRotation
|
99
|
+
# scaleRatio?: number
|
100
|
+
# }
|
101
|
+
json_fields :waitBeforeScreenshots,
|
102
|
+
:stitchMode,
|
103
|
+
:hideScrollbars,
|
104
|
+
:hideCaret,
|
105
|
+
:stitchOverlap,
|
106
|
+
:scrollRootElement,
|
107
|
+
:cut,
|
108
|
+
:rotation,
|
109
|
+
:scaleRatio
|
110
|
+
|
111
|
+
# export type EyesUFGConfig = {
|
112
|
+
# concurrentSessions?: number
|
113
|
+
# browsersInfo?: (DesktopBrowserRenderer | ChromeEmulationDeviceRenderer | IOSDeviceRenderer)[]
|
114
|
+
# visualGridOptions?: Record<string, any>
|
115
|
+
# layoutBreakpoints?: boolean | number[]
|
116
|
+
# disableBrowserFetching?: boolean
|
117
|
+
# }
|
118
|
+
json_fields :concurrentSessions,
|
119
|
+
:browsersInfo,
|
120
|
+
:visualGridOptions,
|
121
|
+
:layoutBreakpoints,
|
122
|
+
:disableBrowserFetching
|
123
|
+
|
124
|
+
# 23 + 3 + 2 + 11 = 39
|
125
|
+
FROM_ORIGINAL_EYES = [:api_key, :app_name, :batch, :browsers_info, :concurrent_sessions, :debug_screenshots,
|
126
|
+
:force_full_page_screenshot, :hide_caret, :hide_scrollbars, :host_app, :host_os, :match_timeout, :proxy,
|
127
|
+
:save_failed_tests, :save_new_tests, :scale_ratio, :send_dom, :server_url, :stitch_mode, :test_name,
|
128
|
+
:viewport_size, :visual_grid_options, :wait_before_screenshots] + [
|
129
|
+
:disabled?, # disabled? => is_disabled
|
130
|
+
:stitching_overlap, # SeleniumEyes.stitching_overlap => stitch_overlap
|
131
|
+
:dont_fetch_resources # dont_fetch_resources => disable_browser_fetching
|
132
|
+
] + [
|
133
|
+
:layout_breakpoints,
|
134
|
+
:scroll_root_element,
|
135
|
+
] + [
|
136
|
+
:environment_name, :branch_name, :default_match_settings, :properties, :parent_branch_name,
|
137
|
+
:compare_with_parent_branch, :baseline_env_name, :save_diffs, :session_type, :baseline_branch_name
|
138
|
+
]
|
139
|
+
|
140
|
+
# 51 - 39 - 2 = 10
|
141
|
+
OTHER = [:logs, :remove_session, :remote_events, :display_name, :host_app_info, :host_os_info, :device_info,
|
142
|
+
:ignore_baseline, :cut, :rotation ]
|
143
|
+
|
144
|
+
|
145
|
+
alias disabled= is_disabled=
|
146
|
+
alias stitching_overlap= stitch_overlap=
|
147
|
+
alias dont_fetch_resources= disable_browser_fetching=
|
148
|
+
|
149
|
+
def initialize(*args)
|
150
|
+
options = Applitools::Utils.extract_options! args
|
151
|
+
options.keys.select {|k| options[k] && respond_to?("#{k}=") }.each {|k| send("#{k}=", options[k]) }
|
152
|
+
# other
|
153
|
+
self.connection_timeout = Applitools::Connectivity::ServerConnector::DEFAULT_TIMEOUT
|
154
|
+
if 'true'.casecmp(ENV['APPLITOOLS_DONT_CLOSE_BATCHES'] || '') == 0
|
155
|
+
self.dont_close_batches = true
|
156
|
+
Applitools::EyesLogger.info('APPLITOOLS_DONT_CLOSE_BATCHES environment variable set to true. Doing nothing.')
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def from_original_sdk(original_eyes)
|
161
|
+
FROM_ORIGINAL_EYES.each {|m| copy_from(m, original_eyes) }
|
162
|
+
self.agent_id = original_eyes.base_agent_id if original_eyes.respond_to?(:base_agent_id)
|
163
|
+
self.agent_id = original_eyes.full_agent_id if original_eyes.respond_to?(:full_agent_id)
|
164
|
+
# self.display_name = original_eyes.app_name
|
165
|
+
prepare_for_json!
|
166
|
+
end
|
167
|
+
|
168
|
+
def copy_from(what, from)
|
169
|
+
if from.respond_to?(what)
|
170
|
+
send("#{what.to_s.chomp('?') }=", from.send(what))
|
171
|
+
else
|
172
|
+
puts "respond_to? #{what} - fail"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def prepare_for_json!
|
177
|
+
self.batch = batch.to_hash if batch.is_a?(Applitools::BatchInfo)
|
178
|
+
self.browsers_info = browsers_info.to_hash if browsers_info.is_a?(Applitools::Selenium::BrowsersInfo)
|
179
|
+
self.default_match_settings = default_match_settings.to_hash if default_match_settings.is_a?(Applitools::ImageMatchSettings)
|
180
|
+
self.proxy = proxy.to_hash if proxy.is_a?(Applitools::Connectivity::Proxy)
|
181
|
+
self.viewport_size = viewport_size.to_h if viewport_size.is_a?(Applitools::RectangleSize)
|
182
|
+
# require 'pry'
|
183
|
+
# binding.pry
|
184
|
+
end
|
185
|
+
|
186
|
+
def to_hash
|
187
|
+
json_data.compact.reject do |_, v|
|
188
|
+
case v
|
189
|
+
when Array, Hash
|
190
|
+
v.empty?
|
191
|
+
when Numeric
|
192
|
+
v.zero?
|
193
|
+
# when FalseClass
|
194
|
+
# true
|
195
|
+
else
|
196
|
+
false
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
203
|
+
# U-Notes : Added internal Applitools::UniversalEyesConfig
|