puppeteer-ruby 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +71 -0
- data/.github/stale.yml +16 -0
- data/.gitignore +19 -0
- data/.rspec +3 -0
- data/.rubocop.yml +302 -0
- data/.travis.yml +7 -0
- data/Dockerfile +6 -0
- data/Gemfile +6 -0
- data/README.md +54 -0
- data/Rakefile +1 -0
- data/bin/console +11 -0
- data/bin/setup +8 -0
- data/docker-compose.yml +15 -0
- data/docs/Puppeteer.html +2020 -0
- data/docs/Puppeteer/AsyncAwaitBehavior.html +105 -0
- data/docs/Puppeteer/Browser.html +2148 -0
- data/docs/Puppeteer/BrowserContext.html +809 -0
- data/docs/Puppeteer/BrowserFetcher.html +214 -0
- data/docs/Puppeteer/BrowserRunner.html +914 -0
- data/docs/Puppeteer/BrowserRunner/BrowserProcess.html +477 -0
- data/docs/Puppeteer/CDPSession.html +813 -0
- data/docs/Puppeteer/CDPSession/Error.html +124 -0
- data/docs/Puppeteer/ConcurrentRubyUtils.html +430 -0
- data/docs/Puppeteer/Connection.html +960 -0
- data/docs/Puppeteer/Connection/MessageCallback.html +434 -0
- data/docs/Puppeteer/Connection/ProtocolError.html +216 -0
- data/docs/Puppeteer/Connection/RequestDebugPrinter.html +217 -0
- data/docs/Puppeteer/Connection/ResponseDebugPrinter.html +244 -0
- data/docs/Puppeteer/ConsoleMessage.html +565 -0
- data/docs/Puppeteer/ConsoleMessage/Location.html +433 -0
- data/docs/Puppeteer/DOMWorld.html +2219 -0
- data/docs/Puppeteer/DOMWorld/DetachedError.html +124 -0
- data/docs/Puppeteer/DOMWorld/DocumentEvaluationError.html +124 -0
- data/docs/Puppeteer/DebugPrint.html +233 -0
- data/docs/Puppeteer/Device.html +470 -0
- data/docs/Puppeteer/Devices.html +139 -0
- data/docs/Puppeteer/ElementHandle.html +2542 -0
- data/docs/Puppeteer/ElementHandle/ElementNotFoundError.html +206 -0
- data/docs/Puppeteer/ElementHandle/ElementNotVisibleError.html +206 -0
- data/docs/Puppeteer/ElementHandle/Point.html +492 -0
- data/docs/Puppeteer/ElementHandle/ScrollIntoViewError.html +124 -0
- data/docs/Puppeteer/EmulationManager.html +454 -0
- data/docs/Puppeteer/EventCallbackable.html +433 -0
- data/docs/Puppeteer/EventCallbackable/EventListeners.html +435 -0
- data/docs/Puppeteer/ExecutionContext.html +998 -0
- data/docs/Puppeteer/ExecutionContext/EvaluationError.html +124 -0
- data/docs/Puppeteer/ExecutionContext/JavaScriptExpression.html +357 -0
- data/docs/Puppeteer/ExecutionContext/JavaScriptFunction.html +389 -0
- data/docs/Puppeteer/FileChooser.html +455 -0
- data/docs/Puppeteer/Frame.html +3677 -0
- data/docs/Puppeteer/FrameManager.html +2410 -0
- data/docs/Puppeteer/FrameManager/NavigationError.html +124 -0
- data/docs/Puppeteer/IfPresent.html +222 -0
- data/docs/Puppeteer/JSHandle.html +1352 -0
- data/docs/Puppeteer/Keyboard.html +1557 -0
- data/docs/Puppeteer/Keyboard/KeyDefinition.html +831 -0
- data/docs/Puppeteer/Keyboard/KeyDescription.html +603 -0
- data/docs/Puppeteer/Launcher.html +237 -0
- data/docs/Puppeteer/Launcher/Base.html +385 -0
- data/docs/Puppeteer/Launcher/Base/ExecutablePathNotFound.html +124 -0
- data/docs/Puppeteer/Launcher/BrowserOptions.html +441 -0
- data/docs/Puppeteer/Launcher/Chrome.html +669 -0
- data/docs/Puppeteer/Launcher/Chrome/DefaultArgs.html +382 -0
- data/docs/Puppeteer/Launcher/ChromeArgOptions.html +531 -0
- data/docs/Puppeteer/Launcher/LaunchOptions.html +893 -0
- data/docs/Puppeteer/LifecycleWatcher.html +834 -0
- data/docs/Puppeteer/LifecycleWatcher/ExpectedLifecycle.html +363 -0
- data/docs/Puppeteer/LifecycleWatcher/FrameDetachedError.html +206 -0
- data/docs/Puppeteer/LifecycleWatcher/TerminatedError.html +124 -0
- data/docs/Puppeteer/Mouse.html +1105 -0
- data/docs/Puppeteer/Mouse/Button.html +136 -0
- data/docs/Puppeteer/NetworkManager.html +901 -0
- data/docs/Puppeteer/NetworkManager/Credentials.html +385 -0
- data/docs/Puppeteer/Page.html +5970 -0
- data/docs/Puppeteer/Page/FileChooserTimeoutError.html +206 -0
- data/docs/Puppeteer/Page/ScreenshotOptions.html +845 -0
- data/docs/Puppeteer/Page/ScriptTag.html +555 -0
- data/docs/Puppeteer/Page/StyleTag.html +448 -0
- data/docs/Puppeteer/Page/TargetCrashedError.html +124 -0
- data/docs/Puppeteer/RemoteObject.html +1087 -0
- data/docs/Puppeteer/Target.html +1336 -0
- data/docs/Puppeteer/Target/InitializeFailure.html +124 -0
- data/docs/Puppeteer/Target/TargetInfo.html +729 -0
- data/docs/Puppeteer/TimeoutError.html +135 -0
- data/docs/Puppeteer/TimeoutSettings.html +496 -0
- data/docs/Puppeteer/TouchScreen.html +464 -0
- data/docs/Puppeteer/Viewport.html +837 -0
- data/docs/Puppeteer/WaitTask.html +637 -0
- data/docs/Puppeteer/WaitTask/TerminatedError.html +124 -0
- data/docs/Puppeteer/WaitTask/TimeoutError.html +206 -0
- data/docs/Puppeteer/WebSocket.html +673 -0
- data/docs/Puppeteer/WebSocket/DriverImpl.html +412 -0
- data/docs/Puppeteer/WebSocketTransport.html +600 -0
- data/docs/Puppeteer/WebSocktTransportError.html +124 -0
- data/docs/_index.html +823 -0
- data/docs/class_list.html +51 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +496 -0
- data/docs/file.README.html +123 -0
- data/docs/file_list.html +56 -0
- data/docs/frames.html +17 -0
- data/docs/index.html +123 -0
- data/docs/js/app.js +314 -0
- data/docs/js/full_list.js +216 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +4075 -0
- data/docs/top-level-namespace.html +126 -0
- data/lib/puppeteer.rb +200 -0
- data/lib/puppeteer/async_await_behavior.rb +38 -0
- data/lib/puppeteer/browser.rb +259 -0
- data/lib/puppeteer/browser_context.rb +90 -0
- data/lib/puppeteer/browser_fetcher.rb +6 -0
- data/lib/puppeteer/browser_runner.rb +161 -0
- data/lib/puppeteer/cdp_session.rb +100 -0
- data/lib/puppeteer/concurrent_ruby_utils.rb +37 -0
- data/lib/puppeteer/connection.rb +254 -0
- data/lib/puppeteer/console_message.rb +24 -0
- data/lib/puppeteer/debug_print.rb +20 -0
- data/lib/puppeteer/device.rb +12 -0
- data/lib/puppeteer/devices.rb +885 -0
- data/lib/puppeteer/dom_world.rb +484 -0
- data/lib/puppeteer/element_handle.rb +433 -0
- data/lib/puppeteer/element_handle/bounding_box.rb +12 -0
- data/lib/puppeteer/element_handle/box_model.rb +19 -0
- data/lib/puppeteer/element_handle/point.rb +26 -0
- data/lib/puppeteer/emulation_manager.rb +46 -0
- data/lib/puppeteer/errors.rb +2 -0
- data/lib/puppeteer/event_callbackable.rb +88 -0
- data/lib/puppeteer/execution_context.rb +254 -0
- data/lib/puppeteer/file_chooser.rb +29 -0
- data/lib/puppeteer/frame.rb +286 -0
- data/lib/puppeteer/frame_manager.rb +378 -0
- data/lib/puppeteer/if_present.rb +18 -0
- data/lib/puppeteer/js_handle.rb +142 -0
- data/lib/puppeteer/keyboard.rb +183 -0
- data/lib/puppeteer/keyboard/key_description.rb +19 -0
- data/lib/puppeteer/keyboard/us_keyboard_layout.rb +283 -0
- data/lib/puppeteer/launcher.rb +25 -0
- data/lib/puppeteer/launcher/base.rb +48 -0
- data/lib/puppeteer/launcher/browser_options.rb +41 -0
- data/lib/puppeteer/launcher/chrome.rb +211 -0
- data/lib/puppeteer/launcher/chrome_arg_options.rb +49 -0
- data/lib/puppeteer/launcher/launch_options.rb +68 -0
- data/lib/puppeteer/lifecycle_watcher.rb +171 -0
- data/lib/puppeteer/mouse.rb +123 -0
- data/lib/puppeteer/network_manager.rb +122 -0
- data/lib/puppeteer/page.rb +1065 -0
- data/lib/puppeteer/page/screenshot_options.rb +78 -0
- data/lib/puppeteer/remote_object.rb +143 -0
- data/lib/puppeteer/target.rb +150 -0
- data/lib/puppeteer/timeout_settings.rb +15 -0
- data/lib/puppeteer/touch_screen.rb +43 -0
- data/lib/puppeteer/version.rb +3 -0
- data/lib/puppeteer/viewport.rb +54 -0
- data/lib/puppeteer/wait_task.rb +188 -0
- data/lib/puppeteer/web_socket.rb +122 -0
- data/lib/puppeteer/web_socket_transport.rb +49 -0
- data/puppeteer-ruby.gemspec +32 -0
- metadata +355 -0
@@ -0,0 +1,126 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>
|
7
|
+
Top Level Namespace
|
8
|
+
|
9
|
+
— Documentation by YARD 0.9.24
|
10
|
+
|
11
|
+
</title>
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
16
|
+
|
17
|
+
<script type="text/javascript">
|
18
|
+
pathId = "";
|
19
|
+
relpath = '';
|
20
|
+
</script>
|
21
|
+
|
22
|
+
|
23
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
24
|
+
|
25
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
26
|
+
|
27
|
+
|
28
|
+
</head>
|
29
|
+
<body>
|
30
|
+
<div class="nav_wrap">
|
31
|
+
<iframe id="nav" src="class_list.html?1"></iframe>
|
32
|
+
<div id="resizer"></div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div id="main" tabindex="-1">
|
36
|
+
<div id="header">
|
37
|
+
<div id="menu">
|
38
|
+
|
39
|
+
<a href="_index.html">Index</a> »
|
40
|
+
|
41
|
+
|
42
|
+
<span class="title">Top Level Namespace</span>
|
43
|
+
|
44
|
+
</div>
|
45
|
+
|
46
|
+
<div id="search">
|
47
|
+
|
48
|
+
<a class="full_list_link" id="class_list_link"
|
49
|
+
href="class_list.html">
|
50
|
+
|
51
|
+
<svg width="24" height="24">
|
52
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
53
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
54
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
55
|
+
</svg>
|
56
|
+
</a>
|
57
|
+
|
58
|
+
</div>
|
59
|
+
<div class="clear"></div>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
<div id="content"><h1>Top Level Namespace
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
</h1>
|
67
|
+
<div class="box_info">
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
<dl>
|
75
|
+
<dt>Includes:</dt>
|
76
|
+
<dd><span class='object_link'><a href="Puppeteer/ConcurrentRubyUtils.html" title="Puppeteer::ConcurrentRubyUtils (module)">Puppeteer::ConcurrentRubyUtils</a></span></dd>
|
77
|
+
</dl>
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
</div>
|
85
|
+
|
86
|
+
<h2>Defined Under Namespace</h2>
|
87
|
+
<p class="children">
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
<strong class="classes">Classes:</strong> <span class='object_link'><a href="Puppeteer.html" title="Puppeteer (class)">Puppeteer</a></span>
|
93
|
+
|
94
|
+
|
95
|
+
</p>
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
<h2>Method Summary</h2>
|
111
|
+
|
112
|
+
<h3 class="inherited">Methods included from <span class='object_link'><a href="Puppeteer/ConcurrentRubyUtils.html" title="Puppeteer::ConcurrentRubyUtils (module)">Puppeteer::ConcurrentRubyUtils</a></span></h3>
|
113
|
+
<p class="inherited"><span class='object_link'><a href="Puppeteer/ConcurrentRubyUtils.html#await-instance_method" title="Puppeteer::ConcurrentRubyUtils#await (method)">#await</a></span>, <span class='object_link'><a href="Puppeteer/ConcurrentRubyUtils.html#await_all-instance_method" title="Puppeteer::ConcurrentRubyUtils#await_all (method)">#await_all</a></span>, <span class='object_link'><a href="Puppeteer/ConcurrentRubyUtils.html#await_any-instance_method" title="Puppeteer::ConcurrentRubyUtils#await_any (method)">#await_any</a></span>, <span class='object_link'><a href="Puppeteer/ConcurrentRubyUtils.html#future-instance_method" title="Puppeteer::ConcurrentRubyUtils#future (method)">#future</a></span>, <span class='object_link'><a href="Puppeteer/ConcurrentRubyUtils.html#resolvable_future-instance_method" title="Puppeteer::ConcurrentRubyUtils#resolvable_future (method)">#resolvable_future</a></span></p>
|
114
|
+
|
115
|
+
|
116
|
+
</div>
|
117
|
+
|
118
|
+
<div id="footer">
|
119
|
+
Generated on Fri Jun 12 12:38:32 2020 by
|
120
|
+
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
121
|
+
0.9.24 (ruby-2.6.3).
|
122
|
+
</div>
|
123
|
+
|
124
|
+
</div>
|
125
|
+
</body>
|
126
|
+
</html>
|
data/lib/puppeteer.rb
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'concurrent'
|
2
|
+
|
3
|
+
class Puppeteer; end
|
4
|
+
|
5
|
+
# Custom data types.
|
6
|
+
require 'puppeteer/device'
|
7
|
+
require 'puppeteer/errors'
|
8
|
+
require 'puppeteer/viewport'
|
9
|
+
|
10
|
+
# Modules
|
11
|
+
require 'puppeteer/async_await_behavior'
|
12
|
+
require 'puppeteer/concurrent_ruby_utils'
|
13
|
+
require 'puppeteer/debug_print'
|
14
|
+
require 'puppeteer/event_callbackable'
|
15
|
+
require 'puppeteer/if_present'
|
16
|
+
|
17
|
+
# Classes & values.
|
18
|
+
require 'puppeteer/browser'
|
19
|
+
require 'puppeteer/browser_context'
|
20
|
+
require 'puppeteer/browser_runner'
|
21
|
+
require 'puppeteer/cdp_session'
|
22
|
+
require 'puppeteer/connection'
|
23
|
+
require 'puppeteer/console_message'
|
24
|
+
require 'puppeteer/devices'
|
25
|
+
require 'puppeteer/dom_world'
|
26
|
+
require 'puppeteer/emulation_manager'
|
27
|
+
require 'puppeteer/execution_context'
|
28
|
+
require 'puppeteer/file_chooser'
|
29
|
+
require 'puppeteer/frame'
|
30
|
+
require 'puppeteer/frame_manager'
|
31
|
+
require 'puppeteer/js_handle'
|
32
|
+
require 'puppeteer/keyboard'
|
33
|
+
require 'puppeteer/launcher'
|
34
|
+
require 'puppeteer/lifecycle_watcher'
|
35
|
+
require 'puppeteer/mouse'
|
36
|
+
require 'puppeteer/network_manager'
|
37
|
+
require 'puppeteer/page'
|
38
|
+
require 'puppeteer/remote_object'
|
39
|
+
require 'puppeteer/target'
|
40
|
+
require 'puppeteer/timeout_settings'
|
41
|
+
require 'puppeteer/touch_screen'
|
42
|
+
require 'puppeteer/version'
|
43
|
+
require 'puppeteer/wait_task'
|
44
|
+
require 'puppeteer/web_socket'
|
45
|
+
require 'puppeteer/web_socket_transport'
|
46
|
+
|
47
|
+
# subclasses
|
48
|
+
require 'puppeteer/element_handle'
|
49
|
+
|
50
|
+
# ref: https://github.com/puppeteer/puppeteer/blob/master/lib/Puppeteer.js
|
51
|
+
class Puppeteer
|
52
|
+
class << self
|
53
|
+
def method_missing(method, *args, **kwargs, &block)
|
54
|
+
instance.send(method, *args, **kwargs, &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def instance
|
58
|
+
@instance ||= Puppeteer.new(
|
59
|
+
project_root: __dir__,
|
60
|
+
preferred_revision: '706915',
|
61
|
+
is_puppeteer_core: true,
|
62
|
+
)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# @param {string} projectRoot
|
67
|
+
# @param {string} preferredRevision
|
68
|
+
# @param {boolean} isPuppeteerCore
|
69
|
+
def initialize(project_root:, preferred_revision:, is_puppeteer_core:)
|
70
|
+
@project_root = project_root
|
71
|
+
@preferred_revision = preferred_revision
|
72
|
+
@is_puppeteer_core = is_puppeteer_core
|
73
|
+
end
|
74
|
+
|
75
|
+
# @param {!(Launcher.LaunchOptions & Launcher.ChromeArgOptions & Launcher.BrowserOptions & {product?: string, extraPrefsFirefox?: !object})=} options
|
76
|
+
# @return {!Promise<!Puppeteer.Browser>}
|
77
|
+
def launch(
|
78
|
+
product: nil,
|
79
|
+
executable_path: nil,
|
80
|
+
ignore_default_args: nil,
|
81
|
+
handle_SIGINT: nil,
|
82
|
+
handle_SIGTERM: nil,
|
83
|
+
handle_SIGHUP: nil,
|
84
|
+
timeout: nil,
|
85
|
+
dumpio: nil,
|
86
|
+
env: nil,
|
87
|
+
pipe: nil,
|
88
|
+
args: nil,
|
89
|
+
user_data_dir: nil,
|
90
|
+
devtools: nil,
|
91
|
+
headless: nil,
|
92
|
+
ignore_https_errors: nil,
|
93
|
+
default_viewport: nil,
|
94
|
+
slow_mo: nil
|
95
|
+
)
|
96
|
+
options = {
|
97
|
+
executable_path: executable_path,
|
98
|
+
ignore_default_args: ignore_default_args,
|
99
|
+
handle_SIGINT: handle_SIGINT,
|
100
|
+
handle_SIGTERM: handle_SIGTERM,
|
101
|
+
handle_SIGHUP: handle_SIGHUP,
|
102
|
+
timeout: timeout,
|
103
|
+
dumpio: dumpio,
|
104
|
+
env: env,
|
105
|
+
pipe: pipe,
|
106
|
+
args: args,
|
107
|
+
user_data_dir: user_data_dir,
|
108
|
+
devtools: devtools,
|
109
|
+
headless: headless,
|
110
|
+
ignore_https_errors: ignore_https_errors,
|
111
|
+
default_viewport: default_viewport,
|
112
|
+
slow_mo: slow_mo,
|
113
|
+
}.compact
|
114
|
+
|
115
|
+
@product_name ||= product
|
116
|
+
browser = launcher.launch(options)
|
117
|
+
if block_given?
|
118
|
+
begin
|
119
|
+
yield(browser)
|
120
|
+
ensure
|
121
|
+
browser.close
|
122
|
+
end
|
123
|
+
else
|
124
|
+
browser
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# @param {!(Launcher.BrowserOptions & {browserWSEndpoint?: string, browserURL?: string, transport?: !Puppeteer.ConnectionTransport})} options
|
129
|
+
# @return {!Promise<!Puppeteer.Browser>}
|
130
|
+
def connect(
|
131
|
+
browser_ws_endpoint: nil,
|
132
|
+
browser_url: nil,
|
133
|
+
transport: nil,
|
134
|
+
ignore_https_errors: nil,
|
135
|
+
default_viewport: nil,
|
136
|
+
slow_mo: nil
|
137
|
+
)
|
138
|
+
options = {
|
139
|
+
browser_ws_endpoint: browser_ws_endpoint,
|
140
|
+
browser_url: browser_url,
|
141
|
+
transport: transport,
|
142
|
+
ignore_https_errors: ignore_https_errors,
|
143
|
+
default_viewport: default_viewport,
|
144
|
+
slow_mo: slow_mo,
|
145
|
+
}.compact
|
146
|
+
browser = launcher.connect(options)
|
147
|
+
if block_given?
|
148
|
+
yield(browser)
|
149
|
+
else
|
150
|
+
browser
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# @return {string}
|
155
|
+
def executable_path
|
156
|
+
launcher.executable_path
|
157
|
+
end
|
158
|
+
|
159
|
+
private def launcher
|
160
|
+
@launcher ||= Puppeteer::Launcher.new(
|
161
|
+
project_root: @project_root,
|
162
|
+
preferred_revision: @preferred_revision,
|
163
|
+
is_puppeteer_core: @is_puppeteer_core,
|
164
|
+
product: @product_name,
|
165
|
+
)
|
166
|
+
end
|
167
|
+
|
168
|
+
# @return {string}
|
169
|
+
def product
|
170
|
+
launcher.product
|
171
|
+
end
|
172
|
+
|
173
|
+
# @return {Puppeteer::Devices}
|
174
|
+
def devices
|
175
|
+
Puppeteer::Devices
|
176
|
+
end
|
177
|
+
|
178
|
+
# # @return {Object}
|
179
|
+
# def errors
|
180
|
+
# # ???
|
181
|
+
# end
|
182
|
+
|
183
|
+
# @param {!Launcher.ChromeArgOptions=} options
|
184
|
+
# @return {!Array<string>}
|
185
|
+
def default_args(args: nil, user_data_dir: nil, devtools: nil, headless: nil)
|
186
|
+
options = {
|
187
|
+
args: args,
|
188
|
+
user_data_dir: user_data_dir,
|
189
|
+
devtools: devtools,
|
190
|
+
headless: headless,
|
191
|
+
}.compact
|
192
|
+
launcher.default_args(options)
|
193
|
+
end
|
194
|
+
|
195
|
+
# @param {!BrowserFetcher.Options=} options
|
196
|
+
# @return {!BrowserFetcher}
|
197
|
+
def createBrowserFetcher(options = {})
|
198
|
+
BrowserFetcher.new(@project_root, options)
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Puppeteer::AsyncAwaitBehavior
|
2
|
+
refine Class do
|
3
|
+
# wrap with Concurrent::Promises.future
|
4
|
+
def async(method_name)
|
5
|
+
original_method = instance_method(method_name)
|
6
|
+
|
7
|
+
unless method_name.to_s.start_with?('async_')
|
8
|
+
puts "async method should start with 'async_': #{self.name}##{method_name}"
|
9
|
+
end
|
10
|
+
|
11
|
+
define_method(method_name) do |*args|
|
12
|
+
Concurrent::Promises.future do
|
13
|
+
original_method.bind(self).call(*args)
|
14
|
+
rescue => err
|
15
|
+
Logger.new(STDERR).warn(err)
|
16
|
+
raise err
|
17
|
+
end
|
18
|
+
end
|
19
|
+
rescue NameError
|
20
|
+
if respond_to?(method_name)
|
21
|
+
original_method = singleton_method(method_name)
|
22
|
+
|
23
|
+
unless method_name.to_s.start_with?('async_')
|
24
|
+
puts "async method should start with 'async_': #{method_name}"
|
25
|
+
end
|
26
|
+
|
27
|
+
define_singleton_method(method_name) do |*args|
|
28
|
+
Concurrent::Promises.future do
|
29
|
+
original_method.call(*args)
|
30
|
+
rescue => err
|
31
|
+
Logger.new(STDERR).warn(err)
|
32
|
+
raise err
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,259 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
class Puppeteer::Browser
|
5
|
+
include Puppeteer::DebugPrint
|
6
|
+
include Puppeteer::EventCallbackable
|
7
|
+
include Puppeteer::IfPresent
|
8
|
+
using Puppeteer::AsyncAwaitBehavior
|
9
|
+
|
10
|
+
# @param {!Puppeteer.Connection} connection
|
11
|
+
# @param {!Array<string>} contextIds
|
12
|
+
# @param {boolean} ignoreHTTPSErrors
|
13
|
+
# @param {?Puppeteer.Viewport} defaultViewport
|
14
|
+
# @param process [Puppeteer::BrowserRunner::BrowserProcess|NilClass]
|
15
|
+
# @param {function()=} closeCallback
|
16
|
+
def self.create(connection:, context_ids:, ignore_https_errors:, default_viewport:, process:, close_callback:)
|
17
|
+
browser = Puppeteer::Browser.new(
|
18
|
+
connection: connection,
|
19
|
+
context_ids: context_ids,
|
20
|
+
ignore_https_errors: ignore_https_errors,
|
21
|
+
default_viewport: default_viewport,
|
22
|
+
process: process,
|
23
|
+
close_callback: close_callback,
|
24
|
+
)
|
25
|
+
connection.send_message('Target.setDiscoverTargets', discover: true)
|
26
|
+
browser
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param {!Puppeteer.Connection} connection
|
30
|
+
# @param {!Array<string>} contextIds
|
31
|
+
# @param {boolean} ignoreHTTPSErrors
|
32
|
+
# @param {?Puppeteer.Viewport} defaultViewport
|
33
|
+
# @param {?Puppeteer.ChildProcess} process
|
34
|
+
# @param {(function():Promise)=} closeCallback
|
35
|
+
def initialize(connection:, context_ids:, ignore_https_errors:, default_viewport:, process:, close_callback:)
|
36
|
+
@ignore_https_errors = ignore_https_errors
|
37
|
+
@default_viewport = default_viewport
|
38
|
+
@process = process
|
39
|
+
# @screenshot_task_queue = TaskQueue.new
|
40
|
+
@connection = connection
|
41
|
+
@close_callback = close_callback
|
42
|
+
|
43
|
+
@default_context = Puppeteer::BrowserContext.new(@connection, self, nil)
|
44
|
+
@contexts = {}
|
45
|
+
context_ids.each do |context_id|
|
46
|
+
@contexts[context_id] = Puppeteer::BrowserContext.new(@connection, self. context_id)
|
47
|
+
end
|
48
|
+
@targets = {}
|
49
|
+
@connection.on_event 'Events.CDPSession.Disconnected' do
|
50
|
+
emit_event 'Events.Browser.Disconnected'
|
51
|
+
end
|
52
|
+
@connection.on_event 'Target.targetCreated', &method(:handle_target_created)
|
53
|
+
@connection.on_event 'Target.targetDestroyed', &method(:handle_target_destroyed)
|
54
|
+
@connection.on_event 'Target.targetInfoChanged', &method(:handle_target_info_changed)
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Puppeteer::BrowserRunner::BrowserProcess]
|
58
|
+
def process
|
59
|
+
@process
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Puppeteer::BrowserContext]
|
63
|
+
def create_incognito_browser_context
|
64
|
+
result = @connection.send_message('Target.createBrowserContext')
|
65
|
+
browser_context_id = result['browserContextId']
|
66
|
+
@contexts[browser_context_id] = Puppeteer::BrowserContext.new(@connection, self, browser_context_id)
|
67
|
+
end
|
68
|
+
|
69
|
+
def browser_contexts
|
70
|
+
[@default_context].concat(@contexts.values)
|
71
|
+
end
|
72
|
+
|
73
|
+
# @return [Puppeteer::BrowserContext]
|
74
|
+
def default_browser_context
|
75
|
+
@default_context
|
76
|
+
end
|
77
|
+
|
78
|
+
# @param context_id [String]
|
79
|
+
def dispose_context(context_id)
|
80
|
+
@connection.send_message('Target.disposeBrowserContext', browserContextId: context_id)
|
81
|
+
@contexts.remove(context_id)
|
82
|
+
end
|
83
|
+
|
84
|
+
# @param {!Protocol.Target.targetCreatedPayload} event
|
85
|
+
def handle_target_created(event)
|
86
|
+
target_info = Puppeteer::Target::TargetInfo.new(event['targetInfo'])
|
87
|
+
browser_context_id = target_info.browser_context_id
|
88
|
+
context =
|
89
|
+
if browser_context_id && @contexts.has_key?(browser_context_id)
|
90
|
+
@contexts[browser_context_id]
|
91
|
+
else
|
92
|
+
@default_context
|
93
|
+
end
|
94
|
+
|
95
|
+
target = Puppeteer::Target.new(
|
96
|
+
target_info: target_info,
|
97
|
+
browser_context: context,
|
98
|
+
session_factory: -> { @connection.create_session(target_info) },
|
99
|
+
ignore_https_errors: @ignore_https_errors,
|
100
|
+
default_viewport: @default_viewport,
|
101
|
+
screenshot_task_queue: @screenshot_task_queue,
|
102
|
+
)
|
103
|
+
# assert(!this._targets.has(event.targetInfo.targetId), 'Target should not exist before targetCreated');
|
104
|
+
@targets[target_info.target_id] = target
|
105
|
+
if await target.initialized_promise
|
106
|
+
emit_event 'Events.Browser.TargetCreated', target
|
107
|
+
context.emit_event 'Events.BrowserContext.TargetCreated', target
|
108
|
+
end
|
109
|
+
|
110
|
+
if_present(pending_target_info_changed_event.delete(target_info.target_id)) do |pending_event|
|
111
|
+
handle_target_info_changed(pending_event)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
# @param {{targetId: string}} event
|
117
|
+
def handle_target_destroyed(event)
|
118
|
+
target_id = event['targetId']
|
119
|
+
target = @targets[target_id]
|
120
|
+
target.ignore_initialize_callback_promise
|
121
|
+
@targets.delete(target_id)
|
122
|
+
target.closed_callback
|
123
|
+
if await target.initialized_promise
|
124
|
+
emit_event 'Events.Browser.TargetDestroyed', target
|
125
|
+
target.browser_context.emit_event 'Events.BrowserContext.TargetDestroyed', target
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# @param {!Protocol.Target.targetInfoChangedPayload} event
|
130
|
+
def handle_target_info_changed(event)
|
131
|
+
target_info = Puppeteer::Target::TargetInfo.new(event['targetInfo'])
|
132
|
+
target = @targets[target_info.target_id]
|
133
|
+
if !target
|
134
|
+
# targetCreated is sometimes notified after targetInfoChanged.
|
135
|
+
# We don't raise error. Instead, keep the event as a pending change,
|
136
|
+
# and handle it on handle_target_created.
|
137
|
+
#
|
138
|
+
# D, [2020-04-22T00:22:26.630328 #79646] DEBUG -- : RECV << {"method"=>"Target.targetInfoChanged", "params"=>{"targetInfo"=>{"targetId"=>"8068CED48357B9557EEC85AA62165A8E", "type"=>"iframe", "title"=>"", "url"=>"", "attached"=>true, "browserContextId"=>"7895BFB24BF22CE40584808713D96E8D"}}}
|
139
|
+
# E, [2020-04-22T00:22:26.630448 #79646] ERROR -- : target should exist before targetInfoChanged (StandardError)
|
140
|
+
# D, [2020-04-22T00:22:26.630648 #79646] DEBUG -- : RECV << {"method"=>"Target.targetCreated", "params"=>{"targetInfo"=>{"targetId"=>"8068CED48357B9557EEC85AA62165A8E", "type"=>"iframe", "title"=>"", "url"=>"", "attached"=>false, "browserContextId"=>"7895BFB24BF22CE40584808713D96E8D"}}}
|
141
|
+
pending_target_info_changed_event[target_info.target_id] = event
|
142
|
+
return
|
143
|
+
# original implementation is:
|
144
|
+
#
|
145
|
+
# raise StandardError.new('target should exist before targetInfoChanged')
|
146
|
+
end
|
147
|
+
previous_url = target.url
|
148
|
+
was_initialized = target.initialized?
|
149
|
+
target.handle_target_info_changed(target_info)
|
150
|
+
if was_initialized && previous_url != target.url
|
151
|
+
emit_event 'Events.Browser.TargetChanged', target
|
152
|
+
target.browser_context.emit_event 'Events.BrowserContext.TargetChanged', target
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
private def pending_target_info_changed_event
|
157
|
+
@pending_target_info_changed_event ||= {}
|
158
|
+
end
|
159
|
+
|
160
|
+
# @return [String]
|
161
|
+
def websocket_endpoint
|
162
|
+
@connection.url
|
163
|
+
end
|
164
|
+
|
165
|
+
def new_page
|
166
|
+
@default_context.new_page
|
167
|
+
end
|
168
|
+
|
169
|
+
# @param {?string} contextId
|
170
|
+
# @return {!Promise<!Puppeteer.Page>}
|
171
|
+
def create_page_in_context(context_id)
|
172
|
+
create_target_params = { url: 'about:blank' }
|
173
|
+
if context_id
|
174
|
+
create_target_params[:browserContextId] = context_id
|
175
|
+
end
|
176
|
+
result = @connection.send_message('Target.createTarget', **create_target_params)
|
177
|
+
target_id = result['targetId']
|
178
|
+
target = @targets[target_id]
|
179
|
+
await target.initialized_promise
|
180
|
+
await target.page
|
181
|
+
end
|
182
|
+
|
183
|
+
# @return {!Array<!Target>}
|
184
|
+
def targets
|
185
|
+
@targets.values.select { |target| target.initialized? }
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
# @return {!Target}
|
190
|
+
def target
|
191
|
+
targets.first { |target| target.type == 'browser' }
|
192
|
+
end
|
193
|
+
|
194
|
+
# @param {function(!Target):boolean} predicate
|
195
|
+
# @param {{timeout?: number}=} options
|
196
|
+
# @return {!Promise<!Target>}
|
197
|
+
def wait_for_target(predicate:, timeout: nil)
|
198
|
+
timeout_in_sec = (timeout || 30000).to_i / 1000.0
|
199
|
+
existing_target = targets.first { |target| predicate.call(target) }
|
200
|
+
return existing_target if existing_target
|
201
|
+
|
202
|
+
event_listening_ids = []
|
203
|
+
target_promise = resolvable_future
|
204
|
+
event_listening_ids << add_event_listener('Events.Browser.TargetCreated') do |target|
|
205
|
+
if predicate.call(target)
|
206
|
+
target_promise.fulfill(target)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
event_listening_ids << add_event_listener('Events.Browser.TargetChanged') do |target|
|
210
|
+
if predicate.call(target)
|
211
|
+
target_promise.fulfill(target)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
begin
|
216
|
+
if timeout_in_sec > 0
|
217
|
+
Timeout.timeout(timeout_in_sec) do
|
218
|
+
target_promise.value!
|
219
|
+
end
|
220
|
+
else
|
221
|
+
target_promise.value!
|
222
|
+
end
|
223
|
+
ensure
|
224
|
+
remove_event_listener(*event_listening_ids)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# @return {!Promise<!Array<!Puppeteer.Page>>}
|
229
|
+
def pages
|
230
|
+
browser_contexts.flat_map(&:pages)
|
231
|
+
end
|
232
|
+
|
233
|
+
# @return [String]
|
234
|
+
def version
|
235
|
+
get_version.product
|
236
|
+
end
|
237
|
+
|
238
|
+
# @return [String]
|
239
|
+
def user_agent
|
240
|
+
get_version.user_agent
|
241
|
+
end
|
242
|
+
|
243
|
+
def close
|
244
|
+
@close_callback.call
|
245
|
+
disconnect
|
246
|
+
end
|
247
|
+
|
248
|
+
def disconnect
|
249
|
+
@connection.dispose
|
250
|
+
end
|
251
|
+
|
252
|
+
def connected?
|
253
|
+
!@connection.closed?
|
254
|
+
end
|
255
|
+
|
256
|
+
private def get_version
|
257
|
+
@connection.send_message('Browser.getVersion')
|
258
|
+
end
|
259
|
+
end
|