webkit_remote 0.3.1 → 0.3.2

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.
data/README.md CHANGED
@@ -136,6 +136,42 @@ Again, release the WebKit state.
136
136
  client.clear_all
137
137
  ```
138
138
 
139
+ ### See Network Traffic
140
+
141
+ Record network requests and reload the page.
142
+
143
+ ```ruby
144
+ client.page_events = true
145
+ client.network_events = true
146
+ client.clear_cache
147
+ client.clear_cookies
148
+ client.navigate_to 'http://translate.google.com'
149
+ client.wait_for(type: WebkitRemote::Event::PageLoaded).last
150
+ ```
151
+
152
+ See the network traffic generated by the page.
153
+
154
+ ```ruby
155
+ client.network_resources.length
156
+ resource = client.network_resources.first
157
+ resource.canceled
158
+ resource.type
159
+ resource.request.url
160
+ resource.request.headers
161
+ resource.response.mime_type
162
+ resource.response.url
163
+ resource.response.status
164
+ resource.response.headers
165
+ resource.body
166
+ ```
167
+
168
+ Clean up.
169
+
170
+ ```ruby
171
+ client.clear_all
172
+ ```
173
+
174
+
139
175
  ### Close the Browser
140
176
 
141
177
  ```ruby
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.3.2
@@ -1,3 +1,5 @@
1
+ require 'base64'
2
+
1
3
  module WebkitRemote
2
4
 
3
5
  class Event
@@ -129,7 +131,8 @@ class NetworkMemoryCacheHit < WebkitRemote::Event
129
131
  super
130
132
 
131
133
  if raw_data['resource']
132
- @cache_data = raw_data['resource']
134
+ @cache_data = WebkitRemote::Client::NetworkCacheEntry.new(
135
+ raw_data['resource'])
133
136
  end
134
137
  @document_url = raw_data['documentURL']
135
138
  if raw_data['initiator']
@@ -324,6 +327,24 @@ class NetworkResource
324
327
  @initiator = nil
325
328
  @canceled = false
326
329
  @last_event = nil
330
+ @body = false
331
+ end
332
+
333
+ # @return [String] the contents of the resource
334
+ def body
335
+ @body ||= body!
336
+ end
337
+
338
+ # Re-fetches the resource from the Webkit remote debugging server.
339
+ #
340
+ # @return [String] the contents of the resource
341
+ def body!
342
+ result = @client.rpc.call 'Network.getResponseBody', requestId: @remote_id
343
+ if result['base64Encoded']
344
+ @body = Base64.decode64 result['body']
345
+ else
346
+ @body = result['body']
347
+ end
327
348
  end
328
349
 
329
350
  # @private Rely on the event processing code to set this property.
@@ -168,7 +168,7 @@ class RemoteObject
168
168
  # @return [Webkit::Client::RemoteObject] self
169
169
  def release
170
170
  return if @released
171
- @rpc.call 'Runtime.releaseObject', objectId: @remote_id
171
+ @client.rpc.call 'Runtime.releaseObject', objectId: @remote_id
172
172
  @group.remove self
173
173
  released!
174
174
  end
@@ -191,7 +191,7 @@ class RemoteObject
191
191
  # @return [Hash<Symbol, Webkit::Client::RemoteProperty>] frozen Hash containg
192
192
  # the object's properties
193
193
  def properties!
194
- result = @rpc.call 'Runtime.getProperties', objectId: @remote_id
194
+ result = @client.rpc.call 'Runtime.getProperties', objectId: @remote_id
195
195
  @properties = Hash[
196
196
  result['result'].map do |raw_property|
197
197
  property = WebkitRemote::Client::RemoteProperty.new raw_property, self
@@ -218,7 +218,7 @@ class RemoteObject
218
218
  { value: arg }
219
219
  end
220
220
  end
221
- result = @rpc.call 'Runtime.callFunctionOn', objectId: @remote_id,
221
+ result = @client.rpc.call 'Runtime.callFunctionOn', objectId: @remote_id,
222
222
  functionDeclaration: function_expression, arguments: call_args,
223
223
  returnByValue: false
224
224
  object = WebkitRemote::Client::RemoteObject.for result['result'], @client,
@@ -277,7 +277,6 @@ class RemoteObject
277
277
  def initialize(raw_object, group)
278
278
  @group = group
279
279
  @client = group.client
280
- @rpc = client.rpc
281
280
  @released = false
282
281
 
283
282
  @raw_data = raw_object
@@ -329,7 +328,7 @@ class RemoteObjectGroup
329
328
  object.release
330
329
  end
331
330
  else
332
- @rpc.call 'Runtime.releaseObjectGroup', objectGroup: name
331
+ @client.rpc.call 'Runtime.releaseObjectGroup', objectGroup: name
333
332
  end
334
333
 
335
334
  @released = true
@@ -359,7 +358,6 @@ class RemoteObjectGroup
359
358
  def initialize(name, client)
360
359
  @name = name
361
360
  @client = client
362
- @rpc = client.rpc
363
361
  # TODO(pwnall): turn @objects into a set once equality is working
364
362
  @objects = {}
365
363
  @released = false
@@ -17,6 +17,7 @@ class Client
17
17
  raise ArgumentError, 'Target tab not specified'
18
18
  end
19
19
  @rpc = WebkitRemote::Rpc.new opts
20
+ @debug_url = @rpc.debug_url
20
21
  @browser = tab.browser
21
22
  @close_browser = opts.fetch :close_browser, false
22
23
  @closed = false
@@ -145,6 +146,14 @@ END_METHOD
145
146
  def clear_modules
146
147
  # NOTE: this gets called after all the module cleaners complete
147
148
  end
149
+
150
+ # Debugging output.
151
+ def inspect
152
+ result = self.to_s
153
+ result[-1, 0] =
154
+ " server=#{@debug_url.inspect} closed=#{@closed.inspect}"
155
+ result
156
+ end
148
157
  end # class WebkitRemote::Client
149
158
 
150
159
  end # namespace WebkitRemote
@@ -23,7 +23,8 @@ class Rpc
23
23
  @events = []
24
24
 
25
25
  self.class.em_start
26
- @web_socket = Faye::WebSocket::Client.new tab.debug_url
26
+ @debug_url = tab.debug_url
27
+ @web_socket = Faye::WebSocket::Client.new @debug_url
27
28
  setup_web_socket
28
29
  end
29
30
 
@@ -91,6 +92,9 @@ class Rpc
91
92
  attr_reader :closed
92
93
  alias_method :closed?, :closed
93
94
 
95
+ # @return [String] points to this client's Webkit remote debugging server
96
+ attr_reader :debug_url
97
+
94
98
  # Hooks up the event handlers of the WebSocket client.
95
99
  def setup_web_socket
96
100
  @web_socket.onopen = lambda do |event|
@@ -14,7 +14,7 @@ end
14
14
 
15
15
  # Cache headers for Network domain testing.
16
16
  use Rack::StaticCache, urls: ['/html', '/js', '/png'], root: 'test/fixtures',
17
- versioning: false
17
+ versioning: false, duration: 24 * 60 * 60
18
18
  app = lambda do |env|
19
19
  [
20
20
  200,
@@ -2,6 +2,7 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>WebkitRemote Network test</title>
5
+ <script type="text/javascript" src="../js/network_not_found.js"></script>
5
6
  <script type="text/javascript" src="../js/network.js"></script>
6
7
  </head>
7
8
  <body>
data/test/helper.rb CHANGED
@@ -22,8 +22,8 @@ require 'thread'
22
22
  Thread.abort_on_exception = true
23
23
 
24
24
  # Launch a dev server and wait until it starts.
25
- pid = Process.spawn 'bundle exec puma --port 9969 --quiet test/fixtures/config.ru',
26
- :in => '/dev/null', :out => '/dev/null'
25
+ pid = Process.spawn 'bundle exec puma --port 9969 --quiet --threads 1:1 ' +
26
+ 'test/fixtures/config.ru', :in => '/dev/null', :out => '/dev/null'
27
27
  Process.detach pid
28
28
  at_exit { Process.kill 'TERM', pid }
29
29
  loop do
@@ -14,7 +14,8 @@ describe WebkitRemote::Client::Network do
14
14
  before :all do
15
15
  @client.network_events = false
16
16
  @client.navigate_to fixture_url(:network)
17
- @events = @client.wait_for type: WebkitRemote::Event::ConsoleMessage
17
+ @events = @client.wait_for type: WebkitRemote::Event::ConsoleMessage,
18
+ level: :log
18
19
  end
19
20
 
20
21
  it 'does not receive any network event' do
@@ -38,7 +39,8 @@ describe WebkitRemote::Client::Network do
38
39
  @client.disable_cache = true
39
40
  @client.network_events = true
40
41
  @client.navigate_to fixture_url(:network)
41
- @events = @client.wait_for type: WebkitRemote::Event::ConsoleMessage
42
+ @events = @client.wait_for type: WebkitRemote::Event::ConsoleMessage,
43
+ level: :log
42
44
  @requests = @events.select do |event|
43
45
  event.kind_of? WebkitRemote::Event::NetworkRequest
44
46
  end
@@ -51,6 +53,9 @@ describe WebkitRemote::Client::Network do
51
53
  @chunks = @events.select do |event|
52
54
  event.kind_of? WebkitRemote::Event::NetworkData
53
55
  end
56
+ @failures = @events.select do |event|
57
+ event.kind_of? WebkitRemote::Event::NetworkFailure
58
+ end
54
59
  @resources = @client.network_resources
55
60
  end
56
61
 
@@ -58,7 +63,7 @@ describe WebkitRemote::Client::Network do
58
63
  @requests.wont_be :empty?
59
64
  end
60
65
 
61
- it 'parses initial requests inside NetworkRequest events correctly' do
66
+ it 'parses initial requests inside NetworkRequest events' do
62
67
  @requests[0].request.must_be_kind_of WebkitRemote::Client::NetworkRequest
63
68
  @requests[0].request.url.must_equal fixture_url(:network)
64
69
  @requests[0].request.method.must_equal :get
@@ -68,18 +73,24 @@ describe WebkitRemote::Client::Network do
68
73
  @requests[0].initiator.stack_trace.must_equal nil
69
74
  end
70
75
 
71
- it 'parses derived requests inside NetworkRequest events correctly' do
76
+ it 'parses derived requests inside NetworkRequest events' do
72
77
  @requests[1].document_url.must_equal fixture_url(:network)
73
78
  @requests[1].request.must_be_kind_of WebkitRemote::Client::NetworkRequest
74
- @requests[1].request.url.must_equal fixture_url(:network, :js)
79
+ @requests[1].request.url.must_equal fixture_url(:network_not_found, :js)
75
80
  @requests[1].initiator.type.must_equal :parser
76
81
  @requests[1].initiator.stack_trace.must_equal nil
77
82
 
78
83
  @requests[2].document_url.must_equal fixture_url(:network)
79
84
  @requests[2].request.must_be_kind_of WebkitRemote::Client::NetworkRequest
80
- @requests[2].request.url.must_equal fixture_url(:network, :png)
81
- @requests[2].initiator.type.must_equal :script
82
- @requests[2].initiator.stack_trace.must_equal [
85
+ @requests[2].request.url.must_equal fixture_url(:network, :js)
86
+ @requests[2].initiator.type.must_equal :parser
87
+ @requests[2].initiator.stack_trace.must_equal nil
88
+
89
+ @requests[3].document_url.must_equal fixture_url(:network)
90
+ @requests[3].request.must_be_kind_of WebkitRemote::Client::NetworkRequest
91
+ @requests[3].request.url.must_equal fixture_url(:network, :png)
92
+ @requests[3].initiator.type.must_equal :script
93
+ @requests[3].initiator.stack_trace.must_equal [
83
94
  {column: 7, line: 10, function: "", url: fixture_url(:network, :js)},
84
95
  {column: 3, line: 11, function: "", url: fixture_url(:network, :js)},
85
96
  ]
@@ -89,7 +100,7 @@ describe WebkitRemote::Client::Network do
89
100
  @responses.wont_be :empty?
90
101
  end
91
102
 
92
- it 'parses initial NetworkRequest and NetworkResponse events correctly' do
103
+ it 'parses initial NetworkRequest and NetworkResponse events' do
93
104
  @responses[0].type.must_equal :document
94
105
  @requests[0].initiator.type.must_equal :other
95
106
  @requests[0].loader_id.wont_be :empty?
@@ -99,7 +110,7 @@ describe WebkitRemote::Client::Network do
99
110
  @requests[0].timestamp.must_be :<, @responses[0].timestamp
100
111
  end
101
112
 
102
- it 'parses the initial response inside NetworkResponse events correctly' do
113
+ it 'parses the initial response inside a NetworkResponse event' do
103
114
  @responses[0].type.must_equal :document
104
115
  @responses[0].response.
105
116
  must_be_kind_of WebkitRemote::Client::NetworkResponse
@@ -116,16 +127,34 @@ describe WebkitRemote::Client::Network do
116
127
  @responses[0].response.connection_reused.must_equal false
117
128
  end
118
129
 
119
- it 'parses derived responses inside NetworkResponse events correctly' do
130
+ it 'parses a 404 response inside a NetworkResponse event' do
131
+ @responses[1].type.must_equal :script
132
+ @responses[1].response.
133
+ must_be_kind_of WebkitRemote::Client::NetworkResponse
134
+ @responses[1].response.url.
135
+ must_equal fixture_url(:network_not_found, :js)
136
+ @responses[1].response.status.must_equal 404
137
+ @responses[1].response.status_text.must_match /not found/i
138
+ @responses[1].response.headers.must_include 'X-Unit-Test'
139
+ @responses[1].response.headers['X-Unit-Test'].must_equal 'webkit-remote'
140
+ @responses[1].response.mime_type.must_equal 'text/plain'
141
+ @responses[1].response.request_headers.must_include 'User-Agent'
142
+ @responses[1].response.request_headers['User-Agent']
143
+ .must_match(/webkit/i)
144
+ @responses[1].response.from_cache.must_equal false
145
+ end
146
+
147
+ it 'parses derived responses inside NetworkResponse events' do
120
148
  @responses[1].type.must_equal :script
121
- @responses[2].type.must_equal :xhr
149
+ @responses[2].type.must_equal :script
150
+ @responses[3].type.must_equal :xhr
122
151
  end
123
152
 
124
153
  it 'receives NetworkData events' do
125
154
  @chunks.wont_be :empty?
126
155
  end
127
156
 
128
- it 'parses NetworkData events correctly' do
157
+ it 'parses NetworkData events' do
129
158
  @chunks[0].resource.must_equal @chunks[0].resource
130
159
  @chunks[0].data_length.
131
160
  must_equal File.read(fixture_path(:network)).length
@@ -136,9 +165,19 @@ describe WebkitRemote::Client::Network do
136
165
  @loads.wont_be :empty?
137
166
  end
138
167
 
139
- it 'parses NetworkLoad events correctly' do
168
+ it 'parses NetworkLoad events' do
140
169
  @loads[0].resource.must_equal @requests[0].resource
141
- @loads[1].resource.must_equal @requests[1].resource
170
+ @loads[1].resource.must_equal @requests[2].resource
171
+ end
172
+
173
+ it 'receives NetworkFailure events' do
174
+ @failures.wont_be :empty?
175
+ end
176
+
177
+ it 'parses NetworkFailure events' do
178
+ @failures[0].resource.must_equal @requests[1].resource
179
+ @failures[0].error.wont_equal nil
180
+ @failures[0].canceled.must_equal true
142
181
  end
143
182
 
144
183
  it 'collects request and response data in NetworkResources' do
@@ -148,12 +187,79 @@ describe WebkitRemote::Client::Network do
148
187
  @resources[1].type.must_equal :script
149
188
  @resources[1].document_url.must_equal fixture_url(:network)
150
189
  @resources[1].initiator.must_equal @requests[1].initiator
151
- @resources[1].canceled.must_equal false
152
- @resources[1].error.must_equal nil
153
- @resources[1].last_event.must_equal @loads[1]
190
+ @resources[1].canceled.must_equal true
191
+ @resources[1].error.must_equal @failures[0].error
192
+ @resources[1].last_event.must_equal @failures[0]
154
193
  @resources[1].client.must_equal @client
155
194
 
195
+ @resources[2].must_equal @requests[2].resource
196
+ @resources[2].request.must_equal @requests[2].request
197
+ @resources[2].response.must_equal @responses[2].response
198
+ @resources[2].type.must_equal :script
199
+ @resources[2].document_url.must_equal fixture_url(:network)
200
+ @resources[2].initiator.must_equal @requests[2].initiator
201
+ @resources[2].canceled.must_equal false
202
+ @resources[2].error.must_equal nil
203
+ @resources[2].last_event.must_equal @loads[1]
204
+ @resources[2].client.must_equal @client
205
+
156
206
  @resources[-1].last_event.must_equal @chunks[-1]
157
207
  end
208
+
209
+ it 'retrieves the body for a text NetworkResource' do
210
+ @resources[0].body.must_equal File.read(fixture_path(:network))
211
+ end
212
+
213
+ it 'retrieves the body for a binary NetworkResource' do
214
+ skip 'waiting for http://crbug.com/160397'
215
+ @resources[2].body.must_equal File.binread(fixture_path(:network, :png))
216
+ end
217
+ end
218
+
219
+ describe 'and a cached request' do
220
+ before :all do
221
+ @client.disable_cache = false
222
+ @client.navigate_to fixture_url(:network)
223
+ @client.wait_for type: WebkitRemote::Event::ConsoleMessage, level: :log
224
+ @client.clear_all
225
+
226
+ @client.network_events = true
227
+ @client.navigate_to fixture_url(:network)
228
+ @events = @client.wait_for type: WebkitRemote::Event::ConsoleMessage,
229
+ level: :log
230
+ @requests = @events.select do |event|
231
+ event.kind_of? WebkitRemote::Event::NetworkRequest
232
+ end
233
+ @responses = @events.select do |event|
234
+ event.kind_of? WebkitRemote::Event::NetworkResponse
235
+ end
236
+ @loads = @events.select do |event|
237
+ event.kind_of? WebkitRemote::Event::NetworkLoad
238
+ end
239
+ @chunks = @events.select do |event|
240
+ event.kind_of? WebkitRemote::Event::NetworkData
241
+ end
242
+ @hits = @events.select do |event|
243
+ event.kind_of? WebkitRemote::Event::NetworkCacheHit
244
+ end
245
+ @memory_hits = @events.select do |event|
246
+ event.kind_of? WebkitRemote::Event::NetworkMemoryCacheHit
247
+ end
248
+
249
+ @resources = @client.network_resources
250
+ end
251
+
252
+ it 'receives NetworkCacheHit events' do
253
+ @hits.wont_be :empty?
254
+ end
255
+
256
+ it 'parses NetworkCacheHits events' do
257
+ @hits[0].resource.must_equal @requests[2].resource
258
+ end
259
+
260
+ it 'receives NetworkMemoryCacheHit events' do
261
+ skip 'waiting for http://crbug.com/160404'
262
+ @memory_hits.wont_be :empty?
263
+ end
158
264
  end
159
265
  end
@@ -32,6 +32,10 @@ describe WebkitRemote::Client do
32
32
  it 'closes the browser master debugging session' do
33
33
  @browser.closed?.must_equal true
34
34
  end
35
+
36
+ it 'still retuns a good inspect string' do
37
+ @client.inspect.must_match(/<.*WebkitRemote::Client.*>/)
38
+ end
35
39
  end
36
40
 
37
41
  describe 'each_event' do
@@ -102,5 +106,12 @@ describe WebkitRemote::Client do
102
106
  @client.clear_all
103
107
  end
104
108
  end
109
+
110
+ describe 'inspect' do
111
+ it 'includes the debugging URL and closed flag' do
112
+ @client.inspect.must_match(
113
+ /<WebkitRemote::Client:.*\s+server=".*"\s+closed=.+>/)
114
+ end
115
+ end
105
116
  end
106
117
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "webkit_remote"
8
- s.version = "0.3.1"
8
+ s.version = "0.3.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Victor Costan"]
12
- s.date = "2012-11-08"
12
+ s.date = "2012-11-10"
13
13
  s.description = "Launches Google Chrome instances and controls them via the Remote Debugging server"
14
14
  s.email = "victor@costan.us"
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webkit_remote
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-08 00:00:00.000000000 Z
12
+ date: 2012-11-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -286,7 +286,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
286
286
  version: '0'
287
287
  segments:
288
288
  - 0
289
- hash: 2944886604051237369
289
+ hash: 3000124756786155400
290
290
  required_rubygems_version: !ruby/object:Gem::Requirement
291
291
  none: false
292
292
  requirements: