eyes_selenium 3.14.3 → 3.14.4
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 +5 -5
- data/lib/applitools/selenium/border_aware_element_content_location_provider.rb +2 -0
- data/lib/applitools/selenium/browser.rb +66 -56
- data/lib/applitools/selenium/context_based_scale_provider.rb +2 -0
- data/lib/applitools/selenium/css_transform/css_transform.rb +21 -0
- data/lib/applitools/selenium/css_translate_element_position_provider.rb +48 -0
- data/lib/applitools/selenium/css_translate_position_provider.rb +29 -10
- data/lib/applitools/selenium/dom_capture/dom_capture.rb +113 -0
- data/lib/applitools/selenium/dom_capture/dom_capture_script.rb +103 -0
- data/lib/applitools/selenium/driver.rb +9 -2
- data/lib/applitools/selenium/element.rb +2 -0
- data/lib/applitools/selenium/element_position_provider.rb +3 -1
- data/lib/applitools/selenium/entire_element_screenshot.rb +20 -0
- data/lib/applitools/selenium/eyes.rb +203 -396
- data/lib/applitools/selenium/eyes_screenshot.rb +60 -0
- data/lib/applitools/selenium/eyes_target_locator.rb +12 -24
- data/lib/applitools/selenium/fixed_cut_provider.rb +48 -0
- data/lib/applitools/selenium/frame.rb +11 -1
- data/lib/applitools/selenium/frame_chain.rb +9 -1
- data/lib/applitools/selenium/full_page_capture_algorithm.rb +85 -50
- data/lib/applitools/selenium/fullpage_screenshot.rb +37 -0
- data/lib/applitools/selenium/keyboard.rb +2 -0
- data/lib/applitools/selenium/mouse.rb +2 -0
- data/lib/applitools/selenium/move_to_region_visibility_strategy.rb +2 -0
- data/lib/applitools/selenium/nop_region_visibility_strategy.rb +2 -0
- data/lib/applitools/selenium/region_provider.rb +91 -0
- data/lib/applitools/selenium/sauce/driver.rb +2 -0
- data/lib/applitools/selenium/scroll_position_provider.rb +13 -2
- data/lib/applitools/selenium/takes_screenshot_image_provider.rb +5 -3
- data/lib/applitools/selenium/target.rb +32 -6
- data/lib/applitools/selenium/viewport_screenshot.rb +46 -0
- data/lib/applitools/selenium/viewport_size.rb +2 -0
- data/lib/applitools/version.rb +3 -1
- data/lib/eyes_selenium.rb +4 -9
- metadata +16 -27
- data/lib/applitools/capybara.rb +0 -8
- data/lib/applitools/poltergeist/applitools_compatible.rb +0 -32
- data/lib/applitools/poltergeist/driver.rb +0 -11
- data/lib/applitools/selenium/capybara/capybara_settings.rb +0 -23
- data/lib/applitools/selenium/capybara/driver.rb +0 -37
- data/lib/applitools/selenium/eyes_full_page_screenshot.rb +0 -47
- data/lib/applitools/selenium/eyes_web_driver_screenshot.rb +0 -341
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
1
3
|
require 'socket'
|
2
4
|
require 'selenium-webdriver'
|
3
5
|
|
@@ -137,13 +139,19 @@ module Applitools::Selenium
|
|
137
139
|
|
138
140
|
def find_element(*args)
|
139
141
|
how, what = extract_args(args)
|
140
|
-
|
142
|
+
return find_element_by_name_or_id(what) if how == :name_or_id
|
141
143
|
# Make sure that "how" is a valid locator.
|
142
144
|
raise ArgumentError, "cannot find element by: #{how.inspect}" unless FINDERS[how.to_sym]
|
143
145
|
|
144
146
|
Applitools::Selenium::Element.new(self, driver.find_element(how, what))
|
145
147
|
end
|
146
148
|
|
149
|
+
def find_element_by_name_or_id(name_or_id)
|
150
|
+
found_by_name = find_elements name: name_or_id
|
151
|
+
return found_by_name.first unless found_by_name.empty?
|
152
|
+
find_element id: name_or_id
|
153
|
+
end
|
154
|
+
|
147
155
|
# Finds elements in a window.
|
148
156
|
# @param [Symbol] how Defines the way that +what+ parameter will be interpreted (finder). Can be one
|
149
157
|
# of: +:class+, +:class_name+, +:css+, +:id+, +:link+, +:link_text+, +:name+, +:partial_link_text+, +:tag_name+,
|
@@ -278,7 +286,6 @@ module Applitools::Selenium
|
|
278
286
|
when :frame
|
279
287
|
logger.info 'Frame.'
|
280
288
|
frame_location_size = Applitools::Selenium::BorderAwareElementContentLocationProvider.new target_frame
|
281
|
-
|
282
289
|
return parent.frame_chain!.push(
|
283
290
|
Applitools::Selenium::Frame.new(
|
284
291
|
reference: target_frame, frame_id: '',
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Applitools::Selenium
|
2
4
|
# @!visibility private
|
3
5
|
class ElementPositionProvider
|
@@ -30,7 +32,7 @@ module Applitools::Selenium
|
|
30
32
|
# Gets the enitire size of the element.
|
31
33
|
#
|
32
34
|
# @return [Applitools::RectangleSize] The size of the element.
|
33
|
-
def entire_size
|
35
|
+
def entire_size(_image_width, _image_height)
|
34
36
|
logger.info 'entire_size()'
|
35
37
|
result = Applitools::RectangleSize.new(element.scroll_width, element.scroll_height)
|
36
38
|
logger.info "Entire size: #{result}"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'eyes_screenshot'
|
4
|
+
|
5
|
+
module Applitools::Selenium
|
6
|
+
# @!visibility private
|
7
|
+
class EntireElementScreenshot < Applitools::Selenium::EyesScreenshot
|
8
|
+
def sub_screenshot(*_args)
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def screenshot_offset
|
13
|
+
region_provider.eye_region.location
|
14
|
+
end
|
15
|
+
|
16
|
+
def top_left_location
|
17
|
+
@top_left_location ||= screenshot_offset
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
1
3
|
module Applitools::Selenium
|
2
4
|
# The main API gateway for the SDK
|
3
5
|
class Eyes < Applitools::EyesBase
|
@@ -13,6 +15,12 @@ module Applitools::Selenium
|
|
13
15
|
|
14
16
|
DEFAULT_STITCHING_OVERLAP = 50 # Pixels
|
15
17
|
|
18
|
+
ENTIRE_ELEMENT_SCREENSHOT = 0
|
19
|
+
|
20
|
+
FULLPAGE_SCREENSHOT = 1
|
21
|
+
|
22
|
+
VIEWPORT_SCREENSHOT = 2
|
23
|
+
|
16
24
|
extend Forwardable
|
17
25
|
# @!visibility public
|
18
26
|
|
@@ -20,8 +28,6 @@ module Applitools::Selenium
|
|
20
28
|
def eyes_driver(driver, eyes = nil)
|
21
29
|
if driver.respond_to? :driver_for_eyes
|
22
30
|
driver.driver_for_eyes eyes
|
23
|
-
elsif defined?(::Capybara::Poltergeist) && (driver.is_a? ::Capybara::Poltergeist::Driver)
|
24
|
-
Applitools::Poltergeist::Driver.new(eyes, driver: driver)
|
25
31
|
else
|
26
32
|
unless driver.is_a?(Applitools::Selenium::Driver)
|
27
33
|
Applitools::EyesLogger.warn("Unrecognized driver type: (#{driver.class.name})!")
|
@@ -32,6 +38,20 @@ module Applitools::Selenium
|
|
32
38
|
end
|
33
39
|
end
|
34
40
|
|
41
|
+
def obtain_screenshot_type(is_element, inside_a_frame, stitch_content, force_fullpage)
|
42
|
+
if stitch_content || force_fullpage
|
43
|
+
unless inside_a_frame
|
44
|
+
return FULLPAGE_SCREENSHOT if force_fullpage && !stitch_content
|
45
|
+
return FULLPAGE_SCREENSHOT if stitch_content && !is_element
|
46
|
+
end
|
47
|
+
return ENTIRE_ELEMENT_SCREENSHOT if inside_a_frame
|
48
|
+
return ENTIRE_ELEMENT_SCREENSHOT if stitch_content
|
49
|
+
else
|
50
|
+
return VIEWPORT_SCREENSHOT unless stitch_content || force_fullpage
|
51
|
+
end
|
52
|
+
VIEWPORT_SCREENSHOT
|
53
|
+
end
|
54
|
+
|
35
55
|
# Set the viewport size.
|
36
56
|
#
|
37
57
|
# @param [Applitools::Selenium::Driver] driver The driver instance.
|
@@ -76,8 +96,9 @@ module Applitools::Selenium
|
|
76
96
|
# @return [Applitools::RectangleSize] explicit_entire_size
|
77
97
|
|
78
98
|
attr_accessor :base_agent_id, :screenshot, :force_full_page_screenshot, :hide_scrollbars,
|
79
|
-
:wait_before_screenshots, :
|
80
|
-
:disable_vertical_scrolling, :explicit_entire_size, :debug_screenshot_provider, :stitching_overlap
|
99
|
+
:wait_before_screenshots, :debug_screenshots, :stitch_mode, :disable_horizontal_scrolling,
|
100
|
+
:disable_vertical_scrolling, :explicit_entire_size, :debug_screenshot_provider, :stitching_overlap,
|
101
|
+
:full_page_capture_algorithm_left_top_offset, :screenshot_type, :send_dom
|
81
102
|
attr_reader :driver
|
82
103
|
|
83
104
|
def_delegators 'Applitools::EyesLogger', :logger, :log_handler, :log_handler=
|
@@ -98,15 +119,18 @@ module Applitools::Selenium
|
|
98
119
|
self.stitch_mode = Applitools::STITCH_MODE[:scroll]
|
99
120
|
self.wait_before_screenshots = DEFAULT_WAIT_BEFORE_SCREENSHOTS
|
100
121
|
self.region_visibility_strategy = MoveToRegionVisibilityStrategy.new
|
101
|
-
self.
|
122
|
+
self.debug_screenshots = false
|
102
123
|
self.debug_screenshot_provider = Applitools::DebugScreenshotProvider.new
|
103
124
|
.tag_access { tag_for_debug }
|
104
|
-
.debug_flag_access {
|
125
|
+
.debug_flag_access { debug_screenshots }
|
105
126
|
self.disable_horizontal_scrolling = false
|
106
127
|
self.disable_vertical_scrolling = false
|
107
128
|
self.explicit_entire_size = nil
|
108
129
|
self.force_driver_resolution_as_viewport_size = false
|
109
130
|
self.stitching_overlap = DEFAULT_STITCHING_OVERLAP
|
131
|
+
self.full_page_capture_algorithm_left_top_offset = Applitools::Location::TOP_LEFT
|
132
|
+
self.send_dom = false
|
133
|
+
self.prevent_dom_processing = false
|
110
134
|
end
|
111
135
|
|
112
136
|
# Starts a test
|
@@ -143,7 +167,7 @@ module Applitools::Selenium
|
|
143
167
|
)
|
144
168
|
|
145
169
|
self.eyes_screenshot_factory = lambda do |image|
|
146
|
-
Applitools::Selenium::
|
170
|
+
Applitools::Selenium::ViewportScreenshot.new(
|
147
171
|
image, driver: @driver, force_offset: position_provider.force_offset
|
148
172
|
)
|
149
173
|
end
|
@@ -161,12 +185,6 @@ module Applitools::Selenium
|
|
161
185
|
send(method_name) if respond_to?(method_name, :include_private)
|
162
186
|
end
|
163
187
|
|
164
|
-
def perform_driver_settings_for_appium_driver
|
165
|
-
self.region_visibility_strategy = NopRegionVisibilityStrategy.new
|
166
|
-
self.force_driver_resolution_as_viewport_size = true
|
167
|
-
end
|
168
|
-
|
169
|
-
private :perform_driver_settings_for_appium_driver
|
170
188
|
private :perform_driver_specific_settings
|
171
189
|
|
172
190
|
# Sets the stitch mode.
|
@@ -231,84 +249,61 @@ module Applitools::Selenium
|
|
231
249
|
logger.info "check(#{name}) is called"
|
232
250
|
self.tag_for_debug = name
|
233
251
|
Applitools::ArgumentGuard.is_a? target, 'target', Applitools::Selenium::Target
|
252
|
+
target_to_check = target.finalize
|
234
253
|
original_overflow = nil
|
235
254
|
original_position_provider = position_provider
|
236
255
|
original_force_full_page_screenshot = force_full_page_screenshot
|
256
|
+
|
237
257
|
eyes_element = nil
|
238
|
-
timeout =
|
258
|
+
timeout = target_to_check.options[:timeout] || USE_DEFAULT_MATCH_TIMEOUT
|
259
|
+
|
239
260
|
self.eyes_screenshot_factory = lambda do |image|
|
240
|
-
Applitools::Selenium::
|
241
|
-
image,
|
242
|
-
|
243
|
-
position_provider: self.class.position_provider(
|
244
|
-
:SCROLL, driver, disable_horizontal_scrolling, disable_vertical_scrolling, explicit_entire_size
|
245
|
-
)
|
261
|
+
Applitools::Selenium::ViewportScreenshot.new(
|
262
|
+
image,
|
263
|
+
region_provider: region_to_check
|
246
264
|
)
|
247
265
|
end
|
248
266
|
|
249
|
-
|
250
|
-
|
267
|
+
self.prevent_dom_processing = !((!target.options[:send_dom].nil? && target.options[:send_dom]) || send_dom)
|
268
|
+
|
269
|
+
check_in_frame target_frames: target_to_check.frames do
|
251
270
|
begin
|
252
271
|
match_data = Applitools::MatchWindowData.new
|
253
272
|
match_data.tag = name
|
254
273
|
update_default_settings(match_data)
|
255
|
-
|
256
|
-
eyes_element = target.region_to_check.call(driver)
|
274
|
+
eyes_element = target_to_check.region_to_check.call(driver)
|
257
275
|
|
258
276
|
unless force_full_page_screenshot
|
259
277
|
region_visibility_strategy.move_to_region original_position_provider,
|
260
278
|
Applitools::Location.new(eyes_element.location.x.to_i, eyes_element.location.y.to_i)
|
261
279
|
end
|
262
280
|
|
263
|
-
|
264
|
-
if !target.frames.empty? && eyes_element.is_a?(Applitools::Region)
|
265
|
-
# check_current_frame
|
266
|
-
logger.info "check_region_in_frame(#{eyes_element})"
|
267
|
-
region_provider = region_provider_for_frame
|
268
|
-
|
269
|
-
elsif eyes_element.is_a? Applitools::Selenium::Element
|
270
|
-
# check_element
|
271
|
-
logger.info 'check_region(' \
|
272
|
-
"#{Applitools::Region.from_location_size(eyes_element.location, eyes_element.size)})"
|
273
|
-
|
274
|
-
use_coordinates =
|
275
|
-
if position_provider.is_a?(Applitools::Selenium::CssTranslatePositionProvider) &&
|
276
|
-
driver.frame_chain.empty?
|
277
|
-
Applitools::EyesScreenshot::COORDINATE_TYPES[:context_as_is]
|
278
|
-
else
|
279
|
-
target.coordinate_type
|
280
|
-
end
|
281
|
-
|
282
|
-
region_provider = Applitools::RegionProvider.new(
|
283
|
-
region_for_element(eyes_element), use_coordinates
|
284
|
-
)
|
285
|
-
else
|
286
|
-
# check_window
|
287
|
-
logger.info "check_window(match_timeout: #{timeout}, tag: #{match_data.tag})"
|
288
|
-
region_provider = Applitools::RegionProvider.new(
|
289
|
-
region_for_element(eyes_element),
|
290
|
-
target.coordinate_type
|
291
|
-
)
|
292
|
-
check_window = true
|
293
|
-
end
|
281
|
+
region_provider = Applitools::Selenium::RegionProvider.new(driver, region_for_element(eyes_element))
|
294
282
|
|
295
|
-
|
296
|
-
check_window ? self.force_full_page_screenshot = true : self.check_frame_or_element = true
|
297
|
-
if eyes_element.is_a? Applitools::Selenium::Element
|
298
|
-
self.position_provider = Applitools::Selenium::ElementPositionProvider.new driver, eyes_element
|
283
|
+
self.region_to_check = region_provider
|
299
284
|
|
300
|
-
|
301
|
-
eyes_element.overflow = 'hidden'
|
302
|
-
end
|
285
|
+
match_data.read_target(target_to_check, driver)
|
303
286
|
|
304
|
-
|
287
|
+
is_element = eyes_element.is_a? Applitools::Selenium::Element
|
288
|
+
inside_a_frame = !driver.frame_chain.empty?
|
305
289
|
|
306
|
-
|
290
|
+
self.screenshot_type = self.class.obtain_screenshot_type(
|
291
|
+
is_element,
|
292
|
+
inside_a_frame,
|
293
|
+
target_to_check.options[:stitch_content],
|
294
|
+
force_full_page_screenshot
|
295
|
+
)
|
307
296
|
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
297
|
+
case screenshot_type
|
298
|
+
when ENTIRE_ELEMENT_SCREENSHOT
|
299
|
+
if eyes_element.is_a? Applitools::Selenium::Element
|
300
|
+
original_overflow = eyes_element.overflow
|
301
|
+
eyes_element.overflow = 'hidden'
|
302
|
+
self.position_provider = Applitools::Selenium::CssTranslateElementPositionProvider.new(
|
303
|
+
driver,
|
304
|
+
eyes_element
|
305
|
+
)
|
306
|
+
end
|
312
307
|
end
|
313
308
|
|
314
309
|
check_window_base(
|
@@ -320,10 +315,12 @@ module Applitools::Selenium
|
|
320
315
|
self.force_full_page_screenshot = original_force_full_page_screenshot
|
321
316
|
self.position_provider = original_position_provider
|
322
317
|
self.region_to_check = nil
|
323
|
-
|
318
|
+
self.full_page_capture_algorithm_left_top_offset = Applitools::Location::TOP_LEFT
|
319
|
+
region_visibility_strategy.return_to_original_position original_position_provider
|
324
320
|
end
|
325
321
|
# rubocop:enable BlockLength
|
326
322
|
end
|
323
|
+
self.prevent_dom_processing = false
|
327
324
|
end
|
328
325
|
|
329
326
|
# Validates the contents of an iframe and matches it with the expected output.
|
@@ -339,12 +336,18 @@ module Applitools::Selenium
|
|
339
336
|
return yield if block_given? && frames.empty?
|
340
337
|
|
341
338
|
original_frame_chain = driver.frame_chain
|
339
|
+
|
342
340
|
logger.info 'Switching to target frame according to frames path...'
|
343
341
|
driver.switch_to.frames(frames_path: frames)
|
342
|
+
frame_chain_to_reset = driver.frame_chain
|
344
343
|
logger.info 'Done!'
|
345
344
|
|
345
|
+
ensure_frame_visible
|
346
|
+
|
346
347
|
yield if block_given?
|
347
348
|
|
349
|
+
reset_frames_scroll_position(frame_chain_to_reset)
|
350
|
+
|
348
351
|
logger.info 'Switching back into top level frame...'
|
349
352
|
driver.switch_to.default_content
|
350
353
|
return unless original_frame_chain
|
@@ -368,41 +371,18 @@ module Applitools::Selenium
|
|
368
371
|
border_bottom_width = element.border_bottom_width
|
369
372
|
|
370
373
|
Applitools::Region.new(
|
371
|
-
p.x + border_left_width,
|
372
|
-
p.y + border_top_width,
|
374
|
+
p.x.round + border_left_width,
|
375
|
+
p.y.round + border_top_width,
|
373
376
|
d.width - border_left_width - border_right_width,
|
374
377
|
d.height - border_top_width - border_bottom_width
|
375
|
-
)
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
current_frame_size = lambda do
|
384
|
-
frame_region = Applitools::Region.from_location_size(
|
385
|
-
Applitools::Location.new(0, 0), driver.frame_chain!.current_frame.size
|
386
|
-
)
|
387
|
-
begin
|
388
|
-
frame_region.intersect Applitools::Region.from_location_size(
|
389
|
-
Applitools::Location.new(0, 0),
|
390
|
-
Applitools::Utils::EyesSeleniumUtils.entire_page_size(driver)
|
391
|
-
)
|
392
|
-
frame_region
|
393
|
-
ensure
|
394
|
-
frame_region
|
395
|
-
end
|
396
|
-
end
|
397
|
-
|
398
|
-
provider.instance_eval do
|
399
|
-
define_singleton_method :region do
|
400
|
-
current_frame_size.call
|
401
|
-
end
|
402
|
-
define_singleton_method :coordinate_type do
|
403
|
-
Applitools::EyesScreenshot::COORDINATE_TYPES[:context_relative]
|
404
|
-
end
|
405
|
-
end
|
378
|
+
).tap do |r|
|
379
|
+
border_padding = Applitools::PaddingBounds.new(
|
380
|
+
border_left_width,
|
381
|
+
border_top_width,
|
382
|
+
border_right_width,
|
383
|
+
border_bottom_width
|
384
|
+
)
|
385
|
+
r.padding(border_padding)
|
406
386
|
end
|
407
387
|
end
|
408
388
|
|
@@ -512,15 +492,31 @@ module Applitools::Selenium
|
|
512
492
|
end
|
513
493
|
end
|
514
494
|
|
495
|
+
def dom_data
|
496
|
+
return {} if prevent_dom_processing
|
497
|
+
begin
|
498
|
+
Applitools::Selenium::DomCapture.get_window_dom(driver, logger)
|
499
|
+
rescue Applitools::EyesError => e
|
500
|
+
logger.error "DOM capture failed! #{e.message}"
|
501
|
+
return {}
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
515
505
|
private
|
516
506
|
|
517
507
|
attr_accessor :check_frame_or_element, :region_to_check, :dont_get_title,
|
518
508
|
:device_pixel_ratio, :position_provider, :scale_provider, :tag_for_debug,
|
519
|
-
:region_visibility_strategy, :eyes_screenshot_factory, :force_driver_resolution_as_viewport_size
|
509
|
+
:region_visibility_strategy, :eyes_screenshot_factory, :force_driver_resolution_as_viewport_size,
|
510
|
+
:prevent_dom_processing
|
520
511
|
|
521
|
-
def
|
522
|
-
|
512
|
+
def image_provider
|
513
|
+
Applitools::Selenium::TakesScreenshotImageProvider.new(
|
514
|
+
driver,
|
523
515
|
debug_screenshot_provider: debug_screenshot_provider
|
516
|
+
)
|
517
|
+
end
|
518
|
+
|
519
|
+
def capture_screenshot
|
524
520
|
logger.info 'Getting screenshot (capture_screenshot() has been invoked)'
|
525
521
|
|
526
522
|
update_scaling_params
|
@@ -534,72 +530,16 @@ module Applitools::Selenium
|
|
534
530
|
end
|
535
531
|
|
536
532
|
begin
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
position_provider: position_provider,
|
548
|
-
scale_provider: scale_provider,
|
549
|
-
cut_provider: cut_provider,
|
550
|
-
wait_before_screenshots: wait_before_screenshots,
|
551
|
-
eyes_screenshot_factory: eyes_screenshot_factory,
|
552
|
-
stitching_overlap: stitching_overlap
|
553
|
-
)
|
554
|
-
|
555
|
-
logger.info 'Building screenshot object...'
|
556
|
-
self.screenshot = Applitools::Selenium::EyesWebDriverScreenshot.new entire_frame_or_element,
|
557
|
-
driver: driver,
|
558
|
-
entire_frame_size: Applitools::RectangleSize.new(entire_frame_or_element.width,
|
559
|
-
entire_frame_or_element.height)
|
560
|
-
elsif force_full_page_screenshot
|
561
|
-
logger.info 'Full page screenshot requested'
|
562
|
-
original_frame = driver.frame_chain
|
563
|
-
driver.switch_to.default_content
|
564
|
-
algo = Applitools::Selenium::FullPageCaptureAlgorithm.new(
|
565
|
-
debug_screenshot_provider: debug_screenshot_provider
|
566
|
-
)
|
567
|
-
region_provider = Object.new
|
568
|
-
region_provider.instance_eval do
|
569
|
-
def region
|
570
|
-
Applitools::Region::EMPTY
|
571
|
-
end
|
572
|
-
|
573
|
-
def coordinate_type
|
574
|
-
nil
|
575
|
-
end
|
576
|
-
end
|
577
|
-
full_page_image = algo.get_stitched_region image_provider: image_provider,
|
578
|
-
region_to_check: region_provider,
|
579
|
-
origin_provider: Applitools::Selenium::ScrollPositionProvider.new(driver),
|
580
|
-
position_provider: position_provider,
|
581
|
-
scale_provider: scale_provider,
|
582
|
-
cut_provider: cut_provider,
|
583
|
-
wait_before_screenshots: wait_before_screenshots,
|
584
|
-
eyes_screenshot_factory: eyes_screenshot_factory,
|
585
|
-
stitching_overlap: stitching_overlap
|
586
|
-
|
587
|
-
unless driver.frame_chain.empty?
|
588
|
-
logger.info 'Switching back to original frame...'
|
589
|
-
driver.switch_to.frame original_frame
|
590
|
-
logger.info 'Done switching!'
|
591
|
-
end
|
592
|
-
logger.info 'Creating EyesWebDriver screenshot instance..'
|
593
|
-
ewd_screenshot = Applitools::Selenium::EyesFullPageScreenshot.new(full_page_image)
|
594
|
-
logger.info 'Done creating EyesWebDriver screenshot instance!'
|
595
|
-
ewd_screenshot
|
596
|
-
else
|
597
|
-
logger.info 'Screenshot requested...'
|
598
|
-
sleep wait_before_screenshots
|
599
|
-
image = image_provider.take_screenshot
|
600
|
-
scale_provider.scale_image(image) if scale_provider
|
601
|
-
cut_provider.cut(image) if cut_provider
|
602
|
-
self.screenshot = eyes_screenshot_factory.call(image)
|
533
|
+
algo = Applitools::Selenium::FullPageCaptureAlgorithm.new(
|
534
|
+
debug_screenshot_provider: debug_screenshot_provider
|
535
|
+
)
|
536
|
+
case screenshot_type
|
537
|
+
when ENTIRE_ELEMENT_SCREENSHOT
|
538
|
+
self.screenshot = entire_element_screenshot(algo)
|
539
|
+
when FULLPAGE_SCREENSHOT
|
540
|
+
self.screenshot = full_page_screenshot(algo)
|
541
|
+
when VIEWPORT_SCREENSHOT
|
542
|
+
self.screenshot = viewport_screenshot
|
603
543
|
end
|
604
544
|
ensure
|
605
545
|
begin
|
@@ -610,6 +550,75 @@ module Applitools::Selenium
|
|
610
550
|
end
|
611
551
|
end
|
612
552
|
|
553
|
+
def full_page_screenshot(algo)
|
554
|
+
logger.info 'Full page screenshot requested'
|
555
|
+
original_frame = driver.frame_chain
|
556
|
+
driver.switch_to.default_content
|
557
|
+
region_provider = Applitools::Selenium::RegionProvider.new(driver, Applitools::Region::EMPTY)
|
558
|
+
|
559
|
+
full_page_image = algo.get_stitched_region(
|
560
|
+
image_provider: image_provider,
|
561
|
+
region_to_check: region_provider,
|
562
|
+
origin_provider: Applitools::Selenium::ScrollPositionProvider.new(driver),
|
563
|
+
position_provider: position_provider,
|
564
|
+
scale_provider: scale_provider,
|
565
|
+
cut_provider: cut_provider,
|
566
|
+
wait_before_screenshots: wait_before_screenshots,
|
567
|
+
eyes_screenshot_factory: eyes_screenshot_factory,
|
568
|
+
stitching_overlap: stitching_overlap
|
569
|
+
)
|
570
|
+
|
571
|
+
# binding.pry
|
572
|
+
unless original_frame.empty?
|
573
|
+
logger.info 'Switching back to original frame...'
|
574
|
+
driver.switch_to.frames frame_chain: original_frame
|
575
|
+
logger.info 'Done switching!'
|
576
|
+
end
|
577
|
+
logger.info 'Creating EyesWebDriver screenshot instance..'
|
578
|
+
result = Applitools::Selenium::FullpageScreenshot.new(
|
579
|
+
full_page_image,
|
580
|
+
region_provider: region_to_check
|
581
|
+
)
|
582
|
+
logger.info 'Done creating EyesWebDriver screenshot instance!'
|
583
|
+
result
|
584
|
+
end
|
585
|
+
|
586
|
+
def entire_element_screenshot(algo)
|
587
|
+
logger.info 'Entire element screenshot requested'
|
588
|
+
entire_frame_or_element = algo.get_stitched_region(
|
589
|
+
image_provider: image_provider,
|
590
|
+
region_to_check: region_to_check,
|
591
|
+
origin_provider: position_provider,
|
592
|
+
position_provider: position_provider,
|
593
|
+
scale_provider: scale_provider,
|
594
|
+
cut_provider: cut_provider,
|
595
|
+
wait_before_screenshots: wait_before_screenshots,
|
596
|
+
eyes_screenshot_factory: eyes_screenshot_factory,
|
597
|
+
stitching_overlap: stitching_overlap,
|
598
|
+
top_left_position: full_page_capture_algorithm_left_top_offset
|
599
|
+
)
|
600
|
+
|
601
|
+
logger.info 'Building screenshot object (EyesStitchedElementScreenshot)...'
|
602
|
+
result = Applitools::Selenium::EntireElementScreenshot.new(
|
603
|
+
entire_frame_or_element,
|
604
|
+
region_provider: region_to_check
|
605
|
+
)
|
606
|
+
logger.info 'Done!'
|
607
|
+
result
|
608
|
+
end
|
609
|
+
|
610
|
+
def viewport_screenshot
|
611
|
+
logger.info 'Viewport screenshot requested'
|
612
|
+
sleep wait_before_screenshots
|
613
|
+
image = image_provider.take_screenshot
|
614
|
+
scale_provider.scale_image(image) if scale_provider
|
615
|
+
local_cut_provider = (
|
616
|
+
cut_provider || Applitools::Selenium::FixedCutProvider.viewport(image, viewport_size, region_to_check)
|
617
|
+
)
|
618
|
+
local_cut_provider.cut(image) if local_cut_provider
|
619
|
+
eyes_screenshot_factory.call(image)
|
620
|
+
end
|
621
|
+
|
613
622
|
def vp_size=(value, skip_check_if_open = false)
|
614
623
|
raise Applitools::EyesNotOpenException.new 'set_viewport_size: Eyes not open!' unless skip_check_if_open || open?
|
615
624
|
original_frame = driver.frame_chain
|
@@ -749,62 +758,6 @@ module Applitools::Selenium
|
|
749
758
|
|
750
759
|
protected
|
751
760
|
|
752
|
-
def check_current_frame(match_timeout, tag)
|
753
|
-
logger.info "check_current_frame(#{match_timeout}, #{tag})"
|
754
|
-
self.check_frame_or_element = true
|
755
|
-
|
756
|
-
region_provider = Object.new.tap do |provider|
|
757
|
-
provider.instance_eval do
|
758
|
-
define_singleton_method :region do
|
759
|
-
Applitools::Region::EMPTY
|
760
|
-
end
|
761
|
-
define_singleton_method :coordinate_type do
|
762
|
-
nil
|
763
|
-
end
|
764
|
-
end
|
765
|
-
end
|
766
|
-
|
767
|
-
self.region_to_check = Object.new.tap do |provider|
|
768
|
-
current_frame_size = lambda do
|
769
|
-
frame_region = Applitools::Region.from_location_size(
|
770
|
-
Applitools::Location.new(0, 0), driver.frame_chain!.current_frame.size
|
771
|
-
)
|
772
|
-
begin
|
773
|
-
frame_region.intersect Applitools::Region.from_location_size(
|
774
|
-
Applitools::Location.new(0, 0),
|
775
|
-
Applitools::Utils::EyesSeleniumUtils.entire_page_size(driver)
|
776
|
-
)
|
777
|
-
frame_region
|
778
|
-
ensure
|
779
|
-
frame_region
|
780
|
-
end
|
781
|
-
end
|
782
|
-
|
783
|
-
provider.instance_eval do
|
784
|
-
define_singleton_method :region do
|
785
|
-
current_frame_size.call
|
786
|
-
end
|
787
|
-
define_singleton_method :coordinate_type do
|
788
|
-
Applitools::EyesScreenshot::COORDINATE_TYPES[:context_relative]
|
789
|
-
end
|
790
|
-
end
|
791
|
-
end
|
792
|
-
|
793
|
-
self.eyes_screenshot_factory = lambda do |image|
|
794
|
-
Applitools::Selenium::EyesWebDriverScreenshot.new(
|
795
|
-
image, driver: driver, force_offset: position_provider.force_offset
|
796
|
-
)
|
797
|
-
end
|
798
|
-
|
799
|
-
match_data = Applitools::MatchWindowData.new.tap do |d|
|
800
|
-
d.tag = tag
|
801
|
-
d.ignore_mismatch = false
|
802
|
-
d.match_level = default_match_settings[:match_level]
|
803
|
-
end
|
804
|
-
|
805
|
-
check_window_base region_provider, match_timeout, match_data
|
806
|
-
end
|
807
|
-
|
808
761
|
def app_environment
|
809
762
|
app_env = super
|
810
763
|
if app_env.os.nil?
|
@@ -839,175 +792,6 @@ module Applitools::Selenium
|
|
839
792
|
app_env
|
840
793
|
end
|
841
794
|
|
842
|
-
# check a region, specified by element_or_selector parameter
|
843
|
-
#
|
844
|
-
# @param [Array] element_or_selector Array, which contains Applitools::Selenium::Element or [:finder, :value]
|
845
|
-
# pair should be used in find_element
|
846
|
-
# @param [Hash] options
|
847
|
-
# @option options [String] :tag
|
848
|
-
# @option options [Float] :tmatch_timeout
|
849
|
-
def check_region_(element_or_selector, options = {})
|
850
|
-
selector = element_or_selector if Applitools::Selenium::Driver::FINDERS.keys.include? element_or_selector.first
|
851
|
-
element = element_or_selector.first if element_or_selector.first.instance_of? Applitools::Selenium::Element
|
852
|
-
element = driver.find_element(*selector) unless element
|
853
|
-
raise Applitools::EyesIllegalArgument.new 'You should pass :selector or :element!' unless element
|
854
|
-
|
855
|
-
if !options[:tag].nil? && !options[:tag].empty?
|
856
|
-
tag = options[:tag]
|
857
|
-
self.tag_for_debug = tag
|
858
|
-
end
|
859
|
-
|
860
|
-
match_timeout = options[:match_timeout] || USE_DEFAULT_MATCH_TIMEOUT
|
861
|
-
|
862
|
-
logger.info "check_region(element, #{match_timeout}, #{tag}): Ignored" && return if disabled?
|
863
|
-
Applitools::ArgumentGuard.not_nil 'options[:element]', element
|
864
|
-
logger.info "check_region(element: element, #{match_timeout}, #{tag})"
|
865
|
-
|
866
|
-
location_as_point = element.location
|
867
|
-
region_visibility_strategy.move_to_region position_provider,
|
868
|
-
Applitools::Location.new(location_as_point.x.to_i, location_as_point.y.to_i)
|
869
|
-
|
870
|
-
region_provider = Object.new.tap do |prov|
|
871
|
-
prov.instance_eval do
|
872
|
-
define_singleton_method :region do
|
873
|
-
p = element.location
|
874
|
-
d = element.size
|
875
|
-
Applitools::Region.from_location_size p, d
|
876
|
-
end
|
877
|
-
|
878
|
-
define_singleton_method :coordinate_type do
|
879
|
-
Applitools::EyesScreenshot::COORDINATE_TYPES[:context_relative]
|
880
|
-
end
|
881
|
-
end
|
882
|
-
end
|
883
|
-
|
884
|
-
self.eyes_screenshot_factory = lambda do |image|
|
885
|
-
Applitools::Selenium::EyesWebDriverScreenshot.new(image, driver: driver)
|
886
|
-
end
|
887
|
-
|
888
|
-
match_data = Applitools::MatchWindowData.new.tap do |d|
|
889
|
-
d.tag = tag
|
890
|
-
d.ignore_mismatch = false
|
891
|
-
d.match_level = default_match_settings[:match_level]
|
892
|
-
end
|
893
|
-
|
894
|
-
result = check_window_base(
|
895
|
-
region_provider, match_timeout, match_data
|
896
|
-
)
|
897
|
-
|
898
|
-
logger.info 'Done! trying to scroll back to original position...'
|
899
|
-
region_visibility_strategy.return_to_original_position position_provider
|
900
|
-
logger.info 'Done!'
|
901
|
-
result
|
902
|
-
end
|
903
|
-
|
904
|
-
# Checks an element, specified by +element_or_selector+ parameter
|
905
|
-
#
|
906
|
-
# @param [Array] element_or_selector Array, which contains Applitools::Selenium::Element or [:finder, :value]
|
907
|
-
# pair should be used in find_element
|
908
|
-
# @param [Hash] options
|
909
|
-
# @option options [String] :tag
|
910
|
-
# @option options [Float] :match_timeout
|
911
|
-
|
912
|
-
def check_element(element_or_selector, options = {})
|
913
|
-
selector = element_or_selector if Applitools::Selenium::Driver::FINDERS.keys.include? element_or_selector.first
|
914
|
-
if !options[:tag].nil? && !options[:tag].empty?
|
915
|
-
tag = options[:tag]
|
916
|
-
self.tag_for_debug = tag
|
917
|
-
end
|
918
|
-
match_timeout = options[:match_timeout] || USE_DEFAULT_MATCH_TIMEOUT
|
919
|
-
|
920
|
-
if disabled?
|
921
|
-
logger.info "check_element(#{options.inject([]) { |res, (k, v)| res << "#{k}: #{v}" }.join(', ')}):" /
|
922
|
-
' Ignored'
|
923
|
-
return
|
924
|
-
end
|
925
|
-
|
926
|
-
eyes_element = element_or_selector.first if element_or_selector.first.instance_of? Applitools::Selenium::Element
|
927
|
-
eyes_element = driver.find_element(*selector) unless eyes_element
|
928
|
-
raise Applitools::EyesIllegalArgument.new 'You should pass :selector or :element!' unless eyes_element
|
929
|
-
eyes_element = Applitools::Selenium::Element.new(driver, eyes_element) unless
|
930
|
-
eyes_element.is_a? Applitools::Selenium::Element
|
931
|
-
|
932
|
-
location_as_point = eyes_element.location
|
933
|
-
region_visibility_strategy.move_to_region position_provider,
|
934
|
-
Applitools::Location.new(location_as_point.x.to_i, location_as_point.y.to_i)
|
935
|
-
|
936
|
-
original_overflow = nil
|
937
|
-
original_position_provider = position_provider
|
938
|
-
|
939
|
-
begin
|
940
|
-
self.check_frame_or_element = true
|
941
|
-
self.position_provider = Applitools::Selenium::ElementPositionProvider.new driver, eyes_element
|
942
|
-
original_overflow = eyes_element.overflow
|
943
|
-
eyes_element.overflow = 'hidden'
|
944
|
-
|
945
|
-
p = eyes_element.location
|
946
|
-
d = eyes_element.size
|
947
|
-
|
948
|
-
border_left_width = eyes_element.border_left_width
|
949
|
-
border_top_width = eyes_element.border_top_width
|
950
|
-
border_right_width = eyes_element.border_right_width
|
951
|
-
border_bottom_width = eyes_element.border_bottom_width
|
952
|
-
|
953
|
-
element_region = Applitools::Region.new(
|
954
|
-
p.x + border_left_width,
|
955
|
-
p.y + border_top_width,
|
956
|
-
d.width - border_left_width - border_right_width,
|
957
|
-
d.height - border_top_width - border_bottom_width
|
958
|
-
)
|
959
|
-
|
960
|
-
logger.info "Element region: #{element_region}"
|
961
|
-
|
962
|
-
self.region_to_check = Object.new.tap do |prov|
|
963
|
-
prov.instance_eval do
|
964
|
-
define_singleton_method :region do
|
965
|
-
element_region
|
966
|
-
end
|
967
|
-
|
968
|
-
define_singleton_method :coordinate_type do
|
969
|
-
Applitools::EyesScreenshot::COORDINATE_TYPES[:context_relative]
|
970
|
-
end
|
971
|
-
end
|
972
|
-
end
|
973
|
-
|
974
|
-
base_check_region_provider = Object.new.tap do |prov|
|
975
|
-
prov.instance_eval do
|
976
|
-
define_singleton_method :region do
|
977
|
-
Applitools::Region::EMPTY
|
978
|
-
end
|
979
|
-
|
980
|
-
define_singleton_method :coordinate_type do
|
981
|
-
nil
|
982
|
-
end
|
983
|
-
end
|
984
|
-
end
|
985
|
-
|
986
|
-
self.eyes_screenshot_factory = lambda do |image|
|
987
|
-
Applitools::Selenium::EyesWebDriverScreenshot.new(
|
988
|
-
image, driver: driver, force_offset: position_provider.state
|
989
|
-
)
|
990
|
-
end
|
991
|
-
|
992
|
-
match_data = Applitools::MatchWindowData.new.tap do |data|
|
993
|
-
data.tag = tag
|
994
|
-
data.ignore_mismatch = false
|
995
|
-
data.match_level = default_match_settings[:match_level]
|
996
|
-
end
|
997
|
-
|
998
|
-
check_window_base(
|
999
|
-
base_check_region_provider, match_timeout, match_data
|
1000
|
-
)
|
1001
|
-
ensure
|
1002
|
-
eyes_element.overflow = original_overflow unless original_overflow.nil?
|
1003
|
-
self.check_frame_or_element = false
|
1004
|
-
self.position_provider = original_position_provider
|
1005
|
-
self.region_to_check = nil
|
1006
|
-
|
1007
|
-
region_visibility_strategy.return_to_original_position position_provider
|
1008
|
-
end
|
1009
|
-
end
|
1010
|
-
|
1011
795
|
def inferred_environment
|
1012
796
|
return @inferred_environment unless @inferred_environment.nil?
|
1013
797
|
|
@@ -1017,6 +801,29 @@ module Applitools::Selenium
|
|
1017
801
|
nil
|
1018
802
|
end
|
1019
803
|
|
804
|
+
def ensure_frame_visible
|
805
|
+
original_fc = driver.frame_chain
|
806
|
+
return original_fc if original_fc.empty?
|
807
|
+
fc = Applitools::Selenium::FrameChain.new other: original_fc
|
808
|
+
until fc.empty?
|
809
|
+
driver.switch_to.parent_frame
|
810
|
+
position_provider.position = fc.pop.location
|
811
|
+
end
|
812
|
+
driver.switch_to.frames(frame_chain: original_fc)
|
813
|
+
original_fc
|
814
|
+
end
|
815
|
+
|
816
|
+
def reset_frames_scroll_position(original_fc)
|
817
|
+
return original_fc if original_fc.empty?
|
818
|
+
fc = Applitools::Selenium::FrameChain.new other: original_fc
|
819
|
+
until fc.empty?
|
820
|
+
driver.switch_to.parent_frame
|
821
|
+
position_provider.position = fc.pop.parent_scroll_position
|
822
|
+
end
|
823
|
+
driver.switch_to.frames(frame_chain: original_fc)
|
824
|
+
original_fc
|
825
|
+
end
|
826
|
+
|
1020
827
|
class << self
|
1021
828
|
def position_provider(stitch_mode, driver, disable_horizontal = false, disable_vertical = false,
|
1022
829
|
explicit_entire_size = nil)
|