puppeteer-ruby 0.51.0 → 0.52.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/docs/api_coverage.md +34 -5
- data/lib/puppeteer/browser.rb +75 -0
- data/lib/puppeteer/browser_connector.rb +2 -0
- data/lib/puppeteer/chrome_target_manager.rb +49 -2
- data/lib/puppeteer/debug_print.rb +9 -13
- data/lib/puppeteer/element_handle.rb +16 -0
- data/lib/puppeteer/events.rb +3 -0
- data/lib/puppeteer/execution_context.rb +37 -15
- data/lib/puppeteer/extension.rb +70 -0
- data/lib/puppeteer/frame.rb +8 -1
- data/lib/puppeteer/frame_manager.rb +62 -2
- data/lib/puppeteer/isolated_world.rb +22 -1
- data/lib/puppeteer/issue.rb +16 -0
- data/lib/puppeteer/js_coverage.rb +14 -1
- data/lib/puppeteer/launcher/browser_options.rb +6 -1
- data/lib/puppeteer/launcher/chrome.rb +16 -1
- data/lib/puppeteer/launcher/chrome_arg_options.rb +2 -1
- data/lib/puppeteer/network_manager.rb +16 -16
- data/lib/puppeteer/page.rb +36 -4
- data/lib/puppeteer/puppeteer.rb +15 -0
- data/lib/puppeteer/remote_object.rb +2 -1
- data/lib/puppeteer/target.rb +17 -0
- data/lib/puppeteer/version.rb +2 -2
- data/lib/puppeteer.rb +2 -0
- data/sig/_supplementary.rbs +5 -0
- data/sig/puppeteer/browser.rbs +29 -2
- data/sig/puppeteer/element_handle.rbs +5 -0
- data/sig/puppeteer/execution_context.rbs +4 -0
- data/sig/puppeteer/extension.rbs +37 -0
- data/sig/puppeteer/frame.rbs +5 -0
- data/sig/puppeteer/issue.rbs +13 -0
- data/sig/puppeteer/page.rbs +14 -0
- data/sig/puppeteer/puppeteer.rbs +7 -2
- data/sig/puppeteer/remote_object.rbs +2 -0
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dc3601ac8a64edb1a6054663944d5244eb0fcbc774b2d2f73529eef194031689
|
|
4
|
+
data.tar.gz: c364f8b73fc4dc6a591baca37e2e116d3147c5572f42dd026de77e36b0842851
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a4de65d9249823c8532150d9cbeace0670d5e0c35de747193bee4923edb751b3dcc7a46aa6ec5f58393e20fabe9933b12eaca0ac47ead1d91c5793fec8ca0e9b
|
|
7
|
+
data.tar.gz: 4d5d39fe7dac8d74a3f90478f3bae1bd7e9dcb14018518551ca4ca7d59f48ed1e9f9e7205c33956d82591b2985b4fecd5f1eb4f0af8efc03f4a1b3f22a0b2281
|
data/docs/api_coverage.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# API coverages
|
|
2
|
-
- Puppeteer version: v24.
|
|
2
|
+
- Puppeteer version: v24.42.0
|
|
3
3
|
- puppeteer-ruby version: 0.51.0
|
|
4
4
|
|
|
5
5
|
## Puppeteer
|
|
@@ -25,8 +25,9 @@
|
|
|
25
25
|
* ~~deleteCookie~~
|
|
26
26
|
* ~~deleteMatchingCookies~~
|
|
27
27
|
* disconnect
|
|
28
|
+
* extensions
|
|
28
29
|
* ~~getWindowBounds~~
|
|
29
|
-
*
|
|
30
|
+
* installExtension => `#install_extension`
|
|
30
31
|
* isConnected => `#connected?`
|
|
31
32
|
* newPage => `#new_page`
|
|
32
33
|
* pages
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
* ~~setWindowBounds~~
|
|
39
40
|
* target
|
|
40
41
|
* targets
|
|
41
|
-
*
|
|
42
|
+
* uninstallExtension => `#uninstall_extension`
|
|
42
43
|
* userAgent => `#user_agent`
|
|
43
44
|
* version
|
|
44
45
|
* waitForTarget => `#wait_for_target`
|
|
@@ -126,7 +127,7 @@
|
|
|
126
127
|
* $$eval => `#eval_on_selector_all`
|
|
127
128
|
* $eval => `#eval_on_selector`
|
|
128
129
|
* asLocator => `#as_locator`
|
|
129
|
-
*
|
|
130
|
+
* autofill
|
|
130
131
|
* ~~backendNodeId~~
|
|
131
132
|
* boundingBox => `#bounding_box`
|
|
132
133
|
* boxModel => `#box_model`
|
|
@@ -165,6 +166,12 @@
|
|
|
165
166
|
* ~~once~~
|
|
166
167
|
* ~~removeAllListeners~~
|
|
167
168
|
|
|
169
|
+
## Extension
|
|
170
|
+
|
|
171
|
+
* pages
|
|
172
|
+
* triggerAction => `#trigger_action`
|
|
173
|
+
* workers
|
|
174
|
+
|
|
168
175
|
## ~~ExtensionTransport~~
|
|
169
176
|
|
|
170
177
|
* ~~close~~
|
|
@@ -190,6 +197,7 @@
|
|
|
190
197
|
* content
|
|
191
198
|
* evaluate
|
|
192
199
|
* evaluateHandle => `#evaluate_handle`
|
|
200
|
+
* extensionRealms => `#extension_realms`
|
|
193
201
|
* focus
|
|
194
202
|
* frameElement => `#frame_element`
|
|
195
203
|
* goto
|
|
@@ -344,6 +352,7 @@
|
|
|
344
352
|
* evaluateHandle => `#evaluate_handle`
|
|
345
353
|
* evaluateOnNewDocument => `#evaluate_on_new_document`
|
|
346
354
|
* exposeFunction => `#expose_function`
|
|
355
|
+
* extensionRealms => `#extension_realms`
|
|
347
356
|
* focus
|
|
348
357
|
* frames
|
|
349
358
|
* ~~getDefaultNavigationTimeout~~
|
|
@@ -351,6 +360,7 @@
|
|
|
351
360
|
* goBack => `#go_back`
|
|
352
361
|
* goForward => `#go_forward`
|
|
353
362
|
* goto
|
|
363
|
+
* ~~hasDevTools~~
|
|
354
364
|
* hover
|
|
355
365
|
* isClosed => `#closed?`
|
|
356
366
|
* isDragInterceptionEnabled => `#drag_interception_enabled?`
|
|
@@ -387,6 +397,7 @@
|
|
|
387
397
|
* tap
|
|
388
398
|
* target
|
|
389
399
|
* title
|
|
400
|
+
* triggerExtensionAction => `#trigger_extension_action`
|
|
390
401
|
* type => `#type_text`
|
|
391
402
|
* url
|
|
392
403
|
* viewport
|
|
@@ -405,6 +416,13 @@
|
|
|
405
416
|
## ~~ProtocolError~~
|
|
406
417
|
|
|
407
418
|
|
|
419
|
+
## ~~Realm~~
|
|
420
|
+
|
|
421
|
+
* ~~evaluate~~
|
|
422
|
+
* ~~evaluateHandle~~
|
|
423
|
+
* ~~extension~~
|
|
424
|
+
* ~~waitForFunction~~
|
|
425
|
+
|
|
408
426
|
## ~~ScreenRecorder~~
|
|
409
427
|
|
|
410
428
|
* ~~stop~~
|
|
@@ -420,7 +438,7 @@
|
|
|
420
438
|
|
|
421
439
|
## Target
|
|
422
440
|
|
|
423
|
-
*
|
|
441
|
+
* asPage => `#as_page`
|
|
424
442
|
* browser
|
|
425
443
|
* browserContext => `#browser_context`
|
|
426
444
|
* createCDPSession => `#create_cdp_session`
|
|
@@ -451,6 +469,17 @@
|
|
|
451
469
|
## ~~UnsupportedOperation~~
|
|
452
470
|
|
|
453
471
|
|
|
472
|
+
## ~~WebMCP~~
|
|
473
|
+
|
|
474
|
+
* ~~tools~~
|
|
475
|
+
|
|
476
|
+
## ~~WebMCPTool~~
|
|
477
|
+
|
|
478
|
+
* ~~execute~~
|
|
479
|
+
|
|
480
|
+
## ~~WebMCPToolCall~~
|
|
481
|
+
|
|
482
|
+
|
|
454
483
|
## WebWorker
|
|
455
484
|
|
|
456
485
|
* close
|
data/lib/puppeteer/browser.rb
CHANGED
|
@@ -14,6 +14,8 @@ class Puppeteer::Browser
|
|
|
14
14
|
# @rbs ignore_https_errors: bool -- Ignore HTTPS errors
|
|
15
15
|
# @rbs default_viewport: Puppeteer::Viewport? -- Default viewport
|
|
16
16
|
# @rbs network_enabled: bool -- Whether network events are enabled
|
|
17
|
+
# @rbs issues_enabled: bool -- Whether issues events are enabled
|
|
18
|
+
# @rbs block_list: Array[String]? -- URL block list patterns
|
|
17
19
|
# @rbs process: Puppeteer::BrowserRunner::BrowserProcess? -- Browser process handle
|
|
18
20
|
# @rbs close_callback: Proc -- Close callback
|
|
19
21
|
# @rbs target_filter_callback: Proc? -- Target filter callback
|
|
@@ -25,6 +27,8 @@ class Puppeteer::Browser
|
|
|
25
27
|
ignore_https_errors:,
|
|
26
28
|
default_viewport:,
|
|
27
29
|
network_enabled: true,
|
|
30
|
+
issues_enabled: true,
|
|
31
|
+
block_list: nil,
|
|
28
32
|
process:,
|
|
29
33
|
close_callback:,
|
|
30
34
|
target_filter_callback:,
|
|
@@ -36,6 +40,8 @@ class Puppeteer::Browser
|
|
|
36
40
|
ignore_https_errors: ignore_https_errors,
|
|
37
41
|
default_viewport: default_viewport,
|
|
38
42
|
network_enabled: network_enabled,
|
|
43
|
+
issues_enabled: issues_enabled,
|
|
44
|
+
block_list: block_list,
|
|
39
45
|
process: process,
|
|
40
46
|
close_callback: close_callback,
|
|
41
47
|
target_filter_callback: target_filter_callback,
|
|
@@ -51,6 +57,8 @@ class Puppeteer::Browser
|
|
|
51
57
|
# @rbs ignore_https_errors: bool -- Ignore HTTPS errors
|
|
52
58
|
# @rbs default_viewport: Puppeteer::Viewport? -- Default viewport
|
|
53
59
|
# @rbs network_enabled: bool -- Whether network events are enabled
|
|
60
|
+
# @rbs issues_enabled: bool -- Whether issues events are enabled
|
|
61
|
+
# @rbs block_list: Array[String]? -- URL block list patterns
|
|
54
62
|
# @rbs process: Puppeteer::BrowserRunner::BrowserProcess? -- Browser process handle
|
|
55
63
|
# @rbs close_callback: Proc -- Close callback
|
|
56
64
|
# @rbs target_filter_callback: Proc? -- Target filter callback
|
|
@@ -62,6 +70,8 @@ class Puppeteer::Browser
|
|
|
62
70
|
ignore_https_errors:,
|
|
63
71
|
default_viewport:,
|
|
64
72
|
network_enabled: true,
|
|
73
|
+
issues_enabled: true,
|
|
74
|
+
block_list: nil,
|
|
65
75
|
process:,
|
|
66
76
|
close_callback:,
|
|
67
77
|
target_filter_callback:,
|
|
@@ -73,6 +83,8 @@ class Puppeteer::Browser
|
|
|
73
83
|
@ignore_https_errors = ignore_https_errors
|
|
74
84
|
@default_viewport = default_viewport
|
|
75
85
|
@network_enabled = network_enabled
|
|
86
|
+
@issues_enabled = issues_enabled
|
|
87
|
+
@block_list = block_list
|
|
76
88
|
@process = process
|
|
77
89
|
@connection = connection
|
|
78
90
|
@close_callback = close_callback
|
|
@@ -89,7 +101,9 @@ class Puppeteer::Browser
|
|
|
89
101
|
connection: connection,
|
|
90
102
|
target_factory: method(:create_target),
|
|
91
103
|
target_filter_callback: @target_filter_callback,
|
|
104
|
+
block_list: block_list,
|
|
92
105
|
)
|
|
106
|
+
@extensions = {}
|
|
93
107
|
end
|
|
94
108
|
|
|
95
109
|
private def default_target_filter_callback(target_info)
|
|
@@ -163,6 +177,10 @@ class Puppeteer::Browser
|
|
|
163
177
|
@target_manager
|
|
164
178
|
end
|
|
165
179
|
|
|
180
|
+
private def connection
|
|
181
|
+
@connection
|
|
182
|
+
end
|
|
183
|
+
|
|
166
184
|
# @rbs return: Puppeteer::BrowserContext -- New incognito browser context
|
|
167
185
|
def create_incognito_browser_context
|
|
168
186
|
result = @connection.send_message('Target.createBrowserContext')
|
|
@@ -376,6 +394,63 @@ class Puppeteer::Browser
|
|
|
376
394
|
Version.fetch(@connection).user_agent
|
|
377
395
|
end
|
|
378
396
|
|
|
397
|
+
# @rbs page_target_id: String -- Page target id
|
|
398
|
+
# @rbs return: String? -- DevTools target id for page
|
|
399
|
+
def _has_devtools_target(page_target_id)
|
|
400
|
+
result = @connection.send_message('Target.getDevToolsTarget', targetId: page_target_id)
|
|
401
|
+
result['targetId']
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
# @rbs path: String -- Extension path
|
|
405
|
+
# @rbs return: String -- Installed extension id
|
|
406
|
+
def install_extension(path)
|
|
407
|
+
result = @connection.send_message('Extensions.loadUnpacked', path: path)
|
|
408
|
+
extension_id = result['id']
|
|
409
|
+
@extensions.delete(extension_id)
|
|
410
|
+
extension_id
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
# @rbs extension_id: String -- Extension id
|
|
414
|
+
# @rbs return: void -- No return value
|
|
415
|
+
def uninstall_extension(extension_id)
|
|
416
|
+
@connection.send_message('Extensions.uninstall', id: extension_id)
|
|
417
|
+
@extensions.delete(extension_id)
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# @rbs return: Hash[String, Puppeteer::Extension] -- Installed extensions
|
|
421
|
+
def extensions
|
|
422
|
+
response = @connection.send_message('Extensions.getExtensions')
|
|
423
|
+
extension_map = {}
|
|
424
|
+
response.fetch('extensions', []).each do |payload|
|
|
425
|
+
extension_id = payload['id']
|
|
426
|
+
existing_extension = @extensions[extension_id]
|
|
427
|
+
extension_map[extension_id] =
|
|
428
|
+
if existing_extension
|
|
429
|
+
existing_extension
|
|
430
|
+
else
|
|
431
|
+
Puppeteer::Extension.new(
|
|
432
|
+
id: extension_id,
|
|
433
|
+
version: payload['version'],
|
|
434
|
+
name: payload['name'],
|
|
435
|
+
path: payload['path'],
|
|
436
|
+
enabled: payload['enabled'],
|
|
437
|
+
browser: self,
|
|
438
|
+
)
|
|
439
|
+
end
|
|
440
|
+
end
|
|
441
|
+
@extensions = extension_map
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
# @rbs return: bool -- Whether issue events are enabled
|
|
445
|
+
def issues_enabled?
|
|
446
|
+
@issues_enabled
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
# @rbs return: Array[String]? -- URL block list patterns
|
|
450
|
+
def block_list
|
|
451
|
+
@block_list
|
|
452
|
+
end
|
|
453
|
+
|
|
379
454
|
# @rbs return: void -- No return value
|
|
380
455
|
def close
|
|
381
456
|
@close_callback.call
|
|
@@ -28,6 +28,8 @@ class Puppeteer::BrowserConnector
|
|
|
28
28
|
ignore_https_errors: @browser_options.ignore_https_errors?,
|
|
29
29
|
default_viewport: @browser_options.default_viewport,
|
|
30
30
|
network_enabled: @browser_options.network_enabled,
|
|
31
|
+
issues_enabled: @browser_options.issues_enabled,
|
|
32
|
+
block_list: @browser_options.block_list,
|
|
31
33
|
process: nil,
|
|
32
34
|
close_callback: -> { connection.send_message('Browser.close') },
|
|
33
35
|
target_filter_callback: @browser_options.target_filter,
|
|
@@ -2,7 +2,7 @@ class Puppeteer::ChromeTargetManager
|
|
|
2
2
|
include Puppeteer::DebugPrint
|
|
3
3
|
include Puppeteer::EventCallbackable
|
|
4
4
|
|
|
5
|
-
def initialize(connection:, target_factory:, target_filter_callback:)
|
|
5
|
+
def initialize(connection:, target_factory:, target_filter_callback:, block_list: nil)
|
|
6
6
|
@discovered_targets_by_target_id = {}
|
|
7
7
|
@attached_targets_by_target_id = {}
|
|
8
8
|
@attached_targets_by_session_id = {}
|
|
@@ -13,8 +13,13 @@ class Puppeteer::ChromeTargetManager
|
|
|
13
13
|
@connection = connection
|
|
14
14
|
@target_filter_callback = target_filter_callback
|
|
15
15
|
@target_factory = target_factory
|
|
16
|
+
@block_list = block_list
|
|
17
|
+
if @block_list && !@block_list.is_a?(Array)
|
|
18
|
+
raise ArgumentError.new('block_list must be an Array of URL patterns')
|
|
19
|
+
end
|
|
16
20
|
@target_interceptors = {}
|
|
17
21
|
@initialize_promise = Async::Promise.new
|
|
22
|
+
@initial_attach_done = false
|
|
18
23
|
|
|
19
24
|
@connection_event_listeners = []
|
|
20
25
|
@connection_event_listeners << @connection.add_event_listener(
|
|
@@ -52,7 +57,7 @@ class Puppeteer::ChromeTargetManager
|
|
|
52
57
|
|
|
53
58
|
private def store_existing_targets_for_init
|
|
54
59
|
@discovered_targets_by_target_id.each do |target_id, target_info|
|
|
55
|
-
if @target_filter_callback.call(target_info) && target_info.type != 'browser'
|
|
60
|
+
if @target_filter_callback.call(target_info) && target_info.type != 'browser' && url_allowed?(target_info.url)
|
|
56
61
|
@target_ids_for_init << target_id
|
|
57
62
|
end
|
|
58
63
|
end
|
|
@@ -64,6 +69,7 @@ class Puppeteer::ChromeTargetManager
|
|
|
64
69
|
flatten: true,
|
|
65
70
|
autoAttach: true,
|
|
66
71
|
})
|
|
72
|
+
@initial_attach_done = true
|
|
67
73
|
finish_initialization_if_ready
|
|
68
74
|
@initialize_promise.wait
|
|
69
75
|
end
|
|
@@ -204,6 +210,12 @@ class Puppeteer::ChromeTargetManager
|
|
|
204
210
|
|
|
205
211
|
return unless @connection.auto_attached?(target_info.target_id)
|
|
206
212
|
|
|
213
|
+
if !@initial_attach_done && !url_allowed?(target_info.url)
|
|
214
|
+
finish_initialization_if_ready(target_info.target_id)
|
|
215
|
+
silent_detach.call
|
|
216
|
+
return
|
|
217
|
+
end
|
|
218
|
+
|
|
207
219
|
# Special case for service workers: being attached to service workers will
|
|
208
220
|
# prevent them from ever being destroyed. Therefore, we silently detach
|
|
209
221
|
# from service workers unless the connection was manually created via
|
|
@@ -270,6 +282,7 @@ class Puppeteer::ChromeTargetManager
|
|
|
270
282
|
flatten: true,
|
|
271
283
|
autoAttach: true,
|
|
272
284
|
}))
|
|
285
|
+
maybe_setup_network_conditions(session)
|
|
273
286
|
Puppeteer::AsyncUtils.await(session.async_send_message('Runtime.runIfWaitingForDebugger'))
|
|
274
287
|
rescue => err
|
|
275
288
|
Logger.new($stderr).warn(err)
|
|
@@ -292,4 +305,38 @@ class Puppeteer::ChromeTargetManager
|
|
|
292
305
|
@attached_targets_by_target_id.delete(target.target_id)
|
|
293
306
|
emit_event(TargetManagerEmittedEvents::TargetGone, target)
|
|
294
307
|
end
|
|
308
|
+
|
|
309
|
+
private def url_allowed?(url)
|
|
310
|
+
return true if @block_list.nil? || @block_list.empty?
|
|
311
|
+
return true if url.nil? || url.empty? || url == 'about:blank'
|
|
312
|
+
|
|
313
|
+
@block_list.none? do |pattern|
|
|
314
|
+
File.fnmatch?(pattern, url, File::FNM_EXTGLOB)
|
|
315
|
+
rescue ArgumentError
|
|
316
|
+
false
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
private def maybe_setup_network_conditions(session)
|
|
321
|
+
return if @block_list.nil? || @block_list.empty?
|
|
322
|
+
|
|
323
|
+
matched_network_conditions = @block_list.map do |pattern|
|
|
324
|
+
{
|
|
325
|
+
urlPattern: pattern,
|
|
326
|
+
latency: 0,
|
|
327
|
+
downloadThroughput: -1,
|
|
328
|
+
uploadThroughput: -1,
|
|
329
|
+
}
|
|
330
|
+
end
|
|
331
|
+
Puppeteer::AsyncUtils.await(session.async_send_message('Network.enable'))
|
|
332
|
+
Puppeteer::AsyncUtils.await(session.async_send_message('Network.emulateNetworkConditionsByRule', {
|
|
333
|
+
matchedNetworkConditions: matched_network_conditions,
|
|
334
|
+
offline: true,
|
|
335
|
+
}))
|
|
336
|
+
rescue => err
|
|
337
|
+
message = err.message.to_s.downcase
|
|
338
|
+
return if message.include?('target closed') || message.include?('session closed') || message.include?('not found')
|
|
339
|
+
|
|
340
|
+
raise
|
|
341
|
+
end
|
|
295
342
|
end
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
require 'logger'
|
|
2
2
|
|
|
3
3
|
module Puppeteer::DebugPrint
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
@__debug_logger ||= Logger.new($stdout)
|
|
7
|
-
@__debug_logger.debug(*args, **kwargs)
|
|
8
|
-
end
|
|
4
|
+
def debug_puts(*args, **kwargs)
|
|
5
|
+
return unless Puppeteer.env.debug?
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
@__debug_logger ||= Logger.new($stdout)
|
|
8
|
+
@__debug_logger.debug(*args, **kwargs)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def debug_print(*args)
|
|
12
|
+
return unless Puppeteer.env.debug?
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
end
|
|
14
|
+
print(*args)
|
|
19
15
|
end
|
|
20
16
|
end
|
|
@@ -540,6 +540,22 @@ class Puppeteer::ElementHandle < Puppeteer::JSHandle
|
|
|
540
540
|
end
|
|
541
541
|
end
|
|
542
542
|
|
|
543
|
+
# @rbs credit_card: Hash[Symbol | String, untyped]? -- Credit card autofill payload
|
|
544
|
+
# @rbs address: Hash[Symbol | String, untyped]? -- Address autofill payload
|
|
545
|
+
# @rbs return: void -- No return value
|
|
546
|
+
def autofill(credit_card: nil, address: nil)
|
|
547
|
+
node_info = @remote_object.node_info(@client)
|
|
548
|
+
field_id = node_info.dig('node', 'backendNodeId')
|
|
549
|
+
@client.send_message('Autofill.trigger', {
|
|
550
|
+
fieldId: field_id,
|
|
551
|
+
frameId: @frame.id,
|
|
552
|
+
card: credit_card,
|
|
553
|
+
address: address,
|
|
554
|
+
}.compact)
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
define_async_method :async_autofill
|
|
558
|
+
|
|
543
559
|
# @rbs block: Proc? -- Optional block for Object#tap usage
|
|
544
560
|
# @rbs return: Puppeteer::ElementHandle | nil -- Element handle or nil
|
|
545
561
|
def tap(&block)
|
data/lib/puppeteer/events.rb
CHANGED
|
@@ -135,6 +135,9 @@ module PageEmittedEvents ; end
|
|
|
135
135
|
# Emitted when a frame is navigated to a new URL. Will contain a {@link Frame}.
|
|
136
136
|
FrameNavigated: 'framenavigated',
|
|
137
137
|
|
|
138
|
+
# Emitted when a DevTools issue is reported.
|
|
139
|
+
Issue: 'issue',
|
|
140
|
+
|
|
138
141
|
# Emitted when the JavaScript
|
|
139
142
|
# {https://developer.mozilla.org/en-US/docs/Web/Events/load | load} event is dispatched.
|
|
140
143
|
Load: 'load',
|
|
@@ -52,13 +52,18 @@ class Puppeteer::ExecutionContext
|
|
|
52
52
|
# @param context_id [String]
|
|
53
53
|
# @return [Object|JSHandle]
|
|
54
54
|
def evaluate_with(client:, context_id:)
|
|
55
|
-
result =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
result =
|
|
56
|
+
begin
|
|
57
|
+
client.send_message('Runtime.evaluate',
|
|
58
|
+
expression: expression_with_source_url,
|
|
59
|
+
contextId: context_id,
|
|
60
|
+
returnByValue: @return_by_value,
|
|
61
|
+
awaitPromise: true,
|
|
62
|
+
userGesture: true,
|
|
63
|
+
)
|
|
64
|
+
rescue Puppeteer::Connection::ProtocolError => err
|
|
65
|
+
raise @execution_context.send(:rewrite_evaluation_error, err)
|
|
66
|
+
end
|
|
62
67
|
# }).catch(rewriteError);
|
|
63
68
|
|
|
64
69
|
exception_details = result['exceptionDetails']
|
|
@@ -110,14 +115,19 @@ class Puppeteer::ExecutionContext
|
|
|
110
115
|
# Original puppeteer implementation take it into consideration.
|
|
111
116
|
# But we don't support the syntax here.
|
|
112
117
|
|
|
113
|
-
result =
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
result =
|
|
119
|
+
begin
|
|
120
|
+
client.send_message('Runtime.callFunctionOn',
|
|
121
|
+
functionDeclaration: function_declaration,
|
|
122
|
+
executionContextId: context_id,
|
|
123
|
+
arguments: converted_args,
|
|
124
|
+
returnByValue: @return_by_value,
|
|
125
|
+
awaitPromise: true,
|
|
126
|
+
userGesture: true,
|
|
127
|
+
)
|
|
128
|
+
rescue Puppeteer::Connection::ProtocolError => err
|
|
129
|
+
raise @execution_context.send(:rewrite_evaluation_error, err)
|
|
130
|
+
end # .catch(rewriteError);
|
|
121
131
|
|
|
122
132
|
exception_details = result['exceptionDetails']
|
|
123
133
|
if exception_details
|
|
@@ -337,6 +347,18 @@ class Puppeteer::ExecutionContext
|
|
|
337
347
|
)
|
|
338
348
|
end
|
|
339
349
|
|
|
350
|
+
# @param error [Puppeteer::Connection::ProtocolError]
|
|
351
|
+
# @return [StandardError]
|
|
352
|
+
private def rewrite_evaluation_error(error)
|
|
353
|
+
message = error.message
|
|
354
|
+
if message.end_with?('Cannot find context with specified id') ||
|
|
355
|
+
message.end_with?('Inspected target navigated or closed')
|
|
356
|
+
return Puppeteer::Error.new('Execution context was destroyed, most likely because of a navigation.')
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
error
|
|
360
|
+
end
|
|
361
|
+
|
|
340
362
|
# @rbs page_function: String -- JavaScript code to check
|
|
341
363
|
# @rbs return: bool -- Whether the code represents a function
|
|
342
364
|
private def function_string?(page_function)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
2
|
+
|
|
3
|
+
class Puppeteer::Extension
|
|
4
|
+
# @rbs id: String -- Extension id
|
|
5
|
+
# @rbs version: String -- Extension version
|
|
6
|
+
# @rbs name: String -- Extension name
|
|
7
|
+
# @rbs path: String -- Extension path
|
|
8
|
+
# @rbs enabled: bool -- Whether extension is enabled
|
|
9
|
+
# @rbs browser: Puppeteer::Browser -- Browser instance
|
|
10
|
+
# @rbs return: void -- No return value
|
|
11
|
+
def initialize(id:, version:, name:, path:, enabled:, browser:)
|
|
12
|
+
@id = id
|
|
13
|
+
@version = version
|
|
14
|
+
@name = name
|
|
15
|
+
@path = path
|
|
16
|
+
@enabled = enabled
|
|
17
|
+
@browser = browser
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @rbs return: String -- Extension id
|
|
21
|
+
attr_reader :id
|
|
22
|
+
|
|
23
|
+
# @rbs return: String -- Extension version
|
|
24
|
+
attr_reader :version
|
|
25
|
+
|
|
26
|
+
# @rbs return: String -- Extension name
|
|
27
|
+
attr_reader :name
|
|
28
|
+
|
|
29
|
+
# @rbs return: String -- Extension path
|
|
30
|
+
attr_reader :path
|
|
31
|
+
|
|
32
|
+
# @rbs return: bool -- Whether extension is enabled
|
|
33
|
+
attr_reader :enabled
|
|
34
|
+
|
|
35
|
+
# @rbs return: Array[Puppeteer::CdpWebWorker] -- Extension workers
|
|
36
|
+
def workers
|
|
37
|
+
extension_prefix = "chrome-extension://#{@id}"
|
|
38
|
+
extension_targets = @browser.targets.select do |target|
|
|
39
|
+
target.type == 'service_worker' && target.url.start_with?(extension_prefix)
|
|
40
|
+
end
|
|
41
|
+
extension_targets.filter_map do |target|
|
|
42
|
+
target.worker
|
|
43
|
+
rescue
|
|
44
|
+
nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @rbs return: Array[Puppeteer::Page] -- Extension pages
|
|
49
|
+
def pages
|
|
50
|
+
extension_prefix = "chrome-extension://#{@id}"
|
|
51
|
+
extension_targets = @browser.targets.select do |target|
|
|
52
|
+
target_url = target.url
|
|
53
|
+
['page', 'background_page'].include?(target.type) && target_url.start_with?(extension_prefix)
|
|
54
|
+
end
|
|
55
|
+
extension_targets.filter_map do |target|
|
|
56
|
+
target.as_page
|
|
57
|
+
rescue
|
|
58
|
+
nil
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @rbs page: Puppeteer::Page -- Target page
|
|
63
|
+
# @rbs return: void -- No return value
|
|
64
|
+
def trigger_action(page)
|
|
65
|
+
page.browser.send(:connection).send_message('Extensions.triggerAction', {
|
|
66
|
+
id: @id,
|
|
67
|
+
targetId: page._tab_id,
|
|
68
|
+
})
|
|
69
|
+
end
|
|
70
|
+
end
|
data/lib/puppeteer/frame.rb
CHANGED
|
@@ -19,6 +19,7 @@ class Puppeteer::Frame
|
|
|
19
19
|
@url = 'about:blank'
|
|
20
20
|
@lifecycle_events = Set.new
|
|
21
21
|
@child_frames = Set.new
|
|
22
|
+
@extension_worlds = {}
|
|
22
23
|
if parent_frame
|
|
23
24
|
parent_frame._child_frames << self
|
|
24
25
|
end
|
|
@@ -71,7 +72,7 @@ class Puppeteer::Frame
|
|
|
71
72
|
@client != @frame_manager.client
|
|
72
73
|
end
|
|
73
74
|
|
|
74
|
-
attr_accessor :frame_manager, :id, :loader_id, :lifecycle_events, :main_world, :puppeteer_world
|
|
75
|
+
attr_accessor :frame_manager, :id, :loader_id, :lifecycle_events, :main_world, :puppeteer_world, :extension_worlds
|
|
75
76
|
attr_reader :client
|
|
76
77
|
|
|
77
78
|
# @rbs other: Object -- Other object to compare
|
|
@@ -229,6 +230,11 @@ class Puppeteer::Frame
|
|
|
229
230
|
@url
|
|
230
231
|
end
|
|
231
232
|
|
|
233
|
+
# @rbs return: Array[untyped] -- Extension execution realms for this frame
|
|
234
|
+
def extension_realms
|
|
235
|
+
@extension_worlds.values
|
|
236
|
+
end
|
|
237
|
+
|
|
232
238
|
# @rbs return: Puppeteer::Frame? -- Parent frame
|
|
233
239
|
def parent_frame
|
|
234
240
|
@parent_frame
|
|
@@ -425,6 +431,7 @@ class Puppeteer::Frame
|
|
|
425
431
|
@detached = true
|
|
426
432
|
@main_world.detach
|
|
427
433
|
@puppeteer_world.detach
|
|
434
|
+
@extension_worlds.each_value(&:detach)
|
|
428
435
|
if @parent_frame
|
|
429
436
|
@parent_frame._child_frames.delete(self)
|
|
430
437
|
end
|