selenium-webdriver 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. data/chrome/prebuilt/Win32/Release/npchromedriver.dll +0 -0
  2. data/chrome/prebuilt/x64/Release/npchromedriver.dll +0 -0
  3. data/chrome/src/extension/background.html +9 -0
  4. data/chrome/src/extension/background.js +933 -0
  5. data/chrome/src/extension/content_script.js +1286 -0
  6. data/chrome/src/extension/manifest-nonwin.json +15 -0
  7. data/chrome/src/extension/manifest-win.json +16 -0
  8. data/chrome/src/extension/toolstrip.html +28 -0
  9. data/chrome/src/extension/utils.js +196 -0
  10. data/chrome/src/rb/lib/selenium/webdriver/chrome.rb +8 -0
  11. data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +324 -0
  12. data/chrome/src/rb/lib/selenium/webdriver/chrome/command_executor.rb +70 -0
  13. data/chrome/src/rb/lib/selenium/webdriver/chrome/launcher.rb +119 -0
  14. data/common/src/js/abstractcommandprocessor.js +161 -0
  15. data/common/src/js/asserts.js +296 -0
  16. data/common/src/js/by.js +147 -0
  17. data/common/src/js/command.js +274 -0
  18. data/common/src/js/context.js +58 -0
  19. data/common/src/js/extension/README +2 -0
  20. data/common/src/js/extension/dommessenger.js +152 -0
  21. data/common/src/js/factory.js +55 -0
  22. data/common/src/js/future.js +118 -0
  23. data/common/src/js/key.js +117 -0
  24. data/common/src/js/localcommandprocessor.js +181 -0
  25. data/common/src/js/logging.js +249 -0
  26. data/common/src/js/testrunner.js +605 -0
  27. data/common/src/js/timing.js +89 -0
  28. data/common/src/js/wait.js +199 -0
  29. data/common/src/js/webdriver.js +853 -0
  30. data/common/src/js/webelement.js +683 -0
  31. data/common/src/rb/lib/selenium-webdriver.rb +1 -0
  32. data/common/src/rb/lib/selenium/webdriver.rb +52 -0
  33. data/common/src/rb/lib/selenium/webdriver/bridge_helper.rb +88 -0
  34. data/common/src/rb/lib/selenium/webdriver/child_process.rb +85 -0
  35. data/common/src/rb/lib/selenium/webdriver/core_ext/dir.rb +41 -0
  36. data/common/src/rb/lib/selenium/webdriver/driver.rb +128 -0
  37. data/common/src/rb/lib/selenium/webdriver/element.rb +126 -0
  38. data/common/src/rb/lib/selenium/webdriver/error.rb +68 -0
  39. data/common/src/rb/lib/selenium/webdriver/find.rb +69 -0
  40. data/common/src/rb/lib/selenium/webdriver/navigation.rb +23 -0
  41. data/common/src/rb/lib/selenium/webdriver/options.rb +50 -0
  42. data/common/src/rb/lib/selenium/webdriver/platform.rb +82 -0
  43. data/common/src/rb/lib/selenium/webdriver/target_locator.rb +23 -0
  44. data/firefox/prebuilt/nsICommandProcessor.xpt +0 -0
  45. data/firefox/prebuilt/nsINativeEvents.xpt +0 -0
  46. data/firefox/prebuilt/nsIResponseHandler.xpt +0 -0
  47. data/firefox/src/extension/chrome.manifest +3 -0
  48. data/firefox/src/extension/components/context.js +37 -0
  49. data/firefox/src/extension/components/driver-component.js +127 -0
  50. data/firefox/src/extension/components/firefoxDriver.js +706 -0
  51. data/firefox/src/extension/components/json2.js +273 -0
  52. data/firefox/src/extension/components/keytest.html +554 -0
  53. data/firefox/src/extension/components/nsCommandProcessor.js +586 -0
  54. data/firefox/src/extension/components/screenshooter.js +70 -0
  55. data/firefox/src/extension/components/socketListener.js +185 -0
  56. data/firefox/src/extension/components/utils.js +1200 -0
  57. data/firefox/src/extension/components/webLoadingListener.js +57 -0
  58. data/firefox/src/extension/components/webdriverserver.js +101 -0
  59. data/firefox/src/extension/components/wrappedElement.js +609 -0
  60. data/firefox/src/extension/content/fxdriver.xul +30 -0
  61. data/firefox/src/extension/content/server.js +95 -0
  62. data/firefox/src/extension/idl/nsICommandProcessor.idl +38 -0
  63. data/firefox/src/extension/idl/nsIResponseHandler.idl +34 -0
  64. data/firefox/src/extension/install.rdf +29 -0
  65. data/firefox/src/rb/lib/selenium/webdriver/firefox.rb +21 -0
  66. data/firefox/src/rb/lib/selenium/webdriver/firefox/binary.rb +86 -0
  67. data/firefox/src/rb/lib/selenium/webdriver/firefox/bridge.rb +426 -0
  68. data/firefox/src/rb/lib/selenium/webdriver/firefox/extension_connection.rb +82 -0
  69. data/firefox/src/rb/lib/selenium/webdriver/firefox/launcher.rb +132 -0
  70. data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +174 -0
  71. data/firefox/src/rb/lib/selenium/webdriver/firefox/profiles_ini.rb +60 -0
  72. data/firefox/src/rb/lib/selenium/webdriver/firefox/util.rb +23 -0
  73. data/jobbie/prebuilt/Win32/Release/InternetExplorerDriver.dll +0 -0
  74. data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
  75. data/jobbie/src/rb/lib/selenium/webdriver/ie.rb +14 -0
  76. data/jobbie/src/rb/lib/selenium/webdriver/ie/bridge.rb +552 -0
  77. data/jobbie/src/rb/lib/selenium/webdriver/ie/lib.rb +94 -0
  78. data/jobbie/src/rb/lib/selenium/webdriver/ie/util.rb +147 -0
  79. data/remote/client/src/rb/lib/selenium/webdriver/remote.rb +16 -0
  80. data/remote/client/src/rb/lib/selenium/webdriver/remote/bridge.rb +374 -0
  81. data/remote/client/src/rb/lib/selenium/webdriver/remote/capabilities.rb +105 -0
  82. data/remote/client/src/rb/lib/selenium/webdriver/remote/commands.rb +53 -0
  83. data/remote/client/src/rb/lib/selenium/webdriver/remote/default_http_client.rb +71 -0
  84. data/remote/client/src/rb/lib/selenium/webdriver/remote/response.rb +43 -0
  85. data/remote/client/src/rb/lib/selenium/webdriver/remote/server_error.rb +32 -0
  86. metadata +182 -0
@@ -0,0 +1,586 @@
1
+ /*
2
+ Copyright 2007-2009 WebDriver committers
3
+ Copyright 2007-2009 Google Inc.
4
+ Portions copyright 2007 ThoughtWorks, Inc
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ */
18
+
19
+ /**
20
+ * @fileOverview Contains a Javascript implementation for
21
+ * nsICommandProcessor.idl. The implemented XPCOM component is exposed to
22
+ * the content page as a global property so that it can be used from
23
+ * unpriviledged code.
24
+ */
25
+
26
+
27
+ /**
28
+ * When this component is loaded, load the necessary subscripts.
29
+ */
30
+ (function() {
31
+ var scripts = [
32
+ 'context.js',
33
+ 'utils.js'
34
+ ];
35
+
36
+ // Firefox 3.5+ has native JSON support; prefer that over our script from
37
+ // www.json.org, which may be slower.
38
+ var appInfo = Components.classes['@mozilla.org/xre/app-info;1'].
39
+ getService(Components.interfaces.nsIXULAppInfo);
40
+ var versionChecker = Components.classes['@mozilla.org/xpcom/version-comparator;1'].
41
+ getService(Components.interfaces.nsIVersionComparator);
42
+ if (versionChecker.compare(appInfo.version, '3.5') < 0) {
43
+ scripts.push('json2.js');
44
+ }
45
+
46
+ var fileProtocolHandler = Components.
47
+ classes['@mozilla.org/network/protocol;1?name=file'].
48
+ createInstance(Components.interfaces.nsIFileProtocolHandler);
49
+ var loader = Components.classes['@mozilla.org/moz/jssubscript-loader;1'].
50
+ createInstance(Components.interfaces.mozIJSSubScriptLoader);
51
+
52
+ for (var script in scripts) {
53
+ var file = __LOCATION__.parent.clone();
54
+ file.append(scripts[script]);
55
+
56
+ var fileName = fileProtocolHandler.getURLSpecFromFile(file);
57
+ loader.loadSubScript(fileName);
58
+ }
59
+ })();
60
+
61
+
62
+ /**
63
+ * Encapsulates the result of a command to the {@code nsCommandProcessor}.
64
+ * @param {Object} command JSON object describing the command to execute.
65
+ * @param {nsIResponseHandler} responseHandler The handler to send the response
66
+ * to.
67
+ * @constructor
68
+ */
69
+ var Response = function(command, responseHandler) {
70
+ this.statusBarLabel_ = null;
71
+ this.responseHandler_ = responseHandler;
72
+ this.json_ = {
73
+ commandName: command ? command.commandName : 'Unknown command',
74
+ isError: false,
75
+ response: '',
76
+ elementId: command.elementId,
77
+ context: command.context
78
+ };
79
+ };
80
+
81
+ Response.prototype = {
82
+
83
+ /**
84
+ * Updates the extension status label to indicate we are about to execute a
85
+ * command.
86
+ * @param {window} win The content window that the command will be executed on.
87
+ */
88
+ startCommand: function(win) {
89
+ this.statusBarLabel_ = win.document.getElementById("fxdriver-label");
90
+ if (this.statusBarLabel_) {
91
+ this.statusBarLabel_.style.color = "red";
92
+ }
93
+ },
94
+
95
+ /**
96
+ * Sends the encapsulated response to the registered callback.
97
+ */
98
+ send: function() {
99
+ // Indicate that we are no longer executing a command.
100
+ if (this.statusBarLabel_) {
101
+ this.statusBarLabel_.style.color = 'black';
102
+ }
103
+ this.context = this.context.toString();
104
+ this.responseHandler_.handleResponse(JSON.stringify(this.json_));
105
+ },
106
+
107
+ /**
108
+ * Helper function for reporting internal errors to the client.
109
+ * @param {Error} ex The internal error to report to the client.
110
+ */
111
+ reportError: function(ex) {
112
+ Utils.dump(ex);
113
+ this.response = 'Internal error: ' + JSON.stringify({
114
+ fileName : ex.fileName,
115
+ lineNumber : ex.lineNumber,
116
+ message : ex.message,
117
+ name : ex.name
118
+ });
119
+ this.isError = true;
120
+ this.send();
121
+ },
122
+
123
+ setField: function(name, value) { this.json_[name] = value; },
124
+ set commandName(name) { this.json_.commandName = name; },
125
+ get commandName() { return this.json_.commandName; },
126
+ set elementId(id) { this.json_.elementId = id; },
127
+ get elementId() { return this.json_.elementId; },
128
+ set isError(error) { this.json_.isError = error; },
129
+ get isError() { return this.json_.isError; },
130
+ set response(res) { this.json_.response = res; },
131
+ get response() { return this.json_.response; },
132
+ set context(c) { this.json_.context = c; },
133
+ get context() { return this.json_.context; }
134
+ };
135
+
136
+
137
+ /**
138
+ * Handles executing a command from the {@code CommandProcessor} once the window
139
+ * has fully loaded.
140
+ * @param {FirefoxDriver} driver The FirefoxDriver instance to execute the
141
+ * command with.
142
+ * @param {Object} command JSON object describing the command to execute.
143
+ * @param {Response} response The response object to send the command response
144
+ * in.
145
+ * @param {Number} opt_sleepDelay The amount of time to wait before attempting
146
+ * the command again if the window is not ready.
147
+ * @constructor
148
+ */
149
+ var DelayedCommand = function(driver, command, response, opt_sleepDelay) {
150
+ this.driver_ = driver;
151
+ this.command_ = command;
152
+ this.response_ = response;
153
+ this.onBlank_ = false;
154
+ this.sleepDelay_ = opt_sleepDelay || DelayedCommand.DEFAULT_SLEEP_DELAY;
155
+
156
+ var activeWindow =
157
+ response.context.frame || response.context.fxbrowser.contentWindow;
158
+ this.loadGroup_ = activeWindow.
159
+ QueryInterface(Components.interfaces.nsIInterfaceRequestor).
160
+ getInterface(Components.interfaces.nsIWebNavigation).
161
+ QueryInterface(Components.interfaces.nsIInterfaceRequestor).
162
+ getInterface(Components.interfaces.nsILoadGroup);
163
+ };
164
+
165
+
166
+ /**
167
+ * Default amount of time, in milliseconds, to wait before (re)attempting a
168
+ * {@code DelayedCommand}.
169
+ * @type {Number}
170
+ */
171
+ DelayedCommand.DEFAULT_SLEEP_DELAY = 100;
172
+
173
+
174
+ /**
175
+ * Executes the command after the specified delay.
176
+ * @param {Number} ms The delay in milliseconds.
177
+ */
178
+ DelayedCommand.prototype.execute = function(ms) {
179
+ var self = this;
180
+ this.driver_.window.setTimeout(function() {
181
+ self.executeInternal_();
182
+ }, ms);
183
+ };
184
+
185
+
186
+ /**
187
+ * Attempts to execute the command. If the window is not ready for the command
188
+ * to execute, will set a timeout to try again.
189
+ * @private
190
+ */
191
+ DelayedCommand.prototype.executeInternal_ = function() {
192
+ if (this.loadGroup_.isPending()) {
193
+ return this.execute(this.sleepDelay_);
194
+ } else {
195
+ // Ugh! New windows open on "about:blank" before going to their
196
+ // destination URL. This check attempts to tell the difference between a
197
+ // newly opened window and someone actually wanting to do something on
198
+ // about:blank.
199
+ if (this.driver_.window.location == 'about:blank' && !this.onBlank_) {
200
+ this.onBlank_ = true;
201
+ return this.execute(this.sleepDelay_);
202
+ } else {
203
+ try {
204
+ this.response_.commandName = this.command_.commandName;
205
+ this.driver_[this.command_.commandName](
206
+ this.response_, this.command_.parameters);
207
+ } catch (e) {
208
+ // if (e instanceof StaleElementError) won't work here since
209
+ // StaleElementError is defined in the utils.js subscript which is
210
+ // loaded independently in this component and in the main driver
211
+ // component.
212
+ // TODO(jmleyba): Continue cleaning up the extension and replacing the
213
+ // subscripts with proper components.
214
+ if (e.isStaleElementError) {
215
+ this.response_.isError = true;
216
+ this.response_.response = 'element is obsolete';
217
+ this.response_.send();
218
+ } else {
219
+ Utils.dumpn(
220
+ 'Exception caught by driver: ' + this.command_.commandName +
221
+ '(' + this.command_.parameters + ')\n' + e);
222
+ this.response_.reportError(e);
223
+ }
224
+ }
225
+ }
226
+ }
227
+ };
228
+
229
+
230
+ /**
231
+ * Class for dispatching WebDriver requests. Handles window locating commands
232
+ * (e.g. switching, searching, etc.), all other commands are executed with the
233
+ * {@code FirefoxDriver} through reflection. Note this is a singleton class.
234
+ * @constructor
235
+ */
236
+ var nsCommandProcessor = function() {
237
+ this.wrappedJSObject = this;
238
+ this.wm = Components.classes['@mozilla.org/appshell/window-mediator;1'].
239
+ getService(Components.interfaces.nsIWindowMediator);
240
+ };
241
+
242
+ /**
243
+ * Flags for the {@code nsIClassInfo} interface.
244
+ * @type {Number}
245
+ */
246
+ nsCommandProcessor.prototype.flags =
247
+ Components.interfaces.nsIClassInfo.DOM_OBJECT;
248
+
249
+ /**
250
+ * Implementaiton language detail for the {@code nsIClassInfo} interface.
251
+ * @type {String}
252
+ */
253
+ nsCommandProcessor.prototype.implementationLanguage =
254
+ Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT;
255
+
256
+
257
+ /**
258
+ * Logs a message to the Console Service and then throws an error.
259
+ * @param {String} message The message to log.
260
+ * @throws {Components.results.NS_ERROR_FAILURE}
261
+ */
262
+ nsCommandProcessor.logError = function(message) {
263
+ // TODO(jleyba): This should log an error and not a generic message.
264
+ Utils.dumpn(message);
265
+ throw Components.results.NS_ERROR_FAILURE;
266
+ };
267
+
268
+
269
+ /**
270
+ * Processes a command request for the {@code FirefoxDriver}.
271
+ * @param {string} jsonCommandString The command to execute, specified in a
272
+ * JSON string.
273
+ * @param {nsIResponseHandler} responseHandler The callback to send the response
274
+ * to.
275
+ */
276
+ nsCommandProcessor.prototype.execute = function(jsonCommandString,
277
+ responseHandler) {
278
+ var command, response;
279
+ try {
280
+ command = JSON.parse(jsonCommandString);
281
+ } catch (ex) {
282
+ response = JSON.stringify({
283
+ 'isError': true,
284
+ 'value': 'Error parsing command: "' + jsonCommandString + '"'
285
+ });
286
+ responseHandler.handleResponse(response);
287
+ return;
288
+ }
289
+
290
+ command.context = Context.fromString(command.context);
291
+ response = new Response(command, responseHandler);
292
+
293
+ // These are used to locate a new driver, and so not having one is a fine
294
+ // thing to do
295
+ if (command.commandName == 'newSession' ||
296
+ command.commandName == 'switchToWindow' ||
297
+ command.commandName == 'getWindowHandles' ||
298
+ command.commandName == 'quit') {
299
+ return this[command.commandName](response, command.parameters);
300
+ }
301
+
302
+ var win, fxbrowser, driver;
303
+ var allWindows = this.wm.getEnumerator(null);
304
+ while (allWindows.hasMoreElements()) {
305
+ win = allWindows.getNext();
306
+ if (win["fxdriver"] && win.fxdriver.id == response.context.windowId) {
307
+ fxbrowser = win.getBrowser();
308
+ driver = win.fxdriver;
309
+ break;
310
+ }
311
+ }
312
+
313
+ if (!fxbrowser) {
314
+ response.isError = true;
315
+ response.response = 'Unable to find browser with id ' +
316
+ response.context.windowId;
317
+ return response.send();
318
+ }
319
+
320
+ if (!driver) {
321
+ response.isError = true;
322
+ response.response = 'Unable to find the driver for browser with id ' +
323
+ response.context.windowId;
324
+ return response.send();
325
+ }
326
+
327
+ if (typeof driver[command.commandName] != 'function') {
328
+ response.isError = true;
329
+ response.response = 'Unrecognised command: ' + command.commandName;
330
+ return response.send();
331
+ }
332
+
333
+ response.context.fxbrowser = fxbrowser;
334
+
335
+ // Determine whether or not we need to care about frames.
336
+ var frames = fxbrowser.contentWindow.frames;
337
+ if ("?" == response.context.frameId) {
338
+ if (frames && frames.length) {
339
+ if ("FRAME" == frames[0].frameElement.tagName) {
340
+ response.context.frameId = 0;
341
+ } else {
342
+ response.context.frameId = undefined;
343
+ }
344
+ } else {
345
+ response.context.frameId = undefined;
346
+ }
347
+ }
348
+
349
+ if (response.context.frameId !== undefined) {
350
+ response.context.frame = Utils.findFrame(
351
+ fxbrowser, response.context.frameId);
352
+ }
353
+
354
+ response.startCommand(win);
355
+ new DelayedCommand(driver, command, response).execute(0);
356
+ };
357
+
358
+
359
+
360
+ /**
361
+ * Changes the context of the caller to the window specified by the first
362
+ * element of the {@code windowId} array.
363
+ * @param {Response} response The response object to send the command response
364
+ * in.
365
+ * @param {Array.<*>} windowId The parameters sent with the original command.
366
+ * The first element in the array must be the ID of the window to switch to.
367
+ * Note all other command parameters are ignored.
368
+ * @param {boolean} opt_isSecondSearch Whether this is the second attempt to
369
+ * find the window.
370
+ */
371
+ nsCommandProcessor.prototype.switchToWindow = function(response, windowId,
372
+ opt_isSecondSearch) {
373
+ var lookFor = windowId[0];
374
+ var matches = function(win, lookFor) {
375
+ return !win.closed &&
376
+ (win.content && win.content.name == lookFor) ||
377
+ (win.top && win.top.fxdriver && win.top.fxdriver.id == lookFor);
378
+ };
379
+
380
+ var windowFound = this.searchWindows_('navigator:browser', function(win) {
381
+ if (matches(win, lookFor)) {
382
+ // Create a switch indicator file so the native events library
383
+ // will know a window switch is in progress and will indeed
384
+ // switch focus.
385
+ createSwitchFile("switch:" + win.fxdriver.id);
386
+
387
+ win.focus();
388
+ if (win.top.fxdriver) {
389
+ response.response = new Context(win.fxdriver.id).toString();
390
+ } else {
391
+ response.isError = true;
392
+ response.response = 'No driver found attached to top window!';
393
+ }
394
+ response.send();
395
+ // Found the desired window, stop the search.
396
+ return true;
397
+ }
398
+ });
399
+
400
+ // It is possible that the window won't be found on the first attempt. This is
401
+ // typically true for anchors with a target attribute set. This search could
402
+ // execute before the target window has finished loaded, meaning the content
403
+ // window won't have a name or FirefoxDriver instance yet (see matches above).
404
+ // If we don't find the window, set a timeout to try one more time.
405
+ if (!windowFound) {
406
+ if (opt_isSecondSearch) {
407
+ response.isError = true;
408
+ response.response = 'Unable to locate window "' + lookFor + '"';
409
+ response.send();
410
+ } else {
411
+ var self = this;
412
+ this.wm.getMostRecentWindow('navigator:browser').
413
+ setTimeout(function() {
414
+ self.switchToWindow(response, windowId, true);
415
+ }, 500);
416
+ }
417
+ }
418
+ };
419
+
420
+
421
+ /**
422
+ * Retrieves a list of all known FirefoxDriver windows.
423
+ * @param {Response} response The response object to send the command response
424
+ * in.
425
+ */
426
+ nsCommandProcessor.prototype.getWindowHandles = function(response) {
427
+ var res = [];
428
+ this.searchWindows_('navigator:browser', function(win) {
429
+ if (win.top && win.top.fxdriver) {
430
+ res.push(win.top.fxdriver.id);
431
+ } else if (win.content) {
432
+ res.push(win.content.name);
433
+ } else {
434
+ res.push('');
435
+ }
436
+ });
437
+ response.response = res.join(',');
438
+ response.send();
439
+ };
440
+
441
+
442
+ /**
443
+ * Searches over a selection of windows, calling a visitor function on each
444
+ * window found in the search.
445
+ * @param {?string} search_criteria The category of windows to search or
446
+ * {@code null} to search all windows.
447
+ * @param {function} visitor_fn A visitor function to call with each window. The
448
+ * function may return true to indicate that the window search should abort
449
+ * early.
450
+ * @return {boolean} Whether the visitor function short circuited the search.
451
+ */
452
+ nsCommandProcessor.prototype.searchWindows_ = function(search_criteria,
453
+ visitor_fn) {
454
+ var allWindows = this.wm.getEnumerator(search_criteria);
455
+ while (allWindows.hasMoreElements()) {
456
+ var win = allWindows.getNext();
457
+ if (visitor_fn(win)) {
458
+ return true;
459
+ }
460
+ }
461
+ return false;
462
+ };
463
+
464
+
465
+ /**
466
+ * Locates the most recently used FirefoxDriver window.
467
+ * @param {Response} response The response object to send the command response
468
+ * in.
469
+ */
470
+ nsCommandProcessor.prototype.newSession = function(response) {
471
+ var win = this.wm.getMostRecentWindow("navigator:browser");
472
+ var driver = win.fxdriver;
473
+ if (!driver) {
474
+ response.isError = true;
475
+ response.response = 'No drivers associated with the window';
476
+ } else {
477
+ response.context = new Context(driver.id);
478
+ response.response = driver.id;
479
+ }
480
+ response.send();
481
+ };
482
+
483
+
484
+ /**
485
+ * Forcefully shuts down the Firefox application.
486
+ */
487
+ nsCommandProcessor.prototype.quit = function() {
488
+ // Create a switch file so the native events library will
489
+ // let all events through in case of a close.
490
+ createSwitchFile("close:<ALL>");
491
+ Components.classes['@mozilla.org/toolkit/app-startup;1'].
492
+ getService(Components.interfaces.nsIAppStartup).
493
+ quit(Components.interfaces.nsIAppStartup.eForceQuit);
494
+ };
495
+
496
+
497
+ nsCommandProcessor.prototype.getInterfaces = function(count) {
498
+ var ifaces = [
499
+ Components.interfaces.nsICommandProcessor,
500
+ Components.interfaces.nsISupports
501
+ ];
502
+ count.value = ifaces.length;
503
+ return ifaces;
504
+ };
505
+
506
+
507
+ nsCommandProcessor.prototype.QueryInterface = function (aIID) {
508
+ if (!aIID.equals(Components.interfaces.nsICommandProcessor) &&
509
+ !aIID.equals(Components.interfaces.nsISupports)) {
510
+ throw Components.results.NS_ERROR_NO_INTERFACE;
511
+ }
512
+ return this;
513
+ };
514
+
515
+
516
+ nsCommandProcessor.CLASS_ID =
517
+ Components.ID('{692e5117-a4a2-4b00-99f7-0685285b4db5}');
518
+ nsCommandProcessor.CLASS_NAME = 'Firefox WebDriver CommandProcessor';
519
+ nsCommandProcessor.CONTRACT_ID =
520
+ '@googlecode.com/webdriver/command-processor;1';
521
+
522
+
523
+ /**
524
+ * Factory object for obtaining a reference to the singleton instance of
525
+ * {@code CommandProcessor}.
526
+ */
527
+ nsCommandProcessor.Factory = {
528
+ instance_ : null,
529
+
530
+ createInstance: function(aOuter, aIID) {
531
+ if (aOuter != null) {
532
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
533
+ }
534
+ if (!this.instance_) {
535
+ this.instance_ = new nsCommandProcessor();
536
+ }
537
+ return this.instance_.QueryInterface(aIID);
538
+ }
539
+ };
540
+
541
+
542
+ /**
543
+ * Module definition for registering this XPCOM component.
544
+ */
545
+ nsCommandProcessor.Module = {
546
+ firstTime_: true,
547
+
548
+ registerSelf: function(aCompMgr, aFileSpec, aLocation, aType) {
549
+ if (this.firstTime_) {
550
+ this.firstTime_ = false;
551
+ throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
552
+ }
553
+ aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar).
554
+ registerFactoryLocation(
555
+ nsCommandProcessor.CLASS_ID,
556
+ nsCommandProcessor.CLASS_NAME,
557
+ nsCommandProcessor.CONTRACT_ID,
558
+ aFileSpec, aLocation, aType);
559
+ },
560
+
561
+ unregisterSelf: function(aCompMgr, aLocation) {
562
+ aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar).
563
+ unregisterFactoryLocation(nsCommandProcessor.CLASS_ID, aLocation);
564
+ },
565
+
566
+ getClassObject: function(aCompMgr, aCID, aIID) {
567
+ if (!aIID.equals(Components.interfaces.nsIFactory)) {
568
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
569
+ } else if (!aCID.equals(nsCommandProcessor.CLASS_ID)) {
570
+ throw Components.results.NS_ERROR_NO_INTERFACE;
571
+ }
572
+ return nsCommandProcessor.Factory;
573
+ },
574
+
575
+ canUnload: function() {
576
+ return true;
577
+ }
578
+ };
579
+
580
+
581
+ /**
582
+ * Module initialization.
583
+ */
584
+ function NSGetModule() {
585
+ return nsCommandProcessor.Module;
586
+ }