webkit_remote 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ before_install:
5
+ - "export DISPLAY=:99.0"
6
+ - "sh -e /etc/init.d/xvfb start"
7
+ - "sudo sh -c \"echo \\\"deb https://dl.google.com/linux/deb/ stable main\\\" >> /etc/apt/sources.list\""
8
+ - "sudo wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -"
9
+ - "sudo apt-get -qq update"
10
+ - "sudo apt-get -qq install google-chrome-stable"
data/Gemfile CHANGED
@@ -9,6 +9,7 @@ group :development do
9
9
  gem 'minitest', '>= 4.1.0'
10
10
  gem 'puma', '>= 1.6.3'
11
11
  gem 'rack', '>= 1.4.1'
12
+ gem 'rack-contrib', '>= 1.1.0'
12
13
  gem 'rdoc', '>= 3.12'
13
14
  gem 'ruby-prof', '>= 0.11.2'
14
15
  gem 'simplecov', '>= 0.7.1'
data/Gemfile.lock CHANGED
@@ -17,6 +17,8 @@ GEM
17
17
  puma (1.6.3)
18
18
  rack (~> 1.2)
19
19
  rack (1.4.1)
20
+ rack-contrib (1.1.0)
21
+ rack (>= 0.9.1)
20
22
  rake (0.9.2.2)
21
23
  rdoc (3.12)
22
24
  json (~> 1.4)
@@ -39,6 +41,7 @@ DEPENDENCIES
39
41
  posix-spawn (>= 0.3.6)
40
42
  puma (>= 1.6.3)
41
43
  rack (>= 1.4.1)
44
+ rack-contrib (>= 1.1.0)
42
45
  rdoc (>= 3.12)
43
46
  ruby-prof (>= 0.11.2)
44
47
  simplecov (>= 0.7.1)
data/README.md CHANGED
@@ -105,10 +105,10 @@ END_JS
105
105
  client.remote_eval('window').bound_call js_code, element, '你好'
106
106
  ```
107
107
 
108
- Finally, release the JavaScript objects that the debugger is holding onto.
108
+ Finally, release the WebKit state that the debugger is holding onto.
109
109
 
110
110
  ```ruby
111
- element.group.release_all
111
+ client.clear_all
112
112
  ```
113
113
 
114
114
  ### Read the Console
@@ -130,8 +130,13 @@ message.params
130
130
  message.stack_trace
131
131
  ```
132
132
 
133
+ Again, release the WebKit state.
133
134
 
134
- ### Clean Up
135
+ ```ruby
136
+ client.clear_all
137
+ ```
138
+
139
+ ### Close the Browser
135
140
 
136
141
  ```ruby
137
142
  client.close
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
data/lib/webkit_remote.rb CHANGED
@@ -9,6 +9,8 @@ require 'webkit_remote/client.rb'
9
9
  require 'webkit_remote/event.rb'
10
10
  require 'webkit_remote/client/console.rb'
11
11
  require 'webkit_remote/client/console_events.rb'
12
+ require 'webkit_remote/client/network.rb'
13
+ require 'webkit_remote/client/network_events.rb'
12
14
  require 'webkit_remote/client/page.rb'
13
15
  require 'webkit_remote/client/page_events.rb'
14
16
  require 'webkit_remote/client/runtime.rb'
@@ -81,6 +81,23 @@ class Client
81
81
  events
82
82
  end
83
83
 
84
+ # Removes all the remote debugging data cached by this client.
85
+ #
86
+ # Some modules accumulate data throughout the debigging process. For example,
87
+ # WebkitRemote::Client::Remote#remote_eval and
88
+ # WebkitRemote::Events#ConsoleMessage build Ruby equivalents of the returned
89
+ # JavaScript objects, and prevent Chrome from garbage-collecting the
90
+ # returned JavaScript objects.
91
+ #
92
+ # Although modules have individual methods for releasing this data, such as
93
+ # WebkitRemote::Client::RemoteGroup#release, keeping track of individual data
94
+ # items is very inconvenient. Therefore, if you need to run a WebkitRemote
95
+ # client for an extended period of time, you might find it easier to
96
+ # periodically call this method.
97
+ def clear_all
98
+ clear_modules
99
+ end
100
+
84
101
  # @return [WebkitRemote::Rpc] the WebSocket RPC client; useful for making raw
85
102
  # RPC calls to unsupported methods
86
103
  attr_reader :rpc
@@ -89,13 +106,6 @@ class Client
89
106
  # tab debugged by this client
90
107
  attr_reader :browser
91
108
 
92
- # Call by the constructor. Replaced by the module initializers.
93
- #
94
- # @private Hook for module initializers to do their own setups.
95
- def initialize_modules
96
- # NOTE: this gets called after all the module initializers complete
97
- end
98
-
99
109
  # Registers a module initializer.
100
110
  def self.initializer(name)
101
111
  before_name = :"initialize_modules_before_#{name}"
@@ -108,6 +118,33 @@ class Client
108
118
  end
109
119
  END_METHOD
110
120
  end
121
+
122
+ # Registers a module clearer.
123
+ def self.clearer(name)
124
+ before_name = :"clear_modules_before_#{name}"
125
+ alias_method before_name, :clear_modules
126
+ remove_method :clear_modules
127
+ eval <<END_METHOD
128
+ def clear_modules
129
+ #{name}
130
+ #{before_name.to_s}
131
+ end
132
+ END_METHOD
133
+ end
134
+
135
+ # Called by the constructor. Aliased by the module initializers.
136
+ #
137
+ # @private Hook for module initializers to do their own setups.
138
+ def initialize_modules
139
+ # NOTE: this gets called after all the module initializers complete
140
+ end
141
+
142
+ # Called by clear_all.
143
+ #
144
+ # @private Hook for modules to run their own clearing code.
145
+ def clear_modules
146
+ # NOTE: this gets called after all the module cleaners complete
147
+ end
111
148
  end # class WebkitRemote::Client
112
149
 
113
150
  end # namespace WebkitRemote
@@ -4,14 +4,6 @@ class Client
4
4
 
5
5
  # API for the Console domain.
6
6
  module Console
7
- # Removes all the messages in the console.
8
- #
9
- # @return [WebkitRemote::Client] self
10
- def clear_console
11
- @rpc.call 'Console.clearMessages'
12
- self
13
- end
14
-
15
7
  # Enables or disables the generation of events in the Console domain.
16
8
  #
17
9
  # @param [Boolean] new_console_events if true, the browser debugger will
@@ -19,22 +11,31 @@ module Console
19
11
  def console_events=(new_console_events)
20
12
  new_console_events = !!new_console_events
21
13
  if new_console_events != console_events
14
+ @rpc.call(new_console_events ? 'Console.enable' : 'Console.disable')
22
15
  @console_events = new_console_events
23
- @rpc.call(@console_events ? 'Console.enable' : 'Console.disable')
24
16
  end
25
17
  new_console_events
26
18
  end
27
19
 
20
+ # Removes all the messages in the console.
21
+ #
22
+ # @return [WebkitRemote::Client] self
23
+ def clear_console
24
+ @rpc.call 'Console.clearMessages'
25
+ self
26
+ end
27
+
28
28
  # @return [Boolean] true if the debugger generates Console.* events
29
29
  attr_reader :console_events
30
30
 
31
31
  # @private Called by the Client constructor to set up Console data.
32
32
  def initialize_console
33
- @console_events = nil
33
+ @console_events = false
34
34
  end
35
35
  end # module WebkitRemote::Client::Console
36
36
 
37
37
  initializer :initialize_console
38
+ clearer :clear_console
38
39
  include WebkitRemote::Client::Console
39
40
 
40
41
  end # namespace WebkitRemote::Client
@@ -65,26 +65,8 @@ class ConsoleMessage < WebkitRemote::Event
65
65
  else
66
66
  @reason = :other
67
67
  end
68
- if raw_message['stackTrace']
69
- @stack_trace = raw_message['stackTrace'].map do |raw_frame|
70
- frame = {}
71
- if raw_frame['columnNumber']
72
- frame[:column] = raw_frame['columnNumber'].to_i
73
- end
74
- if raw_frame['lineNumber']
75
- frame[:line] = raw_frame['lineNumber'].to_i
76
- end
77
- if raw_frame['functionName']
78
- frame[:function] = raw_frame['functionName']
79
- end
80
- if raw_frame['url']
81
- frame[:url] = raw_frame['url']
82
- end
83
- frame
84
- end
85
- else
86
- @trace = nil
87
- end
68
+ @stack_trace = WebkitRemote::Event::ConsoleMessage.parse_stack_trace(
69
+ raw_message['stackTrace'])
88
70
  @text = raw_message['text']
89
71
  @type = raw_message['type'] ? raw_message['type'].to_sym : nil
90
72
  @source_url = raw_message['url']
@@ -107,6 +89,33 @@ class ConsoleMessage < WebkitRemote::Event
107
89
  def self.can_reach?(client)
108
90
  client.console_events
109
91
  end
92
+
93
+
94
+ # Parses a StackTrace object returned by a RPC request.
95
+ #
96
+ # @param [Array<String, Object>] raw_stack_trace the raw StackTrace object
97
+ # in the Console domain returned by a RPC request
98
+ # @return [Array<Symbol, Object>] Ruby-friendly stack trace
99
+ def self.parse_stack_trace(raw_stack_trace)
100
+ return nil unless raw_stack_trace
101
+
102
+ raw_stack_trace.map do |raw_frame|
103
+ frame = {}
104
+ if raw_frame['columnNumber']
105
+ frame[:column] = raw_frame['columnNumber'].to_i
106
+ end
107
+ if raw_frame['lineNumber']
108
+ frame[:line] = raw_frame['lineNumber'].to_i
109
+ end
110
+ if raw_frame['functionName']
111
+ frame[:function] = raw_frame['functionName']
112
+ end
113
+ if raw_frame['url']
114
+ frame[:url] = raw_frame['url']
115
+ end
116
+ frame
117
+ end
118
+ end
110
119
  end # class WebkitRemote::Event::ConsoleMessage
111
120
 
112
121
  # Emitted when the same console message is produced repeatedly.
@@ -0,0 +1,155 @@
1
+ module WebkitRemote
2
+
3
+ class Client
4
+
5
+ # API for the Network domain.
6
+ module Network
7
+ # Enables or disables the generation of events in the Network domain.
8
+ #
9
+ # @param [Boolean] new_network_events if true, the browser debugger will
10
+ # generate Network.* events
11
+ def network_events=(new_network_events)
12
+ new_network_events = !!new_network_events
13
+ if new_network_events != network_events
14
+ @rpc.call(new_network_events ? 'Network.enable' : 'Network.disable')
15
+ @network_events = new_network_events
16
+ end
17
+ new_network_events
18
+ end
19
+
20
+ # Enables or disables the use of the network cache.
21
+ #
22
+ # @param [Boolean] new_disable_cache if true, the browser will not use its
23
+ # network cache, and will always generate HTTP requests
24
+ def disable_cache=(new_disable_cache)
25
+ new_disable_cache = !!new_disable_cache
26
+ if new_disable_cache != disable_cache
27
+ @rpc.call 'Network.setCacheDisabled', cacheDisabled: new_disable_cache
28
+ @disable_cache = new_disable_cache
29
+ end
30
+ new_disable_cache
31
+ end
32
+
33
+ # Sets the User-Agent header that the browser will use to identify itself.
34
+ #
35
+ # @param [String] new_user_agent will be used instead of the browser's
36
+ # hard-coded User-Agent header
37
+ def user_agent=(new_user_agent)
38
+ if new_user_agent != user_agent
39
+ @rpc.call 'Network.setUserAgentOverride', userAgent: new_user_agent
40
+ @user_agent = new_user_agent
41
+ end
42
+ new_user_agent
43
+ end
44
+
45
+ # Sets extra headers to be sent with every HTTP request.
46
+ #
47
+ # @param [Hash<String, String>] new_extra_headers HTTP headers to be added to
48
+ # every HTTP request sent by the browser
49
+ def http_headers=(new_http_headers)
50
+ new_http_headers = Hash[new_http_headers.map { |k, v|
51
+ [k.to_s, v.to_s]
52
+ }].freeze
53
+ if new_http_headers != http_headers
54
+ @rpc.call 'Network.setExtraHTTPHeaders', headers: new_http_headers
55
+ @http_headers = new_http_headers
56
+ end
57
+ new_http_headers
58
+ end
59
+
60
+ # Checks if the debugger can clear the browser's cookies.
61
+ #
62
+ # @return [Boolean] true if WebkitRemote::Client::Network#clear_cookies can
63
+ # be succesfully called
64
+ def can_clear_cookies?
65
+ response = @rpc.call 'Network.canClearBrowserCookies'
66
+ !!response['result']
67
+ end
68
+
69
+ # Removes all the cookies in the debugged browser.
70
+ #
71
+ # @return [WebkitRemote::Client] self
72
+ def clear_cookies
73
+ @rpc.call 'Network.clearBrowserCookies'
74
+ self
75
+ end
76
+
77
+ # Checks if the debugger can clear the browser's cache.
78
+ #
79
+ # @return [Boolean] true if WebkitRemote::Client::Network#clear_network_cache
80
+ # can be succesfully called
81
+ def can_clear_network_cache?
82
+ response = @rpc.call 'Network.canClearBrowserCache'
83
+ !!response['result']
84
+ end
85
+
86
+ # Removes all the cached data in the debugged browser.
87
+ #
88
+ # @return [WebkitRemote::Client] self
89
+ def clear_network_cache
90
+ @rpc.call 'Network.clearBrowserCache'
91
+ self
92
+ end
93
+
94
+ # @return [Boolean] true if the debugger generates Network.* events
95
+ attr_reader :network_events
96
+
97
+ # @return [Array<WebkitRemote::Client::NetworkResource>] the resources
98
+ # fetched during the debugging session
99
+ #
100
+ # This is only populated when Network events are received.
101
+ attr_reader :network_resources
102
+
103
+ # @return [Boolean] true if the browser's network cache is disabled, so every
104
+ # resource load generates an HTTP request
105
+ attr_reader :disable_cache
106
+
107
+ # @return [String] replaces the brower's built-in User-Agent string
108
+ attr_reader :user_agent
109
+
110
+ # @return [Hash<String, String>]
111
+ attr_reader :http_headers
112
+
113
+ # Looks up network resources by IDs assigned by the WebKit remote debugger.
114
+ #
115
+ # @private Use the #resource property of Network events instead of calling
116
+ # this directly.
117
+ #
118
+ # @param [String] remote_id the WebKit-assigned request_id
119
+ # @return [WebkitRemote::Client::NetworkResource] the cached information
120
+ # about the resource with the given ID
121
+ def network_resource(remote_id)
122
+ if @network_resource_hash[remote_id]
123
+ return @network_resource_hash[remote_id]
124
+ end
125
+ resource = WebkitRemote::Client::NetworkResource.new remote_id, self
126
+
127
+ @network_resources << resource
128
+ @network_resource_hash[remote_id] = resource
129
+ end
130
+
131
+ # Removes the cached network request information.
132
+ #
133
+ # @return [WebkitRemote::Client] self
134
+ def clear_network
135
+ @network_resource_hash.clear
136
+ @network_resources.clear
137
+ self
138
+ end
139
+
140
+ # @private Called by the Client constructor to set up Network data.
141
+ def initialize_network
142
+ @disable_cache = false
143
+ @network_events = false
144
+ @network_resources = []
145
+ @network_resource_hash = {}
146
+ @user_agent = nil
147
+ end
148
+ end # module WebkitRemote::Client::Network
149
+
150
+ initializer :initialize_network
151
+ include WebkitRemote::Client::Network
152
+
153
+ end # namespace WebkitRemote::Client
154
+
155
+ end # namespace WebkitRemote
@@ -0,0 +1,584 @@
1
+ module WebkitRemote
2
+
3
+ class Event
4
+
5
+ # Emitted when a chunk of data is received over the network.
6
+ class NetworkData < WebkitRemote::Event
7
+ register 'Network.dataReceived'
8
+
9
+ # @return [WebkitRemote::Client::NetworkResource] information about the
10
+ # resource fetched by this network operation
11
+ attr_reader :resource
12
+
13
+ # @return [Number] the event timestamp
14
+ attr_reader :timestamp
15
+
16
+ # @return [Number] number of bytes actually received
17
+ attr_reader :bytes_received
18
+
19
+ # @return [Number] number of data bytes received (after decompression)
20
+ attr_reader :data_length
21
+
22
+ # @private Use Event#for instead of calling this constructor directly.
23
+ def initialize(rpc_event, client)
24
+ super
25
+ @data_length = raw_data['dataLength']
26
+ @bytes_received = raw_data['encodedDataLength']
27
+ @timestamp = raw_data['timestamp']
28
+
29
+ @resource = client.network_resource raw_data['requestId']
30
+ @resource.add_event self
31
+ end
32
+ end # class WebkitRemote::Event::NetworkData
33
+
34
+ # Emitted when a resource fails to load.
35
+ class NetworkFailure < WebkitRemote::Event
36
+ register 'Network.loadingFailed'
37
+
38
+ # @return [WebkitRemote::Client::NetworkResource] information about the
39
+ # resource fetched by this network operation
40
+ attr_reader :resource
41
+
42
+ # @return [Number] the event timestamp
43
+ attr_reader :timestamp
44
+
45
+ # @return [String] the error message
46
+ attr_reader :error
47
+
48
+ # @return [Boolean] true if the request was canceled
49
+ #
50
+ # For example, CORS violations cause requests to be canceled.
51
+ attr_reader :canceled
52
+
53
+ # @private Use Event#for instead of calling this constructor directly.
54
+ def initialize(rpc_event, client)
55
+ super
56
+ @canceled = !!raw_data['canceled']
57
+ @error = raw_data['errorText']
58
+ @timestamp = raw_data['timestamp']
59
+
60
+ @resource = client.network_resource raw_data['requestId']
61
+ @resource.set_canceled @canceled
62
+ @resource.set_error @error
63
+ @resource.add_event self
64
+ end
65
+ end # class WebkitRemote::Event::NetworkFailure
66
+
67
+ # Emitted when a resource finishes loading from the network.
68
+ class NetworkLoad < WebkitRemote::Event
69
+ register 'Network.loadingFinished'
70
+
71
+ # @return [WebkitRemote::Client::NetworkResource] information about the
72
+ # resource fetched by this network operation
73
+ attr_reader :resource
74
+
75
+ # @return [Number] the event timestamp
76
+ attr_reader :timestamp
77
+
78
+ # @private Use Event#for instead of calling this constructor directly.
79
+ def initialize(rpc_event, client)
80
+ super
81
+ @timestamp = raw_data['timestamp']
82
+
83
+ @resource = client.network_resource raw_data['requestId']
84
+ @resource.add_event self
85
+ end
86
+ end # class WebkitRemote::Event::NetworkLoad
87
+
88
+ # Emitted when a resource is served from the local cache.
89
+ class NetworkCacheHit < WebkitRemote::Event
90
+ register 'Network.requestServedFromCache'
91
+
92
+ # @return [WebkitRemote::Client::NetworkResource] information about the
93
+ # resource fetched by this network operation
94
+ attr_reader :resource
95
+
96
+ # @private Use Event#for instead of calling this constructor directly.
97
+ def initialize(rpc_event, client)
98
+ super
99
+
100
+ @resource = client.network_resource raw_data['requestId']
101
+ @resource.add_event self
102
+ end
103
+ end # class WebkitRemote::Event::NetworkCacheHit
104
+
105
+ # Emitted when a resource is served from the local cache.
106
+ class NetworkMemoryCacheHit < WebkitRemote::Event
107
+ register 'Network.requestServedFromMemoryCache'
108
+
109
+ # @return [WebkitRemote::Client::NetworkResource] information about the
110
+ # resource fetched by this network operation
111
+ attr_reader :resource
112
+
113
+ # @return [WebkitRemote::Client::NetworkCacheEntry] cached information used
114
+ # to produce the resource
115
+ attr_reader :cache_data
116
+
117
+ # @return [String] the URL of the document that caused this network request
118
+ attr_reader :document_url
119
+
120
+ # @return [WebkitRemote::Client::NetworkRequestInitiator] cause for this
121
+ # network request
122
+ attr_reader :initiator
123
+
124
+ # @return [Number] the event timestamp
125
+ attr_reader :timestamp
126
+
127
+ # @private Use Event#for instead of calling this constructor directly.
128
+ def initialize(rpc_event, client)
129
+ super
130
+
131
+ if raw_data['resource']
132
+ @cache_data = raw_data['resource']
133
+ end
134
+ @document_url = raw_data['documentURL']
135
+ if raw_data['initiator']
136
+ @initiator = WebkitRemote::Client::NetworkRequestInitiator.new(
137
+ raw_data['initiator'])
138
+ end
139
+ @loader_id = raw_data['loaderId']
140
+ @timestamp = raw_data['timestamp']
141
+
142
+ @resource = client.network_resource raw_data['requestId']
143
+ @resource.set_document_url @document_url
144
+ @resource.set_initiator @initiator
145
+ if @cache_data
146
+ @resource.set_response @cache_data.response
147
+ @resource.set_type @cache_data.type
148
+ end
149
+ @resource.add_event self
150
+ end
151
+ end # class WebkitRemote::Event::NetworkMemoryCacheHit
152
+
153
+ # Emitted right before a network request.
154
+ class NetworkRequest < WebkitRemote::Event
155
+ register 'Network.requestWillBeSent'
156
+
157
+ # @return [WebkitRemote::Client::NetworkResource] information about the
158
+ # resource fetched by this network operation
159
+ attr_reader :resource
160
+
161
+ # @return [WebkitRemote::Client::NetworkRequest] information about this
162
+ # network request
163
+ attr_reader :request
164
+
165
+ # @return [String] the URL of the document that caused this network request
166
+ attr_reader :document_url
167
+
168
+ # @return [WebkitRemote::Client::NetworkRequestInitiator] cause for this
169
+ # network request
170
+ attr_reader :initiator
171
+
172
+ # @return [WebkitRemote::Client::NetworkResponse] the HTTP redirect that
173
+ # caused this request; can be nil
174
+ attr_reader :redirect_response
175
+
176
+ # @return [String] used to correlate events
177
+ attr_reader :loader_id
178
+
179
+ # @return [Number] the event timestamp
180
+ attr_reader :timestamp
181
+
182
+ # @private Use Event#for instead of calling this constructor directly.
183
+ def initialize(rpc_event, client)
184
+ super
185
+ if raw_data['initiator']
186
+ @initiator = WebkitRemote::Client::NetworkRequestInitiator.new(
187
+ raw_data['initiator'])
188
+ end
189
+ @loader_id = raw_data['loaderId']
190
+ if raw_data['request']
191
+ @request = WebkitRemote::Client::NetworkRequest.new(
192
+ raw_data['request'])
193
+ end
194
+ if raw_data['redirectResponse']
195
+ @redirect_response = WebkitRemote::Client::NetworkResponse.new(
196
+ raw_data['redirectResponse'])
197
+ end
198
+ if raw_data['stackTrace']
199
+ @stack_trace = WebkitRemote::Event::ConsoleMessage.parse_stack_trace(
200
+ raw_initiator['stackTrace'])
201
+ else
202
+ @stack_trace = nil
203
+ end
204
+ @timestamp = raw_data['timestamp']
205
+
206
+ @resource = client.network_resource raw_data['requestId']
207
+ @resource.set_initiator @initiator
208
+ @resource.set_request @request
209
+ # TODO(pwnall): consider tracking redirects
210
+ @resource.add_event self
211
+ end
212
+
213
+ # @private Use Event#can_receive instead of calling this directly.
214
+ def self.can_reach?(client)
215
+ client.network_events
216
+ end
217
+ end # class WebkitRemote::Event::NetworkRequest
218
+
219
+ # Emitted right after receiving a response to a network request.
220
+ class NetworkResponse < WebkitRemote::Event
221
+ register 'Network.responseReceived'
222
+
223
+ # @return [WebkitRemote::Client::NetworkResource] information about the
224
+ # resource fetched by this network operation
225
+ attr_reader :resource
226
+
227
+ # @return [WebkitRemote::Client::NetworkResponse] information about the HTTP
228
+ # response behind this event
229
+ attr_reader :response
230
+
231
+ # @return [Symbol] the type of resource returned by this response; documented
232
+ # values are :document, :font, :image, :other, :script, :stylesheet,
233
+ # :websocket and :xhr
234
+ attr_reader :type
235
+
236
+ # @return [Number] the event timestamp
237
+ attr_reader :timestamp
238
+
239
+ # @return [String] used to correlate events
240
+ attr_reader :loader_id
241
+
242
+ # @private Use Event#for instead of calling this constructor directly.
243
+ def initialize(rpc_event, client)
244
+ super
245
+ @loader_id = raw_data['loaderId']
246
+ if raw_data['response']
247
+ @response = WebkitRemote::Client::NetworkResponse.new(
248
+ raw_data['response'])
249
+ end
250
+ @type = (raw_data['type'] || 'other').downcase.to_sym
251
+ @timestamp = raw_data['timestamp']
252
+
253
+ @resource = client.network_resource raw_data['requestId']
254
+ @resource.set_response @response
255
+ @resource.set_type @type
256
+ @resource.add_event self
257
+ end
258
+
259
+ # @private Use Event#can_receive instead of calling this directly.
260
+ def self.can_reach?(client)
261
+ client.network_events
262
+ end
263
+ end # class WebkitRemote::Event::NetworkResponse
264
+
265
+ end # namespace WebkitRemote::Event
266
+
267
+
268
+ class Client
269
+
270
+ # Wraps information about the network operations for retrieving a resource.
271
+ class NetworkResource
272
+ # @return [WebkitRemote::Client::NetworkRequest] network request (most likely
273
+ # HTTP) used to fetch this resource
274
+ attr_reader :request
275
+
276
+ # @return [WebkitRemote::Client::NetworkRequest] network response that
277
+ # contains this resource
278
+ attr_reader :response
279
+
280
+ # @return [Symbol] the type of this resource; documented values are
281
+ # :document, :font, :image, :other, :script, :stylesheet, :websocket and
282
+ # :xhr
283
+ attr_reader :type
284
+
285
+ # @return [String] the URL of the document that referenced this resource
286
+ attr_reader :document_url
287
+
288
+ # @return [WebkitRemote::Client::NetworkRequestInitiator] cause for this
289
+ # resource to be fetched from the network
290
+ attr_reader :initiator
291
+
292
+ # @return [Boolean] true if the request fetch was canceled
293
+ attr_reader :canceled
294
+
295
+ # @return [String] error message, if the resource fetching failed
296
+ attr_reader :error
297
+
298
+ # @return [WebkitRemote::Event] last event connected to this resource; can be
299
+ # used to determine the resource's status
300
+ attr_reader :last_event
301
+
302
+ # @return [WebkitRemote::Client] remote debugging client that reported this
303
+ attr_reader :client
304
+
305
+ # @return [String] request_id assigned by the remote WebKit debugger
306
+ attr_reader :remote_id
307
+
308
+ # Creates an empty network operation wrapper.
309
+ #
310
+ # @private Use WebkitRemote::Client::Network#network_op instead of calling
311
+ # this directly.
312
+ # @param [String] remote_id the request_id used by the remote debugging
313
+ # server to identify this network operation
314
+ # @param [WebkitRemote::Client]
315
+ def initialize(remote_id, client)
316
+ @remote_id = remote_id
317
+ @client = client
318
+ @request = nil
319
+ @response = nil
320
+ @type = nil
321
+ @document_url = nil
322
+ @initiator = nil
323
+ @canceled = false
324
+ @last_event = nil
325
+ end
326
+
327
+ # @private Rely on the event processing code to set this property.
328
+ def set_canceled(new_canceled)
329
+ @canceled ||= new_canceled
330
+ end
331
+
332
+ # @private Rely on the event processing code to set this property.
333
+ def set_document_url(new_document_url)
334
+ return if new_document_url == nil
335
+ @document_url = new_document_url
336
+ end
337
+
338
+ # @private Rely on the event processing code to set this property.
339
+ def set_error(new_error)
340
+ return if new_error == nil
341
+ @error = new_error
342
+ end
343
+
344
+ # @private Rely on the event processing code to set this property.
345
+ def set_initiator(new_initiator)
346
+ return if new_initiator == nil
347
+ @initiator = new_initiator
348
+ end
349
+
350
+ # @private Rely on the event processing code to set this property.
351
+ def set_request(new_request)
352
+ return if new_request == nil
353
+ # TODO(pwnall): consider handling multiple requests
354
+ @request = new_request
355
+ end
356
+
357
+ # @private Rely on the event processing code to set this property.
358
+ def set_response(new_response)
359
+ return if new_response == nil
360
+ @response = new_response
361
+ end
362
+
363
+ # @private Rely on the event processing code to set this property.
364
+ def set_type(new_type)
365
+ return if new_type == nil
366
+ @type = new_type
367
+ end
368
+
369
+ # @private Rely on the event processing code to set this property.
370
+ def add_event(event)
371
+ @last_event = event
372
+ # TODO(pwnall): consider keeping track of all events
373
+ end
374
+ end # namespace WebkitRemote::Event
375
+
376
+ # Wraps information about HTTP requests.
377
+ class NetworkRequest
378
+ # @return [String] the URL of the request
379
+ attr_reader :url
380
+
381
+ # @return [Symbol, nil] HTTP request method, e.g. :get
382
+ attr_reader :method
383
+
384
+ # @return [Hash<String, String>] the HTTP headers of the request
385
+ attr_reader :headers
386
+
387
+ # @return [String] the body of a POST request
388
+ attr_reader :body
389
+
390
+ # @private use Event#for instead of calling this constructor directly
391
+ #
392
+ # @param [Hash<String, Number>] the raw RPC data for a Response object
393
+ # in the Network domain
394
+ def initialize(raw_response)
395
+ @headers = raw_response['headers'] || {}
396
+ @method = raw_response['method'] ? raw_response['method'].downcase.to_sym :
397
+ nil
398
+ @body = raw_response['postData']
399
+ @url = raw_response['url']
400
+ end
401
+ end # class WebkitRemote::Client::NetworkRequest
402
+
403
+ # Wraps information about responses to network requests.
404
+ class NetworkResponse
405
+ # @return [String] the URL of the response
406
+ attr_reader :url
407
+
408
+ # @return [Number] HTTP status code
409
+ attr_reader :status
410
+
411
+ # @return [String] HTTP status message
412
+ attr_reader :status_text
413
+
414
+ # @return [Hash<String, String>] HTTP response headers
415
+ attr_reader :headers
416
+
417
+ # @return [String] the browser-determined response MIME type
418
+ attr_reader :mime_type
419
+
420
+ # @return [Hash<String, String>] HTTP request headers
421
+ attr_reader :request_headers
422
+
423
+ # @return [Boolean] true if the request was served from cache
424
+ attr_reader :from_cache
425
+
426
+ # @return [Number] id of the network connection used by the browser to fetch
427
+ # this resource
428
+ attr_reader :connection_id
429
+
430
+ # @return [Boolean] true if the network connection used for this request was
431
+ # already open
432
+ attr_reader :connection_reused
433
+
434
+ # @private use Event#for instead of calling this constructor directly
435
+ #
436
+ # @param [Hash<String, Number>] the raw RPC data for a Response object
437
+ # in the Network domain
438
+ def initialize(raw_response)
439
+ @connection_id = raw_response['connectionId']
440
+ @connection_reused = raw_response['connectionReused'] || false
441
+ @from_cache = raw_response['fromDiskCache'] || false
442
+ @headers = raw_response['headers'] || {}
443
+ @mime_type = raw_response['mimeType']
444
+ @request_headers = raw_response['requestHeaders'] || {}
445
+ @status = raw_response['status']
446
+ @status_text = raw_response['statusText']
447
+ if raw_response['timing']
448
+ @timing = WebkitRemote::Client::NetworkResourceTiming.new(
449
+ raw_response['timing'])
450
+ else
451
+ @timing = nil
452
+ end
453
+ @url = raw_response['url']
454
+ end
455
+ end # class WebkitRemote::Client::NetworkResponse
456
+
457
+ # Wraps timing information for network events.
458
+ class NetworkResourceTiming
459
+ # @param [Number] baseline time for the HTTP request used to fetch a resource
460
+ attr_reader :time
461
+
462
+ # @param [Number] milliseconds from {#time} until the start of the server DNS
463
+ # resolution
464
+ attr_reader :dns_start_ms
465
+
466
+ # @param [Number] milliseconds from {#time} until the server DNS resolution
467
+ # completed
468
+ attr_reader :dns_end_ms
469
+
470
+ # @param [Number] milliseconds from {#time} until the start of the proxy DNS
471
+ # resolution
472
+ attr_reader :proxy_start_ms
473
+
474
+ # @param [Number] milliseconds from {#time} until the proxy DNS resolution
475
+ # completed
476
+ attr_reader :proxy_end_ms
477
+
478
+ # @param [Number] milliseconds from {#time} until the TCP connection
479
+ # started being established
480
+ attr_reader :connect_start_ms
481
+
482
+ # @param [Number] milliseconds from {#time} until the TCP connection
483
+ # was established
484
+ attr_reader :connect_end_ms
485
+
486
+ # @param [Number] milliseconds from {#time} until the start of the SSL
487
+ # handshake
488
+ attr_reader :ssl_start_ms
489
+
490
+ # @param [Number] milliseconds from {#time} until the SSL handshake completed
491
+ attr_reader :ssl_end_ms
492
+
493
+ # @param [Number] milliseconds from {#time} until the HTTP request started
494
+ # being transmitted
495
+ attr_reader :send_start_ms
496
+
497
+ # @param [Number] milliseconds from {#time} until the HTTP request finished
498
+ # transmitting
499
+ attr_reader :send_end_ms
500
+
501
+ # @param [Number] milliseconds from {#time} until all the response HTTP
502
+ # headers were received
503
+ attr_reader :receive_headers_end_ms
504
+
505
+ # @private use Event#for instead of calling this constructor directly
506
+ #
507
+ # @param [Hash<String, Number>] the raw RPC data for a ResourceTiming object
508
+ # in the Network domain
509
+ def initialize(raw_timing)
510
+ @time = raw_timing['requestTime'].to_f
511
+
512
+ @connect_start_ms = raw_timing['connectStart'].to_f
513
+ @connect_end_ms = raw_timing['connectEnd'].to_f
514
+ @dns_start_ms = raw_timing['dnsStart'].to_f
515
+ @dns_end_ms = raw_timing['dnsEnd'].to_f
516
+ @proxy_start_ms = raw_timing['proxyStart'].to_f
517
+ @proxy_end_ms = raw_timing['proxyEnd'].to_f
518
+ @receive_headers_end_ms = raw_timing['receiveHeadersEnd'].to_f
519
+ @send_start_ms = raw_timing['sendStart'].to_f
520
+ @send_end_ms = raw_timing['sendEnd'].to_f
521
+ @ssl_start_ms = raw_timing['sslStart'].to_f
522
+ @ssl_end_ms = raw_timing['sslEnd'].to_f
523
+ end
524
+ end # class WebkitRemote::Client::NetworkResourceTiming
525
+
526
+ # Wraps information about the reason behind a network request.
527
+ class NetworkRequestInitiator
528
+ # @return [Symbol] reason behind the request; documented values are :parser,
529
+ # :script and :other
530
+ attr_reader :type
531
+
532
+ # @return [String] URL of the document that references the requested resource
533
+ attr_reader :url
534
+
535
+ # @return [Number] number of the line that references the requested resource
536
+ attr_reader :line
537
+
538
+ # @return [WebkitRemote::Console
539
+ attr_reader :stack_trace
540
+
541
+ # @private Use Event#for instead of calling this constructor directly
542
+ def initialize(raw_initiator)
543
+ if raw_initiator['lineNumber']
544
+ @line = raw_initiator['lineNumber'].to_i
545
+ else
546
+ @line = nil
547
+ end
548
+ @stack_trace = WebkitRemote::Event::ConsoleMessage.parse_stack_trace(
549
+ raw_initiator['stackTrace'])
550
+ @type = (raw_initiator['type'] || 'other').to_sym
551
+ @url = raw_initiator['url']
552
+ end
553
+ end # class WebkitRemote::Client::NetworkRequestInitiator
554
+
555
+
556
+ # Wraps information about a resource served out of the browser's cache.
557
+ class NetworkCacheEntry
558
+ # @return [Symbol] the type of resource returned by this response; documented
559
+ # values are :document, :font, :image, :other, :script, :stylesheet,
560
+ # :websocket and :xhr
561
+ attr_reader :type
562
+
563
+ # @return [String] the URL of the response
564
+ attr_reader :url
565
+
566
+ # @return [WebkitRemote::Client::NetworkResponse] the cached response data
567
+ attr_reader :response
568
+
569
+ # @private Use Event#for instead of calling this constructor directly
570
+ def initialize(raw_cached_resource)
571
+ if raw_cached_resource['response']
572
+ @response = WebkitRemote::Client::NetworkResponse.new(
573
+ raw_cached_resource['response'])
574
+ else
575
+ @response = nil
576
+ end
577
+ @type = (raw_cached_resource['type'] || 'other').downcase.to_sym
578
+ @url = raw_cached_resource['url']
579
+ end
580
+ end # namespace WebkitRemote::Client::NetworkCacheEntry
581
+
582
+ end # namespace WebkitRemote::Client
583
+
584
+ end # namepspace WebkitRemote