selenium-webdriver 0.0.17 → 0.0.18

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 (77) 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.js +64 -48
  4. data/chrome/src/extension/content_script.js +253 -132
  5. data/chrome/src/extension/manifest-nonwin.json +1 -1
  6. data/chrome/src/extension/manifest-win.json +1 -1
  7. data/chrome/src/extension/utils.js +8 -8
  8. data/chrome/src/rb/lib/selenium/webdriver/chrome.rb +9 -0
  9. data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +38 -280
  10. data/chrome/src/rb/lib/selenium/webdriver/chrome/command_executor.rb +119 -117
  11. data/chrome/src/rb/lib/selenium/webdriver/chrome/launcher.rb +36 -26
  12. data/common/src/js/abstractcommandprocessor.js +9 -11
  13. data/common/src/js/command.js +159 -83
  14. data/common/src/js/core/RemoteRunner.html +2 -2
  15. data/common/src/js/core/TestRunner-splash.html +3 -3
  16. data/common/src/js/core/TestRunner.html +5 -17
  17. data/common/src/js/core/scripts/htmlutils.js +4208 -2506
  18. data/common/src/js/core/scripts/selenium-api.js +2 -2
  19. data/common/src/js/core/scripts/selenium-browserbot.js +66 -58
  20. data/common/src/js/core/scripts/selenium-version.js +1 -1
  21. data/common/src/js/localcommandprocessor.js +5 -19
  22. data/common/src/js/testcase.js +2 -0
  23. data/common/src/js/webdriver.js +63 -93
  24. data/common/src/js/webelement.js +40 -42
  25. data/common/src/rb/lib/selenium/webdriver.rb +23 -14
  26. data/common/src/rb/lib/selenium/webdriver/bridge_helper.rb +8 -35
  27. data/common/src/rb/lib/selenium/webdriver/child_process.rb +2 -0
  28. data/common/src/rb/lib/selenium/webdriver/core_ext/dir.rb +1 -0
  29. data/common/src/rb/lib/selenium/webdriver/core_ext/string.rb +5 -0
  30. data/common/src/rb/lib/selenium/webdriver/driver.rb +20 -15
  31. data/common/src/rb/lib/selenium/webdriver/driver_extensions/takes_screenshot.rb +7 -2
  32. data/common/src/rb/lib/selenium/webdriver/element.rb +11 -2
  33. data/common/src/rb/lib/selenium/webdriver/error.rb +9 -5
  34. data/common/src/rb/lib/selenium/webdriver/keys.rb +1 -2
  35. data/common/src/rb/lib/selenium/webdriver/navigation.rb +16 -0
  36. data/common/src/rb/lib/selenium/webdriver/options.rb +32 -0
  37. data/common/src/rb/lib/selenium/webdriver/platform.rb +17 -1
  38. data/firefox/prebuilt/Win32/Release/webdriver-firefox.dll +0 -0
  39. data/firefox/src/extension/components/dispatcher.js +492 -0
  40. data/firefox/src/extension/components/driver-component.js +4 -1
  41. data/firefox/src/extension/components/errorcode.js +70 -0
  42. data/firefox/src/extension/components/firefoxDriver.js +173 -154
  43. data/firefox/src/extension/components/nsCommandProcessor.js +171 -132
  44. data/firefox/src/extension/components/promptService.js +5 -5
  45. data/firefox/src/extension/components/request.js +219 -0
  46. data/firefox/src/extension/components/response.js +276 -0
  47. data/firefox/src/extension/components/session.js +281 -0
  48. data/firefox/src/extension/components/sessionstore.js +226 -0
  49. data/firefox/src/extension/components/socketListener.js +350 -100
  50. data/firefox/src/extension/components/utils.js +166 -98
  51. data/firefox/src/extension/components/webdriverserver.js +9 -5
  52. data/firefox/src/extension/components/wrappedElement.js +189 -166
  53. data/firefox/src/extension/install.rdf +1 -1
  54. data/firefox/src/rb/lib/selenium/webdriver/firefox.rb +2 -0
  55. data/firefox/src/rb/lib/selenium/webdriver/firefox/binary.rb +39 -33
  56. data/firefox/src/rb/lib/selenium/webdriver/firefox/bridge.rb +7 -421
  57. data/firefox/src/rb/lib/selenium/webdriver/firefox/extension_connection.rb +7 -64
  58. data/firefox/src/rb/lib/selenium/webdriver/firefox/launcher.rb +2 -3
  59. data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +54 -10
  60. data/firefox/src/rb/lib/selenium/webdriver/firefox/profiles_ini.rb +2 -0
  61. data/firefox/src/rb/lib/selenium/webdriver/firefox/util.rb +6 -0
  62. data/jobbie/prebuilt/Win32/Release/InternetExplorerDriver.dll +0 -0
  63. data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
  64. data/jobbie/src/rb/lib/selenium/webdriver/ie.rb +2 -0
  65. data/jobbie/src/rb/lib/selenium/webdriver/ie/bridge.rb +38 -13
  66. data/jobbie/src/rb/lib/selenium/webdriver/ie/lib.rb +9 -2
  67. data/jobbie/src/rb/lib/selenium/webdriver/ie/util.rb +5 -0
  68. data/remote/client/src/rb/lib/selenium/webdriver/remote.rb +2 -0
  69. data/remote/client/src/rb/lib/selenium/webdriver/remote/bridge.rb +42 -38
  70. data/remote/client/src/rb/lib/selenium/webdriver/remote/commands.rb +56 -47
  71. data/remote/client/src/rb/lib/selenium/webdriver/remote/default_http_client.rb +26 -26
  72. data/remote/client/src/rb/lib/selenium/webdriver/remote/patron_http_client.rb +58 -0
  73. data/remote/client/src/rb/lib/selenium/webdriver/remote/response.rb +10 -12
  74. data/remote/client/src/rb/lib/selenium/webdriver/remote/server_error.rb +2 -17
  75. metadata +44 -23
  76. data/common/src/js/context.js +0 -58
  77. data/firefox/src/extension/components/context.js +0 -37
@@ -29,7 +29,7 @@
29
29
  */
30
30
  (function() {
31
31
  var scripts = [
32
- 'context.js',
32
+ 'errorcode.js',
33
33
  'utils.js'
34
34
  ];
35
35
 
@@ -70,12 +70,15 @@ var Response = function(command, responseHandler) {
70
70
  this.statusBarLabel_ = null;
71
71
  this.responseHandler_ = responseHandler;
72
72
  this.json_ = {
73
- commandName: command ? command.commandName : 'Unknown command',
74
- isError: false,
75
- response: '',
76
- elementId: command.elementId,
77
- context: command.context
73
+ name: command ? command.name : 'Unknown command',
74
+ sessionId: command['sessionId'],
75
+ status: ErrorCode.SUCCESS,
76
+ value: ''
78
77
  };
78
+ if (this.json_['sessionId'] && this.json_['sessionId']['value']) {
79
+ this.json_['sessionId'] = this.json_['sessionId']['value'];
80
+ }
81
+ this.session = null;
79
82
  };
80
83
 
81
84
  Response.prototype = {
@@ -105,7 +108,6 @@ Response.prototype = {
105
108
  this.statusBarLabel_.style.color = 'black';
106
109
  }
107
110
 
108
- this.context = this.context.toString();
109
111
  this.responseHandler_.handleResponse(JSON.stringify(this.json_));
110
112
 
111
113
  // Neuter ourselves
@@ -113,32 +115,25 @@ Response.prototype = {
113
115
  },
114
116
 
115
117
  /**
116
- * Helper function for reporting internal errors to the client.
117
- * @param {Error} ex The internal error to report to the client.
118
+ * Sends a WebDriver error response.
119
+ * @param {WebDriverError} e The error to send.
118
120
  */
119
- reportError: function(ex) {
120
- Utils.dump(ex);
121
- this.response = 'Internal error: ' + JSON.stringify({
122
- fileName : ex.fileName,
123
- lineNumber : ex.lineNumber,
124
- message : ex.message,
125
- name : ex.name
126
- });
127
- this.isError = true;
121
+ sendError: function(e) {
122
+ // if (e instanceof WebDriverError) won't work here since
123
+ // WebDriverError is defined in the utils.js subscript which is
124
+ // loaded independently in this component and in the main driver
125
+ // component.
126
+ this.status = e.isWebDriverError ? e.code : ErrorCode.UNHANDLED_ERROR;
127
+ this.value = ErrorCode.toJSON(e);
128
128
  this.send();
129
129
  },
130
130
 
131
- setField: function(name, value) { this.json_[name] = value; },
132
- set commandName(name) { this.json_.commandName = name; },
133
- get commandName() { return this.json_.commandName; },
134
- set elementId(id) { this.json_.elementId = id; },
135
- get elementId() { return this.json_.elementId; },
136
- set isError(error) { this.json_.isError = error; },
137
- get isError() { return this.json_.isError; },
138
- set response(res) { this.json_.response = res; },
139
- get response() { return this.json_.response; },
140
- set context(c) { this.json_.context = c; },
141
- get context() { return this.json_.context; }
131
+ set name(name) { this.json_.name = name; },
132
+ get name() { return this.json_.name; },
133
+ set status(newStatus) { this.json_.status = newStatus; },
134
+ get status() { return this.json_.status; },
135
+ set value(val) { this.json_.value = val; },
136
+ get value() { return this.json_.value; },
142
137
  };
143
138
 
144
139
 
@@ -161,13 +156,22 @@ var DelayedCommand = function(driver, command, response, opt_sleepDelay) {
161
156
  this.onBlank_ = false;
162
157
  this.sleepDelay_ = opt_sleepDelay || DelayedCommand.DEFAULT_SLEEP_DELAY;
163
158
 
164
- var activeWindow =
165
- response.context.frame || response.context.fxbrowser.contentWindow;
166
- this.loadGroup_ = activeWindow.
167
- QueryInterface(Components.interfaces.nsIInterfaceRequestor).
168
- getInterface(Components.interfaces.nsIWebNavigation).
169
- QueryInterface(Components.interfaces.nsIInterfaceRequestor).
170
- getInterface(Components.interfaces.nsILoadGroup);
159
+ var activeWindow = response.session.getWindow();
160
+ try {
161
+ var webNav = activeWindow.
162
+ QueryInterface(Components.interfaces.nsIInterfaceRequestor).
163
+ getInterface(Components.interfaces.nsIWebNavigation);
164
+ this.loadGroup_ = webNav.
165
+ QueryInterface(Components.interfaces.nsIInterfaceRequestor).
166
+ getInterface(Components.interfaces.nsILoadGroup);
167
+ } catch (ex) {
168
+ // Well this sucks. This can happen if the DOM gets trashed or if the window
169
+ // is unexpectedly closed. We need to report this error to the user so they
170
+ // can let us (webdriver-eng) know that the FirefoxDriver is busted.
171
+ response.sendError(ex);
172
+ // Re-throw the error so the command will be aborted.
173
+ throw ex;
174
+ }
171
175
  };
172
176
 
173
177
 
@@ -229,6 +233,7 @@ DelayedCommand.prototype.shouldDelayExecutionForPendingRequest_ = function() {
229
233
  }
230
234
  } catch(e) {
231
235
  Utils.dumpn('Problem while checking if we should delay execution: ' + e);
236
+ return true;
232
237
  }
233
238
 
234
239
  return false;
@@ -254,30 +259,20 @@ DelayedCommand.prototype.executeInternal_ = function() {
254
259
  return this.execute(this.sleepDelay_);
255
260
  } else {
256
261
  try {
257
- this.response_.commandName = this.command_.commandName;
262
+ this.response_.name = this.command_.name;
258
263
  // TODO(simon): This is rampantly ugly, but allows an alert to kill the command
259
264
  // TODO(simon): This is never cleared, but _should_ be okay, because send wipes itself
260
265
  this.driver_.response_ = this.response_;
261
266
 
262
- this.driver_[this.command_.commandName](
267
+ this.driver_[this.command_.name](
263
268
  this.response_, this.command_.parameters);
264
269
  } catch (e) {
265
- // if (e instanceof StaleElementError) won't work here since
266
- // StaleElementError is defined in the utils.js subscript which is
267
- // loaded independently in this component and in the main driver
268
- // component.
269
- // TODO(jmleyba): Continue cleaning up the extension and replacing the
270
- // subscripts with proper components.
271
- if (e.isStaleElementError) {
272
- this.response_.isError = true;
273
- this.response_.response = 'element is obsolete';
274
- this.response_.send();
275
- } else {
270
+ if (!e.isWebDriverError) {
276
271
  Utils.dumpn(
277
- 'Exception caught by driver: ' + this.command_.commandName +
272
+ 'Exception caught by driver: ' + this.command_.name +
278
273
  '(' + this.command_.parameters + ')\n' + e);
279
- this.response_.reportError(e);
280
274
  }
275
+ this.response_.sendError(e);
281
276
  }
282
277
  }
283
278
  };
@@ -336,97 +331,84 @@ nsCommandProcessor.prototype.execute = function(jsonCommandString,
336
331
  command = JSON.parse(jsonCommandString);
337
332
  } catch (ex) {
338
333
  response = JSON.stringify({
339
- 'isError': true,
334
+ 'status': ErrorCode.UNHANDLED_ERROR,
340
335
  'value': 'Error parsing command: "' + jsonCommandString + '"'
341
336
  });
342
337
  responseHandler.handleResponse(response);
343
338
  return;
344
339
  }
345
340
 
346
- command.context = Context.fromString(command.context);
347
341
  response = new Response(command, responseHandler);
348
342
 
349
- // These are used to locate a new driver, and so not having one is a fine
350
- // thing to do
351
- if (command.commandName == 'newSession' ||
352
- command.commandName == 'switchToWindow' ||
353
- command.commandName == 'getWindowHandles' ||
354
- command.commandName == 'quit') {
355
- return this[command.commandName](response, command.parameters);
356
- }
357
-
358
- var win, fxbrowser, driver;
359
- var allWindows = this.wm.getEnumerator(null);
360
- while (allWindows.hasMoreElements()) {
361
- win = allWindows.getNext();
362
- if (win["fxdriver"] && win.fxdriver.id == response.context.windowId) {
363
- fxbrowser = win.getBrowser();
364
- driver = win.fxdriver;
365
- break;
343
+ // These commands do not require a session.
344
+ if (command.name == 'newSession' ||
345
+ command.name == 'quit' ||
346
+ command.name == 'getWindowHandles') {
347
+ try {
348
+ this[command.name](response, command.parameters);
349
+ } catch (ex) {
350
+ response.sendError(ex);
366
351
  }
352
+ return;
367
353
  }
368
354
 
369
- if (!fxbrowser) {
370
- response.isError = true;
371
- response.response = 'Unable to find browser with id ' +
372
- response.context.windowId;
373
- return response.send();
355
+ var sessionId = command.sessionId;
356
+ if (!sessionId) {
357
+ response.sendError(new WebDriverError(ErrorCode.UNHANDLED_ERROR,
358
+ 'No session ID specified'));
359
+ return;
374
360
  }
375
361
 
376
- if (!driver) {
377
- response.isError = true;
378
- response.response = 'Unable to find the driver for browser with id ' +
379
- response.context.windowId;
380
- return response.send();
362
+ sessionId = sessionId.value;
363
+ try {
364
+ response.session = Components.
365
+ classes['@googlecode.com/webdriver/wdsessionstoreservice;1'].
366
+ getService(Components.interfaces.nsISupports).
367
+ wrappedJSObject.
368
+ getSession(sessionId).
369
+ wrappedJSObject;
370
+ } catch (ex) {
371
+ response.sendError(new WebDriverError(ErrorCode.UNHANDLED_ERROR,
372
+ 'Session not found: ' + sessionId));
373
+ return;
381
374
  }
382
375
 
383
- if (typeof driver[command.commandName] != 'function') {
384
- response.isError = true;
385
- response.response = 'Unrecognised command: ' + command.commandName;
386
- return response.send();
376
+ if (command.name == 'deleteSession' ||
377
+ command.name == 'getSessionCapabilities' ||
378
+ command.name == 'switchToWindow') {
379
+ return this[command.name](response, command.parameters);
387
380
  }
388
381
 
389
- response.context.fxbrowser = fxbrowser;
390
-
391
- // Determine whether or not we need to care about frames.
392
- var frames = fxbrowser.contentWindow.frames;
393
- if ("?" == response.context.frameId) {
394
- if (frames && frames.length) {
395
- if ("FRAME" == frames[0].frameElement.tagName) {
396
- response.context.frameId = 0;
397
- } else {
398
- response.context.frameId = undefined;
399
- }
400
- } else {
401
- response.context.frameId = undefined;
402
- }
382
+ var sessionWindow = response.session.getChromeWindow();
383
+ var driver = sessionWindow.fxdriver; // TODO(jmleyba): We only need to store an ID on the window!
384
+ if (!driver) {
385
+ response.sendError(new WebDriverError(ErrorCode.UNHANDLED_ERROR,
386
+ 'Session has no driver: ' + response.session.getId()));
387
+ return;
403
388
  }
404
389
 
405
- if (response.context.frameId !== undefined) {
406
- response.context.frame = Utils.findFrame(
407
- fxbrowser, response.context.frameId);
390
+ if (typeof driver[command.name] != 'function') {
391
+ response.sendError(new WebDriverError(ErrorCode.UNKNOWN_COMMAND,
392
+ 'Unrecognised command: ' + command.name));
393
+ return;
408
394
  }
409
395
 
410
- response.startCommand(win);
396
+ response.startCommand(sessionWindow);
411
397
  new DelayedCommand(driver, command, response).execute(0);
412
398
  };
413
399
 
414
400
 
415
-
416
401
  /**
417
- * Changes the context of the caller to the window specified by the first
418
- * element of the {@code windowId} array.
402
+ * Changes the context of the caller to the specified window.
419
403
  * @param {Response} response The response object to send the command response
420
404
  * in.
421
- * @param {Array.<*>} windowId The parameters sent with the original command.
422
- * The first element in the array must be the ID of the window to switch to.
423
- * Note all other command parameters are ignored.
405
+ * @param {{name: string}} parameters The command parameters.
424
406
  * @param {number} opt_searchAttempt Which attempt this is at finding the
425
407
  * window to switch to.
426
408
  */
427
- nsCommandProcessor.prototype.switchToWindow = function(response, windowId,
409
+ nsCommandProcessor.prototype.switchToWindow = function(response, parameters,
428
410
  opt_searchAttempt) {
429
- var lookFor = windowId[0];
411
+ var lookFor = parameters.name;
430
412
  var matches = function(win, lookFor) {
431
413
  return !win.closed &&
432
414
  (win.content && win.content.name == lookFor) ||
@@ -442,12 +424,13 @@ nsCommandProcessor.prototype.switchToWindow = function(response, windowId,
442
424
 
443
425
  win.focus();
444
426
  if (win.top.fxdriver) {
445
- response.response = new Context(win.fxdriver.id).toString();
427
+ response.session.setChromeWindow(win.top);
428
+ response.value = response.session.getId();
429
+ response.send();
446
430
  } else {
447
- response.isError = true;
448
- response.response = 'No driver found attached to top window!';
431
+ response.sendError(new WebDriverError(ErrorCode.UNHANDLED_ERROR,
432
+ 'No driver found attached to top window!'));
449
433
  }
450
- response.send();
451
434
  // Found the desired window, stop the search.
452
435
  return true;
453
436
  }
@@ -463,14 +446,13 @@ nsCommandProcessor.prototype.switchToWindow = function(response, windowId,
463
446
  // one is still loading vs. a brute force "try again"
464
447
  var searchAttempt = opt_searchAttempt || 0;
465
448
  if (searchAttempt > 3) {
466
- response.isError = true;
467
- response.response = 'Unable to locate window "' + lookFor + '"';
468
- response.send();
449
+ response.sendError(new WebDriverError(ErrorCode.NO_SUCH_WINDOW,
450
+ 'Unable to locate window "' + lookFor + '"'));
469
451
  } else {
470
452
  var self = this;
471
453
  this.wm.getMostRecentWindow('navigator:browser').
472
454
  setTimeout(function() {
473
- self.switchToWindow(response, windowId, (searchAttempt + 1));
455
+ self.switchToWindow(response, parameters, (searchAttempt + 1));
474
456
  }, 500);
475
457
  }
476
458
  }
@@ -491,7 +473,7 @@ nsCommandProcessor.prototype.getWindowHandles = function(response) {
491
473
  res.push(win.content.name);
492
474
  }
493
475
  });
494
- response.response = res;
476
+ response.value = res;
495
477
  response.send();
496
478
  };
497
479
 
@@ -521,33 +503,90 @@ nsCommandProcessor.prototype.searchWindows_ = function(search_criteria,
521
503
 
522
504
  /**
523
505
  * Locates the most recently used FirefoxDriver window.
524
- * @param {Response} response The response object to send the command response
525
- * in.
506
+ * @param {Response} response The object to send the command response in.
526
507
  */
527
508
  nsCommandProcessor.prototype.newSession = function(response) {
528
509
  var win = this.wm.getMostRecentWindow("navigator:browser");
529
510
  var driver = win.fxdriver;
530
511
  if (!driver) {
531
- response.isError = true;
532
- response.response = 'No drivers associated with the window';
512
+ response.sendError(new WebDriverError(ErrorCode.UNHANDLED_ERROR,
513
+ 'No drivers associated with the window'));
533
514
  } else {
534
- response.context = new Context(driver.id);
535
- response.response = driver.id;
515
+ var sessionStore = Components.
516
+ classes['@googlecode.com/webdriver/wdsessionstoreservice;1'].
517
+ getService(Components.interfaces.nsISupports);
518
+
519
+ var session = sessionStore.wrappedJSObject.createSession();
520
+ session = session.wrappedJSObject; // XPConnect...
521
+ session.setChromeWindow(win);
522
+
523
+ response.session = session;
524
+ response.value = session.getId();
536
525
  }
537
526
  response.send();
538
527
  };
539
528
 
540
529
 
530
+ /**
531
+ * Describes a session.
532
+ * @param {Response} response The object to send the command response in.
533
+ */
534
+ nsCommandProcessor.prototype.getSessionCapabilities = function(response) {
535
+ var appInfo = Components.classes['@mozilla.org/xre/app-info;1'].
536
+ getService(Components.interfaces.nsIXULAppInfo);
537
+ var xulRuntime = Components.classes['@mozilla.org/xre/app-info;1'].
538
+ getService(Components.interfaces.nsIXULRuntime);
539
+ response.value = {
540
+ 'browserName': 'firefox',
541
+ 'version': appInfo.version,
542
+ 'javascriptEnabled': true,
543
+ 'platform': xulRuntime.OS // same as Platform.valueOf("name");
544
+ };
545
+ response.send();
546
+ };
547
+
548
+
549
+ /**
550
+ * Deletes the session associated with the current request.
551
+ * @param {Response} response The object to send the command response in.
552
+ */
553
+ nsCommandProcessor.prototype.deleteSession = function(response) {
554
+ var sessionStore = Components.
555
+ classes['@googlecode.com/webdriver/wdsessionstoreservice;1'].
556
+ getService(Components.interfaces.nsISupports);
557
+ sessionStore.wrappedJSObject.deleteSession(response.session.getId());
558
+ response.send();
559
+ };
560
+
561
+
541
562
  /**
542
563
  * Forcefully shuts down the Firefox application.
564
+ * @param {Response} response The object to send the command response in.
543
565
  */
544
- nsCommandProcessor.prototype.quit = function() {
545
- // Create a switch file so the native events library will
546
- // let all events through in case of a close.
547
- createSwitchFile("close:<ALL>");
548
- Components.classes['@mozilla.org/toolkit/app-startup;1'].
549
- getService(Components.interfaces.nsIAppStartup).
550
- quit(Components.interfaces.nsIAppStartup.eForceQuit);
566
+ nsCommandProcessor.prototype.quit = function(response) {
567
+ // Go ahead and respond to the command request to acknowledge that we are
568
+ // shutting down. We do this because once we force a quit, there's no way
569
+ // to respond. Clients will just have to trust that this shutdown didn't
570
+ // fail. Or they could monitor the PID. Either way, not much we can do about
571
+ // it in here.
572
+ response.send();
573
+
574
+ // Use an nsITimer to give the response time to go out.
575
+ var event = {
576
+ notify: function(timer) {
577
+ // Create a switch file so the native events library will
578
+ // let all events through in case of a close.
579
+ createSwitchFile("close:<ALL>");
580
+ Components.classes['@mozilla.org/toolkit/app-startup;1'].
581
+ getService(Components.interfaces.nsIAppStartup).
582
+ quit(Components.interfaces.nsIAppStartup.eForceQuit);
583
+ }
584
+ };
585
+
586
+ var timer = Components.classes['@mozilla.org/timer;1'].
587
+ createInstance(Components.interfaces.nsITimer);
588
+ timer.initWithCallback(event, 500, // milliseconds
589
+ Components.interfaces.nsITimer.TYPE_ONE_SHOT);
551
590
  };
552
591
 
553
592
 
@@ -100,11 +100,11 @@ DrivenPromptService.prototype.alert = function(aParent, aDialogTitle, aText) {
100
100
 
101
101
  if (driver && driver.response_) {
102
102
  var res = driver.response_;
103
- // TODO(simon): We can't rely on the normal JSON library here because it might not be available
104
- // Come up with a cleaner way of doing this.
105
- var json = "{ title: \"" + aDialogTitle + "\", text: \"" + aText + "\", __webdriverType: 'alert' }";
106
-
107
- res.response = json;
103
+ res.value = {
104
+ title: aDialogTitle,
105
+ text: aText,
106
+ __webdriverType: 'alert'
107
+ };
108
108
  res.send();
109
109
  } else {
110
110
  // TODO(simon): we should prevent the next command from blocking.