eyes_selenium 3.15.40 → 3.15.41
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/applitools/selenium/configuration.rb +3 -1
- data/lib/applitools/selenium/css_parser/find_embedded_resources.rb +38 -13
- data/lib/applitools/selenium/dom_capture/dom_capture.rb +4 -1
- data/lib/applitools/selenium/target.rb +3 -1
- data/lib/applitools/selenium/visual_grid/eyes_connector.rb +3 -2
- data/lib/applitools/selenium/visual_grid/render_request.rb +2 -1
- data/lib/applitools/selenium/visual_grid/render_task.rb +28 -8
- data/lib/applitools/selenium/visual_grid/running_test.rb +3 -2
- data/lib/applitools/selenium/visual_grid/vg_resource.rb +25 -6
- data/lib/applitools/selenium/visual_grid/visual_grid_eyes.rb +18 -5
- data/lib/applitools/version.rb +1 -1
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f93929f33d3e8aa38656484f5cda5c572289f4a7710ae041ac154da2ae5030e3
|
4
|
+
data.tar.gz: 01f2484ce2bb35a3e68d9833996bdf7d59fc7f244e2e688127283ce57d7c0b75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e9110c797b43fb30b969b96c05c5f96033da7f6365b290376d6dbd96d70edeef018fa6bfa899cb3cf844552d3a5a93bec880bd634f4c9765b4348d61e9f7461
|
7
|
+
data.tar.gz: '0698188d685f8950b35ab1c80a26b96a3b402f03dc207ab09afde8f022192f23bfd8b0304c19440f34f18811f058178b5bacb97a5111a1d2e7fdb6de6d3e90f5'
|
@@ -14,7 +14,8 @@ module Applitools
|
|
14
14
|
hide_scrollbars: false,
|
15
15
|
hide_caret: false,
|
16
16
|
browsers_info: Applitools::Selenium::BrowsersInfo.new,
|
17
|
-
accessibility_validation: Applitools::AccessibilityLevel::NONE
|
17
|
+
accessibility_validation: Applitools::AccessibilityLevel::NONE,
|
18
|
+
rendering_grid_force_put: (ENV['APPLITOOLS_RENDERING_GRID_FORCE_PUT'] || 'false').casecmp('true') == 0
|
18
19
|
}
|
19
20
|
end
|
20
21
|
class << self
|
@@ -33,6 +34,7 @@ module Applitools
|
|
33
34
|
object_field :browsers_info, Applitools::Selenium::BrowsersInfo
|
34
35
|
int_field :concurrent_sessions
|
35
36
|
enum_field :accessibility_validation, Applitools::AccessibilityLevel.enum_values
|
37
|
+
boolean_field :rendering_grid_force_put
|
36
38
|
|
37
39
|
def match_level_keys
|
38
40
|
super << :accessibility_validation
|
@@ -15,6 +15,7 @@ module Applitools
|
|
15
15
|
|
16
16
|
def initialize(css)
|
17
17
|
self.css = css
|
18
|
+
@nodes_by_type = {}
|
18
19
|
end
|
19
20
|
|
20
21
|
def imported_css
|
@@ -32,37 +33,61 @@ module Applitools
|
|
32
33
|
private
|
33
34
|
|
34
35
|
def url(node)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
url_string_node
|
36
|
+
result = []
|
37
|
+
node[:tokens].select { |t| t[:node] == :url }.uniq.each do |nd|
|
38
|
+
result << nd[:value] if nd && !nd.empty?
|
39
|
+
end
|
40
|
+
node[:tokens].select { |t| t[:node] == :function && t[:value] == 'url' }.uniq do |nd|
|
41
|
+
url_index = node[:tokens].index(nd)
|
42
|
+
url_string_node = url_index && node[:tokens][url_index + 1]
|
43
|
+
result << url_string_node &&
|
44
|
+
url_string_node[:node] == :string && !url_string_node[:value].empty? && url_string_node[:value]
|
45
|
+
end
|
46
|
+
result.compact
|
42
47
|
end
|
43
48
|
|
44
49
|
def fetch_urls(nodes)
|
45
|
-
nodes.map { |n| url(n) }.compact
|
50
|
+
nodes.map { |n| url(n) }.flatten.compact
|
46
51
|
end
|
47
52
|
|
48
53
|
def import_rules
|
49
|
-
css_nodes.select { |n| n[:node] == :at_rule && n[:name] == 'import' }
|
54
|
+
# css_nodes.select { |n| n[:node] == :at_rule && n[:name] == 'import' }
|
55
|
+
nodes_by_type[:import_rules]
|
50
56
|
end
|
51
57
|
|
52
58
|
def font_face_rules
|
53
|
-
css_nodes.select { |n| n[:node] == :at_rule && n[:name] == 'font-face' }
|
59
|
+
# css_nodes.select { |n| n[:node] == :at_rule && n[:name] == 'font-face' }
|
60
|
+
nodes_by_type[:font_face_rules]
|
54
61
|
end
|
55
62
|
|
56
63
|
def images_rules
|
57
|
-
css_nodes.select { |n| n[:node] == :style_rule }.map { |n| n[:children] }
|
58
|
-
|
59
|
-
|
64
|
+
# css_nodes.select { |n| n[:node] == :style_rule }.map { |n| n[:children] }
|
65
|
+
# .flatten
|
66
|
+
# .select { |n| n[:node] == :property && (n[:name] == 'background' || n[:name] == 'background-image') }
|
67
|
+
nodes_by_type[:images_rules]
|
60
68
|
end
|
61
69
|
|
62
70
|
def css_nodes
|
63
71
|
@css_nodes ||= parse_nodes
|
64
72
|
end
|
65
73
|
|
74
|
+
def nodes_by_type
|
75
|
+
return @nodes_by_type unless @nodes_by_type.empty?
|
76
|
+
css_nodes.each do |n|
|
77
|
+
@nodes_by_type[:import_rules] ||= []
|
78
|
+
@nodes_by_type[:font_face_rules] ||= []
|
79
|
+
@nodes_by_type[:images_rules] ||= []
|
80
|
+
@nodes_by_type[:import_rules] << n if n[:node] == :at_rule && n[:name] == 'import'
|
81
|
+
@nodes_by_type[:font_face_rules] << n if n[:node] == :at_rule && n[:name] == 'font-face'
|
82
|
+
@nodes_by_type[:images_rules] << n if n[:node] == :style_rule
|
83
|
+
end
|
84
|
+
@nodes_by_type[:images_rules].map! { |n| n[:children] }.flatten!
|
85
|
+
@nodes_by_type[:images_rules] = @nodes_by_type[:images_rules].select do |n|
|
86
|
+
n[:node] == :property && (n[:name] == 'background' || n[:name] == 'background-image')
|
87
|
+
end
|
88
|
+
@nodes_by_type
|
89
|
+
end
|
90
|
+
|
66
91
|
def parse_nodes
|
67
92
|
Crass.parse css
|
68
93
|
end
|
@@ -72,7 +72,10 @@ module Applitools
|
|
72
72
|
next if /^blob:/ =~ url
|
73
73
|
|
74
74
|
begin
|
75
|
-
missing_css_response = server_connector.download_resource(
|
75
|
+
missing_css_response = server_connector.download_resource(
|
76
|
+
url,
|
77
|
+
Applitools::Utils::EyesSeleniumUtils.user_agent(driver)
|
78
|
+
)
|
76
79
|
response_headers = missing_css_response.headers
|
77
80
|
raise Applitools::EyesError, "Wrong response header: #{response_headers['content-type']}" unless
|
78
81
|
%r{^text/css.*}i =~ response_headers['content-type']
|
@@ -303,11 +303,13 @@ module Applitools
|
|
303
303
|
self
|
304
304
|
end
|
305
305
|
|
306
|
-
def
|
306
|
+
def before_render_screenshot_hook(hook)
|
307
307
|
options[:script_hooks][:beforeCaptureScreenshot] = hook
|
308
308
|
self
|
309
309
|
end
|
310
310
|
|
311
|
+
alias script_hook before_render_screenshot_hook
|
312
|
+
|
311
313
|
def finalize
|
312
314
|
return self unless frame_or_element
|
313
315
|
region = frame_or_element
|
@@ -5,7 +5,7 @@ module Applitools
|
|
5
5
|
USE_DEFAULT_MATCH_TIMEOUT = -1
|
6
6
|
|
7
7
|
attr_accessor :browser_info, :test_result, :driver, :dummy_region_provider, :dont_get_title,
|
8
|
-
:current_uuid, :render_statuses, :device_name, :driver_lock
|
8
|
+
:current_uuid, :render_statuses, :device_name, :driver_lock, :title
|
9
9
|
public :server_connector
|
10
10
|
|
11
11
|
class RegionProvider
|
@@ -33,6 +33,7 @@ module Applitools
|
|
33
33
|
self.device_name = browser_info && browser_info.emulation_info && browser_info.emulation_info.device_name
|
34
34
|
logger.info "opening EyesConnector for #{config.short_description} with viewport size: #{browser_info}"
|
35
35
|
config.viewport_size = browser_info.viewport_size
|
36
|
+
title
|
36
37
|
open_base
|
37
38
|
# ensure_running_session
|
38
39
|
end
|
@@ -138,7 +139,7 @@ module Applitools
|
|
138
139
|
end
|
139
140
|
|
140
141
|
def title
|
141
|
-
|
142
|
+
@title ||= driver.title unless dont_get_title
|
142
143
|
rescue StandardError => e
|
143
144
|
logger.warn "failed (#{e.message})"
|
144
145
|
self.dont_get_title = false
|
@@ -6,12 +6,13 @@ module Applitools
|
|
6
6
|
class RenderRequest
|
7
7
|
include Applitools::Jsonable
|
8
8
|
json_fields :renderId, :webhook, :url, :dom, :resources, :scriptHooks,
|
9
|
-
:selectorsToFindRegionsFor, :sendDom
|
9
|
+
:selectorsToFindRegionsFor, :sendDom, :agentId
|
10
10
|
|
11
11
|
json_fields :renderInfo, :browser
|
12
12
|
|
13
13
|
def initialize(*args)
|
14
14
|
options = Applitools::Utils.extract_options! args
|
15
|
+
self.agent_id = "eyes.selenium.visualgrid.ruby/#{Applitools::VERSION}"
|
15
16
|
self.script_hooks = {}
|
16
17
|
self.selectors_to_find_regions_for = []
|
17
18
|
options.keys.each do |k|
|
@@ -21,10 +21,10 @@ module Applitools
|
|
21
21
|
|
22
22
|
attr_accessor :script, :running_tests, :resource_cache, :put_cache, :server_connector,
|
23
23
|
:rendering_info, :request_resources, :dom_url_mod, :result, :region_selectors, :size_mode,
|
24
|
-
:region_to_check, :script_hooks, :visual_grid_manager, :discovered_resources
|
24
|
+
:region_to_check, :script_hooks, :visual_grid_manager, :discovered_resources, :ua_string, :force_put
|
25
25
|
|
26
26
|
def initialize(name, script_result, visual_grid_manager, server_connector, region_selectors, size_mode,
|
27
|
-
region, script_hooks, mod = nil)
|
27
|
+
region, script_hooks, force_put, ua_string, mod = nil)
|
28
28
|
|
29
29
|
self.result = nil
|
30
30
|
self.script = script_result
|
@@ -37,9 +37,10 @@ module Applitools
|
|
37
37
|
self.size_mode = size_mode
|
38
38
|
self.region_to_check = region
|
39
39
|
self.script_hooks = script_hooks if script_hooks.is_a?(Hash)
|
40
|
-
|
40
|
+
self.ua_string = ua_string
|
41
41
|
self.dom_url_mod = mod
|
42
42
|
self.running_tests = []
|
43
|
+
self.force_put = force_put
|
43
44
|
@discovered_resources_lock = Mutex.new
|
44
45
|
super(name) do
|
45
46
|
perform
|
@@ -72,6 +73,22 @@ module Applitools
|
|
72
73
|
cache_key = URI(dom_resource.url)
|
73
74
|
cache_key.query = "modifier=#{dom_url_mod}" if dom_url_mod
|
74
75
|
|
76
|
+
if force_put
|
77
|
+
request_resources.each do |r, _v|
|
78
|
+
put_cache.fetch_and_store(URI(r)) do |_s|
|
79
|
+
server_connector.render_put_resource(
|
80
|
+
rendering_info['serviceUrl'],
|
81
|
+
rendering_info['accessToken'],
|
82
|
+
request_resources[r],
|
83
|
+
running_render
|
84
|
+
)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
request_resources.each do |r, _v|
|
88
|
+
put_cache[r]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
75
92
|
if need_more_resources
|
76
93
|
running_render['needMoreResources'].each do |resource_url|
|
77
94
|
put_cache.fetch_and_store(URI(resource_url)) do |_s|
|
@@ -148,7 +165,6 @@ module Applitools
|
|
148
165
|
def prepare_data_for_rg(data)
|
149
166
|
self.request_resources = Applitools::Selenium::RenderResources.new
|
150
167
|
dom = parse_frame_dom_resources(data)
|
151
|
-
|
152
168
|
prepare_rg_requests(running_tests, dom)
|
153
169
|
end
|
154
170
|
|
@@ -159,7 +175,7 @@ module Applitools
|
|
159
175
|
|
160
176
|
fetch_block = proc {}
|
161
177
|
|
162
|
-
|
178
|
+
handle_resources_block = proc do |urls_to_fetch, url|
|
163
179
|
urls_to_fetch.each do |discovered_url|
|
164
180
|
target_url = self.class.apply_base_url(URI.parse(discovered_url), url)
|
165
181
|
next unless /^http/i =~ target_url.scheme
|
@@ -171,7 +187,7 @@ module Applitools
|
|
171
187
|
end
|
172
188
|
|
173
189
|
fetch_block = proc do |_s, key|
|
174
|
-
resp_proc = proc { |u| server_connector.download_resource(u) }
|
190
|
+
resp_proc = proc { |u| server_connector.download_resource(u, ua_string) }
|
175
191
|
retry_count = 3
|
176
192
|
response = nil
|
177
193
|
loop do
|
@@ -179,7 +195,11 @@ module Applitools
|
|
179
195
|
response = resp_proc.call(key.dup)
|
180
196
|
break unless response.status != 200 && retry_count > 0
|
181
197
|
end
|
182
|
-
Applitools::Selenium::VGResource.parse_response(
|
198
|
+
Applitools::Selenium::VGResource.parse_response(
|
199
|
+
key.dup,
|
200
|
+
response,
|
201
|
+
on_resources_fetched: handle_resources_block
|
202
|
+
)
|
183
203
|
end
|
184
204
|
|
185
205
|
data['frames'].each do |f|
|
@@ -192,7 +212,7 @@ module Applitools
|
|
192
212
|
end
|
193
213
|
|
194
214
|
blobs.each do |blob|
|
195
|
-
blob.
|
215
|
+
blob.on_resources_fetched(handle_resources_block)
|
196
216
|
blob.lookup_for_resources
|
197
217
|
end
|
198
218
|
|
@@ -133,7 +133,7 @@ module Applitools
|
|
133
133
|
attr_accessor :open_queue, :task_queue, :render_queue, :close_queue, :watch_open, :watch_task,
|
134
134
|
:watch_render, :watch_close
|
135
135
|
|
136
|
-
attr_accessor :eyes, :browser_info, :test_result, :pending_exceptions, :driver, :task_lock
|
136
|
+
attr_accessor :eyes, :browser_info, :test_result, :pending_exceptions, :driver, :task_lock, :test_uuid
|
137
137
|
|
138
138
|
def initialize(eyes, browser_info, driver)
|
139
139
|
Applitools::ArgumentGuard.is_a? eyes, 'eyes', Applitools::Selenium::EyesConnector
|
@@ -185,7 +185,8 @@ module Applitools
|
|
185
185
|
watch_open[open_task] = false
|
186
186
|
end
|
187
187
|
|
188
|
-
def check(tag, target, render_task)
|
188
|
+
def check(tag, target, render_task, title)
|
189
|
+
eyes.title = title
|
189
190
|
result_index = render_task.add_running_test(self)
|
190
191
|
|
191
192
|
check_task = VGTask.new("perform check #{tag} #{target}") do
|
@@ -2,12 +2,14 @@
|
|
2
2
|
|
3
3
|
require 'base64'
|
4
4
|
require 'digest'
|
5
|
+
require 'nokogiri'
|
6
|
+
|
5
7
|
module Applitools
|
6
8
|
module Selenium
|
7
9
|
class VGResource
|
8
10
|
include Applitools::Jsonable
|
9
11
|
json_fields :contentType, :hash, :hashFormat
|
10
|
-
attr_accessor :url, :content, :
|
12
|
+
attr_accessor :url, :content, :handle_discovered_resources_block
|
11
13
|
alias content_type contentType
|
12
14
|
alias content_type= contentType=
|
13
15
|
|
@@ -24,7 +26,8 @@ module Applitools
|
|
24
26
|
end
|
25
27
|
|
26
28
|
def initialize(url, content_type, content, options = {})
|
27
|
-
self.
|
29
|
+
self.handle_discovered_resources_block = options[:on_resources_fetched] if
|
30
|
+
options[:on_resources_fetched].is_a? Proc
|
28
31
|
self.url = URI(url)
|
29
32
|
self.content_type = content_type
|
30
33
|
self.content = content
|
@@ -33,19 +36,35 @@ module Applitools
|
|
33
36
|
lookup_for_resources
|
34
37
|
end
|
35
38
|
|
36
|
-
def
|
37
|
-
self.
|
39
|
+
def on_resources_fetched(block)
|
40
|
+
self.handle_discovered_resources_block = block
|
38
41
|
end
|
39
42
|
|
40
43
|
def lookup_for_resources
|
41
|
-
|
44
|
+
lookup_for_css_resources
|
45
|
+
lookup_for_svg_resources
|
46
|
+
end
|
47
|
+
|
48
|
+
def lookup_for_css_resources
|
49
|
+
return unless %r{^text/css}i =~ content_type && handle_discovered_resources_block
|
42
50
|
parser = Applitools::Selenium::CssParser::FindEmbeddedResources.new(content)
|
43
|
-
|
51
|
+
handle_discovered_resources_block.call(parser.imported_css + parser.fonts + parser.images, url)
|
52
|
+
end
|
53
|
+
|
54
|
+
def lookup_for_svg_resources
|
55
|
+
return unless %r{^image/svg\+xml} =~ content_type && handle_discovered_resources_block
|
56
|
+
attrs = Nokogiri::XML(content)
|
57
|
+
.xpath("//@*[namespace-uri(.) = 'http://www.w3.org/1999/xlink'] | //@href")
|
58
|
+
.select { |a| a.name == 'href' }
|
59
|
+
.map(&:value)
|
60
|
+
handle_discovered_resources_block.call(attrs, url)
|
44
61
|
end
|
45
62
|
|
46
63
|
def stringify
|
47
64
|
url.to_s + content_type.to_s + hash
|
48
65
|
end
|
66
|
+
|
67
|
+
private :lookup_for_svg_resources, :lookup_for_css_resources
|
49
68
|
end
|
50
69
|
end
|
51
70
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'applitools/selenium/configuration'
|
4
4
|
require 'timeout'
|
5
|
+
require 'securerandom'
|
5
6
|
|
6
7
|
module Applitools
|
7
8
|
module Selenium
|
@@ -14,13 +15,13 @@ module Applitools
|
|
14
15
|
def_delegators 'Applitools::EyesLogger', :logger, :log_handler, :log_handler=
|
15
16
|
|
16
17
|
attr_accessor :visual_grid_manager, :driver, :current_url, :current_config, :fetched_cache_map,
|
17
|
-
:config, :driver_lock
|
18
|
+
:config, :driver_lock, :test_uuid, :dont_get_title
|
18
19
|
attr_accessor :test_list
|
19
20
|
|
20
21
|
attr_accessor :api_key, :server_url, :proxy, :opened
|
21
22
|
|
22
23
|
attr_accessor :size_mod, :region_to_check
|
23
|
-
private :size_mod, :size_mod=, :region_to_check, :region_to_check=
|
24
|
+
private :size_mod, :size_mod=, :region_to_check, :region_to_check=, :test_uuid, :test_uuid=
|
24
25
|
|
25
26
|
def_delegators 'config', *Applitools::Selenium::Configuration.methods_to_delegate
|
26
27
|
def_delegators 'config', *Applitools::EyesBaseConfiguration.methods_to_delegate
|
@@ -46,6 +47,7 @@ module Applitools
|
|
46
47
|
end
|
47
48
|
|
48
49
|
def open(*args)
|
50
|
+
self.test_uuid = SecureRandom.uuid
|
49
51
|
options = Applitools::Utils.extract_options!(args)
|
50
52
|
Applitools::ArgumentGuard.hash(options, 'options', [:driver])
|
51
53
|
|
@@ -78,6 +80,7 @@ module Applitools
|
|
78
80
|
t.on_results_received do |results|
|
79
81
|
visual_grid_manager.aggregate_result(results)
|
80
82
|
end
|
83
|
+
t.test_uuid = test_uuid
|
81
84
|
end
|
82
85
|
test_list.push test
|
83
86
|
end
|
@@ -125,7 +128,6 @@ module Applitools
|
|
125
128
|
end
|
126
129
|
sleep 0.5
|
127
130
|
script_thread_result = script_thread.join(DOM_EXTRACTION_TIMEOUT)
|
128
|
-
|
129
131
|
raise ::Applitools::EyesError.new 'Timeout error while getting dom snapshot!' unless script_thread_result
|
130
132
|
Applitools::EyesLogger.info 'Done!'
|
131
133
|
|
@@ -141,11 +143,22 @@ module Applitools
|
|
141
143
|
size_mod,
|
142
144
|
region_to_check,
|
143
145
|
target_to_check.options[:script_hooks],
|
146
|
+
config.rendering_grid_force_put,
|
147
|
+
Applitools::Utils::EyesSeleniumUtils.user_agent(driver),
|
144
148
|
mod
|
145
149
|
)
|
146
150
|
end
|
147
|
-
|
148
|
-
|
151
|
+
|
152
|
+
title = begin
|
153
|
+
driver.title
|
154
|
+
rescue StandardError => e
|
155
|
+
logger.warn "failed (#{e.message})"
|
156
|
+
''
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
test_list.select { |t| t.test_uuid == test_uuid }.each do |t|
|
161
|
+
t.check(tag, target_to_check, render_task, title)
|
149
162
|
end
|
150
163
|
test_list.each(&:becomes_not_rendered)
|
151
164
|
visual_grid_manager.enqueue_render_task render_task
|
data/lib/applitools/version.rb
CHANGED
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.15.
|
4
|
+
version: 3.15.41
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Applitools Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-12-
|
11
|
+
date: 2019-12-08 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.15.
|
19
|
+
version: 3.15.41
|
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.15.
|
26
|
+
version: 3.15.41
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: selenium-webdriver
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: nokogiri
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
description: Provides SDK for writing Applitools Selenium-based tests
|
84
98
|
email:
|
85
99
|
- team@applitools.com
|