opal 1.6.1 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (212) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +17 -0
  3. data/CHANGELOG.md +35 -1
  4. data/Gemfile +1 -0
  5. data/HACKING.md +47 -26
  6. data/benchmark/benchmarks +415 -103
  7. data/benchmark/bm_call_overhead.yml +28 -0
  8. data/benchmark/run.rb +61 -40
  9. data/docs/cdp_common.json +3364 -0
  10. data/docs/cdp_common.md +18 -0
  11. data/docs/{headless_chrome.md → headless_browsers.md} +31 -12
  12. data/lib/opal/ast/builder.rb +1 -1
  13. data/lib/opal/builder.rb +6 -1
  14. data/lib/opal/builder_processors.rb +5 -3
  15. data/lib/opal/cache.rb +1 -7
  16. data/lib/opal/cli_options.rb +72 -58
  17. data/lib/opal/cli_runners/chrome.rb +47 -9
  18. data/lib/opal/cli_runners/chrome_cdp_interface.rb +238 -112
  19. data/lib/opal/cli_runners/compiler.rb +146 -13
  20. data/lib/opal/cli_runners/deno.rb +32 -0
  21. data/lib/opal/cli_runners/firefox.rb +350 -0
  22. data/lib/opal/cli_runners/firefox_cdp_interface.rb +212 -0
  23. data/lib/opal/cli_runners/node_modules/.bin/chrome-remote-interface.cmd +17 -0
  24. data/lib/opal/cli_runners/node_modules/.bin/chrome-remote-interface.ps1 +28 -0
  25. data/lib/opal/cli_runners/node_modules/.package-lock.json +41 -0
  26. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/LICENSE +1 -1
  27. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/README.md +322 -182
  28. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/bin/client.js +99 -114
  29. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/chrome-remote-interface.js +1 -11
  30. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/index.js +16 -11
  31. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/api.js +41 -33
  32. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/chrome.js +224 -214
  33. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/devtools.js +71 -191
  34. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/external-request.js +26 -6
  35. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/protocol.json +20788 -9049
  36. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/websocket-wrapper.js +10 -3
  37. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/package.json +59 -123
  38. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/webpack.config.js +25 -32
  39. data/lib/opal/cli_runners/node_modules/commander/History.md +298 -0
  40. data/lib/opal/cli_runners/node_modules/commander/LICENSE +22 -0
  41. data/lib/opal/cli_runners/node_modules/commander/Readme.md +217 -61
  42. data/lib/opal/cli_runners/node_modules/commander/index.js +431 -145
  43. data/lib/opal/cli_runners/node_modules/commander/package.json +16 -79
  44. data/lib/opal/cli_runners/node_modules/ws/README.md +334 -98
  45. data/lib/opal/cli_runners/node_modules/ws/browser.js +8 -0
  46. data/lib/opal/cli_runners/node_modules/ws/index.js +5 -10
  47. data/lib/opal/cli_runners/node_modules/ws/lib/buffer-util.js +129 -0
  48. data/lib/opal/cli_runners/node_modules/ws/lib/constants.js +10 -0
  49. data/lib/opal/cli_runners/node_modules/ws/lib/event-target.js +184 -0
  50. data/lib/opal/cli_runners/node_modules/ws/lib/extension.js +223 -0
  51. data/lib/opal/cli_runners/node_modules/ws/lib/limiter.js +55 -0
  52. data/lib/opal/cli_runners/node_modules/ws/lib/permessage-deflate.js +518 -0
  53. data/lib/opal/cli_runners/node_modules/ws/lib/receiver.js +607 -0
  54. data/lib/opal/cli_runners/node_modules/ws/lib/sender.js +409 -0
  55. data/lib/opal/cli_runners/node_modules/ws/lib/stream.js +180 -0
  56. data/lib/opal/cli_runners/node_modules/ws/lib/validation.js +104 -0
  57. data/lib/opal/cli_runners/node_modules/ws/lib/websocket-server.js +447 -0
  58. data/lib/opal/cli_runners/node_modules/ws/lib/websocket.js +1195 -0
  59. data/lib/opal/cli_runners/node_modules/ws/package.json +40 -106
  60. data/lib/opal/cli_runners/package-lock.json +62 -0
  61. data/lib/opal/cli_runners/package.json +1 -1
  62. data/lib/opal/cli_runners.rb +26 -4
  63. data/lib/opal/nodes/args/prepare_post_args.rb +2 -2
  64. data/lib/opal/nodes/def.rb +8 -8
  65. data/lib/opal/nodes/iter.rb +12 -12
  66. data/lib/opal/nodes/logic.rb +1 -1
  67. data/lib/opal/nodes/masgn.rb +2 -2
  68. data/lib/opal/parser/with_ruby_lexer.rb +1 -1
  69. data/lib/opal/paths.rb +14 -0
  70. data/lib/opal/rewriter.rb +2 -0
  71. data/lib/opal/rewriters/forward_args.rb +52 -4
  72. data/lib/opal/rewriters/targeted_patches.rb +94 -0
  73. data/lib/opal/version.rb +1 -1
  74. data/opal/corelib/basic_object.rb +1 -1
  75. data/opal/corelib/boolean.rb +2 -2
  76. data/opal/corelib/class.rb +11 -0
  77. data/opal/corelib/constants.rb +3 -3
  78. data/opal/corelib/enumerable.rb +4 -0
  79. data/opal/corelib/enumerator.rb +1 -1
  80. data/opal/corelib/hash.rb +2 -2
  81. data/opal/corelib/helpers.rb +1 -1
  82. data/opal/corelib/kernel.rb +3 -3
  83. data/opal/corelib/method.rb +1 -1
  84. data/opal/corelib/module.rb +29 -8
  85. data/opal/corelib/proc.rb +7 -5
  86. data/opal/corelib/runtime.js +141 -78
  87. data/opal/corelib/set.rb +252 -0
  88. data/opal/corelib/string.rb +2 -1
  89. data/opal/corelib/time.rb +2 -2
  90. data/opal/opal.rb +1 -0
  91. data/opal.gemspec +1 -0
  92. data/spec/filters/bugs/array.rb +22 -13
  93. data/spec/filters/bugs/base64.rb +5 -5
  94. data/spec/filters/bugs/basicobject.rb +16 -8
  95. data/spec/filters/bugs/bigdecimal.rb +161 -160
  96. data/spec/filters/bugs/binding.rb +10 -10
  97. data/spec/filters/bugs/class.rb +8 -8
  98. data/spec/filters/bugs/complex.rb +2 -1
  99. data/spec/filters/bugs/date.rb +79 -81
  100. data/spec/filters/bugs/datetime.rb +29 -29
  101. data/spec/filters/bugs/delegate.rb +1 -3
  102. data/spec/filters/bugs/encoding.rb +69 -69
  103. data/spec/filters/bugs/enumerable.rb +22 -20
  104. data/spec/filters/bugs/enumerator.rb +88 -85
  105. data/spec/filters/bugs/exception.rb +46 -40
  106. data/spec/filters/bugs/file.rb +32 -32
  107. data/spec/filters/bugs/float.rb +26 -21
  108. data/spec/filters/bugs/freeze.rb +88 -0
  109. data/spec/filters/bugs/hash.rb +39 -38
  110. data/spec/filters/bugs/integer.rb +57 -44
  111. data/spec/filters/bugs/io.rb +1 -1
  112. data/spec/filters/bugs/kernel.rb +349 -269
  113. data/spec/filters/bugs/language.rb +220 -188
  114. data/spec/filters/bugs/main.rb +5 -3
  115. data/spec/filters/bugs/marshal.rb +38 -38
  116. data/spec/filters/bugs/math.rb +2 -1
  117. data/spec/filters/bugs/method.rb +73 -62
  118. data/spec/filters/bugs/module.rb +163 -143
  119. data/spec/filters/bugs/numeric.rb +6 -6
  120. data/spec/filters/bugs/objectspace.rb +16 -16
  121. data/spec/filters/bugs/openstruct.rb +1 -1
  122. data/spec/filters/bugs/pack_unpack.rb +51 -51
  123. data/spec/filters/bugs/pathname.rb +7 -7
  124. data/spec/filters/bugs/proc.rb +63 -63
  125. data/spec/filters/bugs/random.rb +7 -6
  126. data/spec/filters/bugs/range.rb +12 -9
  127. data/spec/filters/bugs/rational.rb +8 -7
  128. data/spec/filters/bugs/regexp.rb +49 -48
  129. data/spec/filters/bugs/ruby-32.rb +56 -0
  130. data/spec/filters/bugs/set.rb +30 -30
  131. data/spec/filters/bugs/singleton.rb +4 -4
  132. data/spec/filters/bugs/string.rb +187 -99
  133. data/spec/filters/bugs/stringio.rb +7 -0
  134. data/spec/filters/bugs/stringscanner.rb +68 -68
  135. data/spec/filters/bugs/struct.rb +11 -9
  136. data/spec/filters/bugs/symbol.rb +1 -1
  137. data/spec/filters/bugs/time.rb +78 -63
  138. data/spec/filters/bugs/trace_point.rb +4 -4
  139. data/spec/filters/bugs/unboundmethod.rb +32 -17
  140. data/spec/filters/bugs/warnings.rb +8 -12
  141. data/spec/filters/unsupported/array.rb +24 -107
  142. data/spec/filters/unsupported/basicobject.rb +12 -12
  143. data/spec/filters/unsupported/bignum.rb +27 -52
  144. data/spec/filters/unsupported/class.rb +1 -2
  145. data/spec/filters/unsupported/delegator.rb +3 -3
  146. data/spec/filters/unsupported/enumerable.rb +2 -9
  147. data/spec/filters/unsupported/enumerator.rb +2 -11
  148. data/spec/filters/unsupported/file.rb +1 -1
  149. data/spec/filters/unsupported/float.rb +28 -47
  150. data/spec/filters/unsupported/hash.rb +8 -14
  151. data/spec/filters/unsupported/integer.rb +75 -91
  152. data/spec/filters/unsupported/kernel.rb +17 -35
  153. data/spec/filters/unsupported/language.rb +11 -19
  154. data/spec/filters/unsupported/marshal.rb +22 -41
  155. data/spec/filters/unsupported/matchdata.rb +28 -52
  156. data/spec/filters/unsupported/math.rb +1 -1
  157. data/spec/filters/unsupported/privacy.rb +229 -285
  158. data/spec/filters/unsupported/range.rb +1 -5
  159. data/spec/filters/unsupported/regexp.rb +40 -66
  160. data/spec/filters/unsupported/set.rb +2 -2
  161. data/spec/filters/unsupported/singleton.rb +4 -4
  162. data/spec/filters/unsupported/string.rb +305 -508
  163. data/spec/filters/unsupported/struct.rb +3 -4
  164. data/spec/filters/unsupported/symbol.rb +15 -18
  165. data/spec/filters/unsupported/thread.rb +1 -7
  166. data/spec/filters/unsupported/time.rb +159 -202
  167. data/spec/filters/unsupported/usage_of_files.rb +170 -259
  168. data/spec/lib/builder_spec.rb +4 -4
  169. data/spec/lib/rewriters/forward_args_spec.rb +32 -12
  170. data/spec/mspec-opal/runner.rb +2 -0
  171. data/spec/ruby_specs +4 -0
  172. data/stdlib/deno/base.rb +28 -0
  173. data/stdlib/deno/file.rb +340 -0
  174. data/stdlib/{headless_chrome.rb → headless_browser/base.rb} +1 -1
  175. data/stdlib/headless_browser/file.rb +15 -0
  176. data/stdlib/headless_browser.rb +4 -0
  177. data/stdlib/native.rb +1 -1
  178. data/stdlib/nodejs/file.rb +5 -0
  179. data/stdlib/opal/platform.rb +8 -6
  180. data/stdlib/opal-platform.rb +14 -8
  181. data/stdlib/set.rb +1 -258
  182. data/tasks/benchmarking.rake +62 -19
  183. data/tasks/performance.rake +1 -1
  184. data/tasks/testing.rake +5 -3
  185. data/test/nodejs/test_file.rb +29 -10
  186. data/test/opal/http_server.rb +28 -11
  187. data/test/opal/unsupported_and_bugs.rb +2 -1
  188. metadata +89 -50
  189. data/lib/opal/cli_runners/node_modules/ultron/LICENSE +0 -22
  190. data/lib/opal/cli_runners/node_modules/ultron/index.js +0 -138
  191. data/lib/opal/cli_runners/node_modules/ultron/package.json +0 -112
  192. data/lib/opal/cli_runners/node_modules/ws/SECURITY.md +0 -33
  193. data/lib/opal/cli_runners/node_modules/ws/lib/BufferUtil.fallback.js +0 -56
  194. data/lib/opal/cli_runners/node_modules/ws/lib/BufferUtil.js +0 -15
  195. data/lib/opal/cli_runners/node_modules/ws/lib/ErrorCodes.js +0 -28
  196. data/lib/opal/cli_runners/node_modules/ws/lib/EventTarget.js +0 -158
  197. data/lib/opal/cli_runners/node_modules/ws/lib/Extensions.js +0 -69
  198. data/lib/opal/cli_runners/node_modules/ws/lib/PerMessageDeflate.js +0 -339
  199. data/lib/opal/cli_runners/node_modules/ws/lib/Receiver.js +0 -520
  200. data/lib/opal/cli_runners/node_modules/ws/lib/Sender.js +0 -438
  201. data/lib/opal/cli_runners/node_modules/ws/lib/Validation.fallback.js +0 -9
  202. data/lib/opal/cli_runners/node_modules/ws/lib/Validation.js +0 -17
  203. data/lib/opal/cli_runners/node_modules/ws/lib/WebSocket.js +0 -705
  204. data/lib/opal/cli_runners/node_modules/ws/lib/WebSocketServer.js +0 -336
  205. data/spec/filters/bugs/boolean.rb +0 -3
  206. data/spec/filters/bugs/matrix.rb +0 -3
  207. data/spec/filters/unsupported/fixnum.rb +0 -15
  208. data/spec/filters/unsupported/freeze.rb +0 -102
  209. data/spec/filters/unsupported/pathname.rb +0 -4
  210. data/spec/filters/unsupported/proc.rb +0 -4
  211. data/spec/filters/unsupported/random.rb +0 -5
  212. data/spec/filters/unsupported/taint.rb +0 -162
@@ -1,5 +1,7 @@
1
- chrome-remote-interface [![Build Status](https://travis-ci.org/cyrus-and/chrome-remote-interface.svg?branch=master)](https://travis-ci.org/cyrus-and/chrome-remote-interface)
2
- =======================
1
+ # chrome-remote-interface [![Build Status][]][travis]
2
+
3
+ [Build Status]: https://app.travis-ci.com/cyrus-and/chrome-remote-interface.svg?branch=master
4
+ [travis]: https://app.travis-ci.com/cyrus-and/chrome-remote-interface
3
5
 
4
6
  [Chrome Debugging Protocol] interface that helps to instrument Chrome (or any
5
7
  other suitable [implementation](#implementations)) by providing a simple
@@ -10,55 +12,54 @@ This module is one of the many [third-party protocol clients][3rd-party].
10
12
 
11
13
  [3rd-party]: https://developer.chrome.com/devtools/docs/debugging-clients#chrome-remote-interface
12
14
 
13
- Sample API usage
14
- ----------------
15
+ ## Sample API usage
15
16
 
16
17
  The following snippet loads `https://github.com` and dumps every request made:
17
18
 
18
19
  ```js
19
20
  const CDP = require('chrome-remote-interface');
20
21
 
21
- CDP((client) => {
22
- // extract domains
23
- const {Network, Page} = client;
24
- // setup handlers
25
- Network.requestWillBeSent((params) => {
26
- console.log(params.request.url);
27
- });
28
- Page.loadEventFired(() => {
29
- client.close();
30
- });
31
- // enable events then start!
32
- Promise.all([
33
- Network.enable(),
34
- Page.enable()
35
- ]).then(() => {
36
- return Page.navigate({url: 'https://github.com'});
37
- }).catch((err) => {
22
+ async function example() {
23
+ let client;
24
+ try {
25
+ // connect to endpoint
26
+ client = await CDP();
27
+ // extract domains
28
+ const {Network, Page} = client;
29
+ // setup handlers
30
+ Network.requestWillBeSent((params) => {
31
+ console.log(params.request.url);
32
+ });
33
+ // enable events then start!
34
+ await Network.enable();
35
+ await Page.enable();
36
+ await Page.navigate({url: 'https://github.com'});
37
+ await Page.loadEventFired();
38
+ } catch (err) {
38
39
  console.error(err);
39
- client.close();
40
- });
41
- }).on('error', (err) => {
42
- // cannot connect to the remote endpoint
43
- console.error(err);
44
- });
40
+ } finally {
41
+ if (client) {
42
+ await client.close();
43
+ }
44
+ }
45
+ }
46
+
47
+ example();
45
48
  ```
46
49
 
47
- Find more examples in the [wiki], in particular notice how the above can be
48
- rewritten using the [`async`/`await`][async-await-example] primitives.
50
+ Find more examples in the [wiki]. You may also want to take a look at the [FAQ].
49
51
 
50
52
  [wiki]: https://github.com/cyrus-and/chrome-remote-interface/wiki
51
53
  [async-await-example]: https://github.com/cyrus-and/chrome-remote-interface/wiki/Async-await-example
54
+ [FAQ]: https://github.com/cyrus-and/chrome-remote-interface#faq
52
55
 
53
- Installation
54
- ------------
56
+ ## Installation
55
57
 
56
58
  npm install chrome-remote-interface
57
59
 
58
60
  Install globally (`-g`) to just use the [bundled client](#bundled-client).
59
61
 
60
- Implementations
61
- ---------------
62
+ ## Implementations
62
63
 
63
64
  This module should work with every application implementing the
64
65
  [Chrome Debugging Protocol]. In particular, it has been tested against the
@@ -66,16 +67,22 @@ following implementations:
66
67
 
67
68
  Implementation | Protocol version | [Protocol] | [List] | [New] | [Activate] | [Close] | [Version]
68
69
  ---------------------------|--------------------|------------|--------|-------|------------|---------|-----------
69
- [Google Chrome][1.1] | [tip-of-tree][1.2] | yes | yes | yes | yes | yes | yes
70
- [Microsoft Edge][2.1] | [*partial*][2.2] | yes | yes | no | no | no | yes
70
+ [Chrome][1.1] | [tip-of-tree][1.2] | yes¹ | yes | yes | yes | yes | yes
71
+ [Opera][2.1] | [tip-of-tree][2.2] | yes | yes | yes | yes | yes | yes
71
72
  [Node.js][3.1] ([v6.3.0]+) | [node][3.2] | yes | no | no | no | no | yes
72
73
  [Safari (iOS)][4.1] | [*partial*][4.2] | no | yes | no | no | no | no
74
+ [Edge][5.1] | [*partial*][5.2] | yes | yes | no | no | no | yes
75
+ [Firefox (Nightly)][6.1] | [*partial*][6.2] | yes | yes | no | yes | yes | yes
76
+
77
+ ¹ Not available on [Chrome for Android][chrome-mobile-protocol], hence a local version of the protocol must be used.
78
+
79
+ [chrome-mobile-protocol]: https://bugs.chromium.org/p/chromium/issues/detail?id=824626#c4
73
80
 
74
81
  [1.1]: #chromechromium
75
82
  [1.2]: https://chromedevtools.github.io/devtools-protocol/tot/
76
83
 
77
- [2.1]: #edge
78
- [2.2]: https://github.com/Microsoft/edge-diagnostics-adapter/wiki/Supported-features-and-API
84
+ [2.1]: #opera
85
+ [2.2]: https://chromedevtools.github.io/devtools-protocol/tot/
79
86
 
80
87
  [3.1]: #nodejs
81
88
  [3.2]: https://chromedevtools.github.io/devtools-protocol/v8/
@@ -83,6 +90,12 @@ Implementation | Protocol version | [Protocol] | [List] | [New] |
83
90
  [4.1]: #safari-ios
84
91
  [4.2]: http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/inspector/protocol
85
92
 
93
+ [5.1]: #edge
94
+ [5.2]: https://docs.microsoft.com/en-us/microsoft-edge/devtools-protocol/0.1/domains/
95
+
96
+ [6.1]: #firefox-nightly
97
+ [6.2]: https://firefox-source-docs.mozilla.org/remote/index.html
98
+
86
99
  [v6.3.0]: https://nodejs.org/en/blog/release/v6.3.0/
87
100
 
88
101
  [Protocol]: #cdpprotocoloptions-callback
@@ -96,8 +109,7 @@ The meaning of *target* varies according to the implementation, for example,
96
109
  each Chrome tab represents a target whereas for Node.js a target is the
97
110
  currently inspected script.
98
111
 
99
- Setup
100
- -----
112
+ ## Setup
101
113
 
102
114
  An instance of either Chrome itself or another implementation needs to be
103
115
  running on a known port in order to use this module (defaults to
@@ -123,6 +135,9 @@ Plug the device and enable the [port forwarding][adb], for example:
123
135
 
124
136
  adb forward tcp:9222 localabstract:chrome_devtools_remote
125
137
 
138
+ Note that in Android, Chrome does not have its own protocol available, a local
139
+ version must be used. See [here](#chrome-debugging-protocol-versions) for more information.
140
+
126
141
  [adb]: https://developer.chrome.com/devtools/docs/remote-debugging-legacy
127
142
 
128
143
  ##### WebView
@@ -139,11 +154,11 @@ Finally, port forwarding can be enabled as follows:
139
154
 
140
155
  [webview]: https://developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews#configure_webviews_for_debugging
141
156
 
142
- ### Edge
157
+ ### Opera
143
158
 
144
- Install and run the [Edge Diagnostics Adapter][edge-adapter].
159
+ Start Opera with the `--remote-debugging-port` option, for example:
145
160
 
146
- [edge-adapter]: https://github.com/Microsoft/edge-diagnostics-adapter
161
+ opera --remote-debugging-port=9222
147
162
 
148
163
  ### Node.js
149
164
 
@@ -153,12 +168,31 @@ Start Node.js with the `--inspect` option, for example:
153
168
 
154
169
  ### Safari (iOS)
155
170
 
156
- Install and run the [iOS WebKit Debug Proxy][iwdp].
171
+ Install and run the [iOS WebKit Debug Proxy][iwdp]. Then use it with the `local`
172
+ option set to `true` to use the local version of the protocol or pass a custom
173
+ descriptor upon connection (`protocol` option).
157
174
 
158
175
  [iwdp]: https://github.com/google/ios-webkit-debug-proxy
159
176
 
160
- Bundled client
161
- --------------
177
+ ### Edge
178
+
179
+ Start Edge with the `--devtools-server-port` option, for example:
180
+
181
+ MicrosoftEdge.exe --devtools-server-port 9222 about:blank
182
+
183
+ Please find more information [here][edge-devtools].
184
+
185
+ [edge-devtools]: https://docs.microsoft.com/en-us/microsoft-edge/devtools-protocol/
186
+
187
+ ### Firefox (Nightly)
188
+
189
+ Start Firefox with the `--remote-debugging-port` option, for example:
190
+
191
+ firefox --remote-debugging-port 9222
192
+
193
+ Bear in mind that this is an experimental feature of Firefox.
194
+
195
+ ## Bundled client
162
196
 
163
197
  This module comes with a bundled client application that can be used to
164
198
  interactively control a remote instance.
@@ -171,7 +205,7 @@ run with `--help` to display the list of available options.
171
205
 
172
206
  Here are some examples:
173
207
 
174
- ```javascript
208
+ ```js
175
209
  $ chrome-remote-interface new 'http://example.com'
176
210
  {
177
211
  "description": "",
@@ -188,67 +222,37 @@ $ chrome-remote-interface close 'b049bb56-de7d-424c-a331-6ae44cf7ae01'
188
222
 
189
223
  ### Inspection
190
224
 
191
- Using the `inspect` subcommand it is possible to
192
- perform [command execution](#clientdomainmethodparams-callback)
193
- and [event binding](#clientdomaineventcallback) in a REPL fashion. But unlike
194
- the regular API the callbacks are overridden to conveniently display the result
195
- of the commands and the message of the events. Also, the event binding is
196
- simplified here, executing a shorthand method (e.g., `Page.loadEventFired()`)
197
- toggles the event registration.
198
-
199
- Remember that the REPL interface provides completion.
225
+ Using the `inspect` subcommand it is possible to perform [command execution](#clientdomainmethodparams-callback)
226
+ and [event binding](#clientdomaineventcallback) in a REPL fashion that provides completion.
200
227
 
201
228
  Here is a sample session:
202
229
 
203
- ```javascript
230
+ ```js
204
231
  $ chrome-remote-interface inspect
205
232
  >>> Runtime.evaluate({expression: 'window.location.toString()'})
206
- { result:
207
- { result:
208
- { type: 'string',
209
- value: 'https://www.google.it/_/chrome/newtab?espv=2&ie=UTF-8' },
210
- wasThrown: false } }
233
+ { result: { type: 'string', value: 'about:blank' } }
211
234
  >>> Page.enable()
212
- { result: {} }
213
- >>> Page.loadEventFired() // registered
214
- { 'Page.loadEventFired': true }
215
- >>> Page.loadEventFired() // unregistered
216
- { 'Page.loadEventFired': false }
217
- >>> Page.loadEventFired() // registered
218
- { 'Page.loadEventFired': true }
235
+ {}
236
+ >>> Page.loadEventFired(console.log)
237
+ [Function]
219
238
  >>> Page.navigate({url: 'https://github.com'})
220
- { result: { frameId: '28677.1' } }
221
- { 'Page.loadEventFired': { timestamp: 21385.383076 } }
239
+ { frameId: 'E1657E22F06E6E0BE13DFA8130C20298',
240
+ loaderId: '439236ADE39978F98C20E8939A32D3A5' }
241
+ >>> { timestamp: 7454.721299 } // from Page.loadEventFired
222
242
  >>> Runtime.evaluate({expression: 'window.location.toString()'})
223
- { result:
224
- { result: { type: 'string', value: 'https://github.com/' },
225
- wasThrown: false } }
243
+ { result: { type: 'string', value: 'https://github.com/' } }
226
244
  ```
227
245
 
228
- #### Event filtering
246
+ Additionally there are some custom commands available:
229
247
 
230
- To reduce the amount of data displayed by the event listeners it is possible to
231
- provide a filter function. In this example only the resource URL is shown:
248
+ ```js
249
+ >>> .help
250
+ [...]
251
+ .reset Remove all the registered event handlers
252
+ .target Display the current target
253
+ ```
232
254
 
233
- ```javascript
234
- $ chrome-remote-interface inspect
235
- >>> Network.enable()
236
- { result: {} }
237
- >>> Network.requestWillBeSent(params => params.request.url)
238
- { 'Network.requestWillBeSent': 'params => params.request.url' }
239
- >>> Page.navigate({url: 'https://www.wikipedia.org'})
240
- { 'Network.requestWillBeSent': 'https://www.wikipedia.org/' }
241
- { result: { frameId: '5530.1' } }
242
- { 'Network.requestWillBeSent': 'https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia_wordmark.png' }
243
- { 'Network.requestWillBeSent': 'https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2.png' }
244
- { 'Network.requestWillBeSent': 'https://www.wikipedia.org/portal/wikipedia.org/assets/js/index-3b68787aa6.js' }
245
- { 'Network.requestWillBeSent': 'https://www.wikipedia.org/portal/wikipedia.org/assets/js/gt-ie9-c84bf66d33.js' }
246
- { 'Network.requestWillBeSent': 'https://www.wikipedia.org/portal/wikipedia.org/assets/img/sprite-bookshelf_icons.png?16ed124e8ca7c5ce9d463e8f99b2064427366360' }
247
- { 'Network.requestWillBeSent': 'https://www.wikipedia.org/portal/wikipedia.org/assets/img/sprite-project-logos.png?9afc01c5efe0a8fb6512c776955e2ad3eb48fbca' }
248
- ```
249
-
250
- Embedded documentation
251
- ----------------------
255
+ ## Embedded documentation
252
256
 
253
257
  In both the REPL and the regular API every object of the protocol is *decorated*
254
258
  with the meta information found within the descriptor. In addition The
@@ -257,7 +261,7 @@ with the meta information found within the descriptor. In addition The
257
261
 
258
262
  For example to learn how to call `Page.navigate`:
259
263
 
260
- ```javascript
264
+ ```js
261
265
  >>> Page.navigate
262
266
  { [Function]
263
267
  category: 'command',
@@ -273,7 +277,7 @@ For example to learn how to call `Page.navigate`:
273
277
 
274
278
  To learn about the parameters returned by the `Network.requestWillBeSent` event:
275
279
 
276
- ```javascript
280
+ ```js
277
281
  >>> Network.requestWillBeSent
278
282
  { [Function]
279
283
  category: 'event',
@@ -309,7 +313,7 @@ To learn about the parameters returned by the `Network.requestWillBeSent` event:
309
313
  To inspect the `Network.Request` (note that unlike commands and events, types
310
314
  are named in upper camel case) type:
311
315
 
312
- ```javascript
316
+ ```js
313
317
  >>> Network.Request
314
318
  { category: 'type',
315
319
  id: 'Request',
@@ -333,35 +337,28 @@ are named in upper camel case) type:
333
337
  description: 'Priority of the resource request at the time request is sent.' } } }
334
338
  ```
335
339
 
336
- Chrome Debugging Protocol versions
337
- ----------------------------------
338
-
339
- `chrome-remote-interface` uses the [local version] of the protocol descriptor by
340
- default. This file is manually updated from time to time using
341
- `scripts/update-protocol.sh` and pushed to this repository.
340
+ ## Chrome Debugging Protocol versions
342
341
 
343
- This behavior can be changed by setting the `remote` option to `true`
344
- upon [connection](#cdpoptions-callback), in which case the remote instance is
345
- *asked* to provide its own protocol descriptor.
342
+ By default `chrome-remote-interface` *asks* the remote instance to provide its
343
+ own protocol.
346
344
 
347
- Chrome < 60.0.3097.0 is not able to do that, so in that case the protocol
348
- descriptor is fetched from the source repository.
345
+ This behavior can be changed by setting the `local` option to `true`
346
+ upon [connection](#cdpoptions-callback), in which case the [local version] of
347
+ the protocol descriptor is used. This file is manually updated from time to time
348
+ using `scripts/update-protocol.sh` and pushed to this repository.
349
349
 
350
- To override the above behavior there are basically three options:
350
+ To further override the above behavior there are basically two options:
351
351
 
352
352
  - pass a custom protocol descriptor upon [connection](#cdpoptions-callback)
353
353
  (`protocol` option);
354
354
 
355
355
  - use the *raw* version of the [commands](#clientsendmethod-params-callback)
356
- and [events](#event-domainmethod) interface;
357
-
358
- - update the local copy with `scripts/update-protocol.sh` (not present when
359
- fetched with `npm install`).
356
+ and [events](#event-domainmethod) interface to use bleeding-edge features that
357
+ do not appear in the [local version] of the protocol descriptor;
360
358
 
361
359
  [local version]: lib/protocol.json
362
360
 
363
- Browser usage
364
- -------------
361
+ ## Browser usage
365
362
 
366
363
  This module is able to run within a web context, with obvious limitations
367
364
  though, namely external HTTP requests
@@ -385,10 +382,6 @@ It just works, simply require this module:
385
382
  const CDP = require('chrome-remote-interface');
386
383
  ```
387
384
 
388
- To use a non-minified version manually run webpack with:
389
-
390
- DEBUG=true npm run webpack
391
-
392
385
  ### Using *vanilla* JavaScript
393
386
 
394
387
  To generate a JavaScript file that can be used with a `<script>` element:
@@ -398,7 +391,6 @@ To generate a JavaScript file that can be used with a `<script>` element:
398
391
  2. manually run webpack with:
399
392
 
400
393
  TARGET=var npm run webpack
401
- TARGET=var DEBUG=true npm run webpack
402
394
 
403
395
  3. use as:
404
396
 
@@ -408,9 +400,20 @@ To generate a JavaScript file that can be used with a `<script>` element:
408
400
  </script>
409
401
  <script src="chrome-remote-interface.js"></script>
410
402
  ```
403
+ ## TypeScript Support
411
404
 
412
- API
413
- ---
405
+ [TypeScript][] definitions are kindly provided by [Khairul Azhar Kasmiran][] and [Seth Westphal][], and can be installed from [DefinitelyTyped][]:
406
+
407
+ ```
408
+ npm install --save-dev @types/chrome-remote-interface
409
+ ```
410
+
411
+ [TypeScript]: https://www.typescriptlang.org/
412
+ [Khairul Azhar Kasmiran]: https://github.com/kazarmy
413
+ [Seth Westphal]: https://github.com/westy92
414
+ [DefinitelyTyped]: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/chrome-remote-interface
415
+
416
+ ## API
414
417
 
415
418
  The API consists of three parts:
416
419
 
@@ -431,6 +434,9 @@ Connects to a remote instance using the [Chrome Debugging Protocol].
431
434
  - `host`: HTTP frontend host. Defaults to `localhost`;
432
435
  - `port`: HTTP frontend port. Defaults to `9222`;
433
436
  - `secure`: HTTPS/WSS frontend. Defaults to `false`;
437
+ - `useHostName`: do not perform a DNS lookup of the host. Defaults to `false`;
438
+ - `alterPath`: a `function` taking and returning the path fragment of a URL
439
+ before that a request happens. Defaults to the identity function;
434
440
  - `target`: determines which target this client should attach to. The behavior
435
441
  changes according to the type:
436
442
 
@@ -446,12 +452,14 @@ Connects to a remote instance using the [Chrome Debugging Protocol].
446
452
  the implementation (note that at most one connection can be established to the
447
453
  same target);
448
454
  - `protocol`: [Chrome Debugging Protocol] descriptor object. Defaults to use the
449
- protocol chosen according to the `remote` option;
450
- - `remote`: a boolean indicating whether the protocol must be fetched *remotely*
455
+ protocol chosen according to the `local` option;
456
+ - `local`: a boolean indicating whether the protocol must be fetched *remotely*
451
457
  or if the local version must be used. It has no effect if the `protocol`
452
458
  option is set. Defaults to `false`.
453
459
 
454
- These options are also valid properties of all the instances of the `CDP` class.
460
+ These options are also valid properties of all the instances of the `CDP`
461
+ class. In addition to that, the `webSocketUrl` field contains the currently used
462
+ WebSocket URL.
455
463
 
456
464
  `callback` is a listener automatically added to the `connect` event of the
457
465
  returned `EventEmitter`. When `callback` is omitted a `Promise` object is
@@ -462,7 +470,7 @@ The `EventEmitter` supports the following events:
462
470
 
463
471
  #### Event: 'connect'
464
472
 
465
- ```javascript
473
+ ```js
466
474
  function (client) {}
467
475
  ```
468
476
 
@@ -472,7 +480,7 @@ Emitted when the connection to the WebSocket is established.
472
480
 
473
481
  #### Event: 'error'
474
482
 
475
- ```javascript
483
+ ```js
476
484
  function (err) {}
477
485
  ```
478
486
 
@@ -490,28 +498,27 @@ Fetch the [Chrome Debugging Protocol] descriptor.
490
498
  - `host`: HTTP frontend host. Defaults to `localhost`;
491
499
  - `port`: HTTP frontend port. Defaults to `9222`;
492
500
  - `secure`: HTTPS/WSS frontend. Defaults to `false`;
493
- - `remote`: a boolean indicating whether the protocol must be fetched *remotely*
494
- or if the local version must be returned. If it is not possible to fulfill the
495
- request then the local version is used. Defaults to `false`.
501
+ - `useHostName`: do not perform a DNS lookup of the host. Defaults to `false`;
502
+ - `alterPath`: a `function` taking and returning the path fragment of a URL
503
+ before that a request happens. Defaults to the identity function;
504
+ - `local`: a boolean indicating whether the protocol must be fetched *remotely*
505
+ or if the local version must be returned. Defaults to `false`.
496
506
 
497
507
  `callback` is executed when the protocol is fetched, it gets the following
498
508
  arguments:
499
509
 
500
510
  - `err`: a `Error` object indicating the success status;
501
- - `protocol`: an object with the following properties:
502
- - `remote`: a boolean indicating whether the returned descriptor is the
503
- remote version or not (due to user choice or error);
504
- - `descriptor`: the [Chrome Debugging Protocol] descriptor.
511
+ - `protocol`: the [Chrome Debugging Protocol] descriptor.
505
512
 
506
513
  When `callback` is omitted a `Promise` object is returned.
507
514
 
508
515
  For example:
509
516
 
510
- ```javascript
517
+ ```js
511
518
  const CDP = require('chrome-remote-interface');
512
- CDP.Protocol(function (err, protocol) {
519
+ CDP.Protocol((err, protocol) => {
513
520
  if (!err) {
514
- console.log(JSON.stringify(protocol.descriptor, null, 4));
521
+ console.log(JSON.stringify(protocol, null, 4));
515
522
  }
516
523
  });
517
524
  ```
@@ -524,7 +531,10 @@ Request the list of the available open targets/tabs of the remote instance.
524
531
 
525
532
  - `host`: HTTP frontend host. Defaults to `localhost`;
526
533
  - `port`: HTTP frontend port. Defaults to `9222`;
527
- - `secure`: HTTPS/WSS frontend. Defaults to `false`.
534
+ - `secure`: HTTPS/WSS frontend. Defaults to `false`;
535
+ - `useHostName`: do not perform a DNS lookup of the host. Defaults to `false`;
536
+ - `alterPath`: a `function` taking and returning the path fragment of a URL
537
+ before that a request happens. Defaults to the identity function.
528
538
 
529
539
  `callback` is executed when the list is correctly received, it gets the
530
540
  following arguments:
@@ -537,9 +547,9 @@ When `callback` is omitted a `Promise` object is returned.
537
547
 
538
548
  For example:
539
549
 
540
- ```javascript
550
+ ```js
541
551
  const CDP = require('chrome-remote-interface');
542
- CDP.List(function (err, targets) {
552
+ CDP.List((err, targets) => {
543
553
  if (!err) {
544
554
  console.log(targets);
545
555
  }
@@ -555,6 +565,9 @@ Create a new target/tab in the remote instance.
555
565
  - `host`: HTTP frontend host. Defaults to `localhost`;
556
566
  - `port`: HTTP frontend port. Defaults to `9222`;
557
567
  - `secure`: HTTPS/WSS frontend. Defaults to `false`;
568
+ - `useHostName`: do not perform a DNS lookup of the host. Defaults to `false`;
569
+ - `alterPath`: a `function` taking and returning the path fragment of a URL
570
+ before that a request happens. Defaults to the identity function;
558
571
  - `url`: URL to load in the new target/tab. Defaults to `about:blank`.
559
572
 
560
573
  `callback` is executed when the target is created, it gets the following
@@ -568,9 +581,9 @@ When `callback` is omitted a `Promise` object is returned.
568
581
 
569
582
  For example:
570
583
 
571
- ```javascript
584
+ ```js
572
585
  const CDP = require('chrome-remote-interface');
573
- CDP.New(function (err, target) {
586
+ CDP.New((err, target) => {
574
587
  if (!err) {
575
588
  console.log(target);
576
589
  }
@@ -586,6 +599,9 @@ Activate an open target/tab of the remote instance.
586
599
  - `host`: HTTP frontend host. Defaults to `localhost`;
587
600
  - `port`: HTTP frontend port. Defaults to `9222`;
588
601
  - `secure`: HTTPS/WSS frontend. Defaults to `false`;
602
+ - `useHostName`: do not perform a DNS lookup of the host. Defaults to `false`;
603
+ - `alterPath`: a `function` taking and returning the path fragment of a URL
604
+ before that a request happens. Defaults to the identity function;
589
605
  - `id`: Target id. Required, no default.
590
606
 
591
607
  `callback` is executed when the response to the activation request is
@@ -597,9 +613,9 @@ When `callback` is omitted a `Promise` object is returned.
597
613
 
598
614
  For example:
599
615
 
600
- ```javascript
616
+ ```js
601
617
  const CDP = require('chrome-remote-interface');
602
- CDP.Activate({'id': 'CC46FBFA-3BDA-493B-B2E4-2BE6EB0D97EC'}, function (err) {
618
+ CDP.Activate({id: 'CC46FBFA-3BDA-493B-B2E4-2BE6EB0D97EC'}, (err) => {
603
619
  if (!err) {
604
620
  console.log('target is activated');
605
621
  }
@@ -615,6 +631,9 @@ Close an open target/tab of the remote instance.
615
631
  - `host`: HTTP frontend host. Defaults to `localhost`;
616
632
  - `port`: HTTP frontend port. Defaults to `9222`;
617
633
  - `secure`: HTTPS/WSS frontend. Defaults to `false`;
634
+ - `useHostName`: do not perform a DNS lookup of the host. Defaults to `false`;
635
+ - `alterPath`: a `function` taking and returning the path fragment of a URL
636
+ before that a request happens. Defaults to the identity function;
618
637
  - `id`: Target id. Required, no default.
619
638
 
620
639
  `callback` is executed when the response to the close request is received. It
@@ -626,9 +645,9 @@ When `callback` is omitted a `Promise` object is returned.
626
645
 
627
646
  For example:
628
647
 
629
- ```javascript
648
+ ```js
630
649
  const CDP = require('chrome-remote-interface');
631
- CDP.Close({'id': 'CC46FBFA-3BDA-493B-B2E4-2BE6EB0D97EC'}, function (err) {
650
+ CDP.Close({id: 'CC46FBFA-3BDA-493B-B2E4-2BE6EB0D97EC'}, (err) => {
632
651
  if (!err) {
633
652
  console.log('target is closing');
634
653
  }
@@ -646,7 +665,10 @@ Request version information from the remote instance.
646
665
 
647
666
  - `host`: HTTP frontend host. Defaults to `localhost`;
648
667
  - `port`: HTTP frontend port. Defaults to `9222`;
649
- - `secure`: HTTPS/WSS frontend. Defaults to `false`.
668
+ - `secure`: HTTPS/WSS frontend. Defaults to `false`;
669
+ - `useHostName`: do not perform a DNS lookup of the host. Defaults to `false`;
670
+ - `alterPath`: a `function` taking and returning the path fragment of a URL
671
+ before that a request happens. Defaults to the identity function.
650
672
 
651
673
  `callback` is executed when the version information is correctly received, it
652
674
  gets the following arguments:
@@ -659,9 +681,9 @@ When `callback` is omitted a `Promise` object is returned.
659
681
 
660
682
  For example:
661
683
 
662
- ```javascript
684
+ ```js
663
685
  const CDP = require('chrome-remote-interface');
664
- CDP.Version(function (err, info) {
686
+ CDP.Version((err, info) => {
665
687
  if (!err) {
666
688
  console.log(info);
667
689
  }
@@ -672,7 +694,7 @@ CDP.Version(function (err, info) {
672
694
 
673
695
  #### Event: 'event'
674
696
 
675
- ```javascript
697
+ ```js
676
698
  function (message) {}
677
699
  ```
678
700
 
@@ -682,14 +704,15 @@ Emitted when the remote instance sends any notification through the WebSocket.
682
704
 
683
705
  - `method`: a string describing the notification (e.g.,
684
706
  `'Network.requestWillBeSent'`);
685
- - `params`: an object containing the payload.
707
+ - `params`: an object containing the payload;
708
+ - `sessionId`: an optional string representing the session identifier.
686
709
 
687
710
  Refer to the [Chrome Debugging Protocol] specification for more information.
688
711
 
689
712
  For example:
690
713
 
691
- ```javascript
692
- client.on('event', function (message) {
714
+ ```js
715
+ client.on('event', (message) => {
693
716
  if (message.method === 'Network.requestWillBeSent') {
694
717
  console.log(message.params);
695
718
  }
@@ -698,8 +721,8 @@ client.on('event', function (message) {
698
721
 
699
722
  #### Event: '`<domain>`.`<method>`'
700
723
 
701
- ```javascript
702
- function (params) {}
724
+ ```js
725
+ function (params, sessionId) {}
703
726
  ```
704
727
 
705
728
  Emitted when the remote instance sends a notification for `<domain>.<method>`
@@ -707,16 +730,36 @@ through the WebSocket.
707
730
 
708
731
  `params` is an object containing the payload.
709
732
 
733
+ `sessionId` is an optional string representing the session identifier.
734
+
710
735
  This is just a utility event which allows to easily listen for specific
711
736
  notifications (see [`'event'`](#event-event)), for example:
712
737
 
713
- ```javascript
738
+ ```js
714
739
  client.on('Network.requestWillBeSent', console.log);
715
740
  ```
716
741
 
742
+ Additionally, the equivalent `<domain>.on('<method>', ...)` syntax is available, for example:
743
+
744
+ ```js
745
+ client.Network.on('requestWillBeSent', console.log);
746
+ ```
747
+
748
+ #### Event: '`<domain>`.`<method>`.`<sessionId>`'
749
+
750
+ ```js
751
+ function (params, sessionId) {}
752
+ ```
753
+
754
+ Equivalent to the following but only for those events belonging to the given `session`:
755
+
756
+ ```js
757
+ client.on('<domain>.<event>', callback);
758
+ ```
759
+
717
760
  #### Event: 'ready'
718
761
 
719
- ```javascript
762
+ ```js
720
763
  function () {}
721
764
  ```
722
765
 
@@ -733,11 +776,11 @@ prefer the promises API when dealing with complex asynchronous program flows.
733
776
  For example to load a URL only after having enabled the notifications of both
734
777
  `Network` and `Page` domains:
735
778
 
736
- ```javascript
779
+ ```js
737
780
  client.Network.enable();
738
781
  client.Page.enable();
739
- client.once('ready', function () {
740
- client.Page.navigate({'url': 'https://github.com'});
782
+ client.once('ready', () => {
783
+ client.Page.navigate({url: 'https://github.com'});
741
784
  });
742
785
  ```
743
786
 
@@ -748,7 +791,7 @@ client.
748
791
 
749
792
  #### Event: 'disconnect'
750
793
 
751
- ```javascript
794
+ ```js
752
795
  function () {}
753
796
  ```
754
797
 
@@ -757,7 +800,7 @@ Emitted when the instance closes the WebSocket connection.
757
800
  This may happen for example when the user opens DevTools or when the tab is
758
801
  closed.
759
802
 
760
- #### client.send(method, [params], [callback])
803
+ #### client.send(method, [params], [sessionId], [callback])
761
804
 
762
805
  Issue a command to the remote instance.
763
806
 
@@ -765,6 +808,8 @@ Issue a command to the remote instance.
765
808
 
766
809
  `params` is an object containing the payload.
767
810
 
811
+ `sessionId` is a string representing the session identifier.
812
+
768
813
  `callback` is executed when the remote instance sends a response to this
769
814
  command, it gets the following arguments:
770
815
 
@@ -775,46 +820,57 @@ command, it gets the following arguments:
775
820
  === true`).
776
821
 
777
822
  When `callback` is omitted a `Promise` object is returned instead, with the
778
- fulfilled/rejected states implemented according to the `error` parameter.
823
+ fulfilled/rejected states implemented according to the `error` parameter. The
824
+ `Error` object returned contains two additional parameters: `request` and
825
+ `response` which contain the raw massages, useful for debugging purposes. In
826
+ case of low-level WebSocket errors, the `error` parameter contains the
827
+ originating `Error` object and no `response` is returned.
779
828
 
780
829
  Note that the field `id` mentioned in the [Chrome Debugging Protocol]
781
830
  specification is managed internally and it is not exposed to the user.
782
831
 
783
832
  For example:
784
833
 
785
- ```javascript
786
- client.send('Page.navigate', {'url': 'https://github.com'}, console.log);
834
+ ```js
835
+ client.send('Page.navigate', {url: 'https://github.com'}, console.log);
787
836
  ```
788
837
 
789
- #### client.`<domain>`.`<method>`([params], [callback])
838
+ #### client.`<domain>`.`<method>`([params], [sessionId], [callback])
790
839
 
791
840
  Just a shorthand for:
792
841
 
793
- ```javascript
794
- client.send('<domain>.<method>', params, callback);
842
+ ```js
843
+ client.send('<domain>.<method>', params, sessionId, callback);
795
844
  ```
796
845
 
797
846
  For example:
798
847
 
799
- ```javascript
800
- client.Page.navigate({'url': 'https://github.com'}, console.log);
848
+ ```js
849
+ client.Page.navigate({url: 'https://github.com'}, console.log);
801
850
  ```
802
851
 
803
- #### client.`<domain>`.`<event>`([callback])
852
+ #### client.`<domain>`.`<event>`([sessionId], [callback])
804
853
 
805
854
  Just a shorthand for:
806
855
 
807
- ```javascript
808
- client.on('<domain>.<event>', callback);
856
+ ```js
857
+ client.on('<domain>.<event>[.<sessionId>]', callback);
809
858
  ```
810
859
 
811
- The only difference is that when `callback` is omitted the event is registered
812
- only once and a `Promise` object is returned.
860
+ When `callback` is omitted the event is registered only once and a `Promise`
861
+ object is returned. Notice though that in this case the optional `sessionId` usually passed to `callback` is not returned.
862
+
863
+ When `callback` is provided, it returns a function that can be used to
864
+ unsubscribe `callback` from the event, it can be useful when anonymous functions
865
+ are used as callbacks.
813
866
 
814
867
  For example:
815
868
 
816
- ```javascript
817
- client.Network.requestWillBeSent(console.log);
869
+ ```js
870
+ const unsubscribe = client.Network.requestWillBeSent((params, sessionId) => {
871
+ console.log(params.request.url);
872
+ });
873
+ unsubscribe();
818
874
  ```
819
875
 
820
876
  #### client.close([callback])
@@ -825,14 +881,98 @@ Close the connection to the remote instance.
825
881
 
826
882
  When `callback` is omitted a `Promise` object is returned.
827
883
 
828
- Contributors
829
- ------------
884
+ #### client['`<domain>`.`<name>`']
885
+
886
+ Just a shorthand for:
887
+
888
+ ```js
889
+ client.<domain>.<name>
890
+ ```
891
+
892
+ Where `<name>` can be a command, an event, or a type.
893
+
894
+ ## FAQ
895
+
896
+ ### Invoking `Domain.methodOrEvent` I obtain `Domain.methodOrEvent is not a function`
897
+
898
+ This means that you are trying to use a method or an event that are not present
899
+ in the protocol descriptor that you are using.
900
+
901
+ If the protocol is fetched from Chrome directly, then it means that this version
902
+ of Chrome does not support that feature. The solution is to update it.
903
+
904
+ If you are using a local or custom version of the protocol, then it means that
905
+ the version is obsolete. The solution is to provide an up-to-date one, or if you
906
+ are using the protocol embedded in chrome-remote-interface, make sure to be
907
+ running the latest version of this module. In case the embedded protocol is
908
+ obsolete, please [file an issue](https://github.com/cyrus-and/chrome-remote-interface/issues/new).
909
+
910
+ See [here](#chrome-debugging-protocol-versions) for more information.
911
+
912
+ ### Invoking `Domain.method` I obtain `Domain.method wasn't found`
913
+
914
+ This means that you are providing a custom or local protocol descriptor
915
+ (`CDP({protocol: customProtocol})`) which declares `Domain.method` while the
916
+ Chrome version that you are using does not support it.
917
+
918
+ To inspect the currently available protocol descriptor use:
919
+
920
+ ```
921
+ $ chrome-remote-interface inspect
922
+ ```
923
+
924
+ See [here](#chrome-debugging-protocol-versions) for more information.
925
+
926
+ ### Why my program stalls or behave unexpectedly if I run Chrome in a Docker container?
927
+
928
+ This happens because the size of `/dev/shm` is set to 64MB by default in Docker
929
+ and may not be enough for Chrome to navigate certain web pages.
930
+
931
+ You can change this value by running your container with, say,
932
+ `--shm-size=256m`.
933
+
934
+ ### Using `Runtime.evaluate` with `awaitPromise: true` I sometimes obtain `Error: Promise was collected`
935
+
936
+ This is thrown by `Runtime.evaluate` when the browser-side promise gets
937
+ *collected* by the Chrome's garbage collector, this happens when the whole
938
+ JavaScript execution environment is invalidated, e.g., a when page is navigated
939
+ or reloaded while a promise is still waiting to be resolved.
940
+
941
+ Here is an example:
942
+
943
+ ```
944
+ $ chrome-remote-interface inspect
945
+ >>> Runtime.evaluate({expression: `new Promise(() => {})`, awaitPromise: true})
946
+ >>> Page.reload() // then wait several seconds
947
+ { result: {} }
948
+ { error: { code: -32000, message: 'Promise was collected' } }
949
+ ```
950
+
951
+ To fix this, just make sure there are no pending promises before closing,
952
+ reloading, etc. a page.
953
+
954
+ ### How does this compare to Puppeteer?
955
+
956
+ [Puppeteer] is an additional high-level API built upon the [Chrome Debugging
957
+ Protocol] which, among the other things, may start and use a bundled version of
958
+ Chromium instead of the one installed on your system. Use it if its API meets
959
+ your needs as it would probably be easier to work with.
960
+
961
+ chrome-remote-interface instead is just a general purpose 1:1 Node.js binding
962
+ for the [Chrome Debugging Protocol]. Use it if you need all the power of the raw
963
+ protocol, e.g., to implement your own high-level API.
964
+
965
+ See [#240] for a more thorough discussion.
966
+
967
+ [Puppeteer]: https://github.com/GoogleChrome/puppeteer
968
+ [#240]: https://github.com/cyrus-and/chrome-remote-interface/issues/240
969
+
970
+ ## Contributors
830
971
 
831
972
  - [Andrey Sidorov](https://github.com/sidorares)
832
973
  - [Greg Cochard](https://github.com/gcochard)
833
974
 
834
- Resources
835
- ---------
975
+ ## Resources
836
976
 
837
977
  - [Chrome Debugging Protocol]
838
978
  - [Chrome Debugging Protocol Google group](https://groups.google.com/forum/#!forum/chrome-debugging-protocol)