eyes_selenium 6.12.10 → 6.12.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/eyes_selenium.gemspec +2 -5
- data/lib/applitools/eyes_selenium/version.rb +1 -1
- data/lib/applitools/selenium/browsers_info.rb +2 -0
- data/lib/applitools/selenium/concerns/selenium_eyes.rb +0 -33
- data/lib/applitools/selenium/driver.rb +1 -1
- data/lib/applitools/selenium/eyes.rb +1 -5
- data/lib/applitools/selenium/selenium_eyes.rb +15 -315
- data/lib/applitools/selenium/visual_grid/visual_grid_runner.rb +33 -92
- data/lib/eyes_selenium.rb +0 -2
- metadata +9 -64
- data/lib/applitools/selenium/css_parser/find_embedded_resources.rb +0 -102
- data/lib/applitools/selenium/dom_capture/dom_capture.rb +0 -172
- data/lib/applitools/selenium/dom_capture/dom_capture_script.rb +0 -611
- data/lib/applitools/selenium/external_css_resources.rb +0 -32
- data/lib/applitools/selenium/visual_grid/dom_snapshot_script.rb +0 -198
- data/lib/applitools/selenium/visual_grid/eyes_connector.rb +0 -170
- data/lib/applitools/selenium/visual_grid/render_info.rb +0 -24
- data/lib/applitools/selenium/visual_grid/render_request.rb +0 -24
- data/lib/applitools/selenium/visual_grid/render_requests.rb +0 -12
- data/lib/applitools/selenium/visual_grid/render_task.rb +0 -311
- data/lib/applitools/selenium/visual_grid/resource_cache.rb +0 -69
- data/lib/applitools/selenium/visual_grid/running_test.rb +0 -271
- data/lib/applitools/selenium/visual_grid/thread_pool.rb +0 -95
- data/lib/applitools/selenium/visual_grid/vg_match_window_data.rb +0 -187
- data/lib/applitools/selenium/visual_grid/vg_region.rb +0 -16
- data/lib/applitools/selenium/visual_grid/vg_resource.rb +0 -77
- data/lib/applitools/selenium/visual_grid/vg_task.rb +0 -53
- data/lib/applitools/selenium/visual_grid/visual_grid_eyes.rb +0 -494
- data/lib/applitools/selenium/visual_grid/web_element_region.rb +0 -16
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: false
|
|
2
|
-
|
|
3
|
-
require 'selenium-webdriver'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
module Applitools
|
|
7
|
-
module Selenium
|
|
8
|
-
class DomSnapshotScript
|
|
9
|
-
|
|
10
|
-
attr_accessor :driver
|
|
11
|
-
|
|
12
|
-
def initialize(driver)
|
|
13
|
-
self.driver = driver
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def create_dom_snapshot(
|
|
17
|
-
dont_fetch_resources,
|
|
18
|
-
urls_to_skip,
|
|
19
|
-
cross_origin_rendering,
|
|
20
|
-
use_cookies
|
|
21
|
-
)
|
|
22
|
-
serialize_resources = true
|
|
23
|
-
compress_resources = false
|
|
24
|
-
script = DomSnapshotScript.new(driver, urls_to_skip, dont_fetch_resources, serialize_resources, compress_resources)
|
|
25
|
-
snapshotter = RecursiveSnapshotter.new(driver, script, cross_origin_rendering, use_cookies)
|
|
26
|
-
|
|
27
|
-
begin
|
|
28
|
-
snapshotter.create_cross_frames_dom_snapshots
|
|
29
|
-
rescue StandardError => e
|
|
30
|
-
Applitools::EyesLogger.error e.class.to_s
|
|
31
|
-
Applitools::EyesLogger.error e.message
|
|
32
|
-
raise ::Applitools::EyesError.new 'Error while getting dom snapshot!'
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
class DomSnapshotScript
|
|
38
|
-
DOM_EXTRACTION_TIMEOUT = 300
|
|
39
|
-
|
|
40
|
-
attr_accessor :driver, :urls_to_skip, :dont_fetch_resources, :serialize_resources, :compress_resources
|
|
41
|
-
|
|
42
|
-
def initialize(driver, urls_to_skip, dont_fetch_resources, serialize_resources = false, compress_resources = false)
|
|
43
|
-
self.driver = driver
|
|
44
|
-
self.urls_to_skip = urls_to_skip
|
|
45
|
-
self.dont_fetch_resources = dont_fetch_resources
|
|
46
|
-
self.compress_resources = compress_resources
|
|
47
|
-
self.serialize_resources = serialize_resources
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def process_page_script
|
|
51
|
-
''
|
|
52
|
-
# Applitools::Selenium::Scripts::PROCESS_PAGE_AND_POLL
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def script_options
|
|
56
|
-
options = []
|
|
57
|
-
options.push("dontFetchResources: #{dont_fetch_resources}")
|
|
58
|
-
options.push("skipResources: [#{urls_to_skip}]")
|
|
59
|
-
options.push("compressResources: #{compress_resources}")
|
|
60
|
-
options.push("serializeResources: #{serialize_resources}")
|
|
61
|
-
"{#{options.join(', ')}}"
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def script
|
|
65
|
-
"#{process_page_script} return __processPageAndSerializePoll(#{script_options});"
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def run
|
|
69
|
-
Applitools::EyesLogger.info 'Trying to get DOM snapshot...'
|
|
70
|
-
|
|
71
|
-
script_thread = Thread.new do
|
|
72
|
-
result = {}
|
|
73
|
-
while result['status'] != 'SUCCESS'
|
|
74
|
-
Thread.current[:script_result] = driver.execute_script(script)
|
|
75
|
-
begin
|
|
76
|
-
Thread.current[:result] = result = Oj.load(Thread.current[:script_result])
|
|
77
|
-
sleep 0.5
|
|
78
|
-
rescue Oj::ParseError => e
|
|
79
|
-
Applitools::EyesLogger.warn e.message
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
sleep 0.5
|
|
84
|
-
script_thread_result = script_thread.join(DOM_EXTRACTION_TIMEOUT)
|
|
85
|
-
raise ::Applitools::EyesError.new 'Timeout error while getting dom snapshot!' unless script_thread_result
|
|
86
|
-
Applitools::EyesLogger.info 'Done!'
|
|
87
|
-
|
|
88
|
-
script_thread_result[:result]['value']
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
class RecursiveSnapshotter
|
|
95
|
-
|
|
96
|
-
POLL_INTERVAL_MS = 0.5
|
|
97
|
-
|
|
98
|
-
attr_accessor :should_skip_failed_frames
|
|
99
|
-
|
|
100
|
-
attr_accessor :driver, :script, :cross_origin_rendering, :use_cookies
|
|
101
|
-
|
|
102
|
-
def initialize(driver, script, cross_origin_rendering, use_cookies)
|
|
103
|
-
self.should_skip_failed_frames = true
|
|
104
|
-
self.driver = driver
|
|
105
|
-
self.script = script
|
|
106
|
-
self.cross_origin_rendering = cross_origin_rendering
|
|
107
|
-
self.use_cookies = use_cookies
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def create_cross_frames_dom_snapshots
|
|
111
|
-
dom = create_dom_snapshot_threaded
|
|
112
|
-
process_dom_snapshot_frames dom
|
|
113
|
-
dom
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def create_dom_snapshot_threaded
|
|
117
|
-
script.run
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def process_dom_snapshot_frames dom
|
|
121
|
-
dom["cookies"] = driver.manage.all_cookies if use_cookies
|
|
122
|
-
|
|
123
|
-
dom["frames"].each do |frame|
|
|
124
|
-
selector = frame['selector']
|
|
125
|
-
unless selector
|
|
126
|
-
Applitools::EyesLogger.warn "inner frame with null selector"
|
|
127
|
-
next
|
|
128
|
-
end
|
|
129
|
-
begin
|
|
130
|
-
original_frame_chain = driver.frame_chain
|
|
131
|
-
frame_element = driver.find_element(:css, selector)
|
|
132
|
-
frame_src = frame_element.attribute('src')
|
|
133
|
-
Applitools::EyesLogger.info "process_dom_snapshot_frames src = #{frame_src}"
|
|
134
|
-
driver.switch_to.frame(frame_element)
|
|
135
|
-
|
|
136
|
-
process_dom_snapshot_frames frame
|
|
137
|
-
|
|
138
|
-
driver.switch_to.default_content
|
|
139
|
-
unless original_frame_chain.empty?
|
|
140
|
-
driver.switch_to.frames frame_chain: original_frame_chain
|
|
141
|
-
end
|
|
142
|
-
rescue StandardError => e
|
|
143
|
-
Applitools::EyesLogger.error e.class.to_s
|
|
144
|
-
Applitools::EyesLogger.error e.message
|
|
145
|
-
if should_skip_failed_frames
|
|
146
|
-
Applitools::EyesLogger.warn "failed switching to frame #{selector}"
|
|
147
|
-
else
|
|
148
|
-
raise ::Applitools::EyesError.new 'failed switching to frame'
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
self.snapshot_and_process_cors_frames(dom) if self.cross_origin_rendering
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def snapshot_and_process_cors_frames(dom)
|
|
157
|
-
dom["crossFrames"].each do |frame|
|
|
158
|
-
selector = frame['selector']
|
|
159
|
-
unless selector
|
|
160
|
-
Applitools::EyesLogger.warn "cross frame with null selector"
|
|
161
|
-
next
|
|
162
|
-
end
|
|
163
|
-
frame_index = frame['index']
|
|
164
|
-
begin
|
|
165
|
-
original_frame_chain = driver.frame_chain
|
|
166
|
-
frame_element = driver.find_element(:css, selector) #
|
|
167
|
-
frame_src = frame_element.attribute('src')
|
|
168
|
-
Applitools::EyesLogger.info "snapshot_and_process_cors_frames src = #{frame_src}"
|
|
169
|
-
driver.switch_to.frame(frame_element)
|
|
170
|
-
|
|
171
|
-
frame_dom = create_cross_frames_dom_snapshots
|
|
172
|
-
dom['frames'] ||= []
|
|
173
|
-
dom['frames'].push frame_dom
|
|
174
|
-
frame_url = frame_dom['url']
|
|
175
|
-
dom['cdt'][frame_index]['attributes'].push({ 'name' => 'data-applitools-src', 'value' => frame_url })
|
|
176
|
-
Applitools::EyesLogger.info "Created cross origin frame snapshot #{frame_url}"
|
|
177
|
-
process_dom_snapshot_frames frame_dom
|
|
178
|
-
|
|
179
|
-
driver.switch_to.default_content
|
|
180
|
-
unless original_frame_chain.empty?
|
|
181
|
-
driver.switch_to.frames(frame_chain: original_frame_chain)
|
|
182
|
-
end
|
|
183
|
-
rescue StandardError => e
|
|
184
|
-
Applitools::EyesLogger.error e.class.to_s
|
|
185
|
-
Applitools::EyesLogger.error e.message
|
|
186
|
-
if should_skip_failed_frames
|
|
187
|
-
Applitools::EyesLogger.warn "failed extracting and processing cross frame #{selector}"
|
|
188
|
-
else
|
|
189
|
-
raise ::Applitools::EyesError.new 'failed switching to frame'
|
|
190
|
-
end
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
end
|
|
198
|
-
end
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
module Applitools
|
|
3
|
-
module Selenium
|
|
4
|
-
class EyesConnector < ::Applitools::EyesBase
|
|
5
|
-
USE_DEFAULT_MATCH_TIMEOUT = -1
|
|
6
|
-
|
|
7
|
-
attr_accessor :browser_info, :test_result, :driver, :dummy_region_provider, :dont_get_title,
|
|
8
|
-
:current_uuid, :render_statuses, :device_name, :driver_lock, :title
|
|
9
|
-
public :server_connector
|
|
10
|
-
|
|
11
|
-
class RegionProvider
|
|
12
|
-
def region
|
|
13
|
-
Applitools::Region::EMPTY
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def initialize(*args)
|
|
18
|
-
options = Applitools::Utils.extract_options!(args)
|
|
19
|
-
super
|
|
20
|
-
self.render_statuses = {}
|
|
21
|
-
self.dummy_region_provider = RegionProvider.new
|
|
22
|
-
self.dont_get_title = false
|
|
23
|
-
self.driver_lock = options[:driver_lock]
|
|
24
|
-
self.should_match_window_run_once_on_timeout = true
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def ensure_config
|
|
28
|
-
self.config = Applitools::Selenium::Configuration.new
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def open(driver, browser_info)
|
|
32
|
-
self.driver = driver
|
|
33
|
-
self.browser_info = browser_info
|
|
34
|
-
self.device_name = browser_info.device_name
|
|
35
|
-
logger.info "opening EyesConnector for #{config.short_description} with viewport size: #{browser_info}"
|
|
36
|
-
config.viewport_size = browser_info.viewport_size
|
|
37
|
-
title
|
|
38
|
-
open_base
|
|
39
|
-
# ensure_running_session
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def check(name, target, check_task_uuid)
|
|
43
|
-
self.current_uuid = check_task_uuid
|
|
44
|
-
target_to_check = target.finalize
|
|
45
|
-
timeout = target_to_check.options[:timeout] || USE_DEFAULT_MATCH_TIMEOUT
|
|
46
|
-
|
|
47
|
-
match_data = Applitools::Selenium::VgMatchWindowData.new(default_match_settings)
|
|
48
|
-
match_data.tag = name
|
|
49
|
-
match_data.render_id = render_status['renderId']
|
|
50
|
-
begin
|
|
51
|
-
driver_lock.synchronize do
|
|
52
|
-
match_data.read_target(target_to_check, driver, selector_regions)
|
|
53
|
-
end
|
|
54
|
-
rescue Applitools::Selenium::VgMatchWindowData::RegionCoordinatesError => e
|
|
55
|
-
logger.error "Error retrieving coordinates for region #{e.region}"
|
|
56
|
-
logger.error e.message
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
match_data.variation_group_id = match_data.target.options[:variation_group_id] if match_data.target.options[:variation_group_id]
|
|
60
|
-
|
|
61
|
-
check_result = check_window_base(
|
|
62
|
-
dummy_region_provider, timeout, match_data
|
|
63
|
-
)
|
|
64
|
-
self.current_uuid = nil
|
|
65
|
-
check_result
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def start_session
|
|
69
|
-
super
|
|
70
|
-
self.should_match_window_run_once_on_timeout = true
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def base_agent_id
|
|
74
|
-
"eyes.selenium.visualgrid.ruby/#{Applitools::VERSION}"
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def close(throw_exception = true, be_silent = false)
|
|
78
|
-
self.current_uuid = nil
|
|
79
|
-
self.test_result = super
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def capture_screenshot
|
|
83
|
-
nil
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def render_status_for_task(uuid, status)
|
|
87
|
-
render_statuses[uuid] = status
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def render_status
|
|
91
|
-
status = render_statuses[current_uuid]
|
|
92
|
-
raise Applitools::EyesError, 'Got empty render status!' if
|
|
93
|
-
status.nil? || !status.is_a?(Hash) || status.keys.empty?
|
|
94
|
-
status
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def screenshot_url
|
|
98
|
-
render_status['imageLocation']
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def dom_url
|
|
102
|
-
render_status['domLocation']
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def selector_regions
|
|
106
|
-
render_status['selectorRegions']
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def visual_viewport
|
|
110
|
-
render_status['visualViewport']
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
# def match_level_keys
|
|
114
|
-
# %w(match_level exact scale remainder ).map(&:to_sym)
|
|
115
|
-
# end
|
|
116
|
-
|
|
117
|
-
def inferred_environment
|
|
118
|
-
"useragent: #{render_status['userAgent']}"
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
# def default_match_settings
|
|
122
|
-
# {
|
|
123
|
-
# match_level: match_level,
|
|
124
|
-
# exact: exact,
|
|
125
|
-
# scale: server_scale,
|
|
126
|
-
# remainder: server_remainder
|
|
127
|
-
# }
|
|
128
|
-
# end
|
|
129
|
-
|
|
130
|
-
# rubocop:disable Style/AccessorMethodName
|
|
131
|
-
def set_viewport_size(*_args); end
|
|
132
|
-
# rubocop:enable Style/AccessorMethodName
|
|
133
|
-
|
|
134
|
-
def app_environment
|
|
135
|
-
super.tap do |env|
|
|
136
|
-
env.device_info = device_name
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def viewport_size
|
|
141
|
-
status = render_statuses[render_statuses.keys.first]
|
|
142
|
-
size = status['deviceSize']
|
|
143
|
-
Applitools::RectangleSize.new(size['width'], size['height'])
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
def title
|
|
147
|
-
@title ||= driver.title unless dont_get_title
|
|
148
|
-
rescue StandardError => e
|
|
149
|
-
logger.warn "failed (#{e.message})"
|
|
150
|
-
self.dont_get_title = false
|
|
151
|
-
''
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def get_app_output_with_screenshot(region_provider, _last_screenshot)
|
|
155
|
-
region = region_provider.region
|
|
156
|
-
a_title = title
|
|
157
|
-
Applitools::AppOutputWithScreenshot.new(
|
|
158
|
-
Applitools::AppOutput.new(a_title, '').tap do |o|
|
|
159
|
-
o.location = region.location unless region.empty?
|
|
160
|
-
o.dom_url = dom_url
|
|
161
|
-
o.screenshot_url = screenshot_url if respond_to?(:screenshot_url) && !screenshot_url.nil?
|
|
162
|
-
o.visual_viewport = visual_viewport unless visual_viewport.nil?
|
|
163
|
-
end,
|
|
164
|
-
nil,
|
|
165
|
-
true
|
|
166
|
-
)
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
module Applitools
|
|
3
|
-
module Selenium
|
|
4
|
-
class RenderInfo
|
|
5
|
-
include Applitools::Jsonable
|
|
6
|
-
json_fields :width, :height, :sizeMode, :emulationInfo, :region, :selector, :IosDeviceInfo
|
|
7
|
-
# , :region, :emulationInfo
|
|
8
|
-
|
|
9
|
-
def json_data
|
|
10
|
-
result = {
|
|
11
|
-
width: width,
|
|
12
|
-
height: height,
|
|
13
|
-
sizeMode: size_mode
|
|
14
|
-
}
|
|
15
|
-
result['emulationInfo'] = json_value(emulation_info) if emulation_info
|
|
16
|
-
result['iosDeviceInfo'] = json_value(ios_device_info) if ios_device_info
|
|
17
|
-
result['region'] = json_value(region) if size_mode == 'region'
|
|
18
|
-
result['selector'] = json_value(region) if size_mode == 'selector'
|
|
19
|
-
result['selector'] = json_value(region) if size_mode == 'full-selector'
|
|
20
|
-
result
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'oj'
|
|
4
|
-
module Applitools
|
|
5
|
-
module Selenium
|
|
6
|
-
class RenderRequest
|
|
7
|
-
include Applitools::Jsonable
|
|
8
|
-
json_fields :renderId, :webhook, :url, :dom, :resources, :scriptHooks,
|
|
9
|
-
:selectorsToFindRegionsFor, :sendDom, :agentId
|
|
10
|
-
|
|
11
|
-
json_fields :renderInfo, :browser, :platform, :stitchingService, :options
|
|
12
|
-
|
|
13
|
-
def initialize(*args)
|
|
14
|
-
options = Applitools::Utils.extract_options! args
|
|
15
|
-
self.agent_id = "eyes.selenium.visualgrid.ruby/#{Applitools::VERSION}"
|
|
16
|
-
self.script_hooks = {}
|
|
17
|
-
self.selectors_to_find_regions_for = []
|
|
18
|
-
options.keys.each do |k|
|
|
19
|
-
send("#{k}=", options[k]) if options[k] && respond_to?("#{k}=")
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|