opal 0.11.0.rc1 → 0.11.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.
Files changed (493) hide show
  1. checksums.yaml +4 -4
  2. data/.jshintrc +1 -1
  3. data/.travis.yml +14 -2
  4. data/CHANGELOG.md +30 -5
  5. data/HACKING.md +2 -2
  6. data/README.md +4 -5
  7. data/appveyor.yml +3 -4
  8. data/bin +1 -0
  9. data/docs/headless_chrome.md +105 -0
  10. data/docs/rspec.md +2 -19
  11. data/{bin → exe}/opal +0 -0
  12. data/{bin → exe}/opal-build +0 -0
  13. data/{bin → exe}/opal-mspec +0 -0
  14. data/{bin → exe}/opal-repl +0 -0
  15. data/lib/opal.rb +1 -0
  16. data/lib/opal/ast/builder.rb +0 -4
  17. data/lib/opal/builder.rb +69 -15
  18. data/lib/opal/builder_processors.rb +8 -7
  19. data/lib/opal/cli.rb +1 -1
  20. data/lib/opal/cli_options.rb +1 -1
  21. data/lib/opal/cli_runners.rb +1 -1
  22. data/lib/opal/cli_runners/applescript.rb +0 -1
  23. data/lib/opal/cli_runners/chrome.js +135 -0
  24. data/lib/opal/cli_runners/chrome.rb +100 -0
  25. data/lib/opal/cli_runners/nashorn.rb +0 -1
  26. data/lib/opal/cli_runners/node_modules/.bin/chrome-remote-interface +1 -0
  27. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/LICENSE +18 -0
  28. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/README.md +843 -0
  29. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/bin/client.js +326 -0
  30. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/chrome-remote-interface.js +11 -0
  31. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/index.js +39 -0
  32. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/api.js +84 -0
  33. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/chrome.js +289 -0
  34. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/defaults.js +4 -0
  35. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/devtools.js +245 -0
  36. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/external-request.js +23 -0
  37. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/protocol.json +13303 -0
  38. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/websocket-wrapper.js +32 -0
  39. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/package.json +128 -0
  40. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/webpack.config.js +55 -0
  41. data/lib/opal/cli_runners/node_modules/commander/Readme.md +195 -0
  42. data/lib/opal/cli_runners/node_modules/commander/index.js +851 -0
  43. data/lib/opal/cli_runners/node_modules/commander/package.json +92 -0
  44. data/lib/opal/cli_runners/node_modules/ultron/LICENSE +22 -0
  45. data/lib/opal/cli_runners/node_modules/ultron/index.js +138 -0
  46. data/lib/opal/cli_runners/node_modules/ultron/package.json +112 -0
  47. data/lib/opal/cli_runners/node_modules/ws/LICENSE +21 -0
  48. data/lib/opal/cli_runners/node_modules/ws/README.md +259 -0
  49. data/lib/opal/cli_runners/node_modules/ws/SECURITY.md +33 -0
  50. data/lib/opal/cli_runners/node_modules/ws/index.js +15 -0
  51. data/lib/opal/cli_runners/node_modules/ws/lib/BufferUtil.fallback.js +56 -0
  52. data/lib/opal/cli_runners/node_modules/ws/lib/BufferUtil.js +15 -0
  53. data/lib/opal/cli_runners/node_modules/ws/lib/ErrorCodes.js +28 -0
  54. data/lib/opal/cli_runners/node_modules/ws/lib/EventTarget.js +158 -0
  55. data/lib/opal/cli_runners/node_modules/ws/lib/Extensions.js +69 -0
  56. data/lib/opal/cli_runners/node_modules/ws/lib/PerMessageDeflate.js +339 -0
  57. data/lib/opal/cli_runners/node_modules/ws/lib/Receiver.js +520 -0
  58. data/lib/opal/cli_runners/node_modules/ws/lib/Sender.js +438 -0
  59. data/lib/opal/cli_runners/node_modules/ws/lib/Validation.fallback.js +9 -0
  60. data/lib/opal/cli_runners/node_modules/ws/lib/Validation.js +17 -0
  61. data/lib/opal/cli_runners/node_modules/ws/lib/WebSocket.js +705 -0
  62. data/lib/opal/cli_runners/node_modules/ws/lib/WebSocketServer.js +336 -0
  63. data/lib/opal/cli_runners/node_modules/ws/package.json +122 -0
  64. data/lib/opal/cli_runners/nodejs.rb +0 -1
  65. data/lib/opal/cli_runners/package.json +5 -0
  66. data/lib/opal/cli_runners/server.rb +0 -1
  67. data/lib/opal/compiler.rb +8 -18
  68. data/lib/opal/deprecations.rb +1 -1
  69. data/lib/opal/eof_content.rb +36 -0
  70. data/lib/opal/nodes.rb +0 -1
  71. data/lib/opal/nodes/args/kwarg.rb +8 -6
  72. data/lib/opal/nodes/args/kwoptarg.rb +12 -6
  73. data/lib/opal/nodes/call.rb +3 -2
  74. data/lib/opal/nodes/call_special.rb +10 -1
  75. data/lib/opal/nodes/definitions.rb +5 -3
  76. data/lib/opal/nodes/helpers.rb +4 -8
  77. data/lib/opal/nodes/literal.rb +13 -1
  78. data/lib/opal/nodes/logic.rb +19 -32
  79. data/lib/opal/nodes/node_with_args.rb +1 -1
  80. data/lib/opal/nodes/scope.rb +1 -0
  81. data/lib/opal/nodes/super.rb +0 -4
  82. data/lib/opal/nodes/variables.rb +11 -0
  83. data/lib/opal/parser.rb +24 -19
  84. data/lib/opal/path_reader.rb +17 -4
  85. data/lib/opal/rewriter.rb +5 -1
  86. data/lib/opal/rewriters/base.rb +37 -34
  87. data/lib/opal/rewriters/binary_operator_assignment.rb +0 -3
  88. data/lib/opal/rewriters/for_rewriter.rb +93 -0
  89. data/lib/opal/rewriters/hashes/key_duplicates_rewriter.rb +58 -0
  90. data/lib/opal/rewriters/js_reserved_words.rb +5 -8
  91. data/lib/opal/rewriters/logical_operator_assignment.rb +0 -1
  92. data/lib/opal/simple_server.rb +1 -0
  93. data/lib/opal/util.rb +1 -1
  94. data/lib/opal/version.rb +1 -1
  95. data/opal.gemspec +32 -30
  96. data/opal/corelib/array.rb +53 -30
  97. data/opal/corelib/boolean.rb +11 -3
  98. data/opal/corelib/comparable.rb +16 -0
  99. data/opal/corelib/constants.rb +3 -3
  100. data/opal/corelib/enumerable.rb +48 -1
  101. data/opal/corelib/file.rb +54 -11
  102. data/opal/corelib/hash.rb +98 -0
  103. data/opal/corelib/io.rb +2 -2
  104. data/opal/corelib/kernel.rb +28 -11
  105. data/opal/corelib/marshal/read_buffer.rb +288 -150
  106. data/opal/corelib/marshal/write_buffer.rb +27 -2
  107. data/opal/corelib/nil.rb +11 -3
  108. data/opal/corelib/number.rb +90 -20
  109. data/opal/corelib/numeric.rb +3 -3
  110. data/opal/corelib/random.rb +1 -1
  111. data/opal/corelib/range.rb +22 -22
  112. data/opal/corelib/regexp.rb +45 -4
  113. data/opal/corelib/runtime.js +25 -9
  114. data/opal/corelib/string.rb +1 -1
  115. data/opal/corelib/string/encoding.rb +21 -29
  116. data/opal/corelib/string/inheritance.rb +1 -1
  117. data/opal/corelib/struct.rb +0 -5
  118. data/opal/corelib/time.rb +1 -1
  119. data/stdlib/buffer/array.rb +4 -2
  120. data/stdlib/date.rb +46 -12
  121. data/stdlib/headless_chrome.rb +11 -0
  122. data/stdlib/nodejs/file.rb +36 -11
  123. data/stdlib/nodejs/io.rb +8 -0
  124. data/stdlib/nodejs/stacktrace.rb +116 -100
  125. data/stdlib/opal-builder.rb +1 -0
  126. data/stdlib/opal-platform.rb +6 -6
  127. data/stdlib/opal/platform.rb +2 -2
  128. data/stdlib/rbconfig.rb +1 -1
  129. data/stdlib/securerandom.rb +1 -1
  130. data/tasks/testing.rake +58 -26
  131. data/tasks/testing/opal_rspec_smoketest.Gemfile +5 -12
  132. metadata +64 -733
  133. data/lib/opal/cli_runners/phantom.js +0 -69
  134. data/lib/opal/cli_runners/phantomjs.rb +0 -29
  135. data/lib/opal/hike_path_finder.rb +0 -19
  136. data/lib/opal/nodes/for.rb +0 -75
  137. data/spec/README.md +0 -10
  138. data/spec/filters/bugs/array.rb +0 -16
  139. data/spec/filters/bugs/basicobject.rb +0 -13
  140. data/spec/filters/bugs/bigdecimal.rb +0 -146
  141. data/spec/filters/bugs/class.rb +0 -11
  142. data/spec/filters/bugs/comparable.rb +0 -5
  143. data/spec/filters/bugs/complex.rb +0 -3
  144. data/spec/filters/bugs/date.rb +0 -94
  145. data/spec/filters/bugs/enumerable.rb +0 -43
  146. data/spec/filters/bugs/enumerator.rb +0 -40
  147. data/spec/filters/bugs/exception.rb +0 -72
  148. data/spec/filters/bugs/file.rb +0 -8
  149. data/spec/filters/bugs/float.rb +0 -39
  150. data/spec/filters/bugs/hash.rb +0 -15
  151. data/spec/filters/bugs/inheritance.rb +0 -5
  152. data/spec/filters/bugs/integer.rb +0 -30
  153. data/spec/filters/bugs/io.rb +0 -8
  154. data/spec/filters/bugs/kernel.rb +0 -168
  155. data/spec/filters/bugs/language.rb +0 -190
  156. data/spec/filters/bugs/marshal.rb +0 -41
  157. data/spec/filters/bugs/method.rb +0 -60
  158. data/spec/filters/bugs/module.rb +0 -158
  159. data/spec/filters/bugs/numeric.rb +0 -8
  160. data/spec/filters/bugs/pathname.rb +0 -7
  161. data/spec/filters/bugs/proc.rb +0 -37
  162. data/spec/filters/bugs/random.rb +0 -7
  163. data/spec/filters/bugs/range.rb +0 -36
  164. data/spec/filters/bugs/rational.rb +0 -4
  165. data/spec/filters/bugs/regexp.rb +0 -158
  166. data/spec/filters/bugs/set.rb +0 -41
  167. data/spec/filters/bugs/singleton.rb +0 -6
  168. data/spec/filters/bugs/string.rb +0 -98
  169. data/spec/filters/bugs/stringscanner.rb +0 -71
  170. data/spec/filters/bugs/struct.rb +0 -4
  171. data/spec/filters/bugs/time.rb +0 -35
  172. data/spec/filters/bugs/unboundmethod.rb +0 -17
  173. data/spec/filters/unsupported/array.rb +0 -167
  174. data/spec/filters/unsupported/basicobject.rb +0 -14
  175. data/spec/filters/unsupported/bignum.rb +0 -55
  176. data/spec/filters/unsupported/class.rb +0 -4
  177. data/spec/filters/unsupported/delegator.rb +0 -5
  178. data/spec/filters/unsupported/enumerable.rb +0 -11
  179. data/spec/filters/unsupported/enumerator.rb +0 -13
  180. data/spec/filters/unsupported/file.rb +0 -4
  181. data/spec/filters/unsupported/fixnum.rb +0 -14
  182. data/spec/filters/unsupported/float.rb +0 -46
  183. data/spec/filters/unsupported/freeze.rb +0 -75
  184. data/spec/filters/unsupported/hash.rb +0 -43
  185. data/spec/filters/unsupported/integer.rb +0 -3
  186. data/spec/filters/unsupported/kernel.rb +0 -32
  187. data/spec/filters/unsupported/language.rb +0 -22
  188. data/spec/filters/unsupported/marshal.rb +0 -46
  189. data/spec/filters/unsupported/matchdata.rb +0 -33
  190. data/spec/filters/unsupported/math.rb +0 -3
  191. data/spec/filters/unsupported/pathname.rb +0 -3
  192. data/spec/filters/unsupported/privacy.rb +0 -279
  193. data/spec/filters/unsupported/proc.rb +0 -3
  194. data/spec/filters/unsupported/random.rb +0 -4
  195. data/spec/filters/unsupported/range.rb +0 -7
  196. data/spec/filters/unsupported/regexp.rb +0 -69
  197. data/spec/filters/unsupported/set.rb +0 -4
  198. data/spec/filters/unsupported/singleton.rb +0 -6
  199. data/spec/filters/unsupported/string.rb +0 -546
  200. data/spec/filters/unsupported/struct.rb +0 -6
  201. data/spec/filters/unsupported/symbol.rb +0 -20
  202. data/spec/filters/unsupported/taint.rb +0 -30
  203. data/spec/filters/unsupported/thread.rb +0 -7
  204. data/spec/filters/unsupported/time.rb +0 -202
  205. data/spec/lib/builder_processors_spec.rb +0 -27
  206. data/spec/lib/builder_spec.rb +0 -89
  207. data/spec/lib/cli_runners/phantomjs_spec.rb +0 -39
  208. data/spec/lib/cli_spec.rb +0 -240
  209. data/spec/lib/compiler/call_spec.rb +0 -732
  210. data/spec/lib/compiler_spec.rb +0 -294
  211. data/spec/lib/config_spec.rb +0 -110
  212. data/spec/lib/dependency_resolver_spec.rb +0 -40
  213. data/spec/lib/deprecations_spec.rb +0 -16
  214. data/spec/lib/fixtures/complex_sprockets.js.rb.erb +0 -4
  215. data/spec/lib/fixtures/file_with_directives.js +0 -2
  216. data/spec/lib/fixtures/jst_file.js.jst +0 -1
  217. data/spec/lib/fixtures/no_requires.rb +0 -1
  218. data/spec/lib/fixtures/opal_file.rb +0 -2
  219. data/spec/lib/fixtures/require_tree_test.rb +0 -3
  220. data/spec/lib/fixtures/required_file.js +0 -1
  221. data/spec/lib/fixtures/required_tree_test/required_file1.rb +0 -1
  222. data/spec/lib/fixtures/required_tree_test/required_file2.rb +0 -1
  223. data/spec/lib/fixtures/requires.rb +0 -7
  224. data/spec/lib/fixtures/source_location_test.rb +0 -7
  225. data/spec/lib/fixtures/source_map.rb +0 -1
  226. data/spec/lib/fixtures/source_map/subfolder/other_file.rb +0 -1
  227. data/spec/lib/fixtures/sprockets_file.js.rb +0 -3
  228. data/spec/lib/fixtures/sprockets_require_tree_test.rb +0 -3
  229. data/spec/lib/hike_path_finder_spec.rb +0 -23
  230. data/spec/lib/path_reader_spec.rb +0 -36
  231. data/spec/lib/paths_spec.rb +0 -18
  232. data/spec/lib/rewriters/binary_operator_assignment_spec.rb +0 -151
  233. data/spec/lib/rewriters/block_to_iter_spec.rb +0 -28
  234. data/spec/lib/rewriters/dot_js_syntax_spec.rb +0 -108
  235. data/spec/lib/rewriters/explicit_writer_return_spec.rb +0 -186
  236. data/spec/lib/rewriters/js_reserved_words_spec.rb +0 -116
  237. data/spec/lib/rewriters/logical_operator_assignment_spec.rb +0 -202
  238. data/spec/lib/rewriters/opal_engine_check_spec.rb +0 -82
  239. data/spec/lib/rewriters/rubyspec/filters_rewriter_spec.rb +0 -53
  240. data/spec/lib/shared/path_finder_shared.rb +0 -19
  241. data/spec/lib/shared/path_reader_shared.rb +0 -31
  242. data/spec/lib/simple_server_spec.rb +0 -54
  243. data/spec/lib/spec_helper.rb +0 -100
  244. data/spec/mspec-opal/formatters.rb +0 -236
  245. data/spec/mspec-opal/runner.rb +0 -173
  246. data/spec/opal/compiler/irb_spec.rb +0 -44
  247. data/spec/opal/core/arity_spec.rb +0 -142
  248. data/spec/opal/core/array/intersection_spec.rb +0 -38
  249. data/spec/opal/core/array/minus_spec.rb +0 -38
  250. data/spec/opal/core/array/select_spec.rb +0 -14
  251. data/spec/opal/core/array/set_range_to_array_spec.rb +0 -7
  252. data/spec/opal/core/array/union_spec.rb +0 -38
  253. data/spec/opal/core/array/uniq_spec.rb +0 -49
  254. data/spec/opal/core/date_spec.rb +0 -191
  255. data/spec/opal/core/enumerable/all_break_spec.rb +0 -5
  256. data/spec/opal/core/enumerable/any_break_spec.rb +0 -5
  257. data/spec/opal/core/enumerable/collect_break_spec.rb +0 -13
  258. data/spec/opal/core/enumerable/count_break_spec.rb +0 -5
  259. data/spec/opal/core/enumerable/detect_break_spec.rb +0 -5
  260. data/spec/opal/core/enumerable/drop_while_break_spec.rb +0 -5
  261. data/spec/opal/core/enumerable/each_slice_break.rb +0 -6
  262. data/spec/opal/core/enumerable/each_with_index_break_spec.rb +0 -5
  263. data/spec/opal/core/enumerable/each_with_object_break_spec.rb +0 -5
  264. data/spec/opal/core/enumerable/find_all_break_spec.rb +0 -5
  265. data/spec/opal/core/enumerable/find_index_break_spec.rb +0 -5
  266. data/spec/opal/core/enumerable/grep_break_spec.rb +0 -5
  267. data/spec/opal/core/enumerable/max_break_spec.rb +0 -5
  268. data/spec/opal/core/enumerable/max_by_break_spec.rb +0 -5
  269. data/spec/opal/core/enumerable/min_break_spec.rb +0 -5
  270. data/spec/opal/core/enumerable/min_by_break_spec.rb +0 -5
  271. data/spec/opal/core/enumerable/none_break_spec.rb +0 -5
  272. data/spec/opal/core/enumerable/one_break_spec.rb +0 -5
  273. data/spec/opal/core/enumerable/reduce_break_spec.rb +0 -5
  274. data/spec/opal/core/enumerable/take_while_break_spec.rb +0 -5
  275. data/spec/opal/core/enumerator/with_index_spec.rb +0 -6
  276. data/spec/opal/core/exception_spec.rb +0 -30
  277. data/spec/opal/core/fixtures/class.rb +0 -124
  278. data/spec/opal/core/fixtures/class_variables.rb +0 -0
  279. data/spec/opal/core/fixtures/constants.rb +0 -33
  280. data/spec/opal/core/fixtures/require_tree_files/file 1.rb +0 -1
  281. data/spec/opal/core/fixtures/require_tree_files/file 2.rb +0 -1
  282. data/spec/opal/core/fixtures/require_tree_files/file 3.rb +0 -1
  283. data/spec/opal/core/fixtures/require_tree_files/file 4.rb +0 -1
  284. data/spec/opal/core/fixtures/require_tree_files/file 5.rb +0 -1
  285. data/spec/opal/core/fixtures/require_tree_files/nested/nested 1.rb +0 -1
  286. data/spec/opal/core/fixtures/require_tree_files/nested/nested 2.rb +0 -1
  287. data/spec/opal/core/fixtures/require_tree_files/other/other 1.rb +0 -1
  288. data/spec/opal/core/fixtures/require_tree_with_dot/file 1.rb +0 -1
  289. data/spec/opal/core/fixtures/require_tree_with_dot/file 2.rb +0 -1
  290. data/spec/opal/core/fixtures/require_tree_with_dot/file 3.rb +0 -1
  291. data/spec/opal/core/fixtures/require_tree_with_dot/index.rb +0 -3
  292. data/spec/opal/core/hash/has_value_spec.rb +0 -13
  293. data/spec/opal/core/hash/internals_spec.rb +0 -332
  294. data/spec/opal/core/helpers_spec.rb +0 -14
  295. data/spec/opal/core/kernel/Array_spec.rb +0 -10
  296. data/spec/opal/core/kernel/at_exit_spec.rb +0 -70
  297. data/spec/opal/core/kernel/block_given_spec.rb +0 -30
  298. data/spec/opal/core/kernel/class_spec.rb +0 -6
  299. data/spec/opal/core/kernel/define_singleton_method_spec.rb +0 -21
  300. data/spec/opal/core/kernel/equal_value_spec.rb +0 -12
  301. data/spec/opal/core/kernel/extend_spec.rb +0 -21
  302. data/spec/opal/core/kernel/format_spec.rb +0 -122
  303. data/spec/opal/core/kernel/freeze_spec.rb +0 -15
  304. data/spec/opal/core/kernel/instance_eval_spec.rb +0 -28
  305. data/spec/opal/core/kernel/instance_variable_defined_spec.rb +0 -15
  306. data/spec/opal/core/kernel/instance_variable_get_spec.rb +0 -14
  307. data/spec/opal/core/kernel/instance_variable_set_spec.rb +0 -10
  308. data/spec/opal/core/kernel/instance_variables_spec.rb +0 -110
  309. data/spec/opal/core/kernel/loop_spec.rb +0 -23
  310. data/spec/opal/core/kernel/match_spec.rb +0 -5
  311. data/spec/opal/core/kernel/method_spec.rb +0 -31
  312. data/spec/opal/core/kernel/methods_spec.rb +0 -25
  313. data/spec/opal/core/kernel/nil_spec.rb +0 -7
  314. data/spec/opal/core/kernel/p_spec.rb +0 -15
  315. data/spec/opal/core/kernel/printf_spec.rb +0 -11
  316. data/spec/opal/core/kernel/proc_spec.rb +0 -13
  317. data/spec/opal/core/kernel/raise_spec.rb +0 -13
  318. data/spec/opal/core/kernel/rand_spec.rb +0 -19
  319. data/spec/opal/core/kernel/require_tree_spec.rb +0 -18
  320. data/spec/opal/core/kernel/respond_to_spec.rb +0 -44
  321. data/spec/opal/core/kernel/send_spec.rb +0 -56
  322. data/spec/opal/core/kernel/sprintf_spec.rb +0 -5
  323. data/spec/opal/core/language/arguments/mlhs_arg_spec.rb +0 -19
  324. data/spec/opal/core/language/class_spec.rb +0 -55
  325. data/spec/opal/core/language/constant_lookup_spec.rb +0 -38
  326. data/spec/opal/core/language/equal_spec.rb +0 -8
  327. data/spec/opal/core/language/fixtures/array.rb +0 -11
  328. data/spec/opal/core/language/fixtures/block.rb +0 -57
  329. data/spec/opal/core/language/fixtures/break.rb +0 -240
  330. data/spec/opal/core/language/fixtures/ensure.rb +0 -72
  331. data/spec/opal/core/language/fixtures/literal_lambda.rb +0 -7
  332. data/spec/opal/core/language/fixtures/metaclass.rb +0 -33
  333. data/spec/opal/core/language/fixtures/module.rb +0 -24
  334. data/spec/opal/core/language/fixtures/next.rb +0 -128
  335. data/spec/opal/core/language/fixtures/return.rb +0 -118
  336. data/spec/opal/core/language/fixtures/send.rb +0 -111
  337. data/spec/opal/core/language/fixtures/send_1.9.rb +0 -22
  338. data/spec/opal/core/language/fixtures/super.rb +0 -308
  339. data/spec/opal/core/language/fixtures/variables.rb +0 -58
  340. data/spec/opal/core/language/fixtures/yield.rb +0 -28
  341. data/spec/opal/core/language/heredoc_spec.rb +0 -42
  342. data/spec/opal/core/language/keyword_arguments_spec.rb +0 -11
  343. data/spec/opal/core/language/predefined_spec.rb +0 -138
  344. data/spec/opal/core/language/regexp_spec.rb +0 -20
  345. data/spec/opal/core/language/rescue_spec.rb +0 -18
  346. data/spec/opal/core/language/safe_navigator_spec.rb +0 -7
  347. data/spec/opal/core/language/send_spec.rb +0 -222
  348. data/spec/opal/core/language/string_spec.rb +0 -44
  349. data/spec/opal/core/language/ternary_operator_spec.rb +0 -20
  350. data/spec/opal/core/language/versions/array_1.9.rb +0 -39
  351. data/spec/opal/core/language/versions/block_1.9.rb +0 -0
  352. data/spec/opal/core/language/versions/break_1.9.rb +0 -0
  353. data/spec/opal/core/language/versions/case_1.9.rb +0 -20
  354. data/spec/opal/core/language/versions/def_2_0_spec.rb +0 -58
  355. data/spec/opal/core/language/versions/hash_1_9_spec.rb +0 -23
  356. data/spec/opal/core/language/versions/literal_lambda_1.9.rb +0 -143
  357. data/spec/opal/core/language/versions/not_1.9.rb +0 -22
  358. data/spec/opal/core/language/versions/send_1.9.rb +0 -241
  359. data/spec/opal/core/language/versions/symbol_1.9.rb +0 -15
  360. data/spec/opal/core/language/versions/variables_1.9.rb +0 -8
  361. data/spec/opal/core/language_spec.rb +0 -77
  362. data/spec/opal/core/marshal/dump_spec.rb +0 -53
  363. data/spec/opal/core/marshal/load_spec.rb +0 -7
  364. data/spec/opal/core/method/to_proc_spec.rb +0 -28
  365. data/spec/opal/core/module/alias_method_spec.rb +0 -28
  366. data/spec/opal/core/module/ancestors_spec.rb +0 -11
  367. data/spec/opal/core/module/append_features_spec.rb +0 -14
  368. data/spec/opal/core/module/attr_accessor_spec.rb +0 -26
  369. data/spec/opal/core/module/const_defined_spec.rb +0 -84
  370. data/spec/opal/core/module/const_get_spec.rb +0 -85
  371. data/spec/opal/core/module/const_missing_spec.rb +0 -17
  372. data/spec/opal/core/module/const_set_spec.rb +0 -64
  373. data/spec/opal/core/module/constants_spec.rb +0 -49
  374. data/spec/opal/core/module/fixtures/classes.rb +0 -444
  375. data/spec/opal/core/module/method_defined_spec.rb +0 -48
  376. data/spec/opal/core/module/method_lookup_spec.rb +0 -13
  377. data/spec/opal/core/module/module_function_spec.rb +0 -25
  378. data/spec/opal/core/module/name_spec.rb +0 -41
  379. data/spec/opal/core/module/public_method_defined_spec.rb +0 -18
  380. data/spec/opal/core/module/remove_const_spec.rb +0 -22
  381. data/spec/opal/core/module/undef_method_spec.rb +0 -66
  382. data/spec/opal/core/numeric/bit_and_spec.rb +0 -7
  383. data/spec/opal/core/numeric/bit_or_spec.rb +0 -8
  384. data/spec/opal/core/numeric/bit_xor_spec.rb +0 -6
  385. data/spec/opal/core/numeric/ceil_spec.rb +0 -8
  386. data/spec/opal/core/numeric/chr_spec.rb +0 -8
  387. data/spec/opal/core/numeric/comparison_spec.rb +0 -24
  388. data/spec/opal/core/numeric/complement_spec.rb +0 -8
  389. data/spec/opal/core/numeric/divide_spec.rb +0 -10
  390. data/spec/opal/core/numeric/eql_spec.rb +0 -9
  391. data/spec/opal/core/numeric/exponent_spec.rb +0 -33
  392. data/spec/opal/core/numeric/floor_spec.rb +0 -8
  393. data/spec/opal/core/numeric/gt_spec.rb +0 -11
  394. data/spec/opal/core/numeric/gte_spec.rb +0 -12
  395. data/spec/opal/core/numeric/integer_spec.rb +0 -9
  396. data/spec/opal/core/numeric/left_shift_spec.rb +0 -21
  397. data/spec/opal/core/numeric/lt_spec.rb +0 -11
  398. data/spec/opal/core/numeric/lte_spec.rb +0 -12
  399. data/spec/opal/core/numeric/minus_spec.rb +0 -8
  400. data/spec/opal/core/numeric/modulo_spec.rb +0 -19
  401. data/spec/opal/core/numeric/multiply_spec.rb +0 -9
  402. data/spec/opal/core/numeric/next_spec.rb +0 -9
  403. data/spec/opal/core/numeric/ord_spec.rb +0 -9
  404. data/spec/opal/core/numeric/plus_spec.rb +0 -8
  405. data/spec/opal/core/numeric/pred_spec.rb +0 -7
  406. data/spec/opal/core/numeric/right_shift_spec.rb +0 -25
  407. data/spec/opal/core/numeric/step_spec.rb +0 -11
  408. data/spec/opal/core/numeric/succ_spec.rb +0 -9
  409. data/spec/opal/core/numeric/times_spec.rb +0 -36
  410. data/spec/opal/core/numeric/to_f_spec.rb +0 -7
  411. data/spec/opal/core/numeric/to_i_spec.rb +0 -7
  412. data/spec/opal/core/numeric/to_json_spec.rb +0 -8
  413. data/spec/opal/core/numeric/to_s_spec.rb +0 -26
  414. data/spec/opal/core/numeric/uminus_spec.rb +0 -9
  415. data/spec/opal/core/numeric/upto_spec.rb +0 -19
  416. data/spec/opal/core/numeric/zero_spec.rb +0 -7
  417. data/spec/opal/core/object_id_spec.rb +0 -56
  418. data/spec/opal/core/proc/call_spec.rb +0 -21
  419. data/spec/opal/core/proc/element_reference_spec.rb +0 -21
  420. data/spec/opal/core/proc/proc_tricks_spec.rb +0 -7
  421. data/spec/opal/core/runtime/begin_spec.rb +0 -39
  422. data/spec/opal/core/runtime/block_spec.rb +0 -23
  423. data/spec/opal/core/runtime/bridged_classes_spec.rb +0 -123
  424. data/spec/opal/core/runtime/constants_spec.rb +0 -13
  425. data/spec/opal/core/runtime/donate_spec.rb +0 -53
  426. data/spec/opal/core/runtime/eval_spec.rb +0 -5
  427. data/spec/opal/core/runtime/is_a_spec.rb +0 -36
  428. data/spec/opal/core/runtime/main_methods_spec.rb +0 -27
  429. data/spec/opal/core/runtime/method_missing_spec.rb +0 -68
  430. data/spec/opal/core/runtime/method_spec.rb +0 -31
  431. data/spec/opal/core/runtime/operator_call_spec.rb +0 -13
  432. data/spec/opal/core/runtime/paren_spec.rb +0 -14
  433. data/spec/opal/core/runtime/rescue_spec.rb +0 -106
  434. data/spec/opal/core/runtime/return_spec.rb +0 -38
  435. data/spec/opal/core/runtime/singleton_class_spec.rb +0 -13
  436. data/spec/opal/core/runtime/super_spec.rb +0 -223
  437. data/spec/opal/core/runtime/truthy_spec.rb +0 -63
  438. data/spec/opal/core/runtime/variables_spec.rb +0 -20
  439. data/spec/opal/core/runtime_spec.rb +0 -58
  440. data/spec/opal/core/source_map_spec.rb +0 -49
  441. data/spec/opal/core/string_spec.rb +0 -32
  442. data/spec/opal/core/time_spec.rb +0 -38
  443. data/spec/opal/javascript_api_spec.rb +0 -16
  444. data/spec/opal/stdlib/erb/erb_spec.rb +0 -30
  445. data/spec/opal/stdlib/erb/inline_block.opalerb +0 -3
  446. data/spec/opal/stdlib/erb/quoted.opalerb +0 -1
  447. data/spec/opal/stdlib/erb/simple.opalerb +0 -1
  448. data/spec/opal/stdlib/js_spec.rb +0 -66
  449. data/spec/opal/stdlib/json/ext_spec.rb +0 -48
  450. data/spec/opal/stdlib/json/parse_spec.rb +0 -37
  451. data/spec/opal/stdlib/native/alias_native_spec.rb +0 -27
  452. data/spec/opal/stdlib/native/array_spec.rb +0 -11
  453. data/spec/opal/stdlib/native/each_spec.rb +0 -13
  454. data/spec/opal/stdlib/native/element_reference_spec.rb +0 -16
  455. data/spec/opal/stdlib/native/exposure_spec.rb +0 -33
  456. data/spec/opal/stdlib/native/ext_spec.rb +0 -19
  457. data/spec/opal/stdlib/native/hash_spec.rb +0 -67
  458. data/spec/opal/stdlib/native/initialize_spec.rb +0 -17
  459. data/spec/opal/stdlib/native/method_missing_spec.rb +0 -51
  460. data/spec/opal/stdlib/native/native_alias_spec.rb +0 -19
  461. data/spec/opal/stdlib/native/native_class_spec.rb +0 -18
  462. data/spec/opal/stdlib/native/native_module_spec.rb +0 -13
  463. data/spec/opal/stdlib/native/native_reader_spec.rb +0 -22
  464. data/spec/opal/stdlib/native/native_writer_spec.rb +0 -30
  465. data/spec/opal/stdlib/native/new_spec.rb +0 -92
  466. data/spec/opal/stdlib/native/struct_spec.rb +0 -12
  467. data/spec/opal/stdlib/promise/always_spec.rb +0 -49
  468. data/spec/opal/stdlib/promise/error_spec.rb +0 -15
  469. data/spec/opal/stdlib/promise/rescue_spec.rb +0 -53
  470. data/spec/opal/stdlib/promise/then_spec.rb +0 -79
  471. data/spec/opal/stdlib/promise/trace_spec.rb +0 -51
  472. data/spec/opal/stdlib/promise/value_spec.rb +0 -15
  473. data/spec/opal/stdlib/promise/when_spec.rb +0 -34
  474. data/spec/opal/stdlib/source_map_spec.rb +0 -8
  475. data/spec/opal/stdlib/strscan/scan_spec.rb +0 -11
  476. data/spec/opal/stdlib/template/paths_spec.rb +0 -10
  477. data/spec/opal/stdlib/thread/mutex_spec.rb +0 -40
  478. data/spec/opal/stdlib/thread/thread_queue_spec.rb +0 -32
  479. data/spec/opal/stdlib/thread/thread_spec.rb +0 -60
  480. data/spec/ruby_specs +0 -122
  481. data/spec/spec_helper.rb +0 -27
  482. data/spec/support/match_helpers.rb +0 -57
  483. data/spec/support/mspec_rspec_adapter.rb +0 -33
  484. data/spec/support/rewriters_helper.rb +0 -24
  485. data/stdlib/phantomjs.rb +0 -17
  486. data/tasks/testing/sprockets-phantomjs.js +0 -54
  487. data/test/nodejs/fixtures/hello.rb +0 -1
  488. data/test/nodejs/test_dir.rb +0 -17
  489. data/test/nodejs/test_file.rb +0 -87
  490. data/test/nodejs/test_io.rb +0 -18
  491. data/test/nodejs/test_opal_builder.rb +0 -12
  492. data/test/opal/test_keyword.rb +0 -590
  493. data/test/opal/unsupported_and_bugs.rb +0 -39
@@ -5,13 +5,7 @@ require 'source_map'
5
5
 
6
6
  module Opal
7
7
  module BuilderProcessors
8
- DEFAULT_PROCESSORS = []
9
-
10
8
  class Processor
11
- def self.inherited(processor)
12
- DEFAULT_PROCESSORS << processor
13
- end
14
-
15
9
  def initialize(source, filename, options = {})
16
10
  @source, @filename, @options = source, filename, options
17
11
  @requires = []
@@ -27,8 +21,10 @@ module Opal
27
21
  @extensions = extensions
28
22
  matches = extensions.join('|')
29
23
  matches = "(#{matches})" if extensions.size == 1
30
-
31
24
  @match_regexp = Regexp.new "\\.#{matches}#{REGEXP_END}"
25
+
26
+ ::Opal::Builder.register_processor(self, extensions)
27
+ nil
32
28
  end
33
29
 
34
30
  def self.extensions
@@ -112,6 +108,11 @@ module Opal
112
108
  def compiler_class
113
109
  ::Opal::Compiler
114
110
  end
111
+
112
+ # Also catch a files with missing extensions and nil.
113
+ def self.match? other
114
+ super or File.extname(other.to_s) == ''
115
+ end
115
116
  end
116
117
 
117
118
  class OpalERBProcessor < RubyProcessor
@@ -116,7 +116,7 @@ module Opal
116
116
 
117
117
  def show_sexp
118
118
  evals_or_file do |contents, filename|
119
- buffer = ::Parser::Source::Buffer.new(filename)
119
+ buffer = ::Opal::Source::Buffer.new(filename)
120
120
  buffer.source = contents
121
121
  sexp = Opal::Parser.default_parser.parse(buffer)
122
122
  puts sexp.inspect
@@ -81,7 +81,7 @@ module Opal
81
81
  options[:compile] = true
82
82
  end
83
83
 
84
- on('-R', '--runner RUNNER', %w[nodejs server phantomjs applescript nashorn], 'Choose the runner: nodejs (default), server') do |runner|
84
+ on('-R', '--runner RUNNER', %w[nodejs server applescript nashorn chrome], 'Choose the runner: nodejs (default), server, chrome') do |runner|
85
85
  options[:runner] = runner.to_sym
86
86
  end
87
87
 
@@ -20,7 +20,7 @@ module Opal
20
20
  end
21
21
 
22
22
  require 'opal/cli_runners/applescript'
23
- require 'opal/cli_runners/phantomjs'
24
23
  require 'opal/cli_runners/nodejs'
25
24
  require 'opal/cli_runners/server'
26
25
  require 'opal/cli_runners/nashorn'
26
+ require 'opal/cli_runners/chrome'
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'opal/cli_runners'
3
2
 
4
3
  module Opal
5
4
  module CliRunners
@@ -0,0 +1,135 @@
1
+ var CDP = require("chrome-remote-interface");
2
+ var fs = require("fs");
3
+
4
+ // NOTE: the code above doesn't work on Windows
5
+ // and it doesn't support interactive stdin input (which is ok for our scenario)
6
+ var opal_code = fs.readFileSync("/dev/stdin").toString();
7
+
8
+ // Chrome can't handle huge data passed to `addScriptToEvaluateOnLoad`
9
+ // https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/U5qyeX_ydBo
10
+ // The only way is to create temporary files and pass them to chrome.
11
+ fs.writeFileSync("/tmp/chrome-opal.js", opal_code);
12
+ fs.writeFileSync("/tmp/chrome-opal.html", "" +
13
+ "<html>" +
14
+ "<head>" +
15
+ "<meta charset='utf-8'>" +
16
+ "<script src='chrome-opal.js'></script>" +
17
+ "</head>" +
18
+ "<body>" +
19
+ "</body>" +
20
+ "</html>"
21
+ );
22
+
23
+ var options = {
24
+ host: process.env.CHROME_HOST || 'localhost',
25
+ port: process.env.CHROME_PORT || 9222
26
+ };
27
+
28
+ CDP(options, function(client) {
29
+ var Page = client.Page,
30
+ Runtime = client.Runtime,
31
+ Console = client.Console;
32
+
33
+ Promise.all([
34
+ Console.enable(),
35
+ Page.enable(),
36
+ Runtime.enable(),
37
+ ]).then(function() {
38
+ // This hook catches only the first argument of `console.log`
39
+ // More advanced version Runtime.consoleAPICalled returns all arguments
40
+ // but all of them are not formatted, i.e. by calling
41
+ // console.log('string', [1, 2, 3], {a: 'b'})
42
+ // it returns the following data to the callback:
43
+ // {
44
+ // "type":"log",
45
+ // "args":[
46
+ // {
47
+ // "type":"string",
48
+ // "value":"string"
49
+ // },
50
+ // {
51
+ // "type":"object",
52
+ // "subtype":"array",
53
+ // "className":"Array",
54
+ // "description":"Array(3)",
55
+ // "objectId":"{\"injectedScriptId\":11,\"id\":1}",
56
+ // "preview":{
57
+ // "type":"object",
58
+ // "subtype":"array",
59
+ // "description":"Array(3)",
60
+ // "overflow":false,
61
+ // "properties":[
62
+ // {"name":"0","type":"number","value":"1"},
63
+ // {"name":"1","type":"number","value":"2"},
64
+ // {"name":"2","type":"number","value":"3"}
65
+ // ]
66
+ // }
67
+ // },
68
+ // {
69
+ // "type":"object",
70
+ // "className":"Object",
71
+ // "description":"Object",
72
+ // "objectId":"{\"injectedScriptId\":11,\"id\":2}",
73
+ // "preview":{
74
+ // "type":"object",
75
+ // "description":"Object",
76
+ // "overflow":false,
77
+ // "properties":[
78
+ // {"name":"a","type":"string","value":"b"}
79
+ // ]
80
+ // }
81
+ // }
82
+ // ],
83
+ // // ...
84
+ // }
85
+ // Supporting this format for complex data structure is challenging, feel free to contribute!
86
+ //
87
+ Console.messageAdded(function(console_message) {
88
+ process.stdout.write(console_message.message.text);
89
+ });
90
+
91
+ Runtime.exceptionThrown(function(exception) {
92
+ var exceptionDetails = exception.exceptionDetails,
93
+ properties = exceptionDetails.exception.preview.properties,
94
+ stackTrace = exceptionDetails.stackTrace.callFrames,
95
+ name, message, trace = [], i;
96
+
97
+
98
+ for (i = 0; i < properties.length; i++) {
99
+ var property = properties[i];
100
+
101
+ if (property.name == "name") {
102
+ name = property.value;
103
+ }
104
+
105
+ if (property.name == "message") {
106
+ message = property.value;
107
+ }
108
+ }
109
+
110
+ console.log(name + " : " + message);
111
+
112
+ for (i = 0; i < stackTrace.length; i++) {
113
+ var raw = stackTrace[i];
114
+
115
+ console.log(" at " + raw.functionName + " (" + raw.url + ":" + raw.lineNumber + ":" + raw.columnNumber + ")")
116
+ }
117
+
118
+ process.exit(1);
119
+ })
120
+
121
+ Page.loadEventFired(() => {
122
+ Runtime.evaluate({ expression: "window.OPAL_EXIT_CODE" }).then(function(output) {
123
+ client.close();
124
+
125
+ if (typeof(output.result) !== "undefined" && output.result.type === "number") {
126
+ process.exit(output.result.value);
127
+ } else {
128
+ process.exit(0);
129
+ }
130
+ })
131
+ });
132
+
133
+ Page.navigate({ url: 'file:///tmp/chrome-opal.html' })
134
+ });
135
+ });
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+ require 'shellwords'
3
+ require 'socket'
4
+ require 'timeout'
5
+
6
+ module Opal
7
+ module CliRunners
8
+ class Chrome
9
+ SCRIPT_PATH = File.expand_path('../chrome.js', __FILE__).freeze
10
+
11
+ DEFAULT_CHROME_HOST = 'localhost'.freeze
12
+ DEFAULT_CHROME_PORT = 9222.freeze
13
+
14
+ def initialize(options)
15
+ @output = options.fetch(:output, $stdout)
16
+ end
17
+ attr_reader :output, :exit_status
18
+
19
+ def run(code, argv)
20
+ with_chrome_server do
21
+ cmd = [
22
+ 'env',
23
+ "CHROME_HOST=#{chrome_host}",
24
+ "CHROME_PORT=#{chrome_port}",
25
+ 'node',
26
+ SCRIPT_PATH,
27
+ ]
28
+
29
+ IO.popen(cmd, 'w', out: output) do |io|
30
+ io.write(code)
31
+ end
32
+
33
+ @exit_status = $?.exitstatus
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def chrome_host
40
+ ENV['CHROME_HOST'] || DEFAULT_CHROME_HOST
41
+ end
42
+
43
+ def chrome_port
44
+ ENV['CHROME_PORT'] || DEFAULT_CHROME_PORT
45
+ end
46
+
47
+ def with_chrome_server
48
+ if chrome_server_running?
49
+ yield
50
+ else
51
+ run_chrome_server { yield }
52
+ end
53
+ end
54
+
55
+ def run_chrome_server
56
+ raise "Chrome server can be started only on localhost" if chrome_host != DEFAULT_CHROME_HOST
57
+
58
+ chrome_server_cmd = "#{chrome_executable} --headless --disable-gpu --remote-debugging-port=#{chrome_port} #{ENV['CHROME_OPTS']}"
59
+ puts chrome_server_cmd
60
+
61
+ chrome_pid = Process.spawn(chrome_server_cmd)
62
+
63
+ Timeout.timeout(1) do
64
+ loop do
65
+ break if chrome_server_running?
66
+ sleep 0.1
67
+ end
68
+ end
69
+
70
+ yield
71
+ rescue Timeout::Error
72
+ puts 'Failed to start chrome server'
73
+ puts 'Make sure that you have it installed and that its version is > 59'
74
+ ensure
75
+ Process.kill('HUP', chrome_pid) if chrome_pid
76
+ end
77
+
78
+ def chrome_server_running?
79
+ puts "Connecting to #{chrome_host}:#{chrome_port}..."
80
+ TCPSocket.new(chrome_host, chrome_port).close
81
+ true
82
+ rescue Errno::ECONNREFUSED, Errno::EADDRNOTAVAIL
83
+ false
84
+ end
85
+
86
+ def chrome_executable
87
+ ENV['GOOGLE_CHROME_BINARY'] || case RbConfig::CONFIG['host_os']
88
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
89
+ raise "Headless chrome is supported only by Mac OS and Linux"
90
+ when /darwin|mac os/
91
+ "/Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome"
92
+ when /linux/
93
+ 'google-chrome-stable'
94
+ when /solaris|bsd/
95
+ raise "Headless chrome is supported only by Mac OS and Linux"
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'opal/cli_runners'
3
2
  require 'opal/paths'
4
3
 
5
4
  module Opal
@@ -0,0 +1 @@
1
+ lib/opal/cli_runners/node_modules/.bin/../chrome-remote-interface/bin/client.js
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2017 Andrea Cardaci <cyrus.and@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,843 @@
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
+ =======================
3
+
4
+ [Chrome Debugging Protocol] interface that helps to instrument Chrome (or any
5
+ other suitable [implementation](#implementations)) by providing a simple
6
+ abstraction of commands and notifications using a straightforward JavaScript
7
+ API.
8
+
9
+ This module is one of the many [third-party protocol clients][3rd-party].
10
+
11
+ [3rd-party]: https://developer.chrome.com/devtools/docs/debugging-clients#chrome-remote-interface
12
+
13
+ Sample API usage
14
+ ----------------
15
+
16
+ The following snippet loads `https://github.com` and dumps every request made:
17
+
18
+ ```js
19
+ const CDP = require('chrome-remote-interface');
20
+
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) => {
38
+ console.error(err);
39
+ client.close();
40
+ });
41
+ }).on('error', (err) => {
42
+ // cannot connect to the remote endpoint
43
+ console.error(err);
44
+ });
45
+ ```
46
+
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.
49
+
50
+ [wiki]: https://github.com/cyrus-and/chrome-remote-interface/wiki
51
+ [async-await-example]: https://github.com/cyrus-and/chrome-remote-interface/wiki/Async-await-example
52
+
53
+ Installation
54
+ ------------
55
+
56
+ npm install chrome-remote-interface
57
+
58
+ Install globally (`-g`) to just use the [bundled client](#bundled-client).
59
+
60
+ Implementations
61
+ ---------------
62
+
63
+ This module should work with every application implementing the
64
+ [Chrome Debugging Protocol]. In particular, it has been tested against the
65
+ following implementations:
66
+
67
+ Implementation | Protocol version | [Protocol] | [List] | [New] | [Activate] | [Close] | [Version]
68
+ ---------------------------|--------------------|------------|--------|-------|------------|---------|-----------
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
71
+ [Node.js][3.1] ([v6.3.0]+) | [node][3.2] | yes | no | no | no | no | yes
72
+ [Safari (iOS)][4.1] | [*partial*][4.2] | no | yes | no | no | no | no
73
+
74
+ [1.1]: #chromechromium
75
+ [1.2]: https://chromedevtools.github.io/devtools-protocol/tot/
76
+
77
+ [2.1]: #edge
78
+ [2.2]: https://github.com/Microsoft/edge-diagnostics-adapter/wiki/Supported-features-and-API
79
+
80
+ [3.1]: #nodejs
81
+ [3.2]: https://chromedevtools.github.io/devtools-protocol/v8/
82
+
83
+ [4.1]: #safari-ios
84
+ [4.2]: http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/inspector/protocol
85
+
86
+ [v6.3.0]: https://nodejs.org/en/blog/release/v6.3.0/
87
+
88
+ [Protocol]: #cdpprotocoloptions-callback
89
+ [List]: #cdplistoptions-callback
90
+ [New]: #cdpnewoptions-callback
91
+ [Activate]: #cdpactivateoptions-callback
92
+ [Close]: #cdpcloseoptions-callback
93
+ [Version]: #cdpversionoptions-callback
94
+
95
+ The meaning of *target* varies according to the implementation, for example,
96
+ each Chrome tab represents a target whereas for Node.js a target is the
97
+ currently inspected script.
98
+
99
+ Setup
100
+ -----
101
+
102
+ An instance of either Chrome itself or another implementation needs to be
103
+ running on a known port in order to use this module (defaults to
104
+ `localhost:9222`).
105
+
106
+ ### Chrome/Chromium
107
+
108
+ #### Desktop
109
+
110
+ Start Chrome with the `--remote-debugging-port` option, for example:
111
+
112
+ google-chrome --remote-debugging-port=9222
113
+
114
+ ##### Headless
115
+
116
+ Since version 59, additionally use the `--headless` option, for example:
117
+
118
+ google-chrome --headless --remote-debugging-port=9222
119
+
120
+ #### Android
121
+
122
+ Plug the device and enable the [port forwarding][adb], for example:
123
+
124
+ adb forward tcp:9222 localabstract:chrome_devtools_remote
125
+
126
+ [adb]: https://developer.chrome.com/devtools/docs/remote-debugging-legacy
127
+
128
+ ##### WebView
129
+
130
+ In order to be inspectable, a WebView must
131
+ be [configured for debugging][webview] and the corresponding process ID must be
132
+ known. There are several ways to obtain it, for example:
133
+
134
+ adb shell grep -a webview_devtools_remote /proc/net/unix
135
+
136
+ Finally, port forwarding can be enabled as follows:
137
+
138
+ adb forward tcp:9222 localabstract:webview_devtools_remote_<pid>
139
+
140
+ [webview]: https://developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews#configure_webviews_for_debugging
141
+
142
+ ### Edge
143
+
144
+ Install and run the [Edge Diagnostics Adapter][edge-adapter].
145
+
146
+ [edge-adapter]: https://github.com/Microsoft/edge-diagnostics-adapter
147
+
148
+ ### Node.js
149
+
150
+ Start Node.js with the `--inspect` option, for example:
151
+
152
+ node --inspect=9222 script.js
153
+
154
+ ### Safari (iOS)
155
+
156
+ Install and run the [iOS WebKit Debug Proxy][iwdp].
157
+
158
+ [iwdp]: https://github.com/google/ios-webkit-debug-proxy
159
+
160
+ Bundled client
161
+ --------------
162
+
163
+ This module comes with a bundled client application that can be used to
164
+ interactively control a remote instance.
165
+
166
+ ### Target management
167
+
168
+ The bundled client exposes subcommands to interact with the HTTP frontend
169
+ (e.g., [List](#cdplistoptions-callback), [New](#cdpnewoptions-callback), etc.),
170
+ run with `--help` to display the list of available options.
171
+
172
+ Here are some examples:
173
+
174
+ ```javascript
175
+ $ chrome-remote-interface new 'http://example.com'
176
+ {
177
+ "description": "",
178
+ "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/b049bb56-de7d-424c-a331-6ae44cf7ae01",
179
+ "id": "b049bb56-de7d-424c-a331-6ae44cf7ae01",
180
+ "thumbnailUrl": "/thumb/b049bb56-de7d-424c-a331-6ae44cf7ae01",
181
+ "title": "",
182
+ "type": "page",
183
+ "url": "http://example.com/",
184
+ "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/b049bb56-de7d-424c-a331-6ae44cf7ae01"
185
+ }
186
+ $ chrome-remote-interface close 'b049bb56-de7d-424c-a331-6ae44cf7ae01'
187
+ ```
188
+
189
+ ### Inspection
190
+
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.
200
+
201
+ Here is a sample session:
202
+
203
+ ```javascript
204
+ $ chrome-remote-interface inspect
205
+ >>> 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 } }
211
+ >>> 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 }
219
+ >>> Page.navigate({url: 'https://github.com'})
220
+ { result: { frameId: '28677.1' } }
221
+ { 'Page.loadEventFired': { timestamp: 21385.383076 } }
222
+ >>> Runtime.evaluate({expression: 'window.location.toString()'})
223
+ { result:
224
+ { result: { type: 'string', value: 'https://github.com/' },
225
+ wasThrown: false } }
226
+ ```
227
+
228
+ #### Event filtering
229
+
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:
232
+
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
+ ----------------------
252
+
253
+ In both the REPL and the regular API every object of the protocol is *decorated*
254
+ with the meta information found within the descriptor. In addition The
255
+ `category` field is added, which determines if the member is a `command`, an
256
+ `event` or a `type`.
257
+
258
+ For example to learn how to call `Page.navigate`:
259
+
260
+ ```javascript
261
+ >>> Page.navigate
262
+ { [Function]
263
+ category: 'command',
264
+ parameters: { url: { type: 'string', description: 'URL to navigate the page to.' } },
265
+ returns:
266
+ [ { name: 'frameId',
267
+ '$ref': 'FrameId',
268
+ hidden: true,
269
+ description: 'Frame id that will be navigated.' } ],
270
+ description: 'Navigates current page to the given URL.',
271
+ handlers: [ 'browser', 'renderer' ] }
272
+ ```
273
+
274
+ To learn about the parameters returned by the `Network.requestWillBeSent` event:
275
+
276
+ ```javascript
277
+ >>> Network.requestWillBeSent
278
+ { [Function]
279
+ category: 'event',
280
+ description: 'Fired when page is about to send HTTP request.',
281
+ parameters:
282
+ { requestId: { '$ref': 'RequestId', description: 'Request identifier.' },
283
+ frameId:
284
+ { '$ref': 'Page.FrameId',
285
+ description: 'Frame identifier.',
286
+ hidden: true },
287
+ loaderId: { '$ref': 'LoaderId', description: 'Loader identifier.' },
288
+ documentURL:
289
+ { type: 'string',
290
+ description: 'URL of the document this request is loaded for.' },
291
+ request: { '$ref': 'Request', description: 'Request data.' },
292
+ timestamp: { '$ref': 'Timestamp', description: 'Timestamp.' },
293
+ wallTime:
294
+ { '$ref': 'Timestamp',
295
+ hidden: true,
296
+ description: 'UTC Timestamp.' },
297
+ initiator: { '$ref': 'Initiator', description: 'Request initiator.' },
298
+ redirectResponse:
299
+ { optional: true,
300
+ '$ref': 'Response',
301
+ description: 'Redirect response data.' },
302
+ type:
303
+ { '$ref': 'Page.ResourceType',
304
+ optional: true,
305
+ hidden: true,
306
+ description: 'Type of this resource.' } } }
307
+ ```
308
+
309
+ To inspect the `Network.Request` (note that unlike commands and events, types
310
+ are named in upper camel case) type:
311
+
312
+ ```javascript
313
+ >>> Network.Request
314
+ { category: 'type',
315
+ id: 'Request',
316
+ type: 'object',
317
+ description: 'HTTP request data.',
318
+ properties:
319
+ { url: { type: 'string', description: 'Request URL.' },
320
+ method: { type: 'string', description: 'HTTP request method.' },
321
+ headers: { '$ref': 'Headers', description: 'HTTP request headers.' },
322
+ postData:
323
+ { type: 'string',
324
+ optional: true,
325
+ description: 'HTTP POST request data.' },
326
+ mixedContentType:
327
+ { optional: true,
328
+ type: 'string',
329
+ enum: [Object],
330
+ description: 'The mixed content status of the request, as defined in http://www.w3.org/TR/mixed-content/' },
331
+ initialPriority:
332
+ { '$ref': 'ResourcePriority',
333
+ description: 'Priority of the resource request at the time request is sent.' } } }
334
+ ```
335
+
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.
342
+
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.
346
+
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.
349
+
350
+ To override the above behavior there are basically three options:
351
+
352
+ - pass a custom protocol descriptor upon [connection](#cdpoptions-callback)
353
+ (`protocol` option);
354
+
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`).
360
+
361
+ [local version]: lib/protocol.json
362
+
363
+ Browser usage
364
+ -------------
365
+
366
+ This module is able to run within a web context, with obvious limitations
367
+ though, namely external HTTP requests
368
+ ([List](#cdplistoptions-callback), [New](#cdpnewoptions-callback), etc.) cannot
369
+ be performed directly, for this reason the user must provide a global
370
+ `criRequest` in order to use them:
371
+
372
+ ```js
373
+ function criRequest(options, callback) {}
374
+ ```
375
+
376
+ `options` is the same object used by the Node.js `http` module and `callback` is
377
+ a function taking two arguments: `err` (JavaScript `Error` object or `null`) and
378
+ `data` (string result).
379
+
380
+ ### Using [webpack](https://webpack.github.io/)
381
+
382
+ It just works, simply require this module:
383
+
384
+ ```js
385
+ const CDP = require('chrome-remote-interface');
386
+ ```
387
+
388
+ To use a non-minified version manually run webpack with:
389
+
390
+ DEBUG=true npm run webpack
391
+
392
+ ### Using *vanilla* JavaScript
393
+
394
+ To generate a JavaScript file that can be used with a `<script>` element:
395
+
396
+ 1. run `npm install` from the root directory;
397
+
398
+ 2. manually run webpack with:
399
+
400
+ TARGET=var npm run webpack
401
+ TARGET=var DEBUG=true npm run webpack
402
+
403
+ 3. use as:
404
+
405
+ ```html
406
+ <script>
407
+ function criRequest(options, callback) { /*...*/ }
408
+ </script>
409
+ <script src="chrome-remote-interface.js"></script>
410
+ ```
411
+
412
+ API
413
+ ---
414
+
415
+ The API consists of three parts:
416
+
417
+ - *DevTools* methods (for those [implementations](#implementations) that support
418
+ them, e.g., [List](#cdplistoptions-callback), [New](#cdpnewoptions-callback),
419
+ etc.);
420
+
421
+ - [connection](#cdpoptions-callback) establishment;
422
+
423
+ - the actual [protocol interaction](#class-cdp).
424
+
425
+ ### CDP([options], [callback])
426
+
427
+ Connects to a remote instance using the [Chrome Debugging Protocol].
428
+
429
+ `options` is an object with the following optional properties:
430
+
431
+ - `host`: HTTP frontend host. Defaults to `localhost`;
432
+ - `port`: HTTP frontend port. Defaults to `9222`;
433
+ - `secure`: HTTPS/WSS frontend. Defaults to `false`;
434
+ - `target`: determines which target this client should attach to. The behavior
435
+ changes according to the type:
436
+
437
+ - a `function` that takes the array returned by the `List` method and returns
438
+ a target or its numeric index relative to the array;
439
+ - a target `object` like those returned by the `New` and `List` methods;
440
+ - a `string` representing the raw WebSocket URL, in this case `host` and
441
+ `port` are not used to fetch the target list, yet they are used to complete
442
+ the URL if relative;
443
+ - a `string` representing the target id.
444
+
445
+ Defaults to a function which returns the first available target according to
446
+ the implementation (note that at most one connection can be established to the
447
+ same target);
448
+ - `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*
451
+ or if the local version must be used. It has no effect if the `protocol`
452
+ option is set. Defaults to `false`.
453
+
454
+ These options are also valid properties of all the instances of the `CDP` class.
455
+
456
+ `callback` is a listener automatically added to the `connect` event of the
457
+ returned `EventEmitter`. When `callback` is omitted a `Promise` object is
458
+ returned which becomes fulfilled if the `connect` event is triggered and
459
+ rejected if the `error` event is triggered.
460
+
461
+ The `EventEmitter` supports the following events:
462
+
463
+ #### Event: 'connect'
464
+
465
+ ```javascript
466
+ function (client) {}
467
+ ```
468
+
469
+ Emitted when the connection to the WebSocket is established.
470
+
471
+ `client` is an instance of the `CDP` class.
472
+
473
+ #### Event: 'error'
474
+
475
+ ```javascript
476
+ function (err) {}
477
+ ```
478
+
479
+ Emitted when `http://host:port/json` cannot be reached or if it is not possible
480
+ to connect to the WebSocket.
481
+
482
+ `err` is an instance of `Error`.
483
+
484
+ ### CDP.Protocol([options], [callback])
485
+
486
+ Fetch the [Chrome Debugging Protocol] descriptor.
487
+
488
+ `options` is an object with the following optional properties:
489
+
490
+ - `host`: HTTP frontend host. Defaults to `localhost`;
491
+ - `port`: HTTP frontend port. Defaults to `9222`;
492
+ - `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`.
496
+
497
+ `callback` is executed when the protocol is fetched, it gets the following
498
+ arguments:
499
+
500
+ - `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.
505
+
506
+ When `callback` is omitted a `Promise` object is returned.
507
+
508
+ For example:
509
+
510
+ ```javascript
511
+ const CDP = require('chrome-remote-interface');
512
+ CDP.Protocol(function (err, protocol) {
513
+ if (!err) {
514
+ console.log(JSON.stringify(protocol.descriptor, null, 4));
515
+ }
516
+ });
517
+ ```
518
+
519
+ ### CDP.List([options], [callback])
520
+
521
+ Request the list of the available open targets/tabs of the remote instance.
522
+
523
+ `options` is an object with the following optional properties:
524
+
525
+ - `host`: HTTP frontend host. Defaults to `localhost`;
526
+ - `port`: HTTP frontend port. Defaults to `9222`;
527
+ - `secure`: HTTPS/WSS frontend. Defaults to `false`.
528
+
529
+ `callback` is executed when the list is correctly received, it gets the
530
+ following arguments:
531
+
532
+ - `err`: a `Error` object indicating the success status;
533
+ - `targets`: the array returned by `http://host:port/json/list` containing the
534
+ target list.
535
+
536
+ When `callback` is omitted a `Promise` object is returned.
537
+
538
+ For example:
539
+
540
+ ```javascript
541
+ const CDP = require('chrome-remote-interface');
542
+ CDP.List(function (err, targets) {
543
+ if (!err) {
544
+ console.log(targets);
545
+ }
546
+ });
547
+ ```
548
+
549
+ ### CDP.New([options], [callback])
550
+
551
+ Create a new target/tab in the remote instance.
552
+
553
+ `options` is an object with the following optional properties:
554
+
555
+ - `host`: HTTP frontend host. Defaults to `localhost`;
556
+ - `port`: HTTP frontend port. Defaults to `9222`;
557
+ - `secure`: HTTPS/WSS frontend. Defaults to `false`;
558
+ - `url`: URL to load in the new target/tab. Defaults to `about:blank`.
559
+
560
+ `callback` is executed when the target is created, it gets the following
561
+ arguments:
562
+
563
+ - `err`: a `Error` object indicating the success status;
564
+ - `target`: the object returned by `http://host:port/json/new` containing the
565
+ target.
566
+
567
+ When `callback` is omitted a `Promise` object is returned.
568
+
569
+ For example:
570
+
571
+ ```javascript
572
+ const CDP = require('chrome-remote-interface');
573
+ CDP.New(function (err, target) {
574
+ if (!err) {
575
+ console.log(target);
576
+ }
577
+ });
578
+ ```
579
+
580
+ ### CDP.Activate([options], [callback])
581
+
582
+ Activate an open target/tab of the remote instance.
583
+
584
+ `options` is an object with the following properties:
585
+
586
+ - `host`: HTTP frontend host. Defaults to `localhost`;
587
+ - `port`: HTTP frontend port. Defaults to `9222`;
588
+ - `secure`: HTTPS/WSS frontend. Defaults to `false`;
589
+ - `id`: Target id. Required, no default.
590
+
591
+ `callback` is executed when the response to the activation request is
592
+ received. It gets the following arguments:
593
+
594
+ - `err`: a `Error` object indicating the success status;
595
+
596
+ When `callback` is omitted a `Promise` object is returned.
597
+
598
+ For example:
599
+
600
+ ```javascript
601
+ const CDP = require('chrome-remote-interface');
602
+ CDP.Activate({'id': 'CC46FBFA-3BDA-493B-B2E4-2BE6EB0D97EC'}, function (err) {
603
+ if (!err) {
604
+ console.log('target is activated');
605
+ }
606
+ });
607
+ ```
608
+
609
+ ### CDP.Close([options], [callback])
610
+
611
+ Close an open target/tab of the remote instance.
612
+
613
+ `options` is an object with the following properties:
614
+
615
+ - `host`: HTTP frontend host. Defaults to `localhost`;
616
+ - `port`: HTTP frontend port. Defaults to `9222`;
617
+ - `secure`: HTTPS/WSS frontend. Defaults to `false`;
618
+ - `id`: Target id. Required, no default.
619
+
620
+ `callback` is executed when the response to the close request is received. It
621
+ gets the following arguments:
622
+
623
+ - `err`: a `Error` object indicating the success status;
624
+
625
+ When `callback` is omitted a `Promise` object is returned.
626
+
627
+ For example:
628
+
629
+ ```javascript
630
+ const CDP = require('chrome-remote-interface');
631
+ CDP.Close({'id': 'CC46FBFA-3BDA-493B-B2E4-2BE6EB0D97EC'}, function (err) {
632
+ if (!err) {
633
+ console.log('target is closing');
634
+ }
635
+ });
636
+ ```
637
+
638
+ Note that the callback is fired when the target is *queued* for removal, but the
639
+ actual removal will occur asynchronously.
640
+
641
+ ### CDP.Version([options], [callback])
642
+
643
+ Request version information from the remote instance.
644
+
645
+ `options` is an object with the following optional properties:
646
+
647
+ - `host`: HTTP frontend host. Defaults to `localhost`;
648
+ - `port`: HTTP frontend port. Defaults to `9222`;
649
+ - `secure`: HTTPS/WSS frontend. Defaults to `false`.
650
+
651
+ `callback` is executed when the version information is correctly received, it
652
+ gets the following arguments:
653
+
654
+ - `err`: a `Error` object indicating the success status;
655
+ - `info`: a JSON object returned by `http://host:port/json/version` containing
656
+ the version information.
657
+
658
+ When `callback` is omitted a `Promise` object is returned.
659
+
660
+ For example:
661
+
662
+ ```javascript
663
+ const CDP = require('chrome-remote-interface');
664
+ CDP.Version(function (err, info) {
665
+ if (!err) {
666
+ console.log(info);
667
+ }
668
+ });
669
+ ```
670
+
671
+ ### Class: CDP
672
+
673
+ #### Event: 'event'
674
+
675
+ ```javascript
676
+ function (message) {}
677
+ ```
678
+
679
+ Emitted when the remote instance sends any notification through the WebSocket.
680
+
681
+ `message` is the object received, it has the following properties:
682
+
683
+ - `method`: a string describing the notification (e.g.,
684
+ `'Network.requestWillBeSent'`);
685
+ - `params`: an object containing the payload.
686
+
687
+ Refer to the [Chrome Debugging Protocol] specification for more information.
688
+
689
+ For example:
690
+
691
+ ```javascript
692
+ client.on('event', function (message) {
693
+ if (message.method === 'Network.requestWillBeSent') {
694
+ console.log(message.params);
695
+ }
696
+ });
697
+ ```
698
+
699
+ #### Event: '`<domain>`.`<method>`'
700
+
701
+ ```javascript
702
+ function (params) {}
703
+ ```
704
+
705
+ Emitted when the remote instance sends a notification for `<domain>.<method>`
706
+ through the WebSocket.
707
+
708
+ `params` is an object containing the payload.
709
+
710
+ This is just a utility event which allows to easily listen for specific
711
+ notifications (see [`'event'`](#event-event)), for example:
712
+
713
+ ```javascript
714
+ client.on('Network.requestWillBeSent', console.log);
715
+ ```
716
+
717
+ #### Event: 'ready'
718
+
719
+ ```javascript
720
+ function () {}
721
+ ```
722
+
723
+ Emitted every time that there are no more pending commands waiting for a
724
+ response from the remote instance. The interaction is asynchronous so the only
725
+ way to serialize a sequence of commands is to use the callback provided by
726
+ the [`send`](#clientsendmethod-params-callback) method. This event acts as a
727
+ barrier and it is useful to avoid the *callback hell* in certain simple
728
+ situations.
729
+
730
+ Users are encouraged to extensively check the response of each method and should
731
+ prefer the promises API when dealing with complex asynchronous program flows.
732
+
733
+ For example to load a URL only after having enabled the notifications of both
734
+ `Network` and `Page` domains:
735
+
736
+ ```javascript
737
+ client.Network.enable();
738
+ client.Page.enable();
739
+ client.once('ready', function () {
740
+ client.Page.navigate({'url': 'https://github.com'});
741
+ });
742
+ ```
743
+
744
+ In this particular case, not enforcing this kind of serialization may cause that
745
+ the remote instance does not properly deliver the desired notifications the
746
+ client.
747
+
748
+
749
+ #### Event: 'disconnect'
750
+
751
+ ```javascript
752
+ function () {}
753
+ ```
754
+
755
+ Emitted when the instance closes the WebSocket connection.
756
+
757
+ This may happen for example when the user opens DevTools or when the tab is
758
+ closed.
759
+
760
+ #### client.send(method, [params], [callback])
761
+
762
+ Issue a command to the remote instance.
763
+
764
+ `method` is a string describing the command.
765
+
766
+ `params` is an object containing the payload.
767
+
768
+ `callback` is executed when the remote instance sends a response to this
769
+ command, it gets the following arguments:
770
+
771
+ - `error`: a boolean value indicating the success status, as reported by the
772
+ remote instance;
773
+ - `response`: an object containing either the response (`result` field, if
774
+ `error === false`) or the indication of the error (`error` field, if `error
775
+ === true`).
776
+
777
+ When `callback` is omitted a `Promise` object is returned instead, with the
778
+ fulfilled/rejected states implemented according to the `error` parameter.
779
+
780
+ Note that the field `id` mentioned in the [Chrome Debugging Protocol]
781
+ specification is managed internally and it is not exposed to the user.
782
+
783
+ For example:
784
+
785
+ ```javascript
786
+ client.send('Page.navigate', {'url': 'https://github.com'}, console.log);
787
+ ```
788
+
789
+ #### client.`<domain>`.`<method>`([params], [callback])
790
+
791
+ Just a shorthand for:
792
+
793
+ ```javascript
794
+ client.send('<domain>.<method>', params, callback);
795
+ ```
796
+
797
+ For example:
798
+
799
+ ```javascript
800
+ client.Page.navigate({'url': 'https://github.com'}, console.log);
801
+ ```
802
+
803
+ #### client.`<domain>`.`<event>`([callback])
804
+
805
+ Just a shorthand for:
806
+
807
+ ```javascript
808
+ client.on('<domain>.<event>', callback);
809
+ ```
810
+
811
+ The only difference is that when `callback` is omitted the event is registered
812
+ only once and a `Promise` object is returned.
813
+
814
+ For example:
815
+
816
+ ```javascript
817
+ client.Network.requestWillBeSent(console.log);
818
+ ```
819
+
820
+ #### client.close([callback])
821
+
822
+ Close the connection to the remote instance.
823
+
824
+ `callback` is executed when the WebSocket is successfully closed.
825
+
826
+ When `callback` is omitted a `Promise` object is returned.
827
+
828
+ Contributors
829
+ ------------
830
+
831
+ - [Andrey Sidorov](https://github.com/sidorares)
832
+ - [Greg Cochard](https://github.com/gcochard)
833
+
834
+ Resources
835
+ ---------
836
+
837
+ - [Chrome Debugging Protocol]
838
+ - [Chrome Debugging Protocol Google group](https://groups.google.com/forum/#!forum/chrome-debugging-protocol)
839
+ - [devtools-protocol official repo](https://github.com/ChromeDevTools/devtools-protocol)
840
+ - [Showcase Chrome Debugging Protocol Clients](https://developer.chrome.com/devtools/docs/debugging-clients)
841
+ - [Awesome chrome-devtools](https://github.com/ChromeDevTools/awesome-chrome-devtools)
842
+
843
+ [Chrome Debugging Protocol]: https://chromedevtools.github.io/devtools-protocol/