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
@@ -1,6 +1,8 @@
1
1
  module Selenium
2
2
  module WebDriver
3
3
  module Chrome
4
+
5
+ # @private
4
6
  class Launcher
5
7
  include FileUtils
6
8
 
@@ -21,6 +23,13 @@ module Selenium
21
23
  launcher
22
24
  end
23
25
 
26
+ def self.binary_path
27
+ @binary_path ||= (
28
+ path = possible_paths.find { |f| File.exist?(f) }
29
+ path || raise(Error::WebDriverError, "Could not find Chrome binary. Make sure Chrome is installed (OS: #{Platform.os})")
30
+ )
31
+ end
32
+
24
33
  def launch(server_url)
25
34
  create_extension
26
35
  create_profile
@@ -55,8 +64,7 @@ module Selenium
55
64
  end
56
65
 
57
66
  def launch_chrome(server_url)
58
- check_binary_exists
59
- @process = ChildProcess.new Platform.wrap_in_quotes_if_necessary(binary_path),
67
+ @process = ChildProcess.new Platform.wrap_in_quotes_if_necessary(self.class.binary_path),
60
68
  "--load-extension=#{Platform.wrap_in_quotes_if_necessary tmp_extension_dir}",
61
69
  "--user-data-dir=#{Platform.wrap_in_quotes_if_necessary tmp_profile_dir}",
62
70
  "--activate-on-launch",
@@ -67,12 +75,6 @@ module Selenium
67
75
  @process.start
68
76
  end
69
77
 
70
- def check_binary_exists
71
- unless File.file?(binary_path)
72
- raise Error::WebDriverError, "Could not find Chrome binary. Make sure Chrome is installed (OS: #{Platform.os})"
73
- end
74
- end
75
-
76
78
  def ext_path
77
79
  @ext_path ||= "#{WebDriver.root}/chrome/src/extension"
78
80
  end
@@ -96,36 +98,44 @@ module Selenium
96
98
  end
97
99
 
98
100
  class WindowsLauncher < Launcher
99
- def linked_lib_path
100
- # TODO: x64
101
- @linked_lib_path ||= "#{WebDriver.root}/chrome/prebuilt/Win32/Release/npchromedriver.dll"
101
+ def self.possible_paths
102
+ [
103
+ registry_path,
104
+ "#{ENV['USERPROFILE']}\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chrome.exe",
105
+ "#{ENV['USERPROFILE']}\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
106
+ "#{Platform.home}\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chrome.exe",
107
+ "#{Platform.home}\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
108
+ ].compact
102
109
  end
103
110
 
104
- def binary_path
105
- @binary_path ||= begin
106
- possible_paths = [
107
- "#{ENV['USERPROFILE']}\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chrome.exe",
108
- "#{ENV['USERPROFILE']}\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
109
- "#{Platform.home}\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chrome.exe",
110
- "#{Platform.home}\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
111
- ]
112
-
113
- possible_paths.find { |f| File.exist?(f) } || possible_paths.first
114
- end
111
+ def self.registry_path
112
+ require "win32/registry"
113
+
114
+ reg = Win32::Registry::HKEY_LOCAL_MACHINE.open("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe")
115
+ reg[""]
116
+ rescue LoadError
117
+ # older JRuby and IronRuby does not have win32/registry
118
+ nil
119
+ rescue Win32::Registry::Error
120
+ nil
115
121
  end
116
122
 
123
+ def linked_lib_path
124
+ # TODO: x64
125
+ @linked_lib_path ||= "#{WebDriver.root}/chrome/prebuilt/Win32/Release/npchromedriver.dll"
126
+ end
117
127
  end
118
128
 
119
129
  class UnixLauncher < Launcher
120
- def binary_path
121
- @binary_path ||= "/usr/bin/google-chrome"
130
+ def self.possible_paths
131
+ [Platform.find_binary("google-chrome"), "/usr/bin/google-chrome"].compact
122
132
  end
123
133
 
124
134
  end
125
135
 
126
136
  class MacOSXLauncher < UnixLauncher
127
- def binary_path
128
- @binary_path ||= "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
137
+ def self.possible_paths
138
+ ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", "#{Platform.home}/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"]
129
139
  end
130
140
  end
131
141
 
@@ -28,6 +28,7 @@ goog.require('goog.object');
28
28
  goog.require('webdriver.CommandName');
29
29
  goog.require('webdriver.Future');
30
30
  goog.require('webdriver.Response');
31
+ goog.require('webdriver.Response.Code');
31
32
  goog.require('webdriver.WebElement');
32
33
  goog.require('webdriver.timing');
33
34
 
@@ -63,14 +64,14 @@ webdriver.AbstractCommandProcessor.resolveFutureParams_ = function(
63
64
  } else if (goog.isObject(obj)) {
64
65
  goog.object.forEach(obj, function(value, key) {
65
66
  if (value instanceof webdriver.Future) {
66
- obj[key] = value.getValue();
67
+ obj[key] = getValue(value);
67
68
  }
68
69
  });
69
70
  }
70
71
  return obj;
71
72
  }
72
73
 
73
- command.parameters = goog.array.map(command.parameters, function(param) {
74
+ command.parameters = goog.object.map(command.parameters, function(param) {
74
75
  if (goog.isArray(param)) {
75
76
  return goog.array.map(param, getValue);
76
77
  } else {
@@ -90,25 +91,22 @@ webdriver.AbstractCommandProcessor.prototype.execute = function(command) {
90
91
  var parameters = command.getParameters();
91
92
  switch (command.getName()) {
92
93
  case webdriver.CommandName.SLEEP:
93
- var ms = parameters[0];
94
+ var ms = parameters['ms'];
94
95
  webdriver.timing.setTimeout(function() {
95
96
  command.setResponse(new webdriver.Response(
96
- false, driver.getContext(), ms));
97
+ webdriver.Response.Code.SUCCESS, ms));
97
98
  }, ms);
98
99
  break;
99
100
 
100
101
  case webdriver.CommandName.WAIT:
101
102
  case webdriver.CommandName.FUNCTION:
102
103
  try {
103
- var fn = parameters[0];
104
- var selfObj = parameters[1];
105
- var args = parameters[2];
106
- var result = fn.apply(selfObj, args);
104
+ var result = parameters['function'].apply(null, parameters['args']);
107
105
  command.setResponse(new webdriver.Response(
108
- false, driver.getContext(), result));
106
+ webdriver.Response.Code.SUCCESS, result));
109
107
  } catch (ex) {
110
108
  command.setResponse(new webdriver.Response(
111
- true, driver.getContext(), null, ex));
109
+ webdriver.Response.Code.UNHANDLED_ERROR, ex));
112
110
  }
113
111
  break;
114
112
 
@@ -117,7 +115,7 @@ webdriver.AbstractCommandProcessor.prototype.execute = function(command) {
117
115
  this.dispatchDriverCommand(command);
118
116
  } catch (ex) {
119
117
  command.setResponse(new webdriver.Response(
120
- true, driver.getContext(), null, ex));
118
+ webdriver.Response.Code.UNHANDLED_ERROR, ex));
121
119
  }
122
120
  break;
123
121
  }
@@ -23,6 +23,7 @@ limitations under the License.
23
23
  goog.provide('webdriver.Command');
24
24
  goog.provide('webdriver.CommandName');
25
25
  goog.provide('webdriver.Response');
26
+ goog.provide('webdriver.Response.Code');
26
27
 
27
28
  goog.require('goog.array');
28
29
  goog.require('goog.events.EventTarget');
@@ -35,13 +36,10 @@ goog.require('webdriver.Future');
35
36
  * {@code webdriver.AbstractCommandProcessor}.
36
37
  * @param {webdriver.WebDriver} driver The driver that this is a command for.
37
38
  * @param {webdriver.CommandName} name The name of this command.
38
- * @param {webdriver.WebElement} opt_element The element to perform this
39
- * command on. If not defined, the command will be performed relative to
40
- * the document root.
41
39
  * @constructor
42
40
  * @extends {goog.events.EventTarget}
43
41
  */
44
- webdriver.Command = function(driver, name, opt_element) {
42
+ webdriver.Command = function(driver, name) {
45
43
  goog.events.EventTarget.call(this);
46
44
 
47
45
  /**
@@ -66,18 +64,11 @@ webdriver.Command = function(driver, name, opt_element) {
66
64
  */
67
65
  this.name = name;
68
66
 
69
- /**
70
- * The element to perform this command on. If not defined, the command will be
71
- * performed relative to the document root.
72
- * @type {webdriver.WebElement}
73
- */
74
- this.element = opt_element;
75
-
76
67
  /**
77
68
  * The parameters to this command.
78
- * @type {Array.<*>}
69
+ * @type {Object}
79
70
  */
80
- this.parameters = [];
71
+ this.parameters = {};
81
72
 
82
73
  /**
83
74
  * The response to this command.
@@ -103,7 +94,6 @@ webdriver.Command.prototype.disposeInternal = function() {
103
94
  delete this.driver_;
104
95
  delete this.futureResult_;
105
96
  delete this.name;
106
- delete this.element;
107
97
  delete this.parameters;
108
98
  delete this.response;
109
99
  };
@@ -149,18 +139,19 @@ webdriver.Command.prototype.isFinished = function() {
149
139
 
150
140
 
151
141
  /**
152
- * Set the parameters to send with this command.
153
- * @param {*} var_args The arguments to send to this command.
142
+ * Sets a parameter to send with this command.
143
+ * @param {string} name The parameter name.
144
+ * @param {*} var_args The parameter value.
154
145
  * @return {webdriver.Command} A self reference.
155
146
  */
156
- webdriver.Command.prototype.setParameters = function(var_args) {
157
- this.parameters = goog.array.slice(arguments, 0);
147
+ webdriver.Command.prototype.setParameter = function(name, value) {
148
+ this.parameters[name] = value;
158
149
  return this;
159
150
  };
160
151
 
161
152
 
162
153
  /**
163
- * @return {Array.<*>} The parameters to send with this command.
154
+ * @return {Object} The parameters to send with this command.
164
155
  */
165
156
  webdriver.Command.prototype.getParameters = function() {
166
157
  return this.parameters;
@@ -186,9 +177,8 @@ webdriver.Command.prototype.setResponse = function(response) {
186
177
  return;
187
178
  }
188
179
  this.response = response;
189
- this.driver_.setContext(this.response.context);
190
- if (!this.response.isFailure) {
191
- this.futureResult_.setValue(this.response.value);
180
+ if (this.response.getStatus() == webdriver.Response.Code.SUCCESS) {
181
+ this.futureResult_.setValue(this.response.getValue());
192
182
  } else {
193
183
  this.dispatchEvent(webdriver.Command.ERROR_EVENT);
194
184
  }
@@ -210,67 +200,114 @@ webdriver.CommandName = {
210
200
  // Commands dispatched to the browser driver. -------------------------------
211
201
  NEW_SESSION: 'newSession',
212
202
  DELETE_SESSION: 'deleteSession',
213
- QUIT: 'quit',
214
- GET_CURRENT_WINDOW_HANDLE: 'getCurrentWindowHandle',
215
- GET_WINDOW_HANDLES: 'getWindowHandles',
216
- GET_CURRENT_URL: 'getCurrentUrl',
203
+
217
204
  CLOSE: 'close',
218
- SWITCH_TO_WINDOW: 'switchToWindow',
219
- SWITCH_TO_FRAME: 'switchToFrame',
220
- SWITCH_TO_DEFAULT_CONTENT: 'switchToDefaultContent',
205
+ QUIT: 'quit',
206
+
221
207
  GET: 'get',
222
- FORWARD: 'goForward',
223
- BACK: 'goBack',
208
+ GO_BACK: 'goBack',
209
+ GO_FORWARD: 'goForward',
224
210
  REFRESH: 'refresh',
225
- GET_TITLE: 'title',
226
- GET_PAGE_SOURCE: 'getPageSource',
227
- EXECUTE_SCRIPT: 'executeScript',
228
- GET_MOUSE_SPEED: 'getMouseSpeed',
229
- SET_MOUSE_SPEED: 'setMouseSpeed',
211
+
212
+ ADD_COOKIE: 'addCookie',
213
+ GET_COOKIE: 'getCookie',
214
+ GET_ALL_COOKIES: 'getCookies',
215
+ DELETE_COOKIE: 'deleteCookie',
216
+ DELETE_ALL_COOKIES: 'deleteAllCookies',
217
+
230
218
  FIND_ELEMENT: 'findElement',
231
219
  FIND_ELEMENTS: 'findElements',
232
220
  FIND_CHILD_ELEMENT: 'findChildElement',
233
221
  FIND_CHILD_ELEMENTS: 'findChildElements',
222
+
223
+ CLEAR_ELEMENT: 'clearElement',
224
+ CLICK_ELEMENT: 'clickElement',
225
+ HOVER_OVER_ELEMNET: 'hoverOverElement',
226
+ SEND_KEYS_TO_ELEMENT: 'sendKeysToElement',
227
+ SUBMIT_ELEMENT: 'submitElement',
228
+ TOGGLE_ELEMENT: 'toggleElement',
229
+
230
+ GET_CURRENT_WINDOW_HANDLE: 'getCurrentWindowHandle',
231
+ GET_WINDOW_HANDLES: 'getWindowHandles',
232
+
233
+ SWITCH_TO_WINDOW: 'switchToWindow',
234
+ SWITCH_TO_FRAME: 'switchToFrame',
235
+ SWITCH_TO_DEFAULT_CONTENT: 'switchToDefaultContent',
234
236
  GET_ACTIVE_ELEMENT: 'getActiveElement',
235
- SET_VISIBLE: 'setVisible',
236
- GET_VISIBLE: 'getVisible',
237
- CLICK: 'click',
238
- CLEAR: 'clear',
239
- SUBMIT: 'submit',
240
- GET_TEXT: 'getText',
241
- SEND_KEYS: 'sendKeys',
242
- GET_VALUE: 'getValue',
243
- GET_TAG_NAME: 'getTagName',
244
- IS_SELECTED: 'isSelected',
245
- SET_SELECTED: 'setSelected',
246
- TOGGLE: 'toggle',
247
- IS_ENABLED: 'isEnabled',
248
- IS_DISPLAYED: 'isDisplayed',
249
- GET_LOCATION: 'getLocation',
250
- GET_SIZE: 'getSize',
251
- GET_ATTRIBUTE: 'getAttribute',
237
+
238
+ GET_CURRENT_URL: 'getCurrentUrl',
239
+ GET_PAGE_SOURCE: 'getPageSource',
240
+ GET_TITLE: 'getTitle',
241
+
242
+ EXECUTE_SCRIPT: 'executeScript',
243
+
244
+ GET_SPEED: 'getSpeed',
245
+ SET_SPEED: 'setSpeed',
246
+
247
+ SET_BROWSE_VISIBLE: 'setBrowserVisible',
248
+ IS_BROWSER_VISIBLE: 'isBrowserVisible',
249
+
250
+ GET_ELEMENT_TEXT: 'getElementText',
251
+ GET_ELEMENT_VALUE: 'getElementValue',
252
+ GET_ELEMENT_TAG_NAME: 'getElementTagName',
253
+ SET_ELEMENT_SELECTED: 'setElementSelected',
252
254
  DRAG_ELEMENT: 'dragElement',
253
- GET_VALUE_OF_CSS_PROPERTY: 'getValueOfCssProperty'
255
+ IS_ELEMENT_SELECTED: 'isElementSelected',
256
+ IS_ELEMENT_ENABLED: 'isElementEnabled',
257
+ IS_ELEMENT_DISPLAYED: 'isElementDisplayed',
258
+ GET_ELEMENT_LOCATION: 'getElementLocation',
259
+ GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW:
260
+ 'getElementLocationOnceScrolledIntoView',
261
+ GET_ELEMENT_SIZE: 'getElementSize',
262
+ GET_ELEMENT_ATTRIBUTE: 'getElementAttribute',
263
+ GET_ELEMENT_VALUE_OF_CSS_PROPERTY: 'getElementValueOfCssProperty',
264
+ ELEMENT_EQUALS: 'elementEquals',
265
+
266
+ SCREENSHOT: 'screenshot',
267
+ DIMISS_ALERT: 'dimissAlert'
254
268
  };
255
269
 
256
270
 
257
271
  /**
258
272
  * Encapsulates a response to a {@code webdriver.Command}.
259
- * @param {boolean} isFailure Whether the command resulted in an error. If
260
- * {@code true}, then {@code value} contains the error message.
261
- * @param {webdriver.Context} context The (potentially new) context resulting
262
- * from the command.
273
+ * @param {webdriver.Response.Code} status The status code for this response.
263
274
  * @param {*} value The value of the response, the meaning of which depends
264
275
  * on the command.
265
- * @parma {Error} opt_error An error that caused this command to fail
266
- * prematurely.
267
276
  * @constructor
268
277
  */
269
- webdriver.Response = function(isFailure, context, value, opt_error) {
270
- this.isFailure = isFailure;
271
- this.context = context;
272
- this.value = value;
273
- this.errors = goog.array.slice(arguments, 3);
278
+ webdriver.Response = function(status, value) {
279
+
280
+ /**
281
+ * The status code for this response.
282
+ * @type {webdriver.Response.Code}
283
+ * @private
284
+ */
285
+ this.status_ = status;
286
+
287
+ /**
288
+ * The value for this response.
289
+ * @type {*}
290
+ * @private
291
+ */
292
+ this.value_ = value;
293
+ };
294
+
295
+
296
+ /** @return {webdriver.Response.Code} The status code for this response. */
297
+ webdriver.Response.prototype.getStatus = function() {
298
+ return this.status_;
299
+ };
300
+
301
+
302
+ /** @return {*} The value of this response. */
303
+ webdriver.Response.prototype.getValue = function() {
304
+ return this.value_;
305
+ };
306
+
307
+
308
+ /** @return {!boolean} Whether this is a response to a successful command. */
309
+ webdriver.Response.prototype.isSuccess = function() {
310
+ return this.status_ == webdriver.Response.Code.SUCCESS;
274
311
  };
275
312
 
276
313
 
@@ -279,26 +316,65 @@ webdriver.Response = function(isFailure, context, value, opt_error) {
279
316
  * failure response.
280
317
  */
281
318
  webdriver.Response.prototype.getErrorMessage = function() {
282
- if (!this.isFailure) {
319
+ if (this.status_ == webdriver.Response.Code.SUCCESS) {
283
320
  return null;
284
321
  }
285
- var message = [];
286
- if (goog.isString(this.value)) {
287
- message.push(this.value);
288
- } else if (null != this.value && goog.isDef(this.value.message)) {
289
- message.push(this.value.message);
290
- if (goog.isDef(this.value.fileName)) {
291
- message.push(this.value.fileName + '@' + this.value.lineNumber);
292
- }
322
+
323
+ if (!this.value_) {
324
+ return 'Unknown error'; // Really should never happen
293
325
  }
294
- goog.array.extend(message, goog.array.map(this.errors, function(error) {
295
- if (goog.isString(error)) {
296
- return error;
326
+
327
+ if (goog.isDef(this.value_['message'])) {
328
+ var message = [this.value_['message']];
329
+
330
+ var stackTrace = this.value_['stackTrace'];
331
+ if (goog.isArray(stackTrace)) {
332
+ goog.array.extend(message, goog.array.map(this.value_['stackTrace'],
333
+ function(frame) {
334
+ var buffer = [];
335
+
336
+ // className is provided by remote java servers
337
+ var className = frame['className'];
338
+ if (goog.isDef(className)) {
339
+ buffer.push(className + '.');
340
+ }
341
+ buffer.push(frame['methodName'] || '<anonymous function>');
342
+ buffer.push('() at ');
343
+ // fileName will be undefined if the method call was to an XPCOM
344
+ // interface.
345
+ buffer.push(frame['fileName'] || '<unknown file>');
346
+ buffer.push(':');
347
+ buffer.push(frame['lineNumber']);
348
+ return buffer.join('');
349
+ }));
350
+ } else if (goog.isDef(stackTrace)) {
351
+ message.push(stackTrace);
352
+ } else if (goog.isDef(this.value_.stack)) {
353
+ message.push(goog.testing.stacktrace.canonicalize(this.value_.stack));
297
354
  }
298
- var errMsg = error.message || error.description || error.toString();
299
- var stack = error.stack ?
300
- goog.testing.stacktrace.canonicalize(error.stack) : error['stackTrace'];
301
- return errMsg + '\n' + stack;
302
- }));
303
- return message.join('\n');
355
+ return message.join('\n');
356
+ } else {
357
+ return this.value_.toString();
358
+ }
359
+ };
360
+
361
+
362
+ /**
363
+ * Error codes used by the wire protocol.
364
+ * @enum {number}
365
+ */
366
+ webdriver.Response.Code = {
367
+ /* keep in sync with codes in org.openqa.selenium.remote.ErrorCodes */
368
+ SUCCESS: 0,
369
+ COOKIE_ERROR: 2,
370
+ NO_SUCH_WINDOW: 3,
371
+ NO_SUCH_ELEMENT: 7,
372
+ NO_SUCH_FRAME: 8,
373
+ UNKNOWN_COMMAND: 9,
374
+ STALE_ELEMENT_REFERENCE: 10,
375
+ ELEMENT_NOT_VISIBLE: 11,
376
+ INVALID_ELEMENT_STATE: 12,
377
+ UNHANDLED_ERROR: 13,
378
+ UNEXPECTED_JAVASCRIPT_ERROR: 17,
379
+ XPATH_LOOKUP_ERROR: 19
304
380
  };