puppeteer-ruby 0.42.0 → 0.43.0
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 +5 -1
- data/docs/api_coverage.md +2 -2
- data/lib/puppeteer/browser.rb +109 -75
- data/lib/puppeteer/browser_connector.rb +67 -0
- data/lib/puppeteer/chrome_target_manager.rb +256 -0
- data/lib/puppeteer/connection.rb +16 -0
- data/lib/puppeteer/events.rb +9 -0
- data/lib/puppeteer/firefox_target_manager.rb +158 -0
- data/lib/puppeteer/frame_manager.rb +69 -38
- data/lib/puppeteer/launcher/chrome.rb +3 -56
- data/lib/puppeteer/launcher/firefox.rb +1 -55
- data/lib/puppeteer/lifecycle_watcher.rb +2 -1
- data/lib/puppeteer/page.rb +38 -29
- data/lib/puppeteer/puppeteer.rb +1 -1
- data/lib/puppeteer/target.rb +14 -1
- data/lib/puppeteer/version.rb +1 -1
- data/lib/puppeteer.rb +3 -0
- data/puppeteer-ruby.gemspec +1 -1
- metadata +7 -4
@@ -81,6 +81,7 @@ module Puppeteer::Launcher
|
|
81
81
|
)
|
82
82
|
|
83
83
|
Puppeteer::Browser.create(
|
84
|
+
product: product,
|
84
85
|
connection: connection,
|
85
86
|
context_ids: [],
|
86
87
|
ignore_https_errors: @browser_options.ignore_https_errors?,
|
@@ -126,7 +127,8 @@ module Puppeteer::Launcher
|
|
126
127
|
'--disable-extensions',
|
127
128
|
# TODO: remove AvoidUnnecessaryBeforeUnloadCheckSync below
|
128
129
|
# once crbug.com/1324138 is fixed and released.
|
129
|
-
|
130
|
+
# AcceptCHFrame disabled because of crbug.com/1348106.
|
131
|
+
'--disable-features=Translate,BackForwardCache,AcceptCHFrame,AvoidUnnecessaryBeforeUnloadCheckSync',
|
130
132
|
'--disable-hang-monitor',
|
131
133
|
'--disable-ipc-flooding-protection',
|
132
134
|
'--disable-popup-blocking',
|
@@ -181,61 +183,6 @@ module Puppeteer::Launcher
|
|
181
183
|
DefaultArgs.new(ChromeArgOptions.new(options || {}))
|
182
184
|
end
|
183
185
|
|
184
|
-
# @return [Puppeteer::Browser]
|
185
|
-
def connect(options = {})
|
186
|
-
@browser_options = BrowserOptions.new(options)
|
187
|
-
browser_ws_endpoint = options[:browser_ws_endpoint]
|
188
|
-
browser_url = options[:browser_url]
|
189
|
-
transport = options[:transport]
|
190
|
-
|
191
|
-
connection =
|
192
|
-
if browser_ws_endpoint && browser_url.nil? && transport.nil?
|
193
|
-
connect_with_browser_ws_endpoint(browser_ws_endpoint)
|
194
|
-
elsif browser_ws_endpoint.nil? && browser_url && transport.nil?
|
195
|
-
connect_with_browser_url(browser_url)
|
196
|
-
elsif browser_ws_endpoint.nil? && browser_url.nil? && transport
|
197
|
-
connect_with_transport(transport)
|
198
|
-
else
|
199
|
-
raise ArgumentError.new("Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect")
|
200
|
-
end
|
201
|
-
|
202
|
-
result = connection.send_message('Target.getBrowserContexts')
|
203
|
-
browser_context_ids = result['browserContextIds']
|
204
|
-
|
205
|
-
Puppeteer::Browser.create(
|
206
|
-
connection: connection,
|
207
|
-
context_ids: browser_context_ids,
|
208
|
-
ignore_https_errors: @browser_options.ignore_https_errors?,
|
209
|
-
default_viewport: @browser_options.default_viewport,
|
210
|
-
process: nil,
|
211
|
-
close_callback: -> { connection.send_message('Browser.close') },
|
212
|
-
target_filter_callback: @browser_options.target_filter,
|
213
|
-
is_page_target_callback: @browser_options.is_page_target,
|
214
|
-
)
|
215
|
-
end
|
216
|
-
|
217
|
-
# @return [Puppeteer::Connection]
|
218
|
-
private def connect_with_browser_ws_endpoint(browser_ws_endpoint)
|
219
|
-
transport = Puppeteer::WebSocketTransport.create(browser_ws_endpoint)
|
220
|
-
Puppeteer::Connection.new(browser_ws_endpoint, transport, @browser_options.slow_mo)
|
221
|
-
end
|
222
|
-
|
223
|
-
# @return [Puppeteer::Connection]
|
224
|
-
private def connect_with_browser_url(browser_url)
|
225
|
-
require 'net/http'
|
226
|
-
uri = URI(browser_url)
|
227
|
-
uri.path = '/json/version'
|
228
|
-
response_body = Net::HTTP.get(uri)
|
229
|
-
json = JSON.parse(response_body)
|
230
|
-
connection_url = json['webSocketDebuggerUrl']
|
231
|
-
connect_with_browser_ws_endpoint(connection_url)
|
232
|
-
end
|
233
|
-
|
234
|
-
# @return [Puppeteer::Connection]
|
235
|
-
private def connect_with_transport(transport)
|
236
|
-
Puppeteer::Connection.new('', transport, @browser_options.slow_mo)
|
237
|
-
end
|
238
|
-
|
239
186
|
# @return {string}
|
240
187
|
def executable_path(channel: nil)
|
241
188
|
if channel
|
@@ -79,6 +79,7 @@ module Puppeteer::Launcher
|
|
79
79
|
)
|
80
80
|
|
81
81
|
Puppeteer::Browser.create(
|
82
|
+
product: product,
|
82
83
|
connection: connection,
|
83
84
|
context_ids: [],
|
84
85
|
ignore_https_errors: @browser_options.ignore_https_errors?,
|
@@ -106,61 +107,6 @@ module Puppeteer::Launcher
|
|
106
107
|
browser
|
107
108
|
end
|
108
109
|
|
109
|
-
# @return [Puppeteer::Browser]
|
110
|
-
def connect(options = {})
|
111
|
-
@browser_options = BrowserOptions.new(options)
|
112
|
-
browser_ws_endpoint = options[:browser_ws_endpoint]
|
113
|
-
browser_url = options[:browser_url]
|
114
|
-
transport = options[:transport]
|
115
|
-
|
116
|
-
connection =
|
117
|
-
if browser_ws_endpoint && browser_url.nil? && transport.nil?
|
118
|
-
connect_with_browser_ws_endpoint(browser_ws_endpoint)
|
119
|
-
elsif browser_ws_endpoint.nil? && browser_url && transport.nil?
|
120
|
-
connect_with_browser_url(browser_url)
|
121
|
-
elsif browser_ws_endpoint.nil? && browser_url.nil? && transport
|
122
|
-
connect_with_transport(transport)
|
123
|
-
else
|
124
|
-
raise ArgumentError.new("Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect")
|
125
|
-
end
|
126
|
-
|
127
|
-
result = connection.send_message('Target.getBrowserContexts')
|
128
|
-
browser_context_ids = result['browserContextIds']
|
129
|
-
|
130
|
-
Puppeteer::Browser.create(
|
131
|
-
connection: connection,
|
132
|
-
context_ids: browser_context_ids,
|
133
|
-
ignore_https_errors: @browser_options.ignore_https_errors?,
|
134
|
-
default_viewport: @browser_options.default_viewport,
|
135
|
-
process: nil,
|
136
|
-
close_callback: -> { connection.send_message('Browser.close') },
|
137
|
-
target_filter_callback: nil,
|
138
|
-
is_page_target_callback: nil,
|
139
|
-
)
|
140
|
-
end
|
141
|
-
|
142
|
-
# @return [Puppeteer::Connection]
|
143
|
-
private def connect_with_browser_ws_endpoint(browser_ws_endpoint)
|
144
|
-
transport = Puppeteer::WebSocketTransport.create(browser_ws_endpoint)
|
145
|
-
Puppeteer::Connection.new(browser_ws_endpoint, transport, @browser_options.slow_mo)
|
146
|
-
end
|
147
|
-
|
148
|
-
# @return [Puppeteer::Connection]
|
149
|
-
private def connect_with_browser_url(browser_url)
|
150
|
-
require 'net/http'
|
151
|
-
uri = URI(browser_url)
|
152
|
-
uri.path = '/json/version'
|
153
|
-
response_body = Net::HTTP.get(uri)
|
154
|
-
json = JSON.parse(response_body)
|
155
|
-
connection_url = json['webSocketDebuggerUrl']
|
156
|
-
connect_with_browser_ws_endpoint(connection_url)
|
157
|
-
end
|
158
|
-
|
159
|
-
# @return [Puppeteer::Connection]
|
160
|
-
private def connect_with_transport(transport)
|
161
|
-
Puppeteer::Connection.new('', transport, @browser_options.slow_mo)
|
162
|
-
end
|
163
|
-
|
164
110
|
# @return {string}
|
165
111
|
def executable_path(channel: nil)
|
166
112
|
if channel
|
@@ -65,6 +65,7 @@ class Puppeteer::LifecycleWatcher
|
|
65
65
|
@expected_lifecycle = ExpectedLifecycle.new(wait_until)
|
66
66
|
@frame_manager = frame_manager
|
67
67
|
@frame = frame
|
68
|
+
@initial_loader_id = frame.loader_id
|
68
69
|
@timeout = timeout
|
69
70
|
|
70
71
|
@listener_ids = {}
|
@@ -162,7 +163,7 @@ class Puppeteer::LifecycleWatcher
|
|
162
163
|
if @has_same_document_navigation && @same_document_navigation_promise.pending?
|
163
164
|
@same_document_navigation_promise.fulfill(true)
|
164
165
|
end
|
165
|
-
if (@swapped || @
|
166
|
+
if (@swapped || @frame.loader_id != @initial_loader_id) && @new_document_navigation_promise.pending?
|
166
167
|
@new_document_navigation_promise.fulfill(true)
|
167
168
|
end
|
168
169
|
end
|
data/lib/puppeteer/page.rb
CHANGED
@@ -50,33 +50,11 @@ class Puppeteer::Page
|
|
50
50
|
@workers = {}
|
51
51
|
@user_drag_interception_enabled = false
|
52
52
|
|
53
|
-
@
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
# We detach from all other types out of an abundance of caution.
|
59
|
-
# See https://source.chromium.org/chromium/chromium/src/+/main:content/browser/devtools/devtools_agent_host_impl.cc?ss=chromium&q=f:devtools%20-f:out%20%22::kTypePage%5B%5D%22
|
60
|
-
# for the complete list of available types.
|
61
|
-
@client.async_send_message('Target.detachFromTarget', sessionId: event['sessionId'])
|
62
|
-
next
|
63
|
-
end
|
64
|
-
|
65
|
-
if event['targetInfo']['type'] == 'worker'
|
66
|
-
session = Puppeteer::Connection.from_session(@client).session(event['sessionId']) # rubocop:disable Lint/UselessAssignment
|
67
|
-
# const worker = new Worker(session, event.targetInfo.url, this._addConsoleMessage.bind(this), this._handleException.bind(this));
|
68
|
-
# this._workers.set(event.sessionId, worker);
|
69
|
-
# this.emit(PageEmittedEvents::WorkerCreated, worker);
|
70
|
-
end
|
71
|
-
end
|
72
|
-
@client.add_event_listener('Target.detachedFromTarget') do |event|
|
73
|
-
session_id = event['sessionId']
|
74
|
-
worker = @workers[session_id]
|
75
|
-
next unless worker
|
76
|
-
|
77
|
-
emit_event(PageEmittedEvents::WorkerDestroyed, worker)
|
78
|
-
@workers.delete(session_id)
|
79
|
-
end
|
53
|
+
@target.target_manager.add_target_interceptor(@client, method(:handle_attached_to_target))
|
54
|
+
@target_gone_listener_id = @target.target_manager.add_event_listener(
|
55
|
+
TargetManagerEmittedEvents::TargetGone,
|
56
|
+
&method(:handle_detached_from_target)
|
57
|
+
)
|
80
58
|
|
81
59
|
@frame_manager.on_event(FrameManagerEmittedEvents::FrameAttached) do |event|
|
82
60
|
emit_event(PageEmittedEvents::FrameAttached, event)
|
@@ -135,15 +113,46 @@ class Puppeteer::Page
|
|
135
113
|
handle_file_chooser(event)
|
136
114
|
end
|
137
115
|
@target.is_closed_promise.then do
|
116
|
+
@target.target_manager.remove_target_interceptor(@client, method(:handle_attached_to_target))
|
117
|
+
@target.target_manager.remove_event_listener(@target_gone_listener_id)
|
118
|
+
|
138
119
|
emit_event(PageEmittedEvents::Close)
|
139
120
|
@closed = true
|
140
121
|
end
|
141
122
|
end
|
142
123
|
|
124
|
+
private def handle_detached_from_target(target)
|
125
|
+
session_id = target.session&.id
|
126
|
+
@frame_manager.handle_detached_from_target(target)
|
127
|
+
return unless session_id
|
128
|
+
worker = @workers.delete(session_id)
|
129
|
+
return unless worker
|
130
|
+
emit_event(PageEmittedEvents::WorkerDestroyed, worker)
|
131
|
+
end
|
132
|
+
|
133
|
+
private def handle_attached_to_target(target, _)
|
134
|
+
@frame_manager.handle_attached_to_target(target)
|
135
|
+
if target.raw_type == 'worker'
|
136
|
+
# const session = createdTarget._session();
|
137
|
+
# assert(session);
|
138
|
+
# const worker = new WebWorker(
|
139
|
+
# session,
|
140
|
+
# createdTarget.url(),
|
141
|
+
# this.#addConsoleMessage.bind(this),
|
142
|
+
# this.#handleException.bind(this)
|
143
|
+
# );
|
144
|
+
# this.#workers.set(session.id(), worker);
|
145
|
+
# this.emit(PageEmittedEvents.WorkerCreated, worker);
|
146
|
+
end
|
147
|
+
|
148
|
+
if target.session
|
149
|
+
@target.target_manager.add_target_interceptor(target.session, method(:handle_attached_to_target))
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
143
153
|
def init
|
144
154
|
await_all(
|
145
|
-
@frame_manager.async_init,
|
146
|
-
@client.async_send_message('Target.setAutoAttach', autoAttach: true, waitForDebuggerOnStart: false, flatten: true),
|
155
|
+
@frame_manager.async_init(@target.target_id),
|
147
156
|
@client.async_send_message('Performance.enable'),
|
148
157
|
@client.async_send_message('Log.enable'),
|
149
158
|
)
|
data/lib/puppeteer/puppeteer.rb
CHANGED
@@ -110,7 +110,7 @@ class Puppeteer::Puppeteer
|
|
110
110
|
default_viewport: default_viewport,
|
111
111
|
slow_mo: slow_mo,
|
112
112
|
}.compact
|
113
|
-
browser =
|
113
|
+
browser = Puppeteer::BrowserConnector.new(options).connect_to_browser
|
114
114
|
if block_given?
|
115
115
|
begin
|
116
116
|
yield(browser)
|
data/lib/puppeteer/target.rb
CHANGED
@@ -19,11 +19,15 @@ class Puppeteer::Target
|
|
19
19
|
# @param {boolean} ignoreHTTPSErrors
|
20
20
|
# @param {?Puppeteer.Viewport} defaultViewport
|
21
21
|
def initialize(target_info:,
|
22
|
+
session:,
|
22
23
|
browser_context:,
|
24
|
+
target_manager:,
|
23
25
|
session_factory:,
|
24
26
|
ignore_https_errors:,
|
25
27
|
default_viewport:,
|
26
28
|
is_page_target_callback:)
|
29
|
+
@session = session
|
30
|
+
@target_manager = target_manager
|
27
31
|
@target_info = target_info
|
28
32
|
@browser_context = browser_context
|
29
33
|
@target_id = target_info.target_id
|
@@ -83,13 +87,22 @@ class Puppeteer::Target
|
|
83
87
|
@is_initialized
|
84
88
|
end
|
85
89
|
|
90
|
+
# @return [CDPSession|nil]
|
91
|
+
def session
|
92
|
+
@session
|
93
|
+
end
|
94
|
+
|
86
95
|
def create_cdp_session
|
87
96
|
@session_factory.call
|
88
97
|
end
|
89
98
|
|
99
|
+
def target_manager
|
100
|
+
@target_manager
|
101
|
+
end
|
102
|
+
|
90
103
|
def page
|
91
104
|
if @is_page_target_callback.call(@target_info) && @page.nil?
|
92
|
-
client = @session_factory.call
|
105
|
+
client = @session || @session_factory.call
|
93
106
|
@page = Puppeteer::Page.create(client, self, @ignore_https_errors, @default_viewport)
|
94
107
|
end
|
95
108
|
@page
|
data/lib/puppeteer/version.rb
CHANGED
data/lib/puppeteer.rb
CHANGED
@@ -22,7 +22,9 @@ require 'puppeteer/aria_query_handler'
|
|
22
22
|
require 'puppeteer/browser'
|
23
23
|
require 'puppeteer/browser_context'
|
24
24
|
require 'puppeteer/browser_runner'
|
25
|
+
require 'puppeteer/browser_connector'
|
25
26
|
require 'puppeteer/cdp_session'
|
27
|
+
require 'puppeteer/chrome_target_manager'
|
26
28
|
require 'puppeteer/connection'
|
27
29
|
require 'puppeteer/console_message'
|
28
30
|
require 'puppeteer/coverage'
|
@@ -36,6 +38,7 @@ require 'puppeteer/exception_details'
|
|
36
38
|
require 'puppeteer/executable_path_finder'
|
37
39
|
require 'puppeteer/execution_context'
|
38
40
|
require 'puppeteer/file_chooser'
|
41
|
+
require 'puppeteer/firefox_target_manager'
|
39
42
|
require 'puppeteer/frame'
|
40
43
|
require 'puppeteer/frame_manager'
|
41
44
|
require 'puppeteer/http_request'
|
data/puppeteer-ruby.gemspec
CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.add_development_dependency 'rollbar'
|
33
33
|
spec.add_development_dependency 'rspec', '~> 3.11.0'
|
34
34
|
spec.add_development_dependency 'rspec_junit_formatter' # for CircleCI.
|
35
|
-
spec.add_development_dependency 'rubocop', '~> 1.
|
35
|
+
spec.add_development_dependency 'rubocop', '~> 1.36.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.
|
4
|
+
version: 0.43.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- YusukeIwaki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -170,14 +170,14 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - "~>"
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: 1.
|
173
|
+
version: 1.36.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.
|
180
|
+
version: 1.36.0
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: rubocop-rspec
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -255,10 +255,12 @@ files:
|
|
255
255
|
- lib/puppeteer.rb
|
256
256
|
- lib/puppeteer/aria_query_handler.rb
|
257
257
|
- lib/puppeteer/browser.rb
|
258
|
+
- lib/puppeteer/browser_connector.rb
|
258
259
|
- lib/puppeteer/browser_context.rb
|
259
260
|
- lib/puppeteer/browser_fetcher.rb
|
260
261
|
- lib/puppeteer/browser_runner.rb
|
261
262
|
- lib/puppeteer/cdp_session.rb
|
263
|
+
- lib/puppeteer/chrome_target_manager.rb
|
262
264
|
- lib/puppeteer/concurrent_ruby_utils.rb
|
263
265
|
- lib/puppeteer/connection.rb
|
264
266
|
- lib/puppeteer/console_message.rb
|
@@ -285,6 +287,7 @@ files:
|
|
285
287
|
- lib/puppeteer/executable_path_finder.rb
|
286
288
|
- lib/puppeteer/execution_context.rb
|
287
289
|
- lib/puppeteer/file_chooser.rb
|
290
|
+
- lib/puppeteer/firefox_target_manager.rb
|
288
291
|
- lib/puppeteer/frame.rb
|
289
292
|
- lib/puppeteer/frame_manager.rb
|
290
293
|
- lib/puppeteer/geolocation.rb
|