eyes_selenium 3.18.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,6 +4,7 @@ module Applitools
4
4
  extend self
5
5
  def get_script_by_file_name(fname)
6
6
  script = nil
7
+ return script unless Dir.exist?(Applitools::JS_PATH)
7
8
  begin
8
9
  Dir.chdir(Applitools::JS_PATH) do
9
10
  script = File.open(File.join('@applitools', 'dom-snapshot', 'dist', "#{fname}.js"), 'r').read
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: false
2
2
 
3
+
3
4
  module Applitools::Selenium
4
5
  # The main API gateway for the SDK
5
6
  class SeleniumEyes < Applitools::EyesBase
@@ -56,16 +57,7 @@ module Applitools::Selenium
56
57
  # @param [Applitools::Selenium::Driver] driver The driver instance.
57
58
  # @param [Hash] viewport_size The required browser's viewport size.
58
59
  def set_viewport_size(driver, viewport_size)
59
- Applitools::ArgumentGuard.not_nil(driver, 'Driver')
60
- Applitools::ArgumentGuard.not_nil(viewport_size, 'viewport_size')
61
- Applitools::ArgumentGuard.is_a?(viewport_size, 'viewport_size', Applitools::RectangleSize)
62
- begin
63
- Applitools::Utils::EyesSeleniumUtils.set_viewport_size eyes_driver(driver), viewport_size
64
- rescue => e
65
- Applitools::EyesLogger.error e.class
66
- Applitools::EyesLogger.error e.message
67
- raise Applitools::EyesError.new 'Failed to set viewport size!'
68
- end
60
+ super
69
61
  end
70
62
  end
71
63
 
@@ -100,7 +92,7 @@ module Applitools::Selenium
100
92
  :full_page_capture_algorithm_left_top_offset, :screenshot_type, :send_dom, :use_dom, :enable_patterns,
101
93
  :utils,
102
94
  :config
103
- attr_reader :driver
95
+ attr_accessor :driver
104
96
 
105
97
  def_delegators 'Applitools::EyesLogger', :logger, :log_handler, :log_handler=
106
98
  def_delegators 'config', *Applitools::Selenium::Configuration.methods_to_delegate
@@ -116,7 +108,7 @@ module Applitools::Selenium
116
108
  self.base_agent_id = "eyes.selenium.ruby/#{Applitools::VERSION}".freeze
117
109
  self.check_frame_or_element = false
118
110
  self.region_to_check = nil
119
- self.force_full_page_screenshot = false
111
+ # self.force_full_page_screenshot = false
120
112
  self.dont_get_title = false
121
113
  self.device_pixel_ratio = UNKNOWN_DEVICE_PIXEL_RATIO
122
114
  self.stitch_mode = Applitools::STITCH_MODE[:scroll]
@@ -162,41 +154,42 @@ module Applitools::Selenium
162
154
  # @return [Applitools::Selenium::Driver] A wrapped web driver which enables Eyes
163
155
  # trigger recording and frame handling
164
156
  def open(options = {})
165
- original_driver = options.delete(:driver)
166
- options[:viewport_size] = Applitools::RectangleSize.from_any_argument options[:viewport_size] if
167
- options[:viewport_size]
168
- Applitools::ArgumentGuard.not_nil original_driver, 'options[:driver]'
169
- # Applitools::ArgumentGuard.hash options, 'open(options)', [:app_name, :test_name]
170
-
171
- if disabled?
172
- logger.info('Ignored')
173
- return driver
174
- end
175
-
176
- @driver = self.class.eyes_driver(original_driver, self)
177
- perform_driver_specific_settings(original_driver)
178
-
179
- self.device_pixel_ratio = UNKNOWN_DEVICE_PIXEL_RATIO
180
- self.position_provider = self.class.position_provider(
181
- stitch_mode, driver, disable_horizontal_scrolling, disable_vertical_scrolling, explicit_entire_size
182
- )
183
-
184
- self.eyes_screenshot_factory = lambda do |image|
185
- Applitools::Selenium::ViewportScreenshot.new(
186
- image, driver: @driver, force_offset: position_provider.force_offset
187
- )
188
- end
189
-
190
- open_base(options) do
191
- self.viewport_size = get_viewport_size if force_driver_resolution_as_viewport_size
192
- ensure_running_session
193
- end
194
- if runner
195
- runner.add_batch(batch.id) do
196
- server_connector.close_batch(batch.id)
197
- end
198
- end
199
- @driver
157
+ universal_open(options)
158
+ # original_driver = options.delete(:driver)
159
+ # options[:viewport_size] = Applitools::RectangleSize.from_any_argument options[:viewport_size] if
160
+ # options[:viewport_size]
161
+ # Applitools::ArgumentGuard.not_nil original_driver, 'options[:driver]'
162
+ # # Applitools::ArgumentGuard.hash options, 'open(options)', [:app_name, :test_name]
163
+ #
164
+ # if disabled?
165
+ # logger.info('Ignored')
166
+ # return driver
167
+ # end
168
+ #
169
+ # @driver = self.class.eyes_driver(original_driver, self)
170
+ # perform_driver_specific_settings(original_driver)
171
+ #
172
+ # self.device_pixel_ratio = UNKNOWN_DEVICE_PIXEL_RATIO
173
+ # self.position_provider = self.class.position_provider(
174
+ # stitch_mode, driver, disable_horizontal_scrolling, disable_vertical_scrolling, explicit_entire_size
175
+ # )
176
+ #
177
+ # self.eyes_screenshot_factory = lambda do |image|
178
+ # Applitools::Selenium::ViewportScreenshot.new(
179
+ # image, driver: @driver, force_offset: position_provider.force_offset
180
+ # )
181
+ # end
182
+ #
183
+ # open_base(options) do
184
+ # self.viewport_size = get_viewport_size if force_driver_resolution_as_viewport_size
185
+ # ensure_running_session
186
+ # end
187
+ # if runner
188
+ # runner.add_batch(batch.id) do
189
+ # server_connector.close_batch(batch.id)
190
+ # end
191
+ # end
192
+ # @driver
200
193
  end
201
194
 
202
195
  def perform_driver_specific_settings(original_driver)
@@ -219,7 +212,15 @@ module Applitools::Selenium
219
212
  # @!visibility private
220
213
  def get_viewport_size(web_driver = driver)
221
214
  Applitools::ArgumentGuard.not_nil 'web_driver', web_driver
222
- self.utils.extract_viewport_size(driver)
215
+ # self.utils.extract_viewport_size(driver)
216
+ driver_config_json = web_driver.universal_driver_config
217
+
218
+ Applitools::EyesLogger.debug 'extract_viewport_size()'
219
+ viewport_size = runner.universal_client.core_get_viewport_size(driver_config_json)
220
+ result = Applitools::RectangleSize.new viewport_size[:width], viewport_size[:height]
221
+
222
+ Applitools::EyesLogger.debug "Viewport size is #{result}."
223
+ result
223
224
  end
224
225
 
225
226
  # Takes a snapshot and matches it with the expected output.
@@ -242,6 +243,9 @@ module Applitools::Selenium
242
243
  logger.info "check(#{name}) is called"
243
244
  self.tag_for_debug = name
244
245
  Applitools::ArgumentGuard.is_a? target, 'target', Applitools::Selenium::Target
246
+
247
+ return universal_check(name, target)
248
+
245
249
  target_to_check = target.finalize
246
250
  original_overflow = nil
247
251
  original_position_provider = position_provider
@@ -263,6 +267,7 @@ module Applitools::Selenium
263
267
  begin
264
268
  match_data = Applitools::MatchWindowData.new(default_match_settings)
265
269
  match_data.tag = name
270
+ match_data.variation_group_id = target_to_check.options[:variation_group_id] if target_to_check.options[:variation_group_id]
266
271
  eyes_element = target_to_check.region_to_check.call(driver)
267
272
 
268
273
  unless force_full_page_screenshot
@@ -49,49 +49,10 @@ module Applitools
49
49
  if args.empty?
50
50
  reset_ignore
51
51
  else
52
- requested_padding = if args.last.is_a? Applitools::PaddingBounds
53
- args.pop
54
- else
55
- Applitools::PaddingBounds::PIXEL_PADDING
56
- end
57
- ignored_regions << case args.first
58
- when Applitools::Region
59
- proc { args.first.padding(requested_padding) }
60
- when ::Selenium::WebDriver::Element
61
- proc do |driver, return_element = false|
62
- region = applitools_element_from_selenium_element(driver, args.first)
63
- padding_proc = proc do |reg|
64
- Applitools::Region.from_location_size(
65
- reg.location, reg.size
66
- ).padding(requested_padding)
67
- end
68
- next region, padding_proc if return_element
69
- padding_proc.call(region)
70
- end
71
- when Applitools::Selenium::Element
72
- proc do |_driver, return_element = false|
73
- region = args.first
74
- padding_proc = proc do |reg|
75
- Applitools::Region.from_location_size(
76
- reg.location, reg.size
77
- ).padding(requested_padding)
78
- end
79
- next region, padding_proc if return_element
80
- padding_proc.call(region)
81
- end
82
- else
83
- proc do |driver, return_element = false|
84
- region = driver.find_element(*args)
85
- padding_proc = proc do |reg|
86
- Applitools::Region.from_location_size(
87
- reg.location, reg.size
88
- ).padding(requested_padding)
89
- end
90
- next region, padding_proc if return_element
91
- padding_proc.call(region)
92
- end
93
- end
94
-
52
+ value = convert_to_universal(args)
53
+ value = { type: args[0], selector: args[1] } if value.nil?
54
+ value = value[:selector] if value.is_a?(Hash) && (value[:type].to_s === 'id')
55
+ ignored_regions << value
95
56
  end
96
57
  self
97
58
  end
@@ -120,49 +81,11 @@ module Applitools
120
81
  # @!parse def floating(region_or_element, bounds, left,top, right, bottom, padding); end;
121
82
 
122
83
  def floating(*args)
123
- requested_padding = if args.last.is_a? Applitools::PaddingBounds
124
- args.pop
125
- else
126
- Applitools::PaddingBounds::PIXEL_PADDING
127
- end
128
- value = case args.first
129
- when Applitools::FloatingRegion
130
- args.first.padding(requested_padding)
131
- when ::Applitools::Region
132
- Applitools::FloatingRegion.any(args.shift, *args).padding(requested_padding)
133
- when ::Selenium::WebDriver::Element
134
- proc do |driver, return_element = false|
135
- args_dup = args.dup
136
- region = applitools_element_from_selenium_element(driver, args_dup.shift)
137
- padding_proc = proc do |reg|
138
- Applitools::FloatingRegion.any(reg, *args_dup).padding(requested_padding)
139
- end
140
- next region, padding_proc if return_element
141
- padding_proc.call(region)
142
- end
143
- when ::Applitools::Selenium::Element
144
- proc do |_driver, return_element = false|
145
- args_dup = args.dup
146
- region = args_dup.shift
147
- padding_proc = proc do |reg|
148
- Applitools::FloatingRegion.any(reg, *args_dup).padding(requested_padding)
149
- end
150
- next region, padding_proc if return_element
151
- padding_proc.call(region)
152
- end
153
- else
154
- proc do |driver, return_element = false|
155
- args_dup = args.dup
156
- region = driver.find_element(args_dup.shift, args_dup.shift)
157
- padding_proc = proc do |reg|
158
- Applitools::FloatingRegion.any(
159
- reg, *args_dup
160
- ).padding(requested_padding)
161
- end
162
- next region, padding_proc if return_element
163
- padding_proc.call(region)
164
- end
165
- end
84
+ requested_padding = get_requested_padding(args)
85
+ value = convert_to_universal(args)
86
+ value = { type: args[0], selector: args[1] } if value.nil?
87
+ value = value[:selector] if value.is_a?(Hash) && (value[:type].to_s === 'id')
88
+ value = { region: value }.merge(requested_padding)
166
89
  floating_regions << value
167
90
  self
168
91
  end
@@ -249,6 +172,12 @@ module Applitools
249
172
  self
250
173
  end
251
174
 
175
+ def variation_group_id(value)
176
+ Applitools::ArgumentGuard.not_nil(value, 'variation_group_id')
177
+ options[:variation_group_id] = value
178
+ self
179
+ end
180
+
252
181
  def frame(*args)
253
182
  element = case args.first
254
183
  when ::Selenium::WebDriver::Element, Applitools::Selenium::Element, String
@@ -256,8 +185,9 @@ module Applitools
256
185
  else
257
186
  proc { |d| d.find_element(*args) }
258
187
  end
259
- frames << frame_or_element if frame_or_element
260
- self.frame_or_element = element
188
+ frames << element
189
+ # frames << frame_or_element if frame_or_element
190
+ # self.frame_or_element = element
261
191
  reset_for_fullscreen
262
192
  self
263
193
  end
@@ -274,23 +204,10 @@ module Applitools
274
204
  # @!parse def region(element, how, what); end;
275
205
 
276
206
  def region(*args)
277
- handle_frames
278
- self.region_to_check = case args.first
279
- when ::Selenium::WebDriver::Element
280
- proc do |driver|
281
- applitools_element_from_selenium_element(driver, args.first)
282
- end
283
- when Applitools::Selenium::Element, Applitools::Region
284
- proc { args.first }
285
- when String
286
- proc do |driver|
287
- driver.find_element(name_or_id: args.first)
288
- end
289
- else
290
- proc do |driver|
291
- driver.find_element(*args)
292
- end
293
- end
207
+ value = convert_to_universal(args)
208
+ value = { type: args[0], selector: args[1] } if value.nil?
209
+ value = value[:selector] if value.is_a?(Hash) && (value[:type].to_s === 'id')
210
+ self.region_to_check = value
294
211
  self.coordinate_type = Applitools::EyesScreenshot::COORDINATE_TYPES[:context_relative]
295
212
  options[:timeout] = nil
296
213
  reset_ignore
@@ -309,11 +226,16 @@ module Applitools
309
226
  end
310
227
 
311
228
  def before_render_screenshot_hook(hook)
312
- options[:script_hooks][:beforeCaptureScreenshot] = hook
229
+ if hook.is_a?(Hash) && hook[:beforeCaptureScreenshot]
230
+ options[:script_hooks] = hook
231
+ else
232
+ options[:script_hooks][:beforeCaptureScreenshot] = hook
233
+ end
313
234
  self
314
235
  end
315
236
 
316
237
  alias script_hook before_render_screenshot_hook
238
+ alias hooks before_render_screenshot_hook
317
239
 
318
240
  def finalize
319
241
  return self unless frame_or_element
@@ -333,11 +255,7 @@ module Applitools
333
255
  "The region type should be one of [#{Applitools::AccessibilityRegionType.enum_values.join(', ')}]"
334
256
  end
335
257
  handle_frames
336
- padding_proc = proc do |region|
337
- Applitools::AccessibilityRegion.new(
338
- region, options[:type]
339
- )
340
- end
258
+ padding_proc = proc { |region| Applitools::AccessibilityRegion.new(region, options[:type]) }
341
259
 
342
260
  accessibility_regions << case args.first
343
261
  when ::Selenium::WebDriver::Element
@@ -361,30 +279,34 @@ module Applitools
361
279
  next element, padding_proc if return_element
362
280
  padding_proc.call(element)
363
281
  end
282
+ when :css
283
+ # (:css, '.ignore', type: 'LargeText')
284
+ { region: args[1], type: options[:type] }
364
285
  else
365
286
  proc do |driver, return_element = false|
366
287
  elements = driver.find_elements(*args)
367
288
  next elements, padding_proc if return_element
368
289
  elements.map { |e| padding_proc.call(e) }
369
290
  end
291
+
370
292
  end
371
293
  self
372
294
  end
373
295
 
374
296
  def default_full_page_for_vg
375
- if options[:stitch_content].nil?
376
- case region_to_check
377
- when nil
378
- fully(true)
379
- when Proc
380
- begin
381
- r = region_to_check.call
382
- fully(true) if r == Applitools::Region::EMPTY
383
- rescue StandardError
384
- fully(false)
385
- end
386
- end
387
- end
297
+ # if options[:stitch_content].nil?
298
+ # case region_to_check
299
+ # when nil
300
+ # fully(true)
301
+ # when Proc
302
+ # begin
303
+ # r = region_to_check.call
304
+ # # fully(true) if r == Applitools::Region::EMPTY
305
+ # rescue StandardError
306
+ # fully(false)
307
+ # end
308
+ # end
309
+ # end
388
310
  nil
389
311
  end
390
312
 
@@ -392,6 +314,24 @@ module Applitools
392
314
  self.convert_coordinates_block = block
393
315
  end
394
316
 
317
+ def scroll_root_element(by, what = nil)
318
+ options[:scroll_root_element] = if is_element?(by)
319
+ ref = by.ref
320
+ ref = by.ref[1] if ref.is_a?(Array) && ref[0] === :element
321
+ { elementId: ref }
322
+ elsif what
323
+ { type: by.to_s, selector: what }
324
+ else
325
+ by
326
+ end
327
+ self
328
+ end
329
+
330
+ def layout_breakpoints(value = true)
331
+ options[:layout_breakpoints] = value.is_a?(Array) ? value : value
332
+ self
333
+ end
334
+
395
335
  private
396
336
 
397
337
  def reset_for_fullscreen
@@ -442,6 +382,67 @@ module Applitools
442
382
  xpath = driver.execute_script(Applitools::Selenium::Scripts::GET_ELEMENT_XPATH_JS, selenium_element)
443
383
  driver.find_element(:xpath, xpath)
444
384
  end
385
+
386
+ def get_requested_padding(args)
387
+ if args.last.is_a? Applitools::PaddingBounds
388
+ args.pop
389
+ elsif args.last.is_a?(Applitools::FloatingBounds)
390
+ args.pop.to_hash
391
+ else
392
+ {}
393
+ end
394
+ end
395
+
396
+
397
+
398
+ def is_element?(el)
399
+ el.is_a?(::Selenium::WebDriver::Element) || (el.is_a?(Applitools::Selenium::Element) && el.respond_to?(:ref))
400
+ end
401
+
402
+ def is_region?(region)
403
+ region.is_a?(Applitools::FloatingRegion) || region.is_a?(Applitools::Region) # || region.is_a?(Applitools::Selenium::Element)
404
+ end
405
+
406
+ def is_finder?(finders)
407
+ return false unless finders.is_a?(Array)
408
+ return false unless finders[1]
409
+ return true if [:uiautomator, :predicate, :accessibility_id].include?(finders[0].to_sym)
410
+ Applitools::Selenium::Driver::FINDERS.has_key?(finders[0].to_sym)
411
+ end
412
+
413
+ def convert_to_universal(args)
414
+ if is_element?(args.first)
415
+ ref = args.first.ref
416
+ ref = args.first.ref[1] if ref.is_a?(Array) && ref[0] === :element
417
+ return { elementId: ref }
418
+ end
419
+ return args.first.to_hash if is_region?(args.first)
420
+ if is_finder?(args)
421
+ if Applitools::Selenium::Driver::FINDERS.has_key?(args[0])
422
+ return {type: Applitools::Selenium::Driver::FINDERS[args[0]], selector: args[1]}
423
+ end
424
+ case args[0]
425
+ when :uiautomator # ANDROID_UI_AUTOMATOR: '-android uiautomator'
426
+ return {type: '-android uiautomator', selector: args[1]}
427
+ when :predicate # IOS_PREDICATE: '-ios predicate string',
428
+ return {type: '-ios predicate string', selector: args[1]}
429
+ when :accessibility_id
430
+ return {type: 'accessibility id', selector: args[1]}
431
+ end
432
+ end
433
+ if args.first.is_a?(String)
434
+ return proc { |driver| driver.find_element(name_or_id: args.first) }
435
+ end
436
+ if args.first.is_a?(Hash) && args.first.has_key?('selector')
437
+ if args.first.has_key?('shadow')
438
+ return {selector: args.first['selector'], shadow: args.first['shadow']}
439
+ else
440
+ return {selector: args.first['selector']}
441
+ end
442
+ end
443
+ nil
444
+ end
445
+
445
446
  end
446
447
  end
447
448
  end
@@ -51,6 +51,10 @@ module Applitools
51
51
  emulation_info.device_name + ' (chrome emulation)'
52
52
  end
53
53
 
54
+ def to_hash
55
+ {chromeEmulationInfo: emulation_info.json_data}
56
+ end
57
+
54
58
 
55
59
  private
56
60
 
@@ -40,6 +40,12 @@ module Applitools
40
40
  'desktop'
41
41
  end
42
42
 
43
+ def to_hash
44
+ result = viewport_size.to_h
45
+ result[:name] = browser_type unless browser_type.nil?
46
+ result
47
+ end
48
+
43
49
  end
44
50
  end
45
51
  end