puppeteer-ruby 0.0.18 → 0.0.23
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/.circleci/config.yml +24 -1
- data/.github/workflows/reviewdog.yml +1 -1
- data/.rubocop.yml +50 -3
- data/Dockerfile +9 -0
- data/README.md +38 -0
- data/docker-compose.yml +34 -0
- data/lib/puppeteer.rb +15 -11
- data/lib/puppeteer/browser.rb +19 -26
- data/lib/puppeteer/browser_context.rb +48 -49
- data/lib/puppeteer/browser_runner.rb +20 -6
- data/lib/puppeteer/cdp_session.rb +21 -7
- data/lib/puppeteer/concurrent_ruby_utils.rb +18 -5
- data/lib/puppeteer/connection.rb +32 -13
- data/lib/puppeteer/debug_print.rb +1 -1
- data/lib/puppeteer/define_async_method.rb +1 -1
- data/lib/puppeteer/devices.rb +998 -849
- data/lib/puppeteer/dialog.rb +34 -0
- data/lib/puppeteer/dom_world.rb +2 -2
- data/lib/puppeteer/element_handle.rb +18 -1
- data/lib/puppeteer/env.rb +5 -0
- data/lib/puppeteer/event_callbackable.rb +4 -0
- data/lib/puppeteer/events.rb +184 -0
- data/lib/puppeteer/exception_details.rb +38 -0
- data/lib/puppeteer/frame.rb +1 -3
- data/lib/puppeteer/frame_manager.rb +20 -16
- data/lib/puppeteer/geolocation.rb +24 -0
- data/lib/puppeteer/keyboard/us_keyboard_layout.rb +2 -2
- data/lib/puppeteer/launcher.rb +11 -2
- data/lib/puppeteer/launcher/base.rb +14 -4
- data/lib/puppeteer/launcher/browser_options.rb +2 -1
- data/lib/puppeteer/launcher/chrome.rb +5 -9
- data/lib/puppeteer/launcher/firefox.rb +385 -0
- data/lib/puppeteer/lifecycle_watcher.rb +6 -6
- data/lib/puppeteer/network_manager.rb +6 -6
- data/lib/puppeteer/page.rb +87 -103
- data/lib/puppeteer/remote_object.rb +12 -1
- data/lib/puppeteer/target.rb +2 -2
- data/lib/puppeteer/version.rb +1 -1
- data/puppeteer-ruby.gemspec +1 -1
- metadata +11 -4
@@ -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(
|
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(
|
76
|
+
@frame_manager.add_event_listener(FrameManagerEmittedEvents::LifecycleEvent) do |_|
|
77
77
|
check_lifecycle_complete
|
78
78
|
end,
|
79
|
-
@frame_manager.add_event_listener(
|
80
|
-
@frame_manager.add_event_listener(
|
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(
|
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::
|
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
|
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
|
234
|
-
emit_event
|
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
|
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
|
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
|
278
|
+
emit_event(NetworkManagerEmittedEvents::RequestFailed, request)
|
279
279
|
end
|
280
280
|
end
|
data/lib/puppeteer/page.rb
CHANGED
@@ -46,7 +46,7 @@ class Puppeteer::Page
|
|
46
46
|
@screenshot_task_queue = screenshot_task_queue
|
47
47
|
|
48
48
|
@workers = {}
|
49
|
-
@client.on_event
|
49
|
+
@client.on_event('Target.attachedToTarget') do |event|
|
50
50
|
if event['targetInfo']['type'] != 'worker'
|
51
51
|
# If we don't detach from service workers, they will never die.
|
52
52
|
await @client.send_message('Target.detachFromTarget', sessionId: event['sessionId'])
|
@@ -56,63 +56,69 @@ class Puppeteer::Page
|
|
56
56
|
session = Puppeteer::Connection.from_session(@client).session(event['sessionId']) # rubocop:disable Lint/UselessAssignment
|
57
57
|
# const worker = new Worker(session, event.targetInfo.url, this._addConsoleMessage.bind(this), this._handleException.bind(this));
|
58
58
|
# this._workers.set(event.sessionId, worker);
|
59
|
-
# this.emit(
|
59
|
+
# this.emit(PageEmittedEvents::WorkerCreated, worker);
|
60
60
|
end
|
61
|
-
@client.on_event
|
61
|
+
@client.on_event('Target.detachedFromTarget') do |event|
|
62
62
|
session_id = event['sessionId']
|
63
63
|
worker = @workers[session_id]
|
64
64
|
next unless worker
|
65
65
|
|
66
|
-
emit_event(
|
66
|
+
emit_event(PageEmittedEvents::WorkerDestroyed, worker)
|
67
67
|
@workers.delete(session_id)
|
68
68
|
end
|
69
69
|
|
70
|
-
@frame_manager.on_event
|
71
|
-
emit_event
|
70
|
+
@frame_manager.on_event(FrameManagerEmittedEvents::FrameAttached) do |event|
|
71
|
+
emit_event(PageEmittedEvents::FrameAttached, event)
|
72
72
|
end
|
73
|
-
@frame_manager.on_event
|
74
|
-
emit_event
|
73
|
+
@frame_manager.on_event(FrameManagerEmittedEvents::FrameDetached) do |event|
|
74
|
+
emit_event(PageEmittedEvents::FrameDetached, event)
|
75
75
|
end
|
76
|
-
@frame_manager.on_event
|
77
|
-
emit_event
|
76
|
+
@frame_manager.on_event(FrameManagerEmittedEvents::FrameNavigated) do |event|
|
77
|
+
emit_event(PageEmittedEvents::FrameNavigated, event)
|
78
78
|
end
|
79
79
|
|
80
80
|
network_manager = @frame_manager.network_manager
|
81
|
-
network_manager.on_event
|
82
|
-
emit_event
|
81
|
+
network_manager.on_event(NetworkManagerEmittedEvents::Request) do |event|
|
82
|
+
emit_event(PageEmittedEvents::Request, event)
|
83
83
|
end
|
84
|
-
network_manager.on_event
|
85
|
-
emit_event
|
84
|
+
network_manager.on_event(NetworkManagerEmittedEvents::Response) do |event|
|
85
|
+
emit_event(PageEmittedEvents::Response, event)
|
86
86
|
end
|
87
|
-
network_manager.on_event
|
88
|
-
emit_event
|
87
|
+
network_manager.on_event(NetworkManagerEmittedEvents::RequestFailed) do |event|
|
88
|
+
emit_event(PageEmittedEvents::RequestFailed, event)
|
89
89
|
end
|
90
|
-
network_manager.on_event
|
91
|
-
emit_event
|
90
|
+
network_manager.on_event(NetworkManagerEmittedEvents::RequestFinished) do |event|
|
91
|
+
emit_event(PageEmittedEvents::RequestFinished, event)
|
92
92
|
end
|
93
93
|
@file_chooser_interception_is_disabled = false
|
94
94
|
@file_chooser_interceptors = Set.new
|
95
95
|
|
96
|
-
@client.on_event
|
97
|
-
emit_event
|
96
|
+
@client.on_event('Page.domContentEventFired') do |event|
|
97
|
+
emit_event(PageEmittedEvents::DOMContentLoaded)
|
98
98
|
end
|
99
|
-
@client.on_event
|
100
|
-
emit_event
|
99
|
+
@client.on_event('Page.loadEventFired') do |event|
|
100
|
+
emit_event(PageEmittedEvents::Load)
|
101
101
|
end
|
102
102
|
# client.on('Runtime.consoleAPICalled', event => this._onConsoleAPI(event));
|
103
103
|
# client.on('Runtime.bindingCalled', event => this._onBindingCalled(event));
|
104
|
-
|
105
|
-
|
106
|
-
|
104
|
+
@client.on_event('Page.javascriptDialogOpening') do |event|
|
105
|
+
handle_dialog_opening(event)
|
106
|
+
end
|
107
|
+
@client.on_event('Runtime.exceptionThrown') do |exception|
|
108
|
+
handle_exception(exception['exceptionDetails'])
|
109
|
+
end
|
110
|
+
@client.on_event('Inspector.targetCrashed') do |event|
|
111
|
+
handle_target_crashed
|
112
|
+
end
|
107
113
|
# client.on('Performance.metrics', event => this._emitMetrics(event));
|
108
|
-
@client.on_event
|
114
|
+
@client.on_event('Log.entryAdded') do |event|
|
109
115
|
handle_log_entry_added(event)
|
110
116
|
end
|
111
|
-
@client.on_event
|
117
|
+
@client.on_event('Page.fileChooserOpened') do |event|
|
112
118
|
handle_file_chooser(event)
|
113
119
|
end
|
114
120
|
@target.is_closed_promise.then do
|
115
|
-
emit_event
|
121
|
+
emit_event(PageEmittedEvents::Close)
|
116
122
|
@closed = true
|
117
123
|
end
|
118
124
|
end
|
@@ -126,43 +132,22 @@ class Puppeteer::Page
|
|
126
132
|
)
|
127
133
|
end
|
128
134
|
|
129
|
-
EVENT_MAPPINGS = {
|
130
|
-
close: 'Events.Page.Close',
|
131
|
-
# console: 'Events.Page.Console',
|
132
|
-
# dialog: 'Events.Page.Dialog',
|
133
|
-
domcontentloaded: 'Events.Page.DOMContentLoaded',
|
134
|
-
# error:
|
135
|
-
frameattached: 'Events.Page.FrameAttached',
|
136
|
-
framedetached: 'Events.Page.FrameDetached',
|
137
|
-
framenavigated: 'Events.Page.FrameNavigated',
|
138
|
-
load: 'Events.Page.Load',
|
139
|
-
# metrics: 'Events.Page.Metrics',
|
140
|
-
# pageerror: 'Events.Page.PageError',
|
141
|
-
popup: 'Events.Page.Popup',
|
142
|
-
request: 'Events.Page.Request',
|
143
|
-
requestfailed: 'Events.Page.RequestFailed',
|
144
|
-
requestfinished: 'Events.Page.RequestFinished',
|
145
|
-
response: 'Events.Page.Response',
|
146
|
-
# workercreated: 'Events.Page.WorkerCreated',
|
147
|
-
# workerdestroyed: 'Events.Page.WorkerDestroyed',
|
148
|
-
}
|
149
|
-
|
150
135
|
# @param event_name [Symbol]
|
151
136
|
def on(event_name, &block)
|
152
|
-
unless
|
153
|
-
raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{
|
137
|
+
unless PageEmittedEvents.values.include?(event_name.to_s)
|
138
|
+
raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{PageEmittedEvents.values.to_a.join(", ")}")
|
154
139
|
end
|
155
140
|
|
156
|
-
|
141
|
+
super(event_name.to_s, &block)
|
157
142
|
end
|
158
143
|
|
159
144
|
# @param event_name [Symbol]
|
160
145
|
def once(event_name, &block)
|
161
|
-
unless
|
162
|
-
raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{
|
146
|
+
unless PageEmittedEvents.values.include?(event_name.to_s)
|
147
|
+
raise ArgumentError.new("Unknown event name: #{event_name}. Known events are #{PageEmittedEvents.values.to_a.join(", ")}")
|
163
148
|
end
|
164
149
|
|
165
|
-
|
150
|
+
super(event_name.to_s, &block)
|
166
151
|
end
|
167
152
|
|
168
153
|
def handle_file_chooser(event)
|
@@ -209,19 +194,10 @@ class Puppeteer::Page
|
|
209
194
|
|
210
195
|
define_async_method :async_wait_for_file_chooser
|
211
196
|
|
212
|
-
#
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
# const { longitude, latitude, accuracy = 0} = options;
|
217
|
-
# if (longitude < -180 || longitude > 180)
|
218
|
-
# throw new Error(`Invalid longitude "${longitude}": precondition -180 <= LONGITUDE <= 180 failed.`);
|
219
|
-
# if (latitude < -90 || latitude > 90)
|
220
|
-
# throw new Error(`Invalid latitude "${latitude}": precondition -90 <= LATITUDE <= 90 failed.`);
|
221
|
-
# if (accuracy < 0)
|
222
|
-
# throw new Error(`Invalid accuracy "${accuracy}": precondition 0 <= ACCURACY failed.`);
|
223
|
-
# await this._client.send('Emulation.setGeolocationOverride', {longitude, latitude, accuracy});
|
224
|
-
# }
|
197
|
+
# @param [Puppeteer::Geolocation]
|
198
|
+
def geolocation=(geolocation)
|
199
|
+
@client.send_message('Emulation.setGeolocationOverride', geolocation.to_h)
|
200
|
+
end
|
225
201
|
|
226
202
|
attr_reader :javascript_enabled, :target
|
227
203
|
|
@@ -236,7 +212,7 @@ class Puppeteer::Page
|
|
236
212
|
class TargetCrashedError < StandardError; end
|
237
213
|
|
238
214
|
private def handle_target_crashed
|
239
|
-
emit_event
|
215
|
+
emit_event(PageEmittedEvents::Error, TargetCrashedError.new('Page crashed!'))
|
240
216
|
end
|
241
217
|
|
242
218
|
private def handle_log_entry_added(event)
|
@@ -257,7 +233,7 @@ class Puppeteer::Page
|
|
257
233
|
url: url,
|
258
234
|
line_number: line_number,
|
259
235
|
)
|
260
|
-
emit_event(
|
236
|
+
emit_event(PageEmittedEvents::Console,
|
261
237
|
Puppeteer::ConsoleMessage.new(level, text, [], console_message_location))
|
262
238
|
end
|
263
239
|
end
|
@@ -266,7 +242,13 @@ class Puppeteer::Page
|
|
266
242
|
@frame_manager.main_frame
|
267
243
|
end
|
268
244
|
|
269
|
-
attr_reader :
|
245
|
+
attr_reader :touch_screen, :coverage, :accessibility
|
246
|
+
|
247
|
+
def keyboard(&block)
|
248
|
+
@keyboard.instance_eval(&block) unless block.nil?
|
249
|
+
|
250
|
+
@keyboard
|
251
|
+
end
|
270
252
|
|
271
253
|
def frames
|
272
254
|
@frame_manager.frames
|
@@ -494,7 +476,7 @@ class Puppeteer::Page
|
|
494
476
|
# * @param {!Protocol.Performance.metricsPayload} event
|
495
477
|
# */
|
496
478
|
# _emitMetrics(event) {
|
497
|
-
# this.emit(
|
479
|
+
# this.emit(PageEmittedEvents::Metrics, {
|
498
480
|
# title: event.title,
|
499
481
|
# metrics: this._buildMetricsObject(event.metrics)
|
500
482
|
# });
|
@@ -513,15 +495,14 @@ class Puppeteer::Page
|
|
513
495
|
# return result;
|
514
496
|
# }
|
515
497
|
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
# }
|
498
|
+
class PageError < StandardError ; end
|
499
|
+
|
500
|
+
private def handle_exception(exception_details)
|
501
|
+
message = Puppeteer::ExceptionDetails.new(exception_details).message
|
502
|
+
err = PageError.new(message)
|
503
|
+
# err.stack = ''; // Don't report clientside error with a node stack attached
|
504
|
+
emit_event(PageEmittedEvents::PageError, err)
|
505
|
+
end
|
525
506
|
|
526
507
|
# /**
|
527
508
|
# * @param {!Protocol.Runtime.consoleAPICalledPayload} event
|
@@ -605,7 +586,7 @@ class Puppeteer::Page
|
|
605
586
|
# * @param {Protocol.Runtime.StackTrace=} stackTrace
|
606
587
|
# */
|
607
588
|
# _addConsoleMessage(type, args, stackTrace) {
|
608
|
-
# if (!this.listenerCount(
|
589
|
+
# if (!this.listenerCount(PageEmittedEvents::Console)) {
|
609
590
|
# args.forEach(arg => arg.dispose());
|
610
591
|
# return;
|
611
592
|
# }
|
@@ -623,23 +604,20 @@ class Puppeteer::Page
|
|
623
604
|
# columnNumber: stackTrace.callFrames[0].columnNumber,
|
624
605
|
# } : {};
|
625
606
|
# const message = new ConsoleMessage(type, textTokens.join(' '), args, location);
|
626
|
-
# this.emit(
|
607
|
+
# this.emit(PageEmittedEvents::Console, message);
|
627
608
|
# }
|
628
609
|
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
# const dialog = new Dialog(this._client, dialogType, event.message, event.defaultPrompt);
|
641
|
-
# this.emit(Events.Page.Dialog, dialog);
|
642
|
-
# }
|
610
|
+
private def handle_dialog_opening(event)
|
611
|
+
dialog_type = event['type']
|
612
|
+
unless %w(alert confirm prompt beforeunload).include?(dialog_type)
|
613
|
+
raise ArgumentError.new("Unknown javascript dialog type: #{dialog_type}")
|
614
|
+
end
|
615
|
+
dialog = Puppeteer::Dialog.new(@client,
|
616
|
+
type: dialog_type,
|
617
|
+
message: event['message'],
|
618
|
+
default_value: event['defaultPrompt'])
|
619
|
+
emit_event(PageEmittedEvents::Dialog, dialog)
|
620
|
+
end
|
643
621
|
|
644
622
|
# @return [String]
|
645
623
|
def url
|
@@ -721,7 +699,7 @@ class Puppeteer::Page
|
|
721
699
|
|
722
700
|
private def session_close_promise
|
723
701
|
@disconnect_promise ||= resolvable_future do |future|
|
724
|
-
@client.observe_first(
|
702
|
+
@client.observe_first(CDPSessionEmittedEvents::Disconnected) do
|
725
703
|
future.reject(Puppeteer::CDPSession::Error.new('Target Closed'))
|
726
704
|
end
|
727
705
|
end
|
@@ -741,7 +719,7 @@ class Puppeteer::Page
|
|
741
719
|
-> (request) { predicate.call(request) }
|
742
720
|
end
|
743
721
|
|
744
|
-
wait_for_network_manager_event(
|
722
|
+
wait_for_network_manager_event(NetworkManagerEmittedEvents::Request,
|
745
723
|
predicate: request_predicate,
|
746
724
|
timeout: timeout,
|
747
725
|
)
|
@@ -775,7 +753,7 @@ class Puppeteer::Page
|
|
775
753
|
-> (response) { predicate.call(response) }
|
776
754
|
end
|
777
755
|
|
778
|
-
wait_for_network_manager_event(
|
756
|
+
wait_for_network_manager_event(NetworkManagerEmittedEvents::Response,
|
779
757
|
predicate: response_predicate,
|
780
758
|
timeout: timeout,
|
781
759
|
)
|
@@ -934,16 +912,16 @@ class Puppeteer::Page
|
|
934
912
|
clip = { x: 0, y: 0, width: width, height: height, scale: 1 }
|
935
913
|
|
936
914
|
screen_orientation =
|
937
|
-
if @viewport
|
915
|
+
if @viewport&.landscape?
|
938
916
|
{ angle: 90, type: 'landscapePrimary' }
|
939
917
|
else
|
940
918
|
{ angle: 0, type: 'portraitPrimary' }
|
941
919
|
end
|
942
920
|
@client.send_message('Emulation.setDeviceMetricsOverride',
|
943
|
-
mobile: @viewport
|
921
|
+
mobile: @viewport&.mobile? || false,
|
944
922
|
width: width,
|
945
923
|
height: height,
|
946
|
-
deviceScaleFactor: @viewport
|
924
|
+
deviceScaleFactor: @viewport&.device_scale_factor || 1,
|
947
925
|
screenOrientation: screen_orientation)
|
948
926
|
end
|
949
927
|
|
@@ -1038,6 +1016,12 @@ class Puppeteer::Page
|
|
1038
1016
|
else
|
1039
1017
|
@client.connection.send_message('Target.closeTarget', targetId: @target.target_id)
|
1040
1018
|
await @target.is_closed_promise
|
1019
|
+
|
1020
|
+
# @closed sometimes remains false, so wait for @closed = true with 100ms timeout.
|
1021
|
+
25.times do
|
1022
|
+
break if @closed
|
1023
|
+
sleep 0.004
|
1024
|
+
end
|
1041
1025
|
end
|
1042
1026
|
end
|
1043
1027
|
|
@@ -80,7 +80,18 @@ class Puppeteer::RemoteObject
|
|
80
80
|
|
81
81
|
# used in ElementHandle#_box_model
|
82
82
|
def box_model(client)
|
83
|
-
client.send_message('DOM.getBoxModel', objectId: @object_id)
|
83
|
+
result = client.send_message('DOM.getBoxModel', objectId: @object_id)
|
84
|
+
|
85
|
+
# Firefox returns width/height = 0, content/padding/border/margin = [nil, nil, nil, nil, nil, nil, nil, nil]
|
86
|
+
# while Chrome throws Error(Could not compute box model)
|
87
|
+
model = result['model']
|
88
|
+
if model['width'] == 0 && model['height'] == 0 &&
|
89
|
+
%w(content padding border margin).all? { |key| model[key].all?(&:nil?) }
|
90
|
+
|
91
|
+
debug_puts('Could not compute box model in Firefox.')
|
92
|
+
return nil
|
93
|
+
end
|
94
|
+
result
|
84
95
|
rescue => err
|
85
96
|
debug_puts(err)
|
86
97
|
nil
|
data/lib/puppeteer/target.rb
CHANGED
@@ -68,10 +68,10 @@ class Puppeteer::Target
|
|
68
68
|
if opener_page.nil? || type != 'page'
|
69
69
|
return true
|
70
70
|
end
|
71
|
-
# if (!openerPage.listenerCount(
|
71
|
+
# if (!openerPage.listenerCount(PageEmittedEvents::Popup))
|
72
72
|
# return true;
|
73
73
|
popup_page = page
|
74
|
-
opener_page.emit_event(
|
74
|
+
opener_page.emit_event(PageEmittedEvents::Popup, popup_page)
|
75
75
|
|
76
76
|
true
|
77
77
|
end
|