eyes_core 6.9.10 → 6.9.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 +23 -0
- data/eyes_core.gemspec +1 -17
- data/lib/applitools/connectivity/server_connector.rb +4 -371
- data/lib/applitools/core/classic_runner.rb +0 -4
- data/lib/applitools/core/eyes_base.rb +18 -67
- data/lib/applitools/core/universal_eyes_open.rb +7 -6
- data/lib/applitools/eyes_core/version.rb +1 -1
- data/lib/applitools/universal_sdk/universal_client.rb +12 -2
- metadata +4 -158
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4ae006da25788db912b4d6712f34ff1b8b4893b98357123151b33273808fe4e3
|
|
4
|
+
data.tar.gz: eaa492221c1b63304f625ed339258c8cd8ad88f4b9d9686f70a0c3039a5d6ed4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 497ed2fae5815696d7fe8ef1f0ffa584c79e278e1b76c8890bd9fa5fe4026cd520b24860b22bea1a99c670bb977bef97de795aa56561d0c1808d2ce1a39d88fd
|
|
7
|
+
data.tar.gz: '004888674d2c57d4c37a1f9b54221d68bf1e031312ad0ca47b95c78204b768030e5a95eb403558a379008723462b3ca12022f663746dd14552f10afab12d1297'
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [6.9.11](https://github.com/Applitools-Dev/sdk/compare/ruby/eyes_core@6.9.10...ruby/eyes_core@6.9.11) (2025-12-14)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Dependencies
|
|
7
|
+
|
|
8
|
+
* @applitools/nml-client bumped to 1.11.13
|
|
9
|
+
|
|
10
|
+
* @applitools/core-base bumped to 1.31.0
|
|
11
|
+
#### Features
|
|
12
|
+
|
|
13
|
+
* Baseline branch fallback list | FLD-3837 ([#3373](https://github.com/Applitools-Dev/sdk/issues/3373)) ([e94bb10](https://github.com/Applitools-Dev/sdk/commit/e94bb10ad6b49322a56e4ce6dfde560b237e9ac0))
|
|
14
|
+
* @applitools/core bumped to 4.54.0
|
|
15
|
+
#### Features
|
|
16
|
+
|
|
17
|
+
* Baseline branch fallback list | FLD-3837 ([#3373](https://github.com/Applitools-Dev/sdk/issues/3373)) ([e94bb10](https://github.com/Applitools-Dev/sdk/commit/e94bb10ad6b49322a56e4ce6dfde560b237e9ac0))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
* @applitools/ec-client bumped to 1.12.15
|
|
22
|
+
|
|
23
|
+
* eyes_universal bumped to 4.54.0
|
|
24
|
+
|
|
25
|
+
|
|
3
26
|
## [6.9.10](https://github.com/Applitools-Dev/sdk/compare/ruby/eyes_core@6.9.9...ruby/eyes_core@6.9.10) (2025-12-07)
|
|
4
27
|
|
|
5
28
|
|
data/eyes_core.gemspec
CHANGED
|
@@ -32,28 +32,12 @@ Gem::Specification.new do |spec|
|
|
|
32
32
|
|
|
33
33
|
spec.metadata['yard.run'] = 'yri' # use "yard" to build full HTML docs.
|
|
34
34
|
|
|
35
|
-
spec.add_dependency 'faraday'
|
|
36
|
-
spec.add_dependency 'faraday_middleware'
|
|
37
|
-
spec.add_dependency 'faraday-cookie_jar'
|
|
38
|
-
|
|
39
35
|
spec.add_dependency 'oj'
|
|
40
|
-
spec.add_dependency 'colorize'
|
|
41
36
|
spec.add_dependency 'websocket'
|
|
42
|
-
spec.add_dependency '
|
|
43
|
-
spec.add_dependency 'eyes_universal', "= 4.53.2"
|
|
37
|
+
spec.add_dependency 'eyes_universal', "= 4.54.0"
|
|
44
38
|
|
|
45
39
|
spec.add_development_dependency 'bundler'
|
|
46
40
|
spec.add_development_dependency 'rake'
|
|
47
41
|
spec.add_development_dependency 'rspec', '>= 3'
|
|
48
42
|
spec.add_development_dependency 'rubocop', '<= 0.46.0'
|
|
49
|
-
|
|
50
|
-
# Exclude debugging support on Travis CI, due to its incompatibility with jruby and older rubies.
|
|
51
|
-
unless ENV['TRAVIS']
|
|
52
|
-
spec.add_development_dependency 'pry'
|
|
53
|
-
spec.add_development_dependency 'pry-byebug'
|
|
54
|
-
spec.add_development_dependency 'byebug'
|
|
55
|
-
spec.add_development_dependency 'pry-doc'
|
|
56
|
-
spec.add_development_dependency 'pry-stack_explorer'
|
|
57
|
-
spec.add_development_dependency 'rb-readline'
|
|
58
|
-
end
|
|
59
43
|
end
|
|
@@ -1,44 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: false
|
|
2
2
|
|
|
3
|
-
require 'faraday'
|
|
4
|
-
require 'faraday_middleware'
|
|
5
|
-
require 'faraday-cookie_jar'
|
|
6
3
|
require 'oj'
|
|
7
|
-
require '
|
|
4
|
+
require 'uri'
|
|
8
5
|
|
|
9
6
|
Oj.default_options = { :mode => :compat }
|
|
10
7
|
|
|
11
|
-
require 'uri'
|
|
12
|
-
|
|
13
8
|
module Applitools::Connectivity
|
|
9
|
+
# ServerConnector provides configuration for connecting to Applitools servers.
|
|
10
|
+
# All actual HTTP communication is now handled by the Universal SDK.
|
|
14
11
|
class ServerConnector
|
|
15
|
-
class << self
|
|
16
|
-
attr_accessor :faraday_adapter, :connection_timeout
|
|
17
|
-
end
|
|
18
|
-
self.faraday_adapter = :net_http
|
|
19
|
-
class ScreenshotUploadError < Applitools::EyesError; end
|
|
20
12
|
extend Applitools::Helpers
|
|
21
|
-
DEFAULT_SERVER_URL = 'https://eyesapi.applitools.com'.freeze
|
|
22
13
|
|
|
23
|
-
|
|
14
|
+
DEFAULT_SERVER_URL = 'https://eyesapi.applitools.com'.freeze
|
|
24
15
|
DEFAULT_TIMEOUT = 300_000
|
|
25
16
|
API_SESSIONS = '/api/sessions'.freeze
|
|
26
17
|
API_SESSIONS_RUNNING = API_SESSIONS + '/running/'.freeze
|
|
27
|
-
API_SINGLE_TEST = API_SESSIONS + '/'.freeze
|
|
28
|
-
|
|
29
|
-
RENDER_INFO_PATH = API_SESSIONS + '/renderinfo'.freeze
|
|
30
|
-
RENDER = '/render'.freeze
|
|
31
|
-
|
|
32
|
-
RESOURCES_SHA_256 = '/resources/sha256/'.freeze
|
|
33
|
-
RENDER_STATUS = '/render-status'.freeze
|
|
34
|
-
CLOSE_BATCH = '/api/sessions/batches/%s/close/bypointerid'.freeze
|
|
35
|
-
|
|
36
|
-
HTTP_STATUS_CODES = {
|
|
37
|
-
created: 201,
|
|
38
|
-
accepted: 202,
|
|
39
|
-
ok: 200,
|
|
40
|
-
gone: 410
|
|
41
|
-
}.freeze
|
|
42
18
|
|
|
43
19
|
attr_accessor :server_url
|
|
44
20
|
attr_reader :endpoint_url
|
|
@@ -60,142 +36,6 @@ module Applitools::Connectivity
|
|
|
60
36
|
"eyes.sdk.ruby/#{Applitools::VERSION}"
|
|
61
37
|
end
|
|
62
38
|
|
|
63
|
-
def rendering_info
|
|
64
|
-
response = long_get(URI.join(server_url, RENDER_INFO_PATH), content_type: 'application/json')
|
|
65
|
-
unless response.status == HTTP_STATUS_CODES[:ok]
|
|
66
|
-
raise Applitools::EyesError, "Error getting render info (#{response.status}})"
|
|
67
|
-
end
|
|
68
|
-
Oj.load response.body
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def render(service_url, access_key, requests)
|
|
72
|
-
uri = URI.join(URI(service_url), RENDER)
|
|
73
|
-
response = dummy_post(
|
|
74
|
-
uri,
|
|
75
|
-
body: requests.json,
|
|
76
|
-
headers: {
|
|
77
|
-
'X-Auth-Token' => access_key
|
|
78
|
-
},
|
|
79
|
-
timeout: 10
|
|
80
|
-
)
|
|
81
|
-
unless response.status == HTTP_STATUS_CODES[:ok]
|
|
82
|
-
raise Applitools::EyesError, "Error render processing (#{response.status}, #{response.body})"
|
|
83
|
-
end
|
|
84
|
-
Oj.load response.body
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def put_screenshot(rendering_info, screenshot)
|
|
88
|
-
put_data(rendering_info, screenshot.image.to_blob, 'image/png', 'screenshot')
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def put_dom(rendering_info, dom_data)
|
|
92
|
-
put_data(rendering_info, dom_data, 'application/octet-stream', 'dom data')
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def put_data(rendering_info, data, content_type, log_message_entity)
|
|
96
|
-
uuid = SecureRandom.uuid
|
|
97
|
-
upload_path = URI.parse(rendering_info.results_url.gsub(/__random__/, uuid))
|
|
98
|
-
retry_count = 3
|
|
99
|
-
wait = 0.5
|
|
100
|
-
loop do
|
|
101
|
-
raise ScreenshotUploadError, "Error uploading #{log_message_entity} (#{upload_path})" if retry_count <= 0
|
|
102
|
-
Applitools::EyesLogger.info("Trying to upload #{log_message_entity} (#{upload_path})...")
|
|
103
|
-
begin
|
|
104
|
-
response = dummy_put(
|
|
105
|
-
upload_path,
|
|
106
|
-
body: data,
|
|
107
|
-
headers: {
|
|
108
|
-
'x-ms-blob-type': 'BlockBlob',
|
|
109
|
-
'X-Auth-Token': rendering_info.access_token
|
|
110
|
-
},
|
|
111
|
-
query: URI.decode_www_form(upload_path.query).to_h,
|
|
112
|
-
content_type: content_type
|
|
113
|
-
)
|
|
114
|
-
break if response.status == HTTP_STATUS_CODES[:created]
|
|
115
|
-
Applitools::EyesLogger.info("Failed. Retrying in #{wait} seconds")
|
|
116
|
-
sleep(wait)
|
|
117
|
-
rescue StandardError => e
|
|
118
|
-
Applitools::EyesLogger.error(e.class.to_s)
|
|
119
|
-
Applitools::EyesLogger.error(e.message)
|
|
120
|
-
Applitools::EyesLogger.info("Failed. Retrying in #{wait} seconds")
|
|
121
|
-
sleep(wait)
|
|
122
|
-
ensure
|
|
123
|
-
retry_count -= 1
|
|
124
|
-
wait *= 2
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
Applitools::EyesLogger.info('Done.')
|
|
128
|
-
upload_path.to_s
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def render_put_resource(service_url, access_key, resource, render)
|
|
132
|
-
uri = URI(service_url)
|
|
133
|
-
uri.path = RESOURCES_SHA_256 + resource.hash
|
|
134
|
-
Applitools::EyesLogger.debug("PUT resource: (#{resource.url}) - #{uri}")
|
|
135
|
-
# Applitools::EyesLogger.debug("Resource content: #{resource.content}")
|
|
136
|
-
response = dummy_put(
|
|
137
|
-
uri,
|
|
138
|
-
body: resource.content,
|
|
139
|
-
content_type: resource.content_type,
|
|
140
|
-
headers: {
|
|
141
|
-
'X-Auth-Token' => access_key
|
|
142
|
-
},
|
|
143
|
-
query: { 'render-id' => render['renderId'] }
|
|
144
|
-
)
|
|
145
|
-
unless response.status == HTTP_STATUS_CODES[:ok]
|
|
146
|
-
raise Applitools::EyesError, "Error putting resource: #{response.status}, #{response.body}"
|
|
147
|
-
end
|
|
148
|
-
resource.hash
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def render_status_by_id(service_url, access_key, running_renders_json)
|
|
152
|
-
uri = URI(service_url)
|
|
153
|
-
uri.path = RENDER_STATUS
|
|
154
|
-
response = dummy_post(
|
|
155
|
-
uri,
|
|
156
|
-
body: running_renders_json,
|
|
157
|
-
content_type: 'application/json',
|
|
158
|
-
headers: {
|
|
159
|
-
'X-Auth-Token' => access_key
|
|
160
|
-
},
|
|
161
|
-
timeout: 2
|
|
162
|
-
)
|
|
163
|
-
unless response.status == HTTP_STATUS_CODES[:ok]
|
|
164
|
-
raise Applitools::EyesError, "Error getting server status, #{response.status} #{response.body}"
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
Oj.load(response.body)
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
def download_resource(url, ua_string = nil, cookies=nil)
|
|
171
|
-
Applitools::EyesLogger.debug "Fetching #{url}..."
|
|
172
|
-
resp_proc = proc do |u|
|
|
173
|
-
faraday_connection(u, false).send(:get) do |req|
|
|
174
|
-
req.options.timeout = self.class.connection_timeout || DEFAULT_TIMEOUT
|
|
175
|
-
req.headers[:accept_encoding] = 'identity'
|
|
176
|
-
req.headers[:accept_language] = '*'
|
|
177
|
-
req.headers[:user_agent] = ua_string if ua_string
|
|
178
|
-
req.headers[:Cookie] = cookies.map { |h| [h[:name], h[:value]].join('=') }.join('; ') unless cookies.to_a.empty?
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
response = resp_proc.call(url)
|
|
182
|
-
Applitools::EyesLogger.debug "Done. (#{url} #{response.status})"
|
|
183
|
-
response
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def close_batch(batch_id)
|
|
187
|
-
if 'true'.casecmp(ENV['APPLITOOLS_DONT_CLOSE_BATCHES'] || '') == 0
|
|
188
|
-
return Applitools::EyesLogger.info(
|
|
189
|
-
'APPLITOOLS_DONT_CLOSE_BATCHES environment variable set to true. Doing nothing.'
|
|
190
|
-
) && false
|
|
191
|
-
end
|
|
192
|
-
Applitools::ArgumentGuard.not_nil(batch_id, 'batch_id')
|
|
193
|
-
Applitools::EyesLogger.info("Called with #{batch_id}")
|
|
194
|
-
url = CLOSE_BATCH % batch_id
|
|
195
|
-
response = delete(URI.join(endpoint_url, url))
|
|
196
|
-
Applitools::EyesLogger.info "delete batch is done with #{response.status} status"
|
|
197
|
-
end
|
|
198
|
-
|
|
199
39
|
def server_url=(url)
|
|
200
40
|
if url
|
|
201
41
|
uri = URI.parse(url)
|
|
@@ -207,7 +47,6 @@ module Applitools::Connectivity
|
|
|
207
47
|
" (#{@server_url.class} is passed)"
|
|
208
48
|
end
|
|
209
49
|
@endpoint_url = URI.join(@server_url, API_SESSIONS_RUNNING).to_s
|
|
210
|
-
@single_check_endpoint_url = URI.join(@server_url, API_SINGLE_TEST).to_s
|
|
211
50
|
end
|
|
212
51
|
|
|
213
52
|
def set_proxy(uri, user = nil, password = nil)
|
|
@@ -221,211 +60,5 @@ module Applitools::Connectivity
|
|
|
221
60
|
end
|
|
222
61
|
@proxy = value
|
|
223
62
|
end
|
|
224
|
-
|
|
225
|
-
def match_window(session, data)
|
|
226
|
-
# Notice that this does not include the screenshot.
|
|
227
|
-
json_data = Oj.dump(Applitools::Utils.camelcase_hash_keys(data.to_hash)).force_encoding('BINARY')
|
|
228
|
-
|
|
229
|
-
body = if data.screenshot && data.app_output.screenshot_url.nil?
|
|
230
|
-
content_type = 'application/octet-stream'
|
|
231
|
-
[json_data.length].pack('L>') + json_data + data.screenshot
|
|
232
|
-
else
|
|
233
|
-
content_type = 'application/json'
|
|
234
|
-
json_data
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
Applitools::EyesLogger.debug 'Sending match data...'
|
|
238
|
-
Applitools::EyesLogger.debug json_data
|
|
239
|
-
res = long_post(URI.join(endpoint_url, session.id.to_s), content_type: content_type, body: body)
|
|
240
|
-
raise Applitools::EyesError.new("Request failed: #{res.status} #{res.headers}") unless res.success?
|
|
241
|
-
# puts Oj.load(res.body)
|
|
242
|
-
Applitools::MatchResult.new Oj.load(res.body)
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
RETRY_DELAY = 0.5
|
|
246
|
-
RETRY_STEP_FACTOR = 1.5
|
|
247
|
-
RETRY_MAX_DELAY = 5
|
|
248
|
-
|
|
249
|
-
def match_single_window_data(data)
|
|
250
|
-
# Notice that this does not include the screenshot.
|
|
251
|
-
json_data = Oj.dump(data.to_hash).force_encoding('BINARY')
|
|
252
|
-
body = [json_data.length].pack('L>') + json_data + data.screenshot
|
|
253
|
-
# Applitools::EyesLogger.debug json_data
|
|
254
|
-
begin
|
|
255
|
-
Applitools::EyesLogger.debug 'Sending match data...'
|
|
256
|
-
res = long_post(
|
|
257
|
-
@single_check_endpoint_url,
|
|
258
|
-
content_type: 'application/octet-stream',
|
|
259
|
-
body: body,
|
|
260
|
-
query: { agent_id: data.agent_id }
|
|
261
|
-
)
|
|
262
|
-
rescue Errno::EWOULDBLOCK, Faraday::ConnectionFailed
|
|
263
|
-
@delays ||= request_delay(RETRY_DELAY, RETRY_STEP_FACTOR, RETRY_MAX_DELAY)
|
|
264
|
-
begin
|
|
265
|
-
sleep @delays.next
|
|
266
|
-
rescue StopIteration
|
|
267
|
-
raise Applitools::UnknownNetworkStackError.new('Unknown network stack error')
|
|
268
|
-
end
|
|
269
|
-
res = match_single_window_data(data)
|
|
270
|
-
ensure
|
|
271
|
-
@delays = nil
|
|
272
|
-
end
|
|
273
|
-
raise Applitools::EyesError.new("Request failed: #{res.status} #{res.headers} #{res.body}") unless res.success?
|
|
274
|
-
res
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
def match_single_window(data)
|
|
278
|
-
res = match_single_window_data(data)
|
|
279
|
-
Applitools::TestResults.new Oj.load(res.body)
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
def start_session(session_start_info)
|
|
283
|
-
request_body = session_start_info.json
|
|
284
|
-
res = long_post(
|
|
285
|
-
endpoint_url, body: request_body
|
|
286
|
-
)
|
|
287
|
-
raise Applitools::EyesError.new("Request failed: #{res.status} #{res.body} #{request_body}") unless res.success?
|
|
288
|
-
response = Oj.load(res.body)
|
|
289
|
-
Applitools::Session.new(response, res.status == HTTP_STATUS_CODES[:created])
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
def stop_session(session, aborted = nil, save = false)
|
|
293
|
-
res = long_delete(URI.join(endpoint_url, session.id.to_s), query: { aborted: aborted, updateBaseline: save })
|
|
294
|
-
raise Applitools::EyesError.new("Request failed: #{res.status}") unless res.success?
|
|
295
|
-
|
|
296
|
-
response = Oj.load(res.body)
|
|
297
|
-
Applitools::TestResults.new(response)
|
|
298
|
-
end
|
|
299
|
-
|
|
300
|
-
def post_dom_json(dom_data, rendering_info)
|
|
301
|
-
Applitools::EyesLogger.debug 'About to send captured DOM...'
|
|
302
|
-
request_body = dom_data
|
|
303
|
-
Applitools::EyesLogger.debug request_body
|
|
304
|
-
processed_request_body = yield(request_body) if block_given?
|
|
305
|
-
location = put_dom(rendering_info, processed_request_body)
|
|
306
|
-
Applitools::EyesLogger.debug 'Done!'
|
|
307
|
-
location
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
private
|
|
311
|
-
|
|
312
|
-
def faraday_connection(url, pass_user_agent_header = true)
|
|
313
|
-
raise Applitools::NotUniversalServerRequestError.new(url)
|
|
314
|
-
Faraday.new(
|
|
315
|
-
url: url,
|
|
316
|
-
ssl: { ca_file: SSL_CERT },
|
|
317
|
-
proxy: @proxy.nil? ? nil : {uri: @proxy.uri}
|
|
318
|
-
) do |faraday|
|
|
319
|
-
if pass_user_agent_header
|
|
320
|
-
faraday.use(
|
|
321
|
-
Applitools::Connectivity::UserAgentMiddleware,
|
|
322
|
-
get_user_agent: @agent_id_proc,
|
|
323
|
-
get_server_url: proc { server_url }
|
|
324
|
-
)
|
|
325
|
-
end
|
|
326
|
-
faraday.use FaradayMiddleware::FollowRedirects
|
|
327
|
-
faraday.use :cookie_jar
|
|
328
|
-
faraday.adapter self.class.faraday_adapter
|
|
329
|
-
end
|
|
330
|
-
end
|
|
331
|
-
|
|
332
|
-
DEFAULT_HEADERS = {
|
|
333
|
-
'Accept' => 'application/json',
|
|
334
|
-
'Content-Type' => 'application/json'
|
|
335
|
-
}.freeze
|
|
336
|
-
|
|
337
|
-
LONG_REQUEST_DELAY = 2 # seconds
|
|
338
|
-
MAX_LONG_REQUEST_DELAY = 10 # seconds
|
|
339
|
-
LONG_REQUEST_DELAY_MULTIPLICATIVE_INCREASE_FACTOR = 1.5
|
|
340
|
-
|
|
341
|
-
[:get, :post, :delete, :put].each do |method|
|
|
342
|
-
define_method method do |url, options = {}|
|
|
343
|
-
request(url, method, options)
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
define_method "dummy_#{method}" do |url, options = {}|
|
|
347
|
-
dummy_request(url, method, options)
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
define_method "long_#{method}" do |url, options = {}, request_delay = LONG_REQUEST_DELAY|
|
|
351
|
-
long_request(url, method, request_delay, options)
|
|
352
|
-
end
|
|
353
|
-
|
|
354
|
-
private method, "long_#{method}"
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
def request_delay(first_delay, step_factor, max_delay)
|
|
358
|
-
Enumerator.new do |y|
|
|
359
|
-
delay = first_delay
|
|
360
|
-
loop do
|
|
361
|
-
y << delay
|
|
362
|
-
delay *= step_factor
|
|
363
|
-
break if delay > max_delay
|
|
364
|
-
end
|
|
365
|
-
end
|
|
366
|
-
end
|
|
367
|
-
|
|
368
|
-
def request(url, method, options = {})
|
|
369
|
-
Applitools::EyesLogger.debug("Requesting #{url} (method: #{method})")
|
|
370
|
-
response = faraday_connection(url).send(method) do |req|
|
|
371
|
-
req.options.timeout = DEFAULT_TIMEOUT
|
|
372
|
-
req.headers = DEFAULT_HEADERS.merge(options[:headers] || {})
|
|
373
|
-
req.headers['Content-Type'] = options[:content_type] if options.key?(:content_type)
|
|
374
|
-
req.params = { apiKey: api_key }.merge(options[:query] || {})
|
|
375
|
-
req.body = options[:body]
|
|
376
|
-
end
|
|
377
|
-
Applitools::EyesLogger.debug("Got a response: #{response.status} #{response.reason_phrase}")
|
|
378
|
-
response
|
|
379
|
-
end
|
|
380
|
-
|
|
381
|
-
def dummy_request(url, method, options = {})
|
|
382
|
-
faraday_connection(url).send(method) do |req|
|
|
383
|
-
req.options.timeout = options[:timeout] || DEFAULT_TIMEOUT
|
|
384
|
-
req.headers = DEFAULT_HEADERS.merge(options[:headers] || {})
|
|
385
|
-
req.headers['Content-Type'] = options[:content_type] if options.key?(:content_type)
|
|
386
|
-
req.params = options[:query] || {}
|
|
387
|
-
req.body = options[:body]
|
|
388
|
-
end
|
|
389
|
-
end
|
|
390
|
-
|
|
391
|
-
def long_request(url, method, request_delay, options = {})
|
|
392
|
-
delay = request_delay
|
|
393
|
-
options = { headers: {
|
|
394
|
-
'Eyes-Expect' => '202+location'
|
|
395
|
-
}.merge(eyes_date_header) }.merge! options
|
|
396
|
-
res = request(url, method, options)
|
|
397
|
-
check_status(res, delay)
|
|
398
|
-
end
|
|
399
|
-
|
|
400
|
-
def eyes_date_header
|
|
401
|
-
{ 'Eyes-Date' => Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT') }
|
|
402
|
-
end
|
|
403
|
-
|
|
404
|
-
def check_status(res, delay)
|
|
405
|
-
case res.status
|
|
406
|
-
when HTTP_STATUS_CODES[:ok]
|
|
407
|
-
res
|
|
408
|
-
when HTTP_STATUS_CODES[:accepted]
|
|
409
|
-
second_step_url = res.headers[:location]
|
|
410
|
-
loop do
|
|
411
|
-
delay = [MAX_LONG_REQUEST_DELAY, (delay * LONG_REQUEST_DELAY_MULTIPLICATIVE_INCREASE_FACTOR).round].min
|
|
412
|
-
Applitools::EyesLogger.debug "Still running... retrying in #{delay}s"
|
|
413
|
-
sleep delay
|
|
414
|
-
second_step_options = {
|
|
415
|
-
headers: {}.merge(eyes_date_header)
|
|
416
|
-
}
|
|
417
|
-
res = request(second_step_url, :get, second_step_options)
|
|
418
|
-
break unless res.status == HTTP_STATUS_CODES[:ok]
|
|
419
|
-
end
|
|
420
|
-
check_status(res, delay)
|
|
421
|
-
when HTTP_STATUS_CODES[:created]
|
|
422
|
-
last_step_url = res.headers[:location]
|
|
423
|
-
last_step_url.nil? ? res : request(last_step_url, :delete, headers: eyes_date_header)
|
|
424
|
-
when HTTP_STATUS_CODES[:gone]
|
|
425
|
-
raise Applitools::EyesError.new('The server task has gone.')
|
|
426
|
-
else
|
|
427
|
-
raise Applitools::EyesError.new('Unknown error processing long request')
|
|
428
|
-
end
|
|
429
|
-
end
|
|
430
63
|
end
|
|
431
64
|
end
|
|
@@ -35,10 +35,6 @@ module Applitools
|
|
|
35
35
|
Applitools::TestResultSummary.new(all_universal_results)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
def rendering_info(connector)
|
|
39
|
-
@rendering_info ||= RenderingInfo.new(connector.rendering_info)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
38
|
def universal_eyes_manager_config
|
|
43
39
|
Applitools::UniversalEyesManagerConfig.classic
|
|
44
40
|
end
|
|
@@ -49,7 +49,7 @@ module Applitools
|
|
|
49
49
|
Applitools::ArgumentGuard.is_a?(viewport_size, 'viewport_size', Applitools::RectangleSize)
|
|
50
50
|
Applitools::EyesLogger.info "Set viewport size #{viewport_size}"
|
|
51
51
|
begin
|
|
52
|
-
driver_config_json =
|
|
52
|
+
driver_config_json = Applitools::Selenium.universal_driver_config(driver)
|
|
53
53
|
required_size = Applitools::RectangleSize.from_any_argument viewport_size
|
|
54
54
|
@universal_client = Applitools::Connectivity::UniversalClient.new(self)
|
|
55
55
|
@universal_client.core_set_viewport_size(driver_config_json, required_size.to_hash)
|
|
@@ -93,7 +93,7 @@ module Applitools
|
|
|
93
93
|
:compare_with_parent_branch, :results, :runner, :allow_empty_screenshot, :screenshot_url
|
|
94
94
|
|
|
95
95
|
abstract_attr_accessor :base_agent_id
|
|
96
|
-
|
|
96
|
+
# Note: capture_screenshot removed - handled by Universal SDK
|
|
97
97
|
abstract_method :title, true
|
|
98
98
|
abstract_method :set_viewport_size, true
|
|
99
99
|
abstract_method :get_viewport_size, true
|
|
@@ -134,13 +134,8 @@ module Applitools
|
|
|
134
134
|
@inferred_environment = nil
|
|
135
135
|
@server_scale = 0
|
|
136
136
|
@server_remainder = 0
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
app_output_provider.instance_eval do
|
|
140
|
-
define_singleton_method :app_output do |r, s|
|
|
141
|
-
get_app_output_method.call(r, s)
|
|
142
|
-
end
|
|
143
|
-
end
|
|
137
|
+
# Note: app_output_provider.app_output is now handled by Universal SDK
|
|
138
|
+
# The old get_app_output_with_screenshot method has been removed
|
|
144
139
|
|
|
145
140
|
# self.exact = nil
|
|
146
141
|
self.match_level = Applitools::MatchLevel::STRICT
|
|
@@ -221,6 +216,11 @@ module Applitools
|
|
|
221
216
|
return Applitools::TestResults.new
|
|
222
217
|
end
|
|
223
218
|
|
|
219
|
+
# Check if the session is still open before logging abort
|
|
220
|
+
if universal_eyes && universal_eyes.closed_or_aborted
|
|
221
|
+
# Session already closed, no need to abort or log
|
|
222
|
+
return nil
|
|
223
|
+
end
|
|
224
224
|
|
|
225
225
|
# if running_session.nil?
|
|
226
226
|
# logger.info 'Closed'
|
|
@@ -447,7 +447,7 @@ module Applitools
|
|
|
447
447
|
return false
|
|
448
448
|
end
|
|
449
449
|
|
|
450
|
-
logger.
|
|
450
|
+
logger.debug "close(#{throw_exception})"
|
|
451
451
|
raise Applitools::EyesError.new 'Eyes not open' unless open?
|
|
452
452
|
|
|
453
453
|
if !running_session && !universal_eyes
|
|
@@ -459,7 +459,7 @@ module Applitools
|
|
|
459
459
|
# is_new_session = running_session.new_session?
|
|
460
460
|
# session_results_url = running_session.url
|
|
461
461
|
|
|
462
|
-
logger.
|
|
462
|
+
logger.debug 'Ending server session...'
|
|
463
463
|
|
|
464
464
|
# save = is_new_session && save_new_tests || !is_new_session && failed && save_failed_tests
|
|
465
465
|
|
|
@@ -542,7 +542,7 @@ module Applitools
|
|
|
542
542
|
self.last_screenshot = nil
|
|
543
543
|
clear_user_inputs
|
|
544
544
|
|
|
545
|
-
logger.
|
|
545
|
+
logger.debug 'Getting results...'
|
|
546
546
|
|
|
547
547
|
universal_results = universal_eyes.eyes_get_results # Array even for one test
|
|
548
548
|
# require 'pry'
|
|
@@ -552,13 +552,16 @@ module Applitools
|
|
|
552
552
|
logger.error "--- Error (#{universal_results[:reason]}) : #{universal_results[:message]}"
|
|
553
553
|
error_message = "Test '#{test_name}' of '#{app_name}' " \
|
|
554
554
|
"is failed! Details : #{universal_results[:message]}"
|
|
555
|
-
raise Applitools::TestFailedError.new error_message,
|
|
556
|
-
return
|
|
555
|
+
raise Applitools::TestFailedError.new error_message, nil if throw_exception
|
|
556
|
+
return nil
|
|
557
557
|
end
|
|
558
558
|
key_transformed_results = Applitools::Utils.deep_stringify_keys(universal_results)
|
|
559
559
|
results = key_transformed_results.map {|result| Applitools::TestResults.new(result) }
|
|
560
560
|
# results = results.first if results.size >= 1
|
|
561
561
|
|
|
562
|
+
# Handle case where there are no results (e.g., no checkpoints before close)
|
|
563
|
+
return results if results.empty?
|
|
564
|
+
|
|
562
565
|
session_results_url = results.first.url
|
|
563
566
|
# results = server_connector.stop_session running_session, false, save
|
|
564
567
|
|
|
@@ -768,59 +771,7 @@ module Applitools
|
|
|
768
771
|
end
|
|
769
772
|
end
|
|
770
773
|
|
|
771
|
-
|
|
772
|
-
captured_dom_data = dom_data
|
|
773
|
-
logger.info 'Getting screenshot...'
|
|
774
|
-
screenshot = capture_screenshot
|
|
775
|
-
logger.info 'Done getting screenshot!'
|
|
776
|
-
region = region_provider.region
|
|
777
|
-
|
|
778
|
-
unless region.empty?
|
|
779
|
-
screenshot = screenshot.sub_screenshot region, region_provider.coordinate_type, false
|
|
780
|
-
end
|
|
781
|
-
|
|
782
|
-
screenshot = yield(screenshot) if block_given?
|
|
783
|
-
|
|
784
|
-
logger.info 'Getting title...'
|
|
785
|
-
a_title = title
|
|
786
|
-
logger.info 'Done!'
|
|
787
|
-
Applitools::AppOutputWithScreenshot.new(
|
|
788
|
-
Applitools::AppOutput.new(a_title, screenshot).tap do |o|
|
|
789
|
-
o.location = region.location unless region.empty?
|
|
790
|
-
o.on_need_screenshot_url do
|
|
791
|
-
return unless screenshot
|
|
792
|
-
server_connector.put_screenshot(
|
|
793
|
-
runner.rendering_info(server_connector),
|
|
794
|
-
screenshot
|
|
795
|
-
)
|
|
796
|
-
end
|
|
797
|
-
o.on_need_dom_url do
|
|
798
|
-
unless captured_dom_data.empty?
|
|
799
|
-
begin
|
|
800
|
-
logger.info 'Processing DOM..'
|
|
801
|
-
dom_url = server_connector.post_dom_json(captured_dom_data, runner.rendering_info(server_connector)) do |json|
|
|
802
|
-
io = StringIO.new
|
|
803
|
-
gz = Zlib::GzipWriter.new(io)
|
|
804
|
-
gz.write(json.encode('UTF-8'))
|
|
805
|
-
gz.close
|
|
806
|
-
result = io.string
|
|
807
|
-
io.close
|
|
808
|
-
result
|
|
809
|
-
end
|
|
810
|
-
logger.info 'Done'
|
|
811
|
-
logger.info dom_url
|
|
812
|
-
rescue Applitools::EyesError => e
|
|
813
|
-
logger.warn e.message
|
|
814
|
-
dom_url = nil
|
|
815
|
-
end
|
|
816
|
-
dom_url
|
|
817
|
-
end
|
|
818
|
-
end
|
|
819
|
-
end,
|
|
820
|
-
screenshot,
|
|
821
|
-
allow_empty_screenshot
|
|
822
|
-
)
|
|
823
|
-
end
|
|
774
|
+
# Note: get_app_output_with_screenshot removed - screenshots now handled by Universal SDK
|
|
824
775
|
|
|
825
776
|
class UserInputArray < Array
|
|
826
777
|
def add(trigger)
|
|
@@ -35,7 +35,7 @@ module Applitools
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
update_config_from_options(options)
|
|
38
|
-
universal_driver_config =
|
|
38
|
+
universal_driver_config = Applitools::Selenium.universal_driver_config(driver) if self.class.name != 'Applitools::Images::Eyes'
|
|
39
39
|
|
|
40
40
|
# Ensure we have a runner (default to ClassicRunner if not provided)
|
|
41
41
|
self.runner ||= Applitools::ClassicRunner.new
|
|
@@ -76,7 +76,8 @@ module Applitools
|
|
|
76
76
|
result = result[0] if result.is_a?(Array)
|
|
77
77
|
|
|
78
78
|
if result.is_a? Hash
|
|
79
|
-
|
|
79
|
+
# Only log "Test aborted" if it wasn't already closed
|
|
80
|
+
logger.info "---Test aborted" if !closed_or_aborted && !result[:message] && !result[:stack]
|
|
80
81
|
else
|
|
81
82
|
# TestCheckFrameInFrame_Fully_Fluent_VG\
|
|
82
83
|
# require('pry')
|
|
@@ -105,16 +106,16 @@ module Applitools
|
|
|
105
106
|
|
|
106
107
|
raise Applitools::EyesIllegalArgument, config.validation_errors.values.join('/n') unless config.valid?
|
|
107
108
|
|
|
108
|
-
logger.
|
|
109
|
-
logger.
|
|
109
|
+
logger.debug "Agent = #{full_agent_id}"
|
|
110
|
+
logger.debug "open(app_name: #{app_name}, test_name: #{test_name}," \
|
|
110
111
|
" viewport_size: #{viewport_size})"
|
|
111
112
|
|
|
112
113
|
raise Applitools::EyesError.new 'API key is missing! Please set it using api_key=' if
|
|
113
114
|
api_key.nil? || (api_key && api_key.empty?)
|
|
114
115
|
|
|
115
|
-
logger.
|
|
116
|
+
logger.debug "Batch is #{@batch}" if @batch
|
|
116
117
|
app_env = app_environment if respond_to? :app_environment
|
|
117
|
-
logger.
|
|
118
|
+
logger.debug "Application environment is #{app_env}"
|
|
118
119
|
test_info = "'#{test_name}' of '#{app_name}' #{app_env}"
|
|
119
120
|
logger.info "--- New test started - #{test_info}"
|
|
120
121
|
end
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
require 'json'
|
|
7
7
|
require 'securerandom'
|
|
8
|
-
require 'colorize'
|
|
9
8
|
require 'websocket'
|
|
10
9
|
require 'uri'
|
|
11
10
|
require 'eyes_universal'
|
|
@@ -343,6 +342,16 @@ module Applitools::Connectivity
|
|
|
343
342
|
Applitools::EyesUniversal::UniversalServerControl.configure(mask_log)
|
|
344
343
|
@universal_server_control = Applitools::EyesUniversal::UniversalServerControl.instance
|
|
345
344
|
@web_socket = @universal_server_control.new_server_socket_connection
|
|
345
|
+
|
|
346
|
+
# Check if socket connection was successfully established
|
|
347
|
+
if @web_socket.nil?
|
|
348
|
+
raise Applitools::EyesError.new(
|
|
349
|
+
"Failed to establish connection to Universal SDK server. " \
|
|
350
|
+
"The server may not be running or the connection was refused. " \
|
|
351
|
+
"Check server logs for more details."
|
|
352
|
+
)
|
|
353
|
+
end
|
|
354
|
+
|
|
346
355
|
socket_handshake
|
|
347
356
|
session_init(eyes)
|
|
348
357
|
# connect_and_configure_socket(socket_uri)
|
|
@@ -439,7 +448,8 @@ module Applitools::Connectivity
|
|
|
439
448
|
end
|
|
440
449
|
raise Applitools::EyesError.new "Empty result on #{name}" if web_socket_result.empty?
|
|
441
450
|
|
|
442
|
-
|
|
451
|
+
# Check if more data is available without blocking (Ruby 3.0+ compatibility)
|
|
452
|
+
web_socket_result += receive_result(name) if IO.select([@web_socket], nil, nil, 0)
|
|
443
453
|
web_socket_result
|
|
444
454
|
end
|
|
445
455
|
|
metadata
CHANGED
|
@@ -1,57 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: eyes_core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.9.
|
|
4
|
+
version: 6.9.11
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Applitools Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-12-
|
|
11
|
+
date: 2025-12-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: faraday
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - ">="
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0'
|
|
20
|
-
type: :runtime
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - ">="
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: faraday_middleware
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - ">="
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
34
|
-
type: :runtime
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - ">="
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: faraday-cookie_jar
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - ">="
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '0'
|
|
48
|
-
type: :runtime
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - ">="
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '0'
|
|
55
13
|
- !ruby/object:Gem::Dependency
|
|
56
14
|
name: oj
|
|
57
15
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -66,20 +24,6 @@ dependencies:
|
|
|
66
24
|
- - ">="
|
|
67
25
|
- !ruby/object:Gem::Version
|
|
68
26
|
version: '0'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: colorize
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - ">="
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0'
|
|
76
|
-
type: :runtime
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - ">="
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0'
|
|
83
27
|
- !ruby/object:Gem::Dependency
|
|
84
28
|
name: websocket
|
|
85
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,34 +38,20 @@ dependencies:
|
|
|
94
38
|
- - ">="
|
|
95
39
|
- !ruby/object:Gem::Version
|
|
96
40
|
version: '0'
|
|
97
|
-
- !ruby/object:Gem::Dependency
|
|
98
|
-
name: sorted_set
|
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
|
100
|
-
requirements:
|
|
101
|
-
- - ">="
|
|
102
|
-
- !ruby/object:Gem::Version
|
|
103
|
-
version: '0'
|
|
104
|
-
type: :runtime
|
|
105
|
-
prerelease: false
|
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
-
requirements:
|
|
108
|
-
- - ">="
|
|
109
|
-
- !ruby/object:Gem::Version
|
|
110
|
-
version: '0'
|
|
111
41
|
- !ruby/object:Gem::Dependency
|
|
112
42
|
name: eyes_universal
|
|
113
43
|
requirement: !ruby/object:Gem::Requirement
|
|
114
44
|
requirements:
|
|
115
45
|
- - '='
|
|
116
46
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: 4.
|
|
47
|
+
version: 4.54.0
|
|
118
48
|
type: :runtime
|
|
119
49
|
prerelease: false
|
|
120
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
51
|
requirements:
|
|
122
52
|
- - '='
|
|
123
53
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: 4.
|
|
54
|
+
version: 4.54.0
|
|
125
55
|
- !ruby/object:Gem::Dependency
|
|
126
56
|
name: bundler
|
|
127
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -178,90 +108,6 @@ dependencies:
|
|
|
178
108
|
- - "<="
|
|
179
109
|
- !ruby/object:Gem::Version
|
|
180
110
|
version: 0.46.0
|
|
181
|
-
- !ruby/object:Gem::Dependency
|
|
182
|
-
name: pry
|
|
183
|
-
requirement: !ruby/object:Gem::Requirement
|
|
184
|
-
requirements:
|
|
185
|
-
- - ">="
|
|
186
|
-
- !ruby/object:Gem::Version
|
|
187
|
-
version: '0'
|
|
188
|
-
type: :development
|
|
189
|
-
prerelease: false
|
|
190
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
191
|
-
requirements:
|
|
192
|
-
- - ">="
|
|
193
|
-
- !ruby/object:Gem::Version
|
|
194
|
-
version: '0'
|
|
195
|
-
- !ruby/object:Gem::Dependency
|
|
196
|
-
name: pry-byebug
|
|
197
|
-
requirement: !ruby/object:Gem::Requirement
|
|
198
|
-
requirements:
|
|
199
|
-
- - ">="
|
|
200
|
-
- !ruby/object:Gem::Version
|
|
201
|
-
version: '0'
|
|
202
|
-
type: :development
|
|
203
|
-
prerelease: false
|
|
204
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
205
|
-
requirements:
|
|
206
|
-
- - ">="
|
|
207
|
-
- !ruby/object:Gem::Version
|
|
208
|
-
version: '0'
|
|
209
|
-
- !ruby/object:Gem::Dependency
|
|
210
|
-
name: byebug
|
|
211
|
-
requirement: !ruby/object:Gem::Requirement
|
|
212
|
-
requirements:
|
|
213
|
-
- - ">="
|
|
214
|
-
- !ruby/object:Gem::Version
|
|
215
|
-
version: '0'
|
|
216
|
-
type: :development
|
|
217
|
-
prerelease: false
|
|
218
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
219
|
-
requirements:
|
|
220
|
-
- - ">="
|
|
221
|
-
- !ruby/object:Gem::Version
|
|
222
|
-
version: '0'
|
|
223
|
-
- !ruby/object:Gem::Dependency
|
|
224
|
-
name: pry-doc
|
|
225
|
-
requirement: !ruby/object:Gem::Requirement
|
|
226
|
-
requirements:
|
|
227
|
-
- - ">="
|
|
228
|
-
- !ruby/object:Gem::Version
|
|
229
|
-
version: '0'
|
|
230
|
-
type: :development
|
|
231
|
-
prerelease: false
|
|
232
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
233
|
-
requirements:
|
|
234
|
-
- - ">="
|
|
235
|
-
- !ruby/object:Gem::Version
|
|
236
|
-
version: '0'
|
|
237
|
-
- !ruby/object:Gem::Dependency
|
|
238
|
-
name: pry-stack_explorer
|
|
239
|
-
requirement: !ruby/object:Gem::Requirement
|
|
240
|
-
requirements:
|
|
241
|
-
- - ">="
|
|
242
|
-
- !ruby/object:Gem::Version
|
|
243
|
-
version: '0'
|
|
244
|
-
type: :development
|
|
245
|
-
prerelease: false
|
|
246
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
247
|
-
requirements:
|
|
248
|
-
- - ">="
|
|
249
|
-
- !ruby/object:Gem::Version
|
|
250
|
-
version: '0'
|
|
251
|
-
- !ruby/object:Gem::Dependency
|
|
252
|
-
name: rb-readline
|
|
253
|
-
requirement: !ruby/object:Gem::Requirement
|
|
254
|
-
requirements:
|
|
255
|
-
- - ">="
|
|
256
|
-
- !ruby/object:Gem::Version
|
|
257
|
-
version: '0'
|
|
258
|
-
type: :development
|
|
259
|
-
prerelease: false
|
|
260
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
261
|
-
requirements:
|
|
262
|
-
- - ">="
|
|
263
|
-
- !ruby/object:Gem::Version
|
|
264
|
-
version: '0'
|
|
265
111
|
description: Don't use it directly, take a look at eyes_selenium or eyes_images gems
|
|
266
112
|
instead.
|
|
267
113
|
email:
|