puppeteer-ruby 0.0.22 → 0.28.1

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,24 @@
1
+ class Puppeteer::Geolocation
2
+ # @param latitude [Fixnum]
3
+ # @param longitude [Fixnum]
4
+ # @param accuracy [Fixnum]
5
+ def initialize(latitude:, longitude:, accuracy: 0)
6
+ unless (-180..180).include?(longitude)
7
+ raise ArgumentError.new("Invalid longitude \"#{longitude}\": precondition -180 <= LONGITUDE <= 180 failed.")
8
+ end
9
+ unless (-90..90).include?(latitude)
10
+ raise ArgumentError.new("Invalid latitude \"#{latitude}\": precondition -90 <= LATITUDE <= 90 failed.")
11
+ end
12
+ if accuracy < 0
13
+ raise ArgumentError.new("Invalid accuracy \"#{longitude}\": precondition 0 <= ACCURACY failed.")
14
+ end
15
+
16
+ @latitude = latitude
17
+ @longitude = longitude
18
+ @accuracy = accuracy
19
+ end
20
+
21
+ def to_h
22
+ { latitude: @latitude, longitude: @longitude, accuracy: @accuracy }
23
+ end
24
+ end
@@ -92,7 +92,7 @@ module Puppeteer::Launcher
92
92
  '--disable-default-apps',
93
93
  '--disable-dev-shm-usage',
94
94
  '--disable-extensions',
95
- '--disable-features=TranslateUI',
95
+ '--disable-features=Translate',
96
96
  '--disable-hang-monitor',
97
97
  '--disable-ipc-flooding-protection',
98
98
  '--disable-popup-blocking',
@@ -105,6 +105,9 @@ module Puppeteer::Launcher
105
105
  '--enable-automation',
106
106
  '--password-store=basic',
107
107
  '--use-mock-keychain',
108
+ # TODO(sadym): remove '--enable-blink-features=IdleDetection'
109
+ # once IdleDetection is turned on by default.
110
+ '--enable-blink-features=IdleDetection',
108
111
  ]
109
112
 
110
113
  if chrome_arg_options.user_data_dir
@@ -69,17 +69,17 @@ class Puppeteer::LifecycleWatcher
69
69
  @timeout = timeout
70
70
 
71
71
  @listener_ids = {}
72
- @listener_ids['client'] = @frame_manager.client.add_event_listener('Events.CDPSession.Disconnected') do
72
+ @listener_ids['client'] = @frame_manager.client.add_event_listener(CDPSessionEmittedEvents::Disconnected) do
73
73
  terminate(TerminatedError.new('Navigation failed because browser has disconnected!'))
74
74
  end
75
75
  @listener_ids['frame_manager'] = [
76
- @frame_manager.add_event_listener('Events.FrameManager.LifecycleEvent') do |_|
76
+ @frame_manager.add_event_listener(FrameManagerEmittedEvents::LifecycleEvent) do |_|
77
77
  check_lifecycle_complete
78
78
  end,
79
- @frame_manager.add_event_listener('Events.FrameManager.FrameNavigatedWithinDocument', &method(:navigated_within_document)),
80
- @frame_manager.add_event_listener('Events.FrameManager.FrameDetached', &method(:handle_frame_detached)),
79
+ @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameNavigatedWithinDocument, &method(:navigated_within_document)),
80
+ @frame_manager.add_event_listener(FrameManagerEmittedEvents::FrameDetached, &method(:handle_frame_detached)),
81
81
  ]
82
- @listener_ids['network_manager'] = @frame_manager.network_manager.add_event_listener('Events.NetworkManager.Request', &method(:handle_request))
82
+ @listener_ids['network_manager'] = @frame_manager.network_manager.add_event_listener(NetworkManagerEmittedEvents::Request, &method(:handle_request))
83
83
 
84
84
  @same_document_navigation_promise = resolvable_future
85
85
  @lifecycle_promise = resolvable_future
@@ -128,7 +128,7 @@ class Puppeteer::LifecycleWatcher
128
128
  @termination_promise.value!
129
129
  end
130
130
  rescue Timeout::Error
131
- raise Puppeteer::FrameManager::NavigationError.new("Navigation timeout of #{@timeout}ms exceeded")
131
+ raise Puppeteer::TimeoutError.new("Navigation timeout of #{@timeout}ms exceeded")
132
132
  end
133
133
  else
134
134
  @termination_promise
@@ -212,7 +212,7 @@ class Puppeteer::NetworkManager
212
212
  frame = if_present(event['frameId']) { |frame_id| @frame_manager.frame(frame_id) }
213
213
  request = Puppeteer::Request.new(@client, frame, interception_id, @user_request_interception_enabled, event, redirect_chain)
214
214
  @request_id_to_request[event['requestId']] = request
215
- emit_event 'Events.NetworkManager.Request', request
215
+ emit_event(NetworkManagerEmittedEvents::Request, request)
216
216
  end
217
217
 
218
218
  private def handle_request_served_from_cache(event)
@@ -230,8 +230,8 @@ class Puppeteer::NetworkManager
230
230
  response.internal.body_loaded_promise.reject(Puppeteer::Response::Redirected.new)
231
231
  @request_id_to_request.delete(request.internal.request_id)
232
232
  @attempted_authentications.delete(request.internal.interception_id)
233
- emit_event 'Events.NetworkManager.Response', response
234
- emit_event 'Events.NetworkManager.RequestFinished', request
233
+ emit_event(NetworkManagerEmittedEvents::Response, response)
234
+ emit_event(NetworkManagerEmittedEvents::RequestFinished, request)
235
235
  end
236
236
 
237
237
  # @param event [Hash]
@@ -242,7 +242,7 @@ class Puppeteer::NetworkManager
242
242
 
243
243
  response = Puppeteer::Response.new(@client, request, event['response'])
244
244
  request.internal.response = response
245
- emit_event 'Events.NetworkManager.Response', response
245
+ emit_event(NetworkManagerEmittedEvents::Response, response)
246
246
  end
247
247
 
248
248
  private def handle_loading_finished(event)
@@ -260,7 +260,7 @@ class Puppeteer::NetworkManager
260
260
 
261
261
  @request_id_to_request.delete(request.internal.request_id)
262
262
  @attempted_authentications.delete(request.internal.interception_id)
263
- emit_event 'Events.NetworkManager.RequestFinished', request
263
+ emit_event(NetworkManagerEmittedEvents::RequestFinished, request)
264
264
  end
265
265
 
266
266
  private def handle_loading_failed(event)
@@ -275,6 +275,6 @@ class Puppeteer::NetworkManager
275
275
  end
276
276
  @request_id_to_request.delete(request.internal.request_id)
277
277
  @attempted_authentications.delete(request.internal.interception_id)
278
- emit_event 'Events.NetworkManager.RequestFailed', request
278
+ emit_event(NetworkManagerEmittedEvents::RequestFailed, request)
279
279
  end
280
280
  end
@@ -3,6 +3,7 @@ require "stringio"
3
3
 
4
4
  require_relative './page/pdf_options'
5
5
  require_relative './page/screenshot_options'
6
+ require_relative './page/screenshot_task_queue'
6
7
 
7
8
  class Puppeteer::Page
8
9
  include Puppeteer::EventCallbackable
@@ -13,10 +14,9 @@ class Puppeteer::Page
13
14
  # @param {!Puppeteer.Target} target
14
15
  # @param {boolean} ignoreHTTPSErrors
15
16
  # @param {?Puppeteer.Viewport} defaultViewport
16
- # @param {!Puppeteer.TaskQueue} screenshotTaskQueue
17
17
  # @return {!Promise<!Page>}
18
- def self.create(client, target, ignore_https_errors, default_viewport, screenshot_task_queue)
19
- page = Puppeteer::Page.new(client, target, ignore_https_errors, screenshot_task_queue)
18
+ def self.create(client, target, ignore_https_errors, default_viewport)
19
+ page = Puppeteer::Page.new(client, target, ignore_https_errors)
20
20
  page.init
21
21
  if default_viewport
22
22
  page.viewport = default_viewport
@@ -27,8 +27,7 @@ class Puppeteer::Page
27
27
  # @param {!Puppeteer.CDPSession} client
28
28
  # @param {!Puppeteer.Target} target
29
29
  # @param {boolean} ignoreHTTPSErrors
30
- # @param {!Puppeteer.TaskQueue} screenshotTaskQueue
31
- def initialize(client, target, ignore_https_errors, screenshot_task_queue)
30
+ def initialize(client, target, ignore_https_errors)
32
31
  @closed = false
33
32
  @client = client
34
33
  @target = target
@@ -43,10 +42,10 @@ class Puppeteer::Page
43
42
  @page_bindings = {}
44
43
  # @coverage = Coverage.new(client)
45
44
  @javascript_enabled = true
46
- @screenshot_task_queue = screenshot_task_queue
45
+ @screenshot_task_queue = ScreenshotTaskQueue.new
47
46
 
48
47
  @workers = {}
49
- @client.on_event 'Target.attachedToTarget' do |event|
48
+ @client.on_event('Target.attachedToTarget') do |event|
50
49
  if event['targetInfo']['type'] != 'worker'
51
50
  # If we don't detach from service workers, they will never die.
52
51
  await @client.send_message('Target.detachFromTarget', sessionId: event['sessionId'])
@@ -56,65 +55,69 @@ class Puppeteer::Page
56
55
  session = Puppeteer::Connection.from_session(@client).session(event['sessionId']) # rubocop:disable Lint/UselessAssignment
57
56
  # const worker = new Worker(session, event.targetInfo.url, this._addConsoleMessage.bind(this), this._handleException.bind(this));
58
57
  # this._workers.set(event.sessionId, worker);
59
- # this.emit(Events.Page.WorkerCreated, worker);
58
+ # this.emit(PageEmittedEvents::WorkerCreated, worker);
60
59
  end
61
- @client.on_event 'Target.detachedFromTarget' do |event|
60
+ @client.on_event('Target.detachedFromTarget') do |event|
62
61
  session_id = event['sessionId']
63
62
  worker = @workers[session_id]
64
63
  next unless worker
65
64
 
66
- emit_event('Events.Page.WorkerDestroyed', worker)
65
+ emit_event(PageEmittedEvents::WorkerDestroyed, worker)
67
66
  @workers.delete(session_id)
68
67
  end
69
68
 
70
- @frame_manager.on_event 'Events.FrameManager.FrameAttached' do |event|
71
- emit_event 'Events.Page.FrameAttached', event
69
+ @frame_manager.on_event(FrameManagerEmittedEvents::FrameAttached) do |event|
70
+ emit_event(PageEmittedEvents::FrameAttached, event)
72
71
  end
73
- @frame_manager.on_event 'Events.FrameManager.FrameDetached' do |event|
74
- emit_event 'Events.Page.FrameDetached', event
72
+ @frame_manager.on_event(FrameManagerEmittedEvents::FrameDetached) do |event|
73
+ emit_event(PageEmittedEvents::FrameDetached, event)
75
74
  end
76
- @frame_manager.on_event 'Events.FrameManager.FrameNavigated' do |event|
77
- emit_event 'Events.Page.FrameNavigated', event
75
+ @frame_manager.on_event(FrameManagerEmittedEvents::FrameNavigated) do |event|
76
+ emit_event(PageEmittedEvents::FrameNavigated, event)
78
77
  end
79
78
 
80
79
  network_manager = @frame_manager.network_manager
81
- network_manager.on_event 'Events.NetworkManager.Request' do |event|
82
- emit_event 'Events.Page.Request', event
80
+ network_manager.on_event(NetworkManagerEmittedEvents::Request) do |event|
81
+ emit_event(PageEmittedEvents::Request, event)
83
82
  end
84
- network_manager.on_event 'Events.NetworkManager.Response' do |event|
85
- emit_event 'Events.Page.Response', event
83
+ network_manager.on_event(NetworkManagerEmittedEvents::Response) do |event|
84
+ emit_event(PageEmittedEvents::Response, event)
86
85
  end
87
- network_manager.on_event 'Events.NetworkManager.RequestFailed' do |event|
88
- emit_event 'Events.Page.RequestFailed', event
86
+ network_manager.on_event(NetworkManagerEmittedEvents::RequestFailed) do |event|
87
+ emit_event(PageEmittedEvents::RequestFailed, event)
89
88
  end
90
- network_manager.on_event 'Events.NetworkManager.RequestFinished' do |event|
91
- emit_event 'Events.Page.RequestFinished', event
89
+ network_manager.on_event(NetworkManagerEmittedEvents::RequestFinished) do |event|
90
+ emit_event(PageEmittedEvents::RequestFinished, event)
92
91
  end
93
92
  @file_chooser_interception_is_disabled = false
94
93
  @file_chooser_interceptors = Set.new
95
94
 
96
- @client.on_event 'Page.domContentEventFired' do |event|
97
- emit_event 'Events.Page.DOMContentLoaded'
95
+ @client.on_event('Page.domContentEventFired') do |event|
96
+ emit_event(PageEmittedEvents::DOMContentLoaded)
98
97
  end
99
- @client.on_event 'Page.loadEventFired' do |event|
100
- emit_event 'Events.Page.Load'
98
+ @client.on_event('Page.loadEventFired') do |event|
99
+ emit_event(PageEmittedEvents::Load)
101
100
  end
102
101
  # client.on('Runtime.consoleAPICalled', event => this._onConsoleAPI(event));
103
102
  # client.on('Runtime.bindingCalled', event => this._onBindingCalled(event));
104
- @client.on_event 'Page.javascriptDialogOpening' do |event|
103
+ @client.on_event('Page.javascriptDialogOpening') do |event|
105
104
  handle_dialog_opening(event)
106
105
  end
107
- # client.on('Runtime.exceptionThrown', exception => this._handleException(exception.exceptionDetails));
108
- # client.on('Inspector.targetCrashed', event => this._onTargetCrashed());
106
+ @client.on_event('Runtime.exceptionThrown') do |exception|
107
+ handle_exception(exception['exceptionDetails'])
108
+ end
109
+ @client.on_event('Inspector.targetCrashed') do |event|
110
+ handle_target_crashed
111
+ end
109
112
  # client.on('Performance.metrics', event => this._emitMetrics(event));
110
- @client.on_event 'Log.entryAdded' do |event|
113
+ @client.on_event('Log.entryAdded') do |event|
111
114
  handle_log_entry_added(event)
112
115
  end
113
- @client.on_event 'Page.fileChooserOpened' do |event|
116
+ @client.on_event('Page.fileChooserOpened') do |event|
114
117
  handle_file_chooser(event)
115
118
  end
116
119
  @target.is_closed_promise.then do
117
- emit_event 'Events.Page.Close'
120
+ emit_event(PageEmittedEvents::Close)
118
121
  @closed = true
119
122
  end
120
123
  end
@@ -128,43 +131,22 @@ class Puppeteer::Page
128
131
  )
129
132
  end
130
133
 
131
- EVENT_MAPPINGS = {
132
- close: 'Events.Page.Close',
133
- # console: 'Events.Page.Console',
134
- dialog: 'Events.Page.Dialog',
135
- domcontentloaded: 'Events.Page.DOMContentLoaded',
136
- # error:
137
- frameattached: 'Events.Page.FrameAttached',
138
- framedetached: 'Events.Page.FrameDetached',
139
- framenavigated: 'Events.Page.FrameNavigated',
140
- load: 'Events.Page.Load',
141
- # metrics: 'Events.Page.Metrics',
142
- # pageerror: 'Events.Page.PageError',
143
- popup: 'Events.Page.Popup',
144
- request: 'Events.Page.Request',
145
- requestfailed: 'Events.Page.RequestFailed',
146
- requestfinished: 'Events.Page.RequestFinished',
147
- response: 'Events.Page.Response',
148
- # workercreated: 'Events.Page.WorkerCreated',
149
- # workerdestroyed: 'Events.Page.WorkerDestroyed',
150
- }
151
-
152
134
  # @param event_name [Symbol]
153
135
  def on(event_name, &block)
154
- unless EVENT_MAPPINGS.has_key?(event_name.to_sym)
155
- raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{EVENT_MAPPINGS.keys.join(", ")}")
136
+ unless PageEmittedEvents.values.include?(event_name.to_s)
137
+ raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{PageEmittedEvents.values.to_a.join(", ")}")
156
138
  end
157
139
 
158
- add_event_listener(EVENT_MAPPINGS[event_name.to_sym], &block)
140
+ super(event_name.to_s, &block)
159
141
  end
160
142
 
161
143
  # @param event_name [Symbol]
162
144
  def once(event_name, &block)
163
- unless EVENT_MAPPINGS.has_key?(event_name.to_sym)
164
- raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{EVENT_MAPPINGS.keys.join(", ")}")
145
+ unless PageEmittedEvents.values.include?(event_name.to_s)
146
+ raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{PageEmittedEvents.values.to_a.join(", ")}")
165
147
  end
166
148
 
167
- observe_first(EVENT_MAPPINGS[event_name.to_sym], &block)
149
+ super(event_name.to_s, &block)
168
150
  end
169
151
 
170
152
  def handle_file_chooser(event)
@@ -211,19 +193,10 @@ class Puppeteer::Page
211
193
 
212
194
  define_async_method :async_wait_for_file_chooser
213
195
 
214
- # /**
215
- # * @param {!{longitude: number, latitude: number, accuracy: (number|undefined)}} options
216
- # */
217
- # async setGeolocation(options) {
218
- # const { longitude, latitude, accuracy = 0} = options;
219
- # if (longitude < -180 || longitude > 180)
220
- # throw new Error(`Invalid longitude "${longitude}": precondition -180 <= LONGITUDE <= 180 failed.`);
221
- # if (latitude < -90 || latitude > 90)
222
- # throw new Error(`Invalid latitude "${latitude}": precondition -90 <= LATITUDE <= 90 failed.`);
223
- # if (accuracy < 0)
224
- # throw new Error(`Invalid accuracy "${accuracy}": precondition 0 <= ACCURACY failed.`);
225
- # await this._client.send('Emulation.setGeolocationOverride', {longitude, latitude, accuracy});
226
- # }
196
+ # @param [Puppeteer::Geolocation]
197
+ def geolocation=(geolocation)
198
+ @client.send_message('Emulation.setGeolocationOverride', geolocation.to_h)
199
+ end
227
200
 
228
201
  attr_reader :javascript_enabled, :target
229
202
 
@@ -238,7 +211,7 @@ class Puppeteer::Page
238
211
  class TargetCrashedError < StandardError; end
239
212
 
240
213
  private def handle_target_crashed
241
- emit_event 'error', TargetCrashedError.new('Page crashed!')
214
+ emit_event(PageEmittedEvents::Error, TargetCrashedError.new('Page crashed!'))
242
215
  end
243
216
 
244
217
  private def handle_log_entry_added(event)
@@ -259,7 +232,7 @@ class Puppeteer::Page
259
232
  url: url,
260
233
  line_number: line_number,
261
234
  )
262
- emit_event('Events.Page.Console',
235
+ emit_event(PageEmittedEvents::Console,
263
236
  Puppeteer::ConsoleMessage.new(level, text, [], console_message_location))
264
237
  end
265
238
  end
@@ -367,47 +340,34 @@ class Puppeteer::Page
367
340
 
368
341
  define_async_method :async_Sx
369
342
 
370
- # /**
371
- # * @param {!Array<string>} urls
372
- # * @return {!Promise<!Array<Network.Cookie>>}
373
- # */
374
- # async cookies(...urls) {
375
- # return (await this._client.send('Network.getCookies', {
376
- # urls: urls.length ? urls : [this.url()]
377
- # })).cookies;
378
- # }
343
+ # @return [Array<Hash>]
344
+ def cookies(*urls)
345
+ @client.send_message('Network.getCookies', urls: (urls.empty? ? [url] : urls))['cookies']
346
+ end
379
347
 
380
- # /**
381
- # * @param {Array<Protocol.Network.deleteCookiesParameters>} cookies
382
- # */
383
- # async deleteCookie(...cookies) {
384
- # const pageURL = this.url();
385
- # for (const cookie of cookies) {
386
- # const item = Object.assign({}, cookie);
387
- # if (!cookie.url && pageURL.startsWith('http'))
388
- # item.url = pageURL;
389
- # await this._client.send('Network.deleteCookies', item);
390
- # }
391
- # }
348
+ def delete_cookie(*cookies)
349
+ page_url = url
350
+ starts_with_http = page_url.start_with?("http")
351
+ cookies.each do |cookie|
352
+ item = (starts_with_http ? { url: page_url } : {}).merge(cookie)
353
+ @client.send_message("Network.deleteCookies", item)
354
+ end
355
+ end
392
356
 
393
- # /**
394
- # * @param {Array<Network.CookieParam>} cookies
395
- # */
396
- # async setCookie(...cookies) {
397
- # const pageURL = this.url();
398
- # const startsWithHTTP = pageURL.startsWith('http');
399
- # const items = cookies.map(cookie => {
400
- # const item = Object.assign({}, cookie);
401
- # if (!item.url && startsWithHTTP)
402
- # item.url = pageURL;
403
- # assert(item.url !== 'about:blank', `Blank page can not have cookie "${item.name}"`);
404
- # assert(!String.prototype.startsWith.call(item.url || '', 'data:'), `Data URL page can not have cookie "${item.name}"`);
405
- # return item;
406
- # });
407
- # await this.deleteCookie(...items);
408
- # if (items.length)
409
- # await this._client.send('Network.setCookies', { cookies: items });
410
- # }
357
+ def set_cookie(*cookies)
358
+ page_url = url
359
+ starts_with_http = page_url.start_with?("http")
360
+ items = cookies.map do |cookie|
361
+ (starts_with_http ? { url: page_url } : {}).merge(cookie).tap do |item|
362
+ raise ArgumentError.new("Blank page can not have cookie \"#{item[:name]}\"") if item[:url] == "about:blank"
363
+ raise ArgumetnError.new("Data URL page can not have cookie \"#{item[:name]}\"") if item[:url]&.start_with?("data:")
364
+ end
365
+ end
366
+ delete_cookie(*items)
367
+ unless items.empty?
368
+ @client.send_message("Network.setCookies", cookies: items)
369
+ end
370
+ end
411
371
 
412
372
  class ScriptTag
413
373
  # @param {!{content?: string, path?: string, type?: string, url?: string}} options
@@ -502,7 +462,7 @@ class Puppeteer::Page
502
462
  # * @param {!Protocol.Performance.metricsPayload} event
503
463
  # */
504
464
  # _emitMetrics(event) {
505
- # this.emit(Events.Page.Metrics, {
465
+ # this.emit(PageEmittedEvents::Metrics, {
506
466
  # title: event.title,
507
467
  # metrics: this._buildMetricsObject(event.metrics)
508
468
  # });
@@ -521,15 +481,14 @@ class Puppeteer::Page
521
481
  # return result;
522
482
  # }
523
483
 
524
- # /**
525
- # * @param {!Protocol.Runtime.ExceptionDetails} exceptionDetails
526
- # */
527
- # _handleException(exceptionDetails) {
528
- # const message = helper.getExceptionMessage(exceptionDetails);
529
- # const err = new Error(message);
530
- # err.stack = ''; // Don't report clientside error with a node stack attached
531
- # this.emit(Events.Page.PageError, err);
532
- # }
484
+ class PageError < StandardError ; end
485
+
486
+ private def handle_exception(exception_details)
487
+ message = Puppeteer::ExceptionDetails.new(exception_details).message
488
+ err = PageError.new(message)
489
+ # err.stack = ''; // Don't report clientside error with a node stack attached
490
+ emit_event(PageEmittedEvents::PageError, err)
491
+ end
533
492
 
534
493
  # /**
535
494
  # * @param {!Protocol.Runtime.consoleAPICalledPayload} event
@@ -613,7 +572,7 @@ class Puppeteer::Page
613
572
  # * @param {Protocol.Runtime.StackTrace=} stackTrace
614
573
  # */
615
574
  # _addConsoleMessage(type, args, stackTrace) {
616
- # if (!this.listenerCount(Events.Page.Console)) {
575
+ # if (!this.listenerCount(PageEmittedEvents::Console)) {
617
576
  # args.forEach(arg => arg.dispose());
618
577
  # return;
619
578
  # }
@@ -631,7 +590,7 @@ class Puppeteer::Page
631
590
  # columnNumber: stackTrace.callFrames[0].columnNumber,
632
591
  # } : {};
633
592
  # const message = new ConsoleMessage(type, textTokens.join(' '), args, location);
634
- # this.emit(Events.Page.Console, message);
593
+ # this.emit(PageEmittedEvents::Console, message);
635
594
  # }
636
595
 
637
596
  private def handle_dialog_opening(event)
@@ -643,7 +602,7 @@ class Puppeteer::Page
643
602
  type: dialog_type,
644
603
  message: event['message'],
645
604
  default_value: event['defaultPrompt'])
646
- emit_event('Events.Page.Dialog', dialog)
605
+ emit_event(PageEmittedEvents::Dialog, dialog)
647
606
  end
648
607
 
649
608
  # @return [String]
@@ -726,7 +685,7 @@ class Puppeteer::Page
726
685
 
727
686
  private def session_close_promise
728
687
  @disconnect_promise ||= resolvable_future do |future|
729
- @client.observe_first('Events.CDPSession.Disconnected') do
688
+ @client.observe_first(CDPSessionEmittedEvents::Disconnected) do
730
689
  future.reject(Puppeteer::CDPSession::Error.new('Target Closed'))
731
690
  end
732
691
  end
@@ -746,7 +705,7 @@ class Puppeteer::Page
746
705
  -> (request) { predicate.call(request) }
747
706
  end
748
707
 
749
- wait_for_network_manager_event('Events.NetworkManager.Request',
708
+ wait_for_network_manager_event(NetworkManagerEmittedEvents::Request,
750
709
  predicate: request_predicate,
751
710
  timeout: timeout,
752
711
  )
@@ -780,7 +739,7 @@ class Puppeteer::Page
780
739
  -> (response) { predicate.call(response) }
781
740
  end
782
741
 
783
- wait_for_network_manager_event('Events.NetworkManager.Response',
742
+ wait_for_network_manager_event(NetworkManagerEmittedEvents::Response,
784
743
  predicate: response_predicate,
785
744
  timeout: timeout,
786
745
  )
@@ -870,6 +829,21 @@ class Puppeteer::Page
870
829
  end
871
830
  end
872
831
 
832
+ # @param is_user_active [Boolean]
833
+ # @param is_screen_unlocked [Boolean]
834
+ def emulate_idle_state(is_user_active: nil, is_screen_unlocked: nil)
835
+ overrides = {
836
+ isUserActive: is_user_active,
837
+ isScreenUnlocked: is_screen_unlocked,
838
+ }.compact
839
+
840
+ if overrides.empty?
841
+ @client.send_message('Emulation.clearIdleOverride')
842
+ else
843
+ @client.send_message('Emulation.setIdleOverride', overrides)
844
+ end
845
+ end
846
+
873
847
  # @param viewport [Viewport]
874
848
  def viewport=(viewport)
875
849
  needs_reload = @emulation_manager.emulate_viewport(viewport)
@@ -907,15 +881,28 @@ class Puppeteer::Page
907
881
  main_frame.title
908
882
  end
909
883
 
910
- # /**
911
- # * @param {!ScreenshotOptions=} options
912
- # * @return {!Promise<!Buffer|!String>}
913
- # */
914
- def screenshot(options = {})
884
+ # @param type [String] "png"|"jpeg"
885
+ # @param path [String]
886
+ # @param full_page [Boolean]
887
+ # @param clip [Hash]
888
+ # @param quality [Integer]
889
+ # @param omit_background [Boolean]
890
+ # @param encoding [String]
891
+ def screenshot(type: nil, path: nil, full_page: nil, clip: nil, quality: nil, omit_background: nil, encoding: nil)
892
+ options = {
893
+ type: type,
894
+ path: path,
895
+ full_page: full_page,
896
+ clip: clip,
897
+ quality: quality,
898
+ omit_background: omit_background,
899
+ encoding: encoding,
900
+ }.compact
915
901
  screenshot_options = ScreenshotOptions.new(options)
916
902
 
917
- # @screenshot_task_queue.post_task(-> { screenshot_task(screenshot_options.type, screenshot_options) })
918
- screenshot_task(screenshot_options.type, screenshot_options)
903
+ @screenshot_task_queue.post_task do
904
+ screenshot_task(screenshot_options.type, screenshot_options)
905
+ end
919
906
  end
920
907
 
921
908
  # @param {"png"|"jpeg"} format
@@ -1043,6 +1030,12 @@ class Puppeteer::Page
1043
1030
  else
1044
1031
  @client.connection.send_message('Target.closeTarget', targetId: @target.target_id)
1045
1032
  await @target.is_closed_promise
1033
+
1034
+ # @closed sometimes remains false, so wait for @closed = true with 100ms timeout.
1035
+ 25.times do
1036
+ break if @closed
1037
+ sleep 0.004
1038
+ end
1046
1039
  end
1047
1040
  end
1048
1041