eyes_selenium 3.18.2 → 3.18.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2405810aec21e6cc3e6f1a156954a7d11f08cda1
4
- data.tar.gz: 547bbe8ccae2009b5f2490952e9af6f7531f8bf4
3
+ metadata.gz: 23704229caa8ee5060d9c78411063827f0691448
4
+ data.tar.gz: c4e009752f305985d82633d2cd7428e482a98ae2
5
5
  SHA512:
6
- metadata.gz: 01d7d9768fea60aba826d73283c900f9d8c6e7722989d24cb07c997b1268141d1dca183f4fe7b8f3358d4e359784e28704ae8b35cd9b4a6aa1d248f2e9dc0535
7
- data.tar.gz: ad39a605cfe410bb028bbd57ec39837a9db61d4f722b88069ed133057b060578b82a8e95962aec77584d31034f1ed16bff73c4a91aa96f7cf32ef37c5fb50044
6
+ metadata.gz: 257658592ad5d264372947bc2d51113dfdccca6a6ae87f812fbc4d57f8541d50df838bc832e38992c5197c6e28d4ac44818077a46675ec73b9ec1e3fcac979b8
7
+ data.tar.gz: e6d0593683515bdd315129917eda167a0e1df25521d49e5c30fc36d7ccd86b716849539e75e22f351008aae7ddf63a01d132f84086e4d97727d2f361004f37a1
@@ -0,0 +1,197 @@
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
+ Applitools::Selenium::Scripts::PROCESS_PAGE_AND_POLL
52
+ end
53
+
54
+ def script_options
55
+ options = []
56
+ options.push("dontFetchResources: #{dont_fetch_resources}")
57
+ options.push("skipResources: [#{urls_to_skip}]")
58
+ options.push("compressResources: #{compress_resources}")
59
+ options.push("serializeResources: #{serialize_resources}")
60
+ "{#{options.join(', ')}}"
61
+ end
62
+
63
+ def script
64
+ "#{process_page_script} return __processPageAndSerializePoll(#{script_options});"
65
+ end
66
+
67
+ def run
68
+ Applitools::EyesLogger.info 'Trying to get DOM snapshot...'
69
+
70
+ script_thread = Thread.new do
71
+ result = {}
72
+ while result['status'] != 'SUCCESS'
73
+ Thread.current[:script_result] = driver.execute_script(script)
74
+ begin
75
+ Thread.current[:result] = result = Oj.load(Thread.current[:script_result])
76
+ sleep 0.5
77
+ rescue Oj::ParseError => e
78
+ Applitools::EyesLogger.warn e.message
79
+ end
80
+ end
81
+ end
82
+ sleep 0.5
83
+ script_thread_result = script_thread.join(DOM_EXTRACTION_TIMEOUT)
84
+ raise ::Applitools::EyesError.new 'Timeout error while getting dom snapshot!' unless script_thread_result
85
+ Applitools::EyesLogger.info 'Done!'
86
+
87
+ script_thread_result[:result]['value']
88
+ end
89
+
90
+ end
91
+
92
+
93
+ class RecursiveSnapshotter
94
+
95
+ POLL_INTERVAL_MS = 0.5
96
+
97
+ attr_accessor :should_skip_failed_frames
98
+
99
+ attr_accessor :driver, :script, :cross_origin_rendering, :use_cookies
100
+
101
+ def initialize(driver, script, cross_origin_rendering, use_cookies)
102
+ self.should_skip_failed_frames = true
103
+ self.driver = driver
104
+ self.script = script
105
+ self.cross_origin_rendering = cross_origin_rendering
106
+ self.use_cookies = use_cookies
107
+ end
108
+
109
+ def create_cross_frames_dom_snapshots
110
+ dom = create_dom_snapshot_threaded
111
+ process_dom_snapshot_frames dom
112
+ dom
113
+ end
114
+
115
+ def create_dom_snapshot_threaded
116
+ script.run
117
+ end
118
+
119
+ def process_dom_snapshot_frames dom
120
+ dom["cookies"] = driver.manage.all_cookies if use_cookies
121
+
122
+ dom["frames"].each do |frame|
123
+ selector = frame['selector']
124
+ unless selector
125
+ Applitools::EyesLogger.warn "inner frame with null selector"
126
+ next
127
+ end
128
+ begin
129
+ original_frame_chain = driver.frame_chain
130
+ frame_element = driver.find_element(:css, selector)
131
+ frame_src = frame_element.attribute('src')
132
+ Applitools::EyesLogger.info "process_dom_snapshot_frames src = #{frame_src}"
133
+ driver.switch_to.frame(frame_element)
134
+
135
+ process_dom_snapshot_frames frame
136
+
137
+ driver.switch_to.default_content
138
+ unless original_frame_chain.empty?
139
+ driver.switch_to.frames frame_chain: original_frame_chain
140
+ end
141
+ rescue StandardError => e
142
+ Applitools::EyesLogger.error e.class.to_s
143
+ Applitools::EyesLogger.error e.message
144
+ if should_skip_failed_frames
145
+ Applitools::EyesLogger.warn "failed switching to frame #{selector}"
146
+ else
147
+ raise ::Applitools::EyesError.new 'failed switching to frame'
148
+ end
149
+ end
150
+ end
151
+
152
+ self.snapshot_and_process_cors_frames(dom) if self.cross_origin_rendering
153
+ end
154
+
155
+ def snapshot_and_process_cors_frames(dom)
156
+ dom["crossFrames"].each do |frame|
157
+ selector = frame['selector']
158
+ unless selector
159
+ Applitools::EyesLogger.warn "cross frame with null selector"
160
+ next
161
+ end
162
+ frame_index = frame['index']
163
+ begin
164
+ original_frame_chain = driver.frame_chain
165
+ frame_element = driver.find_element(:css, selector) #
166
+ frame_src = frame_element.attribute('src')
167
+ Applitools::EyesLogger.info "snapshot_and_process_cors_frames src = #{frame_src}"
168
+ driver.switch_to.frame(frame_element)
169
+
170
+ frame_dom = create_cross_frames_dom_snapshots
171
+ dom['frames'] ||= []
172
+ dom['frames'].push frame_dom
173
+ frame_url = frame_dom['url']
174
+ dom['cdt'][frame_index]['attributes'].push({ 'name' => 'data-applitools-src', 'value' => frame_url })
175
+ Applitools::EyesLogger.info "Created cross origin frame snapshot #{frame_url}"
176
+ process_dom_snapshot_frames frame_dom
177
+
178
+ driver.switch_to.default_content
179
+ unless original_frame_chain.empty?
180
+ driver.switch_to.frames(frame_chain: original_frame_chain)
181
+ end
182
+ rescue StandardError => e
183
+ Applitools::EyesLogger.error e.class.to_s
184
+ Applitools::EyesLogger.error e.message
185
+ if should_skip_failed_frames
186
+ Applitools::EyesLogger.warn "failed extracting and processing cross frame #{selector}"
187
+ else
188
+ raise ::Applitools::EyesError.new 'failed switching to frame'
189
+ end
190
+ end
191
+ end
192
+ end
193
+
194
+ end
195
+ end
196
+ end
197
+ end
@@ -188,12 +188,13 @@ module Applitools
188
188
  end
189
189
 
190
190
  fetch_block = proc do |_s, key|
191
- resp_proc = proc { |u| server_connector.download_resource(u, ua_string) }
191
+ resp_proc = proc { |u, cookies| server_connector.download_resource(u, ua_string, cookies) }
192
192
  retry_count = 3
193
+ matching_cookies = data['cookies'].to_a.select {|c| is_cookie_for_url(c, key)}
193
194
  response = nil
194
195
  loop do
195
196
  retry_count -= 1
196
- response = resp_proc.call(key.dup)
197
+ response = resp_proc.call(key.dup, matching_cookies)
197
198
  break unless response.status != 200 && retry_count > 0
198
199
  end
199
200
  Applitools::Selenium::VGResource.parse_response(
@@ -287,6 +288,24 @@ module Applitools
287
288
  running_tests << running_test
288
289
  running_tests.length - 1
289
290
  end
291
+
292
+ def is_cookie_for_url(cookie, url)
293
+ return false if cookie[:secure] && url.scheme != 'https'
294
+ return false if cookie[:expires] && DateTime.now > cookie[:expires]
295
+
296
+ subdomains_allowed = cookie[:domain].start_with? '.'
297
+ domain = subdomains_allowed ? cookie[:domain][1..-1] : cookie[:domain]
298
+ domain_match = url.hostname === domain
299
+ subdomain_match = url.hostname.end_with?('.' + domain)
300
+ return false unless domain_match || (subdomains_allowed && subdomain_match)
301
+
302
+ path = cookie[:path]
303
+ path = path.end_with?('/') ? path[0..-2] : path
304
+
305
+ return true if url.path === path
306
+ return true if url.path.start_with?(path + '/')
307
+ false
308
+ end
290
309
  end
291
310
  end
292
311
  end
@@ -8,7 +8,6 @@ module Applitools
8
8
  module Selenium
9
9
  class VisualGridEyes
10
10
  include Applitools::Selenium::Concerns::SeleniumEyes
11
- DOM_EXTRACTION_TIMEOUT = 300 # seconds or 5 minutes
12
11
  USE_DEFAULT_MATCH_TIMEOUT = -1
13
12
  extend Forwardable
14
13
 
@@ -125,9 +124,6 @@ module Applitools
125
124
  tag = first_arg[:name] || first_arg[:tag]
126
125
  end
127
126
 
128
- script = <<-END
129
- #{Applitools::Selenium::Scripts::PROCESS_PAGE_AND_POLL} return __processPageAndSerializePoll(document, {skipResources: [#{visual_grid_manager.resource_cache.urls_to_skip}]});
130
- END
131
127
  render_task = nil
132
128
  target.default_full_page_for_vg
133
129
 
@@ -136,31 +132,33 @@ module Applitools
136
132
  check_in_frame(target_frames: target_to_check.frames) do
137
133
  sleep wait_before_screenshots
138
134
  Applitools::EyesLogger.info 'Trying to get DOM snapshot...'
139
-
140
- script_thread = Thread.new do
141
- result = {}
142
- while result['status'] != 'SUCCESS'
143
- Thread.current[:script_result] = driver.execute_script(script)
144
- begin
145
- Thread.current[:result] = result = Oj.load(Thread.current[:script_result])
146
- sleep 0.5
147
- rescue Oj::ParseError => e
148
- Applitools::EyesLogger.warn e.message
149
- end
150
- end
135
+ begin
136
+ dont_fetch_resources = self.dont_fetch_resources
137
+ enable_cross_origin_rendering = self.enable_cross_origin_rendering
138
+ use_cookies = !self.dont_use_cookies
139
+ urls_to_skip = visual_grid_manager.resource_cache.urls_to_skip
140
+ dom_script = Applitools::Selenium::DomSnapshotScript.new driver
141
+
142
+ script_dom = dom_script.create_dom_snapshot(
143
+ dont_fetch_resources,
144
+ urls_to_skip,
145
+ enable_cross_origin_rendering,
146
+ use_cookies
147
+ )
148
+ rescue StandardError => e
149
+ Applitools::EyesLogger.error e.class.to_s
150
+ Applitools::EyesLogger.error e.message
151
+ raise ::Applitools::EyesError.new 'Error while getting dom snapshot!'
151
152
  end
152
- sleep 0.5
153
- script_thread_result = script_thread.join(DOM_EXTRACTION_TIMEOUT)
154
- raise ::Applitools::EyesError.new 'Timeout error while getting dom snapshot!' unless script_thread_result
155
153
  Applitools::EyesLogger.info 'Done!'
156
154
 
157
- mod = Digest::SHA2.hexdigest(script_thread_result[:script_result])
155
+ mod = Digest::SHA2.hexdigest(script_dom.to_s)
158
156
 
159
157
  region_x_paths = get_regions_x_paths(target_to_check)
160
158
 
161
159
  render_task = RenderTask.new(
162
160
  "Render #{config.short_description} - #{tag}",
163
- script_thread_result[:result]['value'],
161
+ script_dom,
164
162
  visual_grid_manager,
165
163
  server_connector,
166
164
  region_x_paths,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Applitools
4
- VERSION = '3.18.2'.freeze
4
+ VERSION = '3.18.3'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eyes_selenium
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.18.2
4
+ version: 3.18.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Applitools Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-05 00:00:00.000000000 Z
11
+ date: 2021-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eyes_core
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 3.18.2
19
+ version: 3.18.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 3.18.2
26
+ version: 3.18.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: selenium-webdriver
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -153,6 +153,7 @@ files:
153
153
  - lib/applitools/selenium/viewport_size.rb
154
154
  - lib/applitools/selenium/visual_grid/chrome_emulation_info.rb
155
155
  - lib/applitools/selenium/visual_grid/desktop_browser_info.rb
156
+ - lib/applitools/selenium/visual_grid/dom_snapshot_script.rb
156
157
  - lib/applitools/selenium/visual_grid/emulation_base_info.rb
157
158
  - lib/applitools/selenium/visual_grid/eyes_connector.rb
158
159
  - lib/applitools/selenium/visual_grid/i_render_browser_info.rb