puppeteer-ruby 0.50.0.alpha8 → 0.50.0.alpha10
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/docs/api_coverage.md +1 -1
- data/lib/puppeteer/connection.rb +43 -2
- data/lib/puppeteer/frame_manager.rb +80 -12
- data/lib/puppeteer/version.rb +1 -1
- data/sig/_supplementary.rbs +6 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6ad92e4a471db943a70ea1f6e928ba29e611cba0fc4b62b001bafb0cf444c797
|
|
4
|
+
data.tar.gz: 226103f1934651f038099e58a7b94414e248db9290f928c4fc2d4b262df59807
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1ba290b15ba557824715b8aa82ad8695cdc9d08200381c7e004cb3c3fe63e041bc732e5e27f904e6bf75ff4eef51e6fdb905972d4225cfa495bbde9637a5f2ac
|
|
7
|
+
data.tar.gz: c7a208b38765265b77cef6f81dc1945daa6b4f4c09957c0b9b8e20484630a20a0359bbd3bbde26d5d88c1b55ea5c17cb02d522e358e294aa3db814685559a736
|
data/docs/api_coverage.md
CHANGED
data/lib/puppeteer/connection.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'json'
|
|
2
|
+
require 'async/queue'
|
|
2
3
|
|
|
3
4
|
class Puppeteer::Connection
|
|
4
5
|
include Puppeteer::DebugPrint
|
|
@@ -44,11 +45,16 @@ class Puppeteer::Connection
|
|
|
44
45
|
@delay = delay
|
|
45
46
|
@protocol_timeout = protocol_timeout
|
|
46
47
|
|
|
48
|
+
@network_message_queue = Async::Queue.new
|
|
49
|
+
@network_message_task = nil
|
|
50
|
+
|
|
47
51
|
@transport = transport
|
|
48
52
|
@transport.on_message do |data|
|
|
49
53
|
message = JSON.parse(data)
|
|
50
54
|
sleep_before_handling_message(message)
|
|
51
|
-
if
|
|
55
|
+
if network_event_message?(message)
|
|
56
|
+
enqueue_network_message(message)
|
|
57
|
+
elsif should_handle_synchronously?(message)
|
|
52
58
|
handle_message(message)
|
|
53
59
|
else
|
|
54
60
|
async_handle_message(message)
|
|
@@ -87,7 +93,8 @@ class Puppeteer::Connection
|
|
|
87
93
|
when nil
|
|
88
94
|
false
|
|
89
95
|
when /^Network\./
|
|
90
|
-
|
|
96
|
+
# Network events are queued for ordered async processing.
|
|
97
|
+
false
|
|
91
98
|
when /^Page\.frame/
|
|
92
99
|
# Page.frameAttached
|
|
93
100
|
# Page.frameNavigated
|
|
@@ -112,6 +119,34 @@ class Puppeteer::Connection
|
|
|
112
119
|
end
|
|
113
120
|
end
|
|
114
121
|
|
|
122
|
+
private def network_event_message?(message)
|
|
123
|
+
message['method']&.start_with?('Network.')
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
private def ensure_network_message_task
|
|
127
|
+
return if @network_message_task&.alive?
|
|
128
|
+
return unless Async::Task.current?
|
|
129
|
+
|
|
130
|
+
@network_message_task = Async do
|
|
131
|
+
while (queued = @network_message_queue.dequeue)
|
|
132
|
+
handle_message(queued)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
private def enqueue_network_message(message)
|
|
138
|
+
if Async::Task.current?
|
|
139
|
+
ensure_network_message_task
|
|
140
|
+
begin
|
|
141
|
+
@network_message_queue.enqueue(message)
|
|
142
|
+
rescue Async::Queue::ClosedError
|
|
143
|
+
# Connection is closing; ignore late network events.
|
|
144
|
+
end
|
|
145
|
+
else
|
|
146
|
+
handle_message(message)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
115
150
|
def self.from_session(session)
|
|
116
151
|
session.connection
|
|
117
152
|
end
|
|
@@ -310,6 +345,12 @@ class Puppeteer::Connection
|
|
|
310
345
|
@closed = true
|
|
311
346
|
@transport.on_message
|
|
312
347
|
@transport.on_close
|
|
348
|
+
@network_message_queue.close
|
|
349
|
+
begin
|
|
350
|
+
@network_message_task&.stop
|
|
351
|
+
rescue Async::Stop
|
|
352
|
+
# Task already stopping; ignore.
|
|
353
|
+
end
|
|
313
354
|
callbacks = @callbacks_mutex.synchronize do
|
|
314
355
|
@callbacks.values.tap { @callbacks.clear }
|
|
315
356
|
end
|
|
@@ -34,32 +34,49 @@ class Puppeteer::FrameManager
|
|
|
34
34
|
|
|
35
35
|
# Keeps track of frames that are in the process of being attached in #onFrameAttached.
|
|
36
36
|
@frames_pending_attachment = {}
|
|
37
|
+
@frame_tree_handled_promise = nil
|
|
38
|
+
@queued_frame_events = []
|
|
39
|
+
@frame_tree_mutex = Mutex.new
|
|
37
40
|
|
|
38
41
|
setup_listeners(@client)
|
|
39
42
|
end
|
|
40
43
|
|
|
41
44
|
private def setup_listeners(client)
|
|
42
45
|
client.on_event('Page.frameAttached') do |event|
|
|
43
|
-
|
|
46
|
+
with_frame_tree_handled do
|
|
47
|
+
handle_frame_attached(client, event['frameId'], event['parentFrameId'])
|
|
48
|
+
end
|
|
44
49
|
end
|
|
45
50
|
client.on_event('Page.frameNavigated') do |event|
|
|
46
|
-
|
|
47
|
-
|
|
51
|
+
with_frame_tree_handled do
|
|
52
|
+
@frame_naviigated_received << event['frame']['id']
|
|
53
|
+
handle_frame_navigated(event['frame'])
|
|
54
|
+
end
|
|
48
55
|
end
|
|
49
56
|
client.on_event('Page.navigatedWithinDocument') do |event|
|
|
50
|
-
|
|
57
|
+
with_frame_tree_handled do
|
|
58
|
+
handle_frame_navigated_within_document(event['frameId'], event['url'])
|
|
59
|
+
end
|
|
51
60
|
end
|
|
52
61
|
client.on_event('Page.frameDetached') do |event|
|
|
53
|
-
|
|
62
|
+
with_frame_tree_handled do
|
|
63
|
+
handle_frame_detached(event['frameId'], event['reason'])
|
|
64
|
+
end
|
|
54
65
|
end
|
|
55
66
|
client.on_event('Page.frameStartedLoading') do |event|
|
|
56
|
-
|
|
67
|
+
with_frame_tree_handled do
|
|
68
|
+
handle_frame_started_loading(event['frameId'])
|
|
69
|
+
end
|
|
57
70
|
end
|
|
58
71
|
client.on_event('Page.frameStoppedLoading') do |event|
|
|
59
|
-
|
|
72
|
+
with_frame_tree_handled do
|
|
73
|
+
handle_frame_stopped_loading(event['frameId'])
|
|
74
|
+
end
|
|
60
75
|
end
|
|
61
76
|
client.on_event('Runtime.executionContextCreated') do |event|
|
|
62
|
-
|
|
77
|
+
with_frame_tree_handled do
|
|
78
|
+
handle_execution_context_created(event['context'], client)
|
|
79
|
+
end
|
|
63
80
|
end
|
|
64
81
|
client.on_event('Runtime.executionContextDestroyed') do |event|
|
|
65
82
|
handle_execution_context_destroyed(event['executionContextId'], client)
|
|
@@ -68,7 +85,9 @@ class Puppeteer::FrameManager
|
|
|
68
85
|
handle_execution_contexts_cleared(client)
|
|
69
86
|
end
|
|
70
87
|
client.on_event('Page.lifecycleEvent') do |event|
|
|
71
|
-
|
|
88
|
+
with_frame_tree_handled do
|
|
89
|
+
handle_lifecycle_event(event)
|
|
90
|
+
end
|
|
72
91
|
end
|
|
73
92
|
end
|
|
74
93
|
|
|
@@ -78,6 +97,7 @@ class Puppeteer::FrameManager
|
|
|
78
97
|
@frames_pending_target_init[target_id] ||= Async::Promise.new
|
|
79
98
|
client = cdp_session || @client
|
|
80
99
|
|
|
100
|
+
prepare_frame_tree_handling
|
|
81
101
|
promises = [
|
|
82
102
|
client.async_send_message('Page.enable'),
|
|
83
103
|
client.async_send_message('Page.getFrameTree'),
|
|
@@ -85,6 +105,7 @@ class Puppeteer::FrameManager
|
|
|
85
105
|
results = Puppeteer::AsyncUtils.await_promise_all(*promises)
|
|
86
106
|
frame_tree = results[1]['frameTree']
|
|
87
107
|
handle_frame_tree(client, frame_tree)
|
|
108
|
+
finish_frame_tree_handling
|
|
88
109
|
Puppeteer::AsyncUtils.await_promise_all(
|
|
89
110
|
client.async_send_message('Page.setLifecycleEventsEnabled', enabled: true),
|
|
90
111
|
client.async_send_message('Runtime.enable'),
|
|
@@ -93,10 +114,14 @@ class Puppeteer::FrameManager
|
|
|
93
114
|
@network_manager.init unless cdp_session
|
|
94
115
|
rescue => err
|
|
95
116
|
# The target might have been closed before the initialization finished.
|
|
96
|
-
|
|
117
|
+
if err.message.include?('Target closed') || err.message.include?('Session closed')
|
|
118
|
+
finish_frame_tree_handling
|
|
119
|
+
return
|
|
120
|
+
end
|
|
97
121
|
|
|
98
122
|
raise
|
|
99
123
|
ensure
|
|
124
|
+
finish_frame_tree_handling if @frame_tree_handled_promise && !@frame_tree_handled_promise.resolved?
|
|
100
125
|
@frames_pending_target_init.delete(target_id)&.resolve(nil)
|
|
101
126
|
end
|
|
102
127
|
|
|
@@ -220,6 +245,46 @@ class Puppeteer::FrameManager
|
|
|
220
245
|
emit_event(FrameManagerEmittedEvents::LifecycleEvent, frame)
|
|
221
246
|
end
|
|
222
247
|
|
|
248
|
+
private def with_frame_tree_handled(&block)
|
|
249
|
+
promise = @frame_tree_handled_promise
|
|
250
|
+
if promise && !promise.resolved?
|
|
251
|
+
queued = false
|
|
252
|
+
@frame_tree_mutex.synchronize do
|
|
253
|
+
promise = @frame_tree_handled_promise
|
|
254
|
+
if promise && !promise.resolved?
|
|
255
|
+
@queued_frame_events << block
|
|
256
|
+
queued = true
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
return if queued
|
|
260
|
+
end
|
|
261
|
+
block.call
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
private def prepare_frame_tree_handling
|
|
265
|
+
queued = nil
|
|
266
|
+
@frame_tree_mutex.synchronize do
|
|
267
|
+
if @frame_tree_handled_promise && !@frame_tree_handled_promise.resolved?
|
|
268
|
+
@frame_tree_handled_promise.resolve(nil)
|
|
269
|
+
queued = @queued_frame_events
|
|
270
|
+
end
|
|
271
|
+
@queued_frame_events = []
|
|
272
|
+
@frame_tree_handled_promise = Async::Promise.new
|
|
273
|
+
end
|
|
274
|
+
queued&.each(&:call)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
private def finish_frame_tree_handling
|
|
278
|
+
queued = nil
|
|
279
|
+
@frame_tree_mutex.synchronize do
|
|
280
|
+
return unless @frame_tree_handled_promise
|
|
281
|
+
@frame_tree_handled_promise.resolve(nil) unless @frame_tree_handled_promise.resolved?
|
|
282
|
+
queued = @queued_frame_events
|
|
283
|
+
@queued_frame_events = []
|
|
284
|
+
end
|
|
285
|
+
queued&.each(&:call)
|
|
286
|
+
end
|
|
287
|
+
|
|
223
288
|
# @param frame_id [String]
|
|
224
289
|
def handle_frame_started_loading(frame_id)
|
|
225
290
|
frame = @frames[frame_id]
|
|
@@ -352,8 +417,11 @@ class Puppeteer::FrameManager
|
|
|
352
417
|
if is_main_frame
|
|
353
418
|
if frame
|
|
354
419
|
# Update frame id to retain frame identity on cross-process navigation.
|
|
355
|
-
|
|
356
|
-
|
|
420
|
+
if frame.id != frame_id
|
|
421
|
+
old_frame_id = frame.id
|
|
422
|
+
@frames.delete(old_frame_id)
|
|
423
|
+
frame.id = frame_id
|
|
424
|
+
end
|
|
357
425
|
else
|
|
358
426
|
# Initial main frame navigation.
|
|
359
427
|
frame = Puppeteer::Frame.new(self, nil, frame_id, @client)
|
data/lib/puppeteer/version.rb
CHANGED
data/sig/_supplementary.rbs
CHANGED
|
@@ -178,6 +178,9 @@ class Puppeteer::FrameManager
|
|
|
178
178
|
|
|
179
179
|
def setup_listeners: (Puppeteer::CDPSession client) -> void
|
|
180
180
|
def init: (String target_id, ?Puppeteer::CDPSession cdp_session) -> void
|
|
181
|
+
def with_frame_tree_handled: () { () -> void } -> void
|
|
182
|
+
def prepare_frame_tree_handling: () -> void
|
|
183
|
+
def finish_frame_tree_handling: () -> void
|
|
181
184
|
def attach_child_frame: (Puppeteer::Frame parent_frame, String parent_frame_id, String frame_id, Puppeteer::CDPSession? session) -> void
|
|
182
185
|
def reattach_frame: (Puppeteer::Frame frame, String frame_id, bool is_main_frame, Hash[String, untyped] frame_payload) -> void
|
|
183
186
|
def ensure_isolated_world: (Puppeteer::CDPSession session, String name) -> void
|
|
@@ -286,6 +289,9 @@ class Puppeteer::Connection
|
|
|
286
289
|
|
|
287
290
|
def sleep_before_handling_message: (Hash[String, untyped] message) -> void
|
|
288
291
|
def should_handle_synchronously?: (Hash[String, untyped] message) -> bool
|
|
292
|
+
def network_event_message?: (Hash[String, untyped] message) -> bool
|
|
293
|
+
def ensure_network_message_task: () -> void
|
|
294
|
+
def enqueue_network_message: (Hash[String, untyped] message) -> void
|
|
289
295
|
def request_debug_printer: () -> untyped
|
|
290
296
|
def response_debug_printer: () -> untyped
|
|
291
297
|
def handle_message: (Hash[String, untyped] message) -> void
|
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.50.0.
|
|
4
|
+
version: 0.50.0.alpha10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- YusukeIwaki
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-01-
|
|
11
|
+
date: 2026-01-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: async
|