webkit_remote 0.2.0 → 0.3.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.
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