chrome_remote 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c2aa46eb656817f1c7cef04b5b604bbd7da4aaaa
4
- data.tar.gz: fbad3f461b01b9bde4f6b90dcf46bc23fa18aa6b
2
+ SHA256:
3
+ metadata.gz: 17aac463e9f35f90f51ff383713fd0055ecd1cd39ff4b6bbd1fa8790f30ba2e5
4
+ data.tar.gz: 4c25272969e7b3d692875379c5a38eac31fb49abccfa2cb51b4a3a44ca8ce61a
5
5
  SHA512:
6
- metadata.gz: 5bce9f49de0bb134ff2cb0ed38a36bf1d4e2241a73682e1cf082aee2437e7c2d1842cbb7be3c66471e1bec6efa0dd23f32f1c1a0edd7fd2ddd6063c710200144
7
- data.tar.gz: ce718db0bb534d36a1cc6377ae56150d70ce55f001c50114a1885e1dc4a5f0b16a792dd9e44e061f9726d634b519f6f015fece1f200d84315d789826020a35e0
6
+ metadata.gz: 92be3ac44443cfa7b031ee07f952922e32e0184dd39ffea5cd33b4139649ed42de72c1ee00d6c992dc44876801f5e8493a4315c3311898b4d060fd342f0280dd
7
+ data.tar.gz: 5d1c17b3e6fb9f527d5aa300a3fbbba835f90a93d8955b886c995a2e6aa0a4d9b1d22ad09223c3c25e1697a7119a13691d1aa4d2fc1d3ab4b5a0ff824a801cd9
@@ -1,5 +1,7 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4.0
5
- before_install: gem install bundler -v 1.15.1
4
+ - 2.4
5
+ - 2.5
6
+ - 2.6
7
+ - ruby-head
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # ChromeRemote
2
2
 
3
+ [![Gem Version](https://img.shields.io/gem/v/chrome_remote.svg?style=for-the-badge)](https://rubygems.org/gems/chrome_remote)
4
+ [![Build Status](https://img.shields.io/travis/cavalle/chrome_remote/master?style=for-the-badge)](https://travis-ci.org/cavalle/chrome_remote)
5
+
3
6
  ChromeRemote is a client implementation of the [Chrome DevTools Protocol][1] in Ruby. It lets you remotely control, instrument, inspect, debug and profile instances of Chrome/Chromium based browsers from your Ruby code.
4
7
 
5
8
  [1]: https://chromedevtools.github.io/devtools-protocol/
@@ -82,15 +85,18 @@ Additionally, since version 59, you can use the `--headless` flag to start Chrom
82
85
 
83
86
  ### Using the ChromeRemote API
84
87
 
85
- The [Chrome DevTools Protocol][1] is divided into a number of domains ([Page][3], [DOM][4], [Debugger][5], [Network][6], etc.). Each domain defines a number of **commands** it supports and **events** it generates.
88
+ The [Chrome DevTools Protocol][1] is divided into a number of domains ([Page][3], [DOM][4], [Debugger][5], [Network][6], etc.). Each domain defines a number of **commands** it supports and **events** it generates.
86
89
 
87
90
  ChromeRemote provides a simple API that lets you send commands, and handle events of any of the domains in the protocol.
88
91
 
89
92
  To start with, you need an instance of the `ChromeRemote` class.
90
93
 
91
94
  ```ruby
92
- chrome = ChromeRemote.client host: 'localhost', # optional, default: localhost
93
- port: 9222 # optional, default: 9222
95
+ chrome = ChromeRemote.client(
96
+ host: 'localhost', # optional (default: localhost). Host of the Chrome remote server
97
+ port: 9222, # optional (default: 9222). Port of the Chrome remote server
98
+ new_tab: false # optional (default: false). Whether to use the browser's current tab or a new one
99
+ )
94
100
  ```
95
101
 
96
102
  Now, to send commands, ChromeRemote provides the `ChromeRemote#send_cmd` method. For example, this is how you make Chrome navigate to a url by sending the [Page.navigate][7] command:
@@ -118,7 +124,7 @@ chrome.on "Network.requestWillBeSent" do |params|
118
124
  puts params["request"]["url"]
119
125
  end
120
126
  ```
121
-
127
+
122
128
  With the `ChromeRemote#wait_for` method, you can wait until the next time a given event is triggered. For example, the following snippet navigates to a page and waits for the [Page.loadEventFired][9] event to happen:
123
129
 
124
130
  ```ruby
@@ -177,20 +183,31 @@ chrome.listen_until { requests == 5 }
177
183
  [8]: https://chromedevtools.github.io/devtools-protocol/tot/Network/#event-requestWillBeSent
178
184
  [9]: https://chromedevtools.github.io/devtools-protocol/tot/Page/#event-loadEventFired
179
185
 
186
+ ### Logger
187
+
188
+ To log all incoming and outgoing messages you can pass [Logger](https://github.com/ruby/logger) compatible instance to client.
189
+
190
+ ```ruby
191
+ client = ChromeRemote.client(logger: Logger.new($stdout))
192
+ client.send_cmd('Page.enable')
193
+ # I, [2019-03-06T22:32:28.433643 #5070] INFO -- : SEND ► {"method":"Page.enable","params":{},"id":1}
194
+ # I, [2019-03-06T22:32:28.440294 #5070] INFO -- : ◀ RECV {"id":1,"result":{}}
195
+ ```
196
+
180
197
  ## Development
181
198
 
182
199
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment or any of the scripts in the `/examples` directory (e.g. `bundle exec ruby examples/network_dump_and_screenshot.rb`).
183
200
 
184
- To install this gem onto your local machine, run `bundle exec rake install`.
201
+ To install this gem onto your local machine, run `bundle exec rake install`.
185
202
 
186
203
  To release a new version (if you're a maintainer), update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
187
204
 
188
205
  ## Contributing
189
206
 
190
- Bug reports and pull requests are welcome on GitHub at https://github.com/cavalle/chrome_remote.
207
+ Bug reports and pull requests are welcome on GitHub at https://github.com/cavalle/chrome_remote.
191
208
 
192
209
  This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to follow the [code of conduct](https://github.com/cavalle/chrome_remote/blob/master/CODE_OF_CONDUCT.md).
193
210
 
194
211
  ## License
195
212
 
196
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
213
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -20,7 +20,6 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency "websocket-driver", "~> 0.6"
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.15"
24
23
  spec.add_development_dependency "rake", "~> 10.0"
25
24
  spec.add_development_dependency "rspec", "~> 3.0"
26
25
  spec.add_development_dependency "em-websocket", "~> 0.5"
@@ -18,4 +18,4 @@ chrome.wait_for "Page.loadEventFired"
18
18
 
19
19
  # Take page screenshot
20
20
  response = chrome.send_cmd "Page.captureScreenshot"
21
- File.write "screenshot.png", Base64.decode64(response["data"])
21
+ File.write "screenshot.png", Base64.decode64(response["data"])
@@ -4,6 +4,8 @@ require "json"
4
4
  require "net/http"
5
5
 
6
6
  module ChromeRemote
7
+ class ChromeConnectionError < RuntimeError; end
8
+
7
9
  class << self
8
10
  DEFAULT_OPTIONS = {
9
11
  host: "localhost",
@@ -12,20 +14,38 @@ module ChromeRemote
12
14
 
13
15
  def client(options = {})
14
16
  options = DEFAULT_OPTIONS.merge(options)
17
+ logger = options.delete(:logger)
15
18
 
16
- Client.new(get_ws_url(options))
19
+ Client.new(get_ws_url(options), logger)
17
20
  end
18
21
 
19
22
  private
20
23
 
21
24
  def get_ws_url(options)
22
- response = Net::HTTP.get(options[:host], "/json", options[:port])
23
- # TODO handle unsuccesful request
25
+ path = '/json'
26
+ path += '/new?about:blank' if options.key?(:new_tab)
27
+
28
+ response = Net::HTTP.get(options[:host], path, options[:port])
24
29
  response = JSON.parse(response)
25
30
 
26
- first_page = response.find {|e| e["type"] == "page"}
27
- # TODO handle no entry found
31
+ raise ChromeConnectionError unless response.any?
32
+
33
+ return response['webSocketDebuggerUrl'] if options.key?(:new_tab)
34
+
35
+ first_page = response.find {|e| e["type"] == "page"}
36
+
37
+ raise ChromeConnectionError unless first_page
38
+
28
39
  first_page["webSocketDebuggerUrl"]
40
+ rescue ChromeConnectionError
41
+ try ||= 0
42
+ try += 1
43
+
44
+ # Wait up to 5 seconds for Chrome to start fully
45
+ if try <= 50
46
+ sleep 0.1
47
+ retry
48
+ end
29
49
  end
30
50
  end
31
51
  end
@@ -1,18 +1,23 @@
1
1
  require "chrome_remote/web_socket_client"
2
+ require "logger"
2
3
 
3
4
  module ChromeRemote
4
5
  class Client
5
- attr_reader :ws, :handlers
6
+ attr_reader :ws, :handlers, :logger
6
7
 
7
- def initialize(ws_url)
8
+ def initialize(ws_url, logger = nil)
8
9
  @ws = WebSocketClient.new(ws_url)
9
10
  @handlers = Hash.new { |hash, key| hash[key] = [] }
11
+ @logger = logger || Logger.new(nil)
12
+ @last_id = 0
10
13
  end
11
14
 
12
15
  def send_cmd(command, params = {})
13
16
  msg_id = generate_unique_id
17
+ payload = {method: command, params: params, id: msg_id}.to_json
14
18
 
15
- ws.send_msg({method: command, params: params, id: msg_id}.to_json)
19
+ logger.info "SEND #{payload}"
20
+ ws.send_msg(payload)
16
21
 
17
22
  msg = read_until { |msg| msg["id"] == msg_id }
18
23
  msg["result"]
@@ -42,12 +47,13 @@ module ChromeRemote
42
47
  private
43
48
 
44
49
  def generate_unique_id
45
- @last_id ||= 0
46
50
  @last_id += 1
47
51
  end
48
52
 
49
53
  def read_msg
50
- msg = JSON.parse(ws.read_msg)
54
+ msg = ws.read_msg
55
+ logger.info "◀ RECV #{msg}"
56
+ msg = JSON.parse(msg)
51
57
 
52
58
  # Check if it’s an event and invoke any handlers
53
59
  if event_name = msg["method"]
@@ -19,4 +19,4 @@ module ChromeRemote
19
19
  io.readpartial(1024)
20
20
  end
21
21
  end
22
- end
22
+ end
@@ -1,3 +1,3 @@
1
1
  module ChromeRemote
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -15,11 +15,11 @@ module ChromeRemote
15
15
  setup_driver
16
16
  start_driver
17
17
  end
18
-
18
+
19
19
  def send_msg(msg)
20
20
  driver.text msg
21
21
  end
22
-
22
+
23
23
  def read_msg
24
24
  parse_input until msg = messages.shift
25
25
  msg
@@ -31,11 +31,11 @@ module ChromeRemote
31
31
  driver.on(:message) do |e|
32
32
  messages << e.data
33
33
  end
34
-
34
+
35
35
  driver.on(:error) do |e|
36
36
  raise e.message
37
37
  end
38
-
38
+
39
39
  driver.on(:close) do |e|
40
40
  @status = :closed
41
41
  end
@@ -54,4 +54,4 @@ module ChromeRemote
54
54
  @driver.parse(@socket.read)
55
55
  end
56
56
  end
57
- end
57
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chrome_remote
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luismi Cavalle
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-03 00:00:00.000000000 Z
11
+ date: 2019-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: websocket-driver
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.6'
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1.15'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.15'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rake
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -151,8 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
137
  - !ruby/object:Gem::Version
152
138
  version: '0'
153
139
  requirements: []
154
- rubyforge_project:
155
- rubygems_version: 2.6.12
140
+ rubygems_version: 3.0.3
156
141
  signing_key:
157
142
  specification_version: 4
158
143
  summary: ChromeRemote is a client implementation of the Chrome DevTools Protocol in