puppeteer-ruby 0.38.0 → 0.40.2

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.
@@ -0,0 +1,122 @@
1
+ # Helper class to track network events by request ID
2
+ class Puppeteer::NetworkEventManager
3
+ def initialize
4
+ #
5
+ # There are four possible orders of events:
6
+ # A. `_onRequestWillBeSent`
7
+ # B. `_onRequestWillBeSent`, `_onRequestPaused`
8
+ # C. `_onRequestPaused`, `_onRequestWillBeSent`
9
+ # D. `_onRequestPaused`, `_onRequestWillBeSent`, `_onRequestPaused`,
10
+ # `_onRequestWillBeSent`, `_onRequestPaused`, `_onRequestPaused`
11
+ # (see crbug.com/1196004)
12
+ #
13
+ # For `_onRequest` we need the event from `_onRequestWillBeSent` and
14
+ # optionally the `interceptionId` from `_onRequestPaused`.
15
+ #
16
+ # If request interception is disabled, call `_onRequest` once per call to
17
+ # `_onRequestWillBeSent`.
18
+ # If request interception is enabled, call `_onRequest` once per call to
19
+ # `_onRequestPaused` (once per `interceptionId`).
20
+ #
21
+ # Events are stored to allow for subsequent events to call `_onRequest`.
22
+ #
23
+ # Note that (chains of) redirect requests have the same `requestId` (!) as
24
+ # the original request. We have to anticipate series of events like these:
25
+ # A. `_onRequestWillBeSent`,
26
+ # `_onRequestWillBeSent`, ...
27
+ # B. `_onRequestWillBeSent`, `_onRequestPaused`,
28
+ # `_onRequestWillBeSent`, `_onRequestPaused`, ...
29
+ # C. `_onRequestWillBeSent`, `_onRequestPaused`,
30
+ # `_onRequestPaused`, `_onRequestWillBeSent`, ...
31
+ # D. `_onRequestPaused`, `_onRequestWillBeSent`,
32
+ # `_onRequestPaused`, `_onRequestWillBeSent`, `_onRequestPaused`,
33
+ # `_onRequestWillBeSent`, `_onRequestPaused`, `_onRequestPaused`, ...
34
+ # (see crbug.com/1196004)
35
+ @request_will_be_sent_map = {}
36
+ @request_paused_map = {}
37
+ @http_requests_map = {}
38
+ #
39
+ # The below maps are used to reconcile Network.responseReceivedExtraInfo
40
+ # events with their corresponding request. Each response and redirect
41
+ # response gets an ExtraInfo event, and we don't know which will come first.
42
+ # This means that we have to store a Response or an ExtraInfo for each
43
+ # response, and emit the event when we get both of them. In addition, to
44
+ # handle redirects, we have to make them Arrays to represent the chain of
45
+ # events.
46
+ @response_received_extra_info_map = {}
47
+ @queued_redirect_info_map = {}
48
+ @queued_event_group_map = {}
49
+ end
50
+
51
+ def forget(network_request_id)
52
+ @request_will_be_sent_map.delete(network_request_id)
53
+ @request_paused_map.delete(network_request_id)
54
+ @queued_event_group_map.delete(network_request_id)
55
+ @queued_redirect_info_map.delete(network_request_id)
56
+ @response_received_extra_info_map.delete(network_request_id)
57
+ end
58
+
59
+ def response_extra_info(network_request_id)
60
+ @response_received_extra_info_map[network_request_id] ||= []
61
+ end
62
+
63
+ private def queued_redirect_info(fetch_request_id)
64
+ @queued_redirect_info_map[fetch_request_id] ||= []
65
+ end
66
+
67
+ def enqueue_redirect_info(fetch_request_id, redirect_info)
68
+ queued_redirect_info(fetch_request_id) << redirect_info
69
+ end
70
+
71
+ def take_queued_redirect_info(fetch_request_id)
72
+ queued_redirect_info(fetch_request_id).shift
73
+ end
74
+
75
+ def num_requests_in_progress
76
+ @http_requests_map.count { |_, request| !request.response }
77
+ end
78
+
79
+ def store_request_will_be_sent(network_request_id, event)
80
+ @request_will_be_sent_map[network_request_id] = event
81
+ end
82
+
83
+ def get_request_will_be_sent(network_request_id)
84
+ @request_will_be_sent_map[network_request_id]
85
+ end
86
+
87
+ def forget_request_will_be_sent(network_request_id)
88
+ @request_will_be_sent_map.delete(network_request_id)
89
+ end
90
+
91
+ def store_request_paused(network_request_id, event)
92
+ @request_paused_map[network_request_id] = event
93
+ end
94
+
95
+ def get_request_paused(network_request_id)
96
+ @request_paused_map[network_request_id]
97
+ end
98
+
99
+ def forget_request_paused(network_request_id)
100
+ @request_paused_map.delete(network_request_id)
101
+ end
102
+
103
+ def store_request(network_request_id, request)
104
+ @http_requests_map[network_request_id] = request
105
+ end
106
+
107
+ def get_request(network_request_id)
108
+ @http_requests_map[network_request_id]
109
+ end
110
+
111
+ def forget_request(network_request_id)
112
+ @http_requests_map.delete(network_request_id)
113
+ end
114
+
115
+ def enqueue_event_group(network_request_id, queued_event_group)
116
+ @queued_event_group_map[network_request_id] = queued_event_group
117
+ end
118
+
119
+ def get_queued_event_group(network_request_id)
120
+ @queued_event_group_map[network_request_id]
121
+ end
122
+ end
@@ -53,6 +53,22 @@ class Puppeteer::NetworkManager
53
53
  end
54
54
  end
55
55
 
56
+ class RedirectInfo
57
+ def initialize(event:, fetch_request_id:)
58
+ @event = event
59
+ @fetch_request_id = fetch_request_id
60
+ end
61
+ attr_reader :event, :fetch_request_id
62
+ end
63
+
64
+ class QueuedEventGroup
65
+ def initialize(response_received_event:)
66
+ @response_received_event = response_received_event
67
+ end
68
+ attr_reader :response_received_event
69
+ attr_accessor :loading_finished_event, :loading_failed_event
70
+ end
71
+
56
72
  # @param {!Puppeteer.CDPSession} client
57
73
  # @param {boolean} ignoreHTTPSErrors
58
74
  # @param {!Puppeteer.FrameManager} frameManager
@@ -60,12 +76,7 @@ class Puppeteer::NetworkManager
60
76
  @client = client
61
77
  @ignore_https_errors = ignore_https_errors
62
78
  @frame_manager = frame_manager
63
-
64
- # @type {!Map<string, !Request>}
65
- @request_id_to_request = {}
66
-
67
- # @type {!Map<string, !Protocol.Network.requestWillBeSentPayload>}
68
- @request_id_to_request_with_be_sent_event = {}
79
+ @network_event_manager = Puppeteer::NetworkEventManager.new
69
80
 
70
81
  @extra_http_headers = {}
71
82
 
@@ -73,7 +84,6 @@ class Puppeteer::NetworkManager
73
84
  @user_request_interception_enabled = false
74
85
  @protocol_request_interception_enabled = false
75
86
  @user_cache_disabled = false
76
- @request_id_to_interception_id = {}
77
87
  @internal_network_condition = InternalNetworkCondition.new(@client)
78
88
 
79
89
  @client.on_event('Fetch.requestPaused') do |event|
@@ -97,6 +107,9 @@ class Puppeteer::NetworkManager
97
107
  @client.on_event('Network.loadingFailed') do |event|
98
108
  handle_loading_failed(event)
99
109
  end
110
+ @client.on_event('Network.responseReceivedExtraInfo') do |event|
111
+ handle_response_received_extra_info(event)
112
+ end
100
113
  end
101
114
 
102
115
  def init
@@ -106,6 +119,14 @@ class Puppeteer::NetworkManager
106
119
  end
107
120
  end
108
121
 
122
+ def inspect
123
+ values = %i[network_event_manager].map do |sym|
124
+ value = instance_variable_get(:"@#{sym}")
125
+ "@#{sym}=#{value}"
126
+ end
127
+ "#<Puppeteer::HTTPRequest #{values.join(' ')}>"
128
+ end
129
+
109
130
  # @param username [String|NilClass]
110
131
  # @param password [String|NilClass]
111
132
  def authenticate(username:, password:)
@@ -131,6 +152,10 @@ class Puppeteer::NetworkManager
131
152
  @extra_http_headers.dup
132
153
  end
133
154
 
155
+ def num_requests_in_progress
156
+ @network_event_manager.num_requests_in_progress
157
+ end
158
+
134
159
  # @param value [TrueClass|FalseClass]
135
160
  def offline_mode=(value)
136
161
  @internal_network_condition.offline_mode=(value)
@@ -185,14 +210,17 @@ class Puppeteer::NetworkManager
185
210
 
186
211
  private def handle_request_will_be_sent(event)
187
212
  # Request interception doesn't happen for data URLs with Network Service.
188
- if @protocol_request_interception_enabled && !event['request']['url'].start_with?('data:')
189
- request_id = event['requestId']
190
- interception_id = @request_id_to_interception_id.delete(request_id)
191
- if interception_id
192
- handle_request(event, interception_id)
193
- else
194
- @request_id_to_request_with_be_sent_event[request_id] = event
213
+ if @user_request_interception_enabled && !event['request']['url'].start_with?('data:')
214
+ network_request_id = event['requestId']
215
+ @network_event_manager.store_request_will_be_sent(network_request_id, event)
216
+
217
+ # CDP may have sent a Fetch.requestPaused event already. Check for it.
218
+ if_present(@network_event_manager.get_request_paused(network_request_id)) do |request_paused_event|
219
+ fetch_request_id = request_paused_event['requestId']
220
+ handle_request(event, fetch_request_id)
221
+ @network_event_manager.forget_request_paused(network_request_id)
195
222
  end
223
+
196
224
  return
197
225
  end
198
226
  handle_request(event, nil)
@@ -233,26 +261,61 @@ class Puppeteer::NetworkManager
233
261
  end
234
262
  end
235
263
 
236
- request_id = event['networkId']
237
- interception_id = event['requestId']
238
- if request_id && (request_will_be_sent_event = @request_id_to_request_with_be_sent_event.delete(request_id))
239
- handle_request(request_will_be_sent_event, interception_id)
264
+ network_request_id = event['networkId']
265
+ fetch_request_id = event['requestId']
266
+ return unless network_request_id
267
+
268
+ request_will_be_sent_event = @network_event_manager.get_request_will_be_sent(network_request_id)
269
+
270
+ # redirect requests have the same `requestId`
271
+ if request_will_be_sent_event &&
272
+ (request_will_be_sent_event['request']['url'] != event['request']['url'] ||
273
+ request_will_be_sent_event['request']['method'] != event['request']['method'])
274
+
275
+ @network_event_manager.forget_request_will_be_sent(network_request_id)
276
+ request_will_be_sent_event = nil
277
+ end
278
+
279
+ if request_will_be_sent_event
280
+ handle_request(request_will_be_sent_event, fetch_request_id)
240
281
  else
241
- @request_id_to_interception_id[request_id] = interception_id
282
+ @network_event_manager.store_request_paused(network_request_id, event)
242
283
  end
243
284
  end
244
285
 
245
- private def handle_request(event, interception_id)
286
+ private def handle_request(event, fetch_request_id)
246
287
  redirect_chain = []
247
288
  if event['redirectResponse']
248
- if_present(@request_id_to_request[event['requestId']]) do |request|
249
- handle_request_redirect(request, event['redirectResponse'])
289
+ # We want to emit a response and requestfinished for the
290
+ # redirectResponse, but we can't do so unless we have a
291
+ # responseExtraInfo ready to pair it up with. If we don't have any
292
+ # responseExtraInfos saved in our queue, they we have to wait until
293
+ # the next one to emit response and requestfinished, *and* we should
294
+ # also wait to emit this Request too because it should come after the
295
+ # response/requestfinished.
296
+ redirect_response_extra_info = nil
297
+ if event['redirectHasExtraInfo']
298
+ redirect_response_extra_info = @network_event_manager.response_extra_info(event['requestId']).shift
299
+ unless redirect_response_extra_info
300
+ redirect_info = RedirectInfo.new(
301
+ event: event,
302
+ fetch_request_id: fetch_request_id,
303
+ )
304
+ @network_event_manager.enqueue_redirect_info(event['requestId'], redirect_info)
305
+ return
306
+ end
307
+ end
308
+
309
+ # If we connect late to the target, we could have missed the
310
+ # requestWillBeSent event.
311
+ if_present(@network_event_manager.get_request(event['requestId'])) do |request|
312
+ handle_request_redirect(request, event['redirectResponse'], redirect_response_extra_info)
250
313
  redirect_chain = request.internal.redirect_chain
251
314
  end
252
315
  end
253
316
  frame = if_present(event['frameId']) { |frame_id| @frame_manager.frame(frame_id) }
254
- request = Puppeteer::HTTPRequest.new(@client, frame, interception_id, @user_request_interception_enabled, event, redirect_chain)
255
- @request_id_to_request[event['requestId']] = request
317
+ request = Puppeteer::HTTPRequest.new(@client, frame, fetch_request_id, @user_request_interception_enabled, event, redirect_chain)
318
+ @network_event_manager.store_request(event['requestId'], request)
256
319
  emit_event(NetworkManagerEmittedEvents::Request, request)
257
320
  begin
258
321
  request.finalize_interceptions
@@ -262,55 +325,133 @@ class Puppeteer::NetworkManager
262
325
  end
263
326
 
264
327
  private def handle_request_served_from_cache(event)
265
- if_present(@request_id_to_request[event['requestId']]) do |request|
328
+ request = @network_event_manager.get_request(event['requestId'])
329
+ if request
266
330
  request.internal.from_memory_cache = true
267
331
  end
332
+ emit_event(NetworkManagerEmittedEvents::RequestServedFromCache, request)
268
333
  end
269
334
 
270
335
  # @param request [Puppeteer::HTTPRequest]
271
336
  # @param response_payload [Hash]
272
- private def handle_request_redirect(request, response_payload)
273
- response = Puppeteer::HTTPResponse.new(@client, request, response_payload)
337
+ private def handle_request_redirect(request, response_payload, extra_info)
338
+ response = Puppeteer::HTTPResponse.new(@client, request, response_payload, extra_info)
274
339
  request.internal.response = response
275
340
  request.internal.redirect_chain << request
276
341
  response.internal.body_loaded_promise.reject(Puppeteer::HTTPResponse::Redirected.new)
277
- @request_id_to_request.delete(request.internal.request_id)
278
- @attempted_authentications.delete(request.internal.interception_id)
342
+ forget_request(request, false)
279
343
  emit_event(NetworkManagerEmittedEvents::Response, response)
280
344
  emit_event(NetworkManagerEmittedEvents::RequestFinished, request)
281
345
  end
282
346
 
283
- # @param event [Hash]
284
- private def handle_response_received(event)
285
- request = @request_id_to_request[event['requestId']]
347
+ private def emit_response_event(response_received_event, extra_info)
348
+ request = @network_event_manager.get_request(response_received_event['requestId'])
286
349
  # FileUpload sends a response without a matching request.
287
350
  return unless request
288
351
 
289
- response = Puppeteer::HTTPResponse.new(@client, request, event['response'])
352
+ unless @network_event_manager.response_extra_info(response_received_event['requestId']).empty?
353
+ debug_puts("Unexpected extraInfo events for request #{response_received_event['requestId']}")
354
+ end
355
+
356
+ response = Puppeteer::HTTPResponse.new(@client, request, response_received_event['response'], extra_info)
290
357
  request.internal.response = response
291
358
  emit_event(NetworkManagerEmittedEvents::Response, response)
292
359
  end
293
360
 
361
+ # @param event [Hash]
362
+ private def handle_response_received(event)
363
+ request = @network_event_manager.get_request(event['requestId'])
364
+ extra_info = nil
365
+ if request && !request.internal.from_memory_cache? && event['hasExtraInfo']
366
+ extra_info = @network_event_manager.response_extra_info(event['requestId']).shift
367
+
368
+ unless extra_info
369
+ # Wait until we get the corresponding ExtraInfo event.
370
+ @network_event_manager.enqueue_event_group(event['requestId'], QueuedEventGroup.new(response_received_event: event))
371
+ return
372
+ end
373
+ end
374
+ emit_response_event(event, extra_info)
375
+ end
376
+
377
+ private def handle_response_received_extra_info(event)
378
+ # We may have skipped a redirect response/request pair due to waiting for
379
+ # this ExtraInfo event. If so, continue that work now that we have the
380
+ # request.
381
+ if_present(@network_event_manager.take_queued_redirect_info(event['requestId'])) do |redirect_info|
382
+ @network_event_manager.response_extra_info(event['requestId']) << event
383
+ handle_request(redirect_info.event, redirect_info)
384
+ return
385
+ end
386
+
387
+ # We may have skipped response and loading events because we didn't have
388
+ # this ExtraInfo event yet. If so, emit those events now.
389
+ if_present(@network_event_manager.get_queued_event_group(event['requestId'])) do |queued_events|
390
+ emit_response_event(queued_events.response_received_event, event)
391
+ if_present(queued_events.loading_finished_event) do |loading_finished_event|
392
+ emit_loading_finished(loading_finished_event)
393
+ end
394
+ if_present(queued_events.loading_failed_event) do |loading_failed_event|
395
+ emit_loading_failed(loading_failed_event)
396
+ end
397
+ return
398
+ end
399
+
400
+ # Wait until we get another event that can use this ExtraInfo event.
401
+ @network_event_manager.response_extra_info(event['requestId']) << event
402
+ end
403
+
404
+ private def forget_request(request, forget_events)
405
+ request_id = request.internal.request_id
406
+ interception_id = request.internal.interception_id
407
+
408
+ @network_event_manager.forget_request(request_id)
409
+ @attempted_authentications.delete(interception_id)
410
+ if forget_events
411
+ @network_event_manager.forget(request_id)
412
+ end
413
+ end
414
+
294
415
  private def handle_loading_finished(event)
295
- request = @request_id_to_request[event['requestId']]
416
+ # If the response event for this request is still waiting on a
417
+ # corresponding ExtraInfo event, then wait to emit this event too.
418
+ queued_events = @network_event_manager.get_queued_event_group(event['requestId'])
419
+ if queued_events
420
+ queued_events.loading_finished_event = event
421
+ else
422
+ emit_loading_finished(event)
423
+ end
424
+ end
425
+
426
+ private def emit_loading_finished(event)
427
+ request = @network_event_manager.get_request(event['requestId'])
296
428
  # For certain requestIds we never receive requestWillBeSent event.
297
429
  # @see https://crbug.com/750469
298
430
  return unless request
299
431
 
300
-
301
432
  # Under certain conditions we never get the Network.responseReceived
302
433
  # event from protocol. @see https://crbug.com/883475
303
434
  if_present(request.response) do |response|
304
435
  response.internal.body_loaded_promise.fulfill(nil)
305
436
  end
306
437
 
307
- @request_id_to_request.delete(request.internal.request_id)
308
- @attempted_authentications.delete(request.internal.interception_id)
438
+ forget_request(request, true)
309
439
  emit_event(NetworkManagerEmittedEvents::RequestFinished, request)
310
440
  end
311
441
 
312
442
  private def handle_loading_failed(event)
313
- request = @request_id_to_request[event['requestId']]
443
+ # If the response event for this request is still waiting on a
444
+ # corresponding ExtraInfo event, then wait to emit this event too.
445
+ queued_events = @network_event_manager.get_queued_event_group(event['requestId'])
446
+ if queued_events
447
+ queued_events.loading_failed_event = event
448
+ else
449
+ emit_loading_failed(event)
450
+ end
451
+ end
452
+
453
+ private def emit_loading_failed(event)
454
+ request = @network_event_manager.get_request(event['requestId'])
314
455
  # For certain requestIds we never receive requestWillBeSent event.
315
456
  # @see https://crbug.com/750469
316
457
  return unless request
@@ -319,8 +460,7 @@ class Puppeteer::NetworkManager
319
460
  if_present(request.response) do |response|
320
461
  response.internal.body_loaded_promise.fulfill(nil)
321
462
  end
322
- @request_id_to_request.delete(request.internal.request_id)
323
- @attempted_authentications.delete(request.internal.interception_id)
463
+ forget_request(request, true)
324
464
  emit_event(NetworkManagerEmittedEvents::RequestFailed, request)
325
465
  end
326
466
  end
@@ -26,8 +26,8 @@ class Puppeteer::QueryHandlerManager
26
26
  @query_handler.query_one(element_handle, @selector)
27
27
  end
28
28
 
29
- def wait_for(dom_world, visible:, hidden:, timeout:)
30
- @query_handler.wait_for(dom_world, @selector, visible: visible, hidden: hidden, timeout: timeout)
29
+ def wait_for(dom_world, visible:, hidden:, timeout:, root:)
30
+ @query_handler.wait_for(dom_world, @selector, visible: visible, hidden: hidden, timeout: timeout, root: root)
31
31
  end
32
32
 
33
33
  def query_all(element_handle)
@@ -1,3 +1,3 @@
1
1
  module Puppeteer
2
- VERSION = '0.38.0'
2
+ VERSION = '0.40.2'
3
3
  end
@@ -9,7 +9,7 @@ class Puppeteer::WaitTask
9
9
  end
10
10
  end
11
11
 
12
- def initialize(dom_world:, predicate_body:, title:, polling:, timeout:, args: [], binding_function: nil)
12
+ def initialize(dom_world:, predicate_body:, title:, polling:, timeout:, args: [], binding_function: nil, root: nil)
13
13
  if polling.is_a?(String)
14
14
  if polling != 'raf' && polling != 'mutation'
15
15
  raise ArgumentError.new("Unknown polling option: #{polling}")
@@ -25,6 +25,7 @@ class Puppeteer::WaitTask
25
25
  @dom_world = dom_world
26
26
  @polling = polling
27
27
  @timeout = timeout
28
+ @root = root
28
29
  @predicate_body = "return (#{predicate_body})(...args);"
29
30
  @args = args
30
31
  @binding_function = binding_function
@@ -68,6 +69,7 @@ class Puppeteer::WaitTask
68
69
  begin
69
70
  success = context.evaluate_handle(
70
71
  WAIT_FOR_PREDICATE_PAGE_FUNCTION,
72
+ @root,
71
73
  @predicate_body,
72
74
  @polling,
73
75
  @timeout,
@@ -121,8 +123,9 @@ class Puppeteer::WaitTask
121
123
  private define_async_method :async_rerun
122
124
 
123
125
  WAIT_FOR_PREDICATE_PAGE_FUNCTION = <<~JAVASCRIPT
124
- async function _(predicateBody, polling, timeout, ...args) {
126
+ async function _(root, predicateBody, polling, timeout, ...args) {
125
127
  const predicate = new Function('...args', predicateBody);
128
+ root = root || document
126
129
  let timedOut = false;
127
130
  if (timeout)
128
131
  setTimeout(() => (timedOut = true), timeout);
@@ -136,7 +139,7 @@ class Puppeteer::WaitTask
136
139
  * @return {!Promise<*>}
137
140
  */
138
141
  async function pollMutation() {
139
- const success = await predicate(...args);
142
+ const success = await predicate(root, ...args);
140
143
  if (success) return Promise.resolve(success);
141
144
  let fulfill;
142
145
  const result = new Promise((x) => (fulfill = x));
@@ -145,13 +148,13 @@ class Puppeteer::WaitTask
145
148
  observer.disconnect();
146
149
  fulfill();
147
150
  }
148
- const success = await predicate(...args);
151
+ const success = await predicate(root, ...args);
149
152
  if (success) {
150
153
  observer.disconnect();
151
154
  fulfill(success);
152
155
  }
153
156
  });
154
- observer.observe(document, {
157
+ observer.observe(root, {
155
158
  childList: true,
156
159
  subtree: true,
157
160
  attributes: true,
@@ -168,7 +171,7 @@ class Puppeteer::WaitTask
168
171
  fulfill();
169
172
  return;
170
173
  }
171
- const success = await predicate(...args);
174
+ const success = await predicate(root, ...args);
172
175
  if (success) fulfill(success);
173
176
  else requestAnimationFrame(onRaf);
174
177
  }
@@ -183,7 +186,7 @@ class Puppeteer::WaitTask
183
186
  fulfill();
184
187
  return;
185
188
  }
186
- const success = await predicate(...args);
189
+ const success = await predicate(root, ...args);
187
190
  if (success) fulfill(success);
188
191
  else setTimeout(onTimeout, pollInterval);
189
192
  }
data/lib/puppeteer.rb CHANGED
@@ -47,6 +47,7 @@ require 'puppeteer/launcher'
47
47
  require 'puppeteer/lifecycle_watcher'
48
48
  require 'puppeteer/mouse'
49
49
  require 'puppeteer/network_conditions'
50
+ require 'puppeteer/network_event_manager'
50
51
  require 'puppeteer/network_manager'
51
52
  require 'puppeteer/page'
52
53
  require 'puppeteer/protocol_stream_reader'
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'concurrent-ruby', '~> 1.1.0'
25
25
  spec.add_dependency 'websocket-driver', '>= 0.6.0'
26
26
  spec.add_dependency 'mime-types', '>= 3.0'
27
- spec.add_development_dependency 'bundler', '~> 2.2.3'
27
+ spec.add_development_dependency 'bundler', '~> 2.3.4'
28
28
  spec.add_development_dependency 'chunky_png'
29
29
  spec.add_development_dependency 'dry-inflector'
30
30
  spec.add_development_dependency 'pry-byebug'
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency 'rollbar'
33
33
  spec.add_development_dependency 'rspec', '~> 3.10.0 '
34
34
  spec.add_development_dependency 'rspec_junit_formatter' # for CircleCI.
35
- spec.add_development_dependency 'rubocop', '~> 1.23.0'
35
+ spec.add_development_dependency 'rubocop', '~> 1.24.0'
36
36
  spec.add_development_dependency 'rubocop-rspec'
37
37
  spec.add_development_dependency 'sinatra'
38
38
  spec.add_development_dependency 'webrick'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppeteer-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.38.0
4
+ version: 0.40.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - YusukeIwaki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-06 00:00:00.000000000 Z
11
+ date: 2022-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 2.2.3
61
+ version: 2.3.4
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 2.2.3
68
+ version: 2.3.4
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: chunky_png
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -170,14 +170,14 @@ dependencies:
170
170
  requirements:
171
171
  - - "~>"
172
172
  - !ruby/object:Gem::Version
173
- version: 1.23.0
173
+ version: 1.24.0
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
- version: 1.23.0
180
+ version: 1.24.0
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: rubocop-rspec
183
183
  requirement: !ruby/object:Gem::Requirement
@@ -306,6 +306,7 @@ files:
306
306
  - lib/puppeteer/mouse.rb
307
307
  - lib/puppeteer/network_condition.rb
308
308
  - lib/puppeteer/network_conditions.rb
309
+ - lib/puppeteer/network_event_manager.rb
309
310
  - lib/puppeteer/network_manager.rb
310
311
  - lib/puppeteer/page.rb
311
312
  - lib/puppeteer/page/metrics.rb
@@ -346,7 +347,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
346
347
  - !ruby/object:Gem::Version
347
348
  version: '0'
348
349
  requirements: []
349
- rubygems_version: 3.1.6
350
+ rubygems_version: 3.3.3
350
351
  signing_key:
351
352
  specification_version: 4
352
353
  summary: A ruby port of puppeteer