selenium-webdriver 0.0.17 → 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -16,10 +16,55 @@
16
16
  limitations under the License.
17
17
  */
18
18
 
19
- function StaleElementError() {
20
- this.isStaleElementError = true;
19
+
20
+ /**
21
+ * A WebDriver error.
22
+ * @param {!number} code The error code.
23
+ * @param {!string|Error} messageOrError The error message, or another Error to
24
+ * propagate.
25
+ * @constructor
26
+ */
27
+ function WebDriverError(code, messageOrError) {
28
+
29
+ var message;
30
+ var stack;
31
+ if (messageOrError instanceof Error) {
32
+ message = messageOrError.message;
33
+ stack = messageOrError.stack;
34
+ } else {
35
+ message = messageOrError.toString();
36
+ stack = Error(message).stack.split('\n');
37
+ stack.shift();
38
+ stack = stack.join('\n');
39
+ }
40
+
41
+ /**
42
+ * This error's status code.
43
+ * @type {!number}
44
+ */
45
+ this.code = code;
46
+
47
+ /**
48
+ * This error's message.
49
+ * @type {string}
50
+ */
51
+ this.message = message;
52
+
53
+ /**
54
+ * Captures a stack trace for when this error was thrown.
55
+ * @type {string}
56
+ */
57
+ this.stack = stack;
58
+
59
+ /**
60
+ * Used to identify this class since instanceof will not work across
61
+ * component boundaries.
62
+ * @type {!boolean}
63
+ */
64
+ this.isWebDriverError = true;
21
65
  }
22
66
 
67
+
23
68
  function createSwitchFile(file_content) {
24
69
  var filename = "/tmp/switch_window_started";
25
70
  var cc = Components.classes;
@@ -94,39 +139,25 @@ Utils.getServer = function() {
94
139
  };
95
140
 
96
141
 
97
- Utils.getBrowser = function(context) {
98
- return context.fxbrowser;
99
- };
100
-
101
-
102
- Utils.getDocument = function(context) {
103
- if (context.frame) {
104
- return context.frame.document;
105
- }
106
- return context.fxbrowser.contentDocument;
107
- };
108
-
109
-
110
- Utils.getActiveElement = function(context) {
111
- var doc = Utils.getDocument(context);
142
+ Utils.getActiveElement = function(doc) {
112
143
 
113
144
  var element;
114
145
  if (doc["activeElement"]) {
115
146
  element = doc.activeElement;
116
147
  } else {
117
- var commandDispatcher = Utils.getBrowser(context).ownerDocument.
148
+ var topWindow = doc.defaultView.top;
149
+ var commandDispatcher = topWindow.getBrowser().ownerDocument.
118
150
  commandDispatcher;
119
151
 
120
- doc = Utils.getDocument(context);
121
152
  element = commandDispatcher.focusedElement;
122
153
 
123
- if (element && Utils.getDocument(context) != element.ownerDocument)
154
+ if (element && doc != element.ownerDocument)
124
155
  element = null;
125
156
  }
126
157
 
127
158
  // Default to the body
128
159
  if (!element) {
129
- element = Utils.getDocument(context).body;
160
+ element = doc.body;
130
161
  }
131
162
 
132
163
  return element;
@@ -321,8 +352,7 @@ Utils.getText = function(element) {
321
352
  };
322
353
 
323
354
 
324
- Utils.addToKnownElements = function(element, context) {
325
- var doc = Utils.getDocument(context);
355
+ Utils.addToKnownElements = function(element, doc) {
326
356
  if (!doc.fxdriver_elements) {
327
357
  doc.fxdriver_elements = {};
328
358
  }
@@ -340,8 +370,7 @@ Utils.addToKnownElements = function(element, context) {
340
370
  };
341
371
 
342
372
 
343
- Utils.getElementAt = function(index, context) {
344
- var doc = Utils.getDocument(context);
373
+ Utils.getElementAt = function(index, doc) {
345
374
  var e = doc.fxdriver_elements ? doc.fxdriver_elements[index] : undefined;
346
375
  if (e) {
347
376
  // Is this a stale reference?
@@ -353,29 +382,21 @@ Utils.getElementAt = function(index, context) {
353
382
  if (parent !== e.ownerDocument.documentElement) {
354
383
  // Remove from the cache
355
384
  delete doc.fxdriver_elements[index];
356
-
357
- throw new StaleElementError();
385
+ throw new WebDriverError(ErrorCode.STALE_ELEMENT_REFERENCE,
386
+ 'Element is no longer attached to the DOM');
358
387
  }
359
388
  } else {
360
- throw new StaleElementError();
389
+ throw new WebDriverError(ErrorCode.STALE_ELEMENT_REFERENCE,
390
+ 'Element not found in the cache');
361
391
  }
362
392
 
363
393
  return e;
364
394
  };
365
395
 
366
396
 
367
- Utils.currentDocument = function(context) {
368
- if (context) {
369
- return Utils.getDocument(context);
370
- } else {
371
- return document;
372
- }
373
- };
374
-
375
-
376
- Utils.platform = function(context) {
397
+ Utils.platform = function(doc) {
377
398
  if (!this.userAgentPlatformLowercase) {
378
- var currentWindow = Utils.currentDocument(context).defaultView;
399
+ var currentWindow = doc.defaultView;
379
400
  this.userAgentPlatformLowercase =
380
401
  currentWindow.navigator.platform.toLowerCase();
381
402
  }
@@ -417,7 +438,7 @@ Utils.getNodeForNativeEvents = function(element) {
417
438
  };
418
439
 
419
440
 
420
- Utils.type = function(context, element, text, opt_useNativeEvents) {
441
+ Utils.type = function(doc, element, text, opt_useNativeEvents) {
421
442
 
422
443
  // For consistency between native and synthesized events, convert common
423
444
  // escape sequences to their Key enum aliases.
@@ -430,7 +451,7 @@ Utils.type = function(context, element, text, opt_useNativeEvents) {
430
451
  var inputtype = element.getAttribute("type");
431
452
  if (inputtype && inputtype.toLowerCase() == "file") {
432
453
  element.value = text;
433
- Utils.fireHtmlEvent(context, element, "change");
454
+ Utils.fireHtmlEvent(element, "change");
434
455
  return;
435
456
  }
436
457
  }
@@ -545,25 +566,25 @@ Utils.type = function(context, element, text, opt_useNativeEvents) {
545
566
  if (c == '\uE000') {
546
567
  if (controlKey) {
547
568
  var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CONTROL;
548
- Utils.keyEvent(context, element, "keyup", kCode, 0,
569
+ Utils.keyEvent(doc, element, "keyup", kCode, 0,
549
570
  controlKey = false, shiftKey, altKey, metaKey);
550
571
  }
551
572
 
552
573
  if (shiftKey) {
553
574
  var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
554
- Utils.keyEvent(context, element, "keyup", kCode, 0,
575
+ Utils.keyEvent(doc, element, "keyup", kCode, 0,
555
576
  controlKey, shiftKey = false, altKey, metaKey);
556
577
  }
557
578
 
558
579
  if (altKey) {
559
580
  var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_ALT;
560
- Utils.keyEvent(context, element, "keyup", kCode, 0,
581
+ Utils.keyEvent(doc, element, "keyup", kCode, 0,
561
582
  controlKey, shiftKey, altKey = false, metaKey);
562
583
  }
563
584
 
564
585
  if (metaKey) {
565
586
  var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_META;
566
- Utils.keyEvent(context, element, "keyup", kCode, 0,
587
+ Utils.keyEvent(doc, element, "keyup", kCode, 0,
567
588
  controlKey, shiftKey, altKey, metaKey = false);
568
589
  }
569
590
 
@@ -743,7 +764,7 @@ Utils.type = function(context, element, text, opt_useNativeEvents) {
743
764
  // generate modifier key event if needed, and continue
744
765
 
745
766
  if (modifierEvent) {
746
- Utils.keyEvent(context, element, modifierEvent, keyCode, 0,
767
+ Utils.keyEvent(doc, element, modifierEvent, keyCode, 0,
747
768
  controlKey, shiftKey, altKey, metaKey);
748
769
  continue;
749
770
  }
@@ -757,7 +778,7 @@ Utils.type = function(context, element, text, opt_useNativeEvents) {
757
778
 
758
779
  if (needsShift && !shiftKey) {
759
780
  var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
760
- Utils.keyEvent(context, element, "keydown", kCode, 0,
781
+ Utils.keyEvent(doc, element, "keydown", kCode, 0,
761
782
  controlKey, true, altKey, metaKey);
762
783
  Utils.shiftCount += 1;
763
784
  }
@@ -788,20 +809,20 @@ Utils.type = function(context, element, text, opt_useNativeEvents) {
788
809
  }
789
810
 
790
811
  var accepted =
791
- Utils.keyEvent(context, element, "keydown", keyCode, 0,
812
+ Utils.keyEvent(doc, element, "keydown", keyCode, 0,
792
813
  controlKey, needsShift || shiftKey, altKey, metaKey);
793
814
 
794
- Utils.keyEvent(context, element, "keypress", pressCode, charCode,
815
+ Utils.keyEvent(doc, element, "keypress", pressCode, charCode,
795
816
  controlKey, needsShift || shiftKey, altKey, metaKey, !accepted);
796
817
 
797
- Utils.keyEvent(context, element, "keyup", keyCode, 0,
818
+ Utils.keyEvent(doc, element, "keyup", keyCode, 0,
798
819
  controlKey, needsShift || shiftKey, altKey, metaKey);
799
820
 
800
821
  // shift up if needed
801
822
 
802
823
  if (needsShift && !shiftKey) {
803
824
  var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
804
- Utils.keyEvent(context, element, "keyup", kCode, 0,
825
+ Utils.keyEvent(doc, element, "keyup", kCode, 0,
805
826
  controlKey, false, altKey, metaKey);
806
827
  }
807
828
  }
@@ -810,40 +831,38 @@ Utils.type = function(context, element, text, opt_useNativeEvents) {
810
831
 
811
832
  if (controlKey) {
812
833
  var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CONTROL;
813
- Utils.keyEvent(context, element, "keyup", kCode, 0,
834
+ Utils.keyEvent(doc, element, "keyup", kCode, 0,
814
835
  controlKey = false, shiftKey, altKey, metaKey);
815
836
  }
816
837
 
817
838
  if (shiftKey) {
818
839
  var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
819
- Utils.keyEvent(context, element, "keyup", kCode, 0,
840
+ Utils.keyEvent(doc, element, "keyup", kCode, 0,
820
841
  controlKey, shiftKey = false, altKey, metaKey);
821
842
  }
822
843
 
823
844
  if (altKey) {
824
845
  var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_ALT;
825
- Utils.keyEvent(context, element, "keyup", kCode, 0,
846
+ Utils.keyEvent(doc, element, "keyup", kCode, 0,
826
847
  controlKey, shiftKey, altKey = false, metaKey);
827
848
  }
828
849
 
829
850
  if (metaKey) {
830
851
  var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_META;
831
- Utils.keyEvent(context, element, "keyup", kCode, 0,
852
+ Utils.keyEvent(doc, element, "keyup", kCode, 0,
832
853
  controlKey, shiftKey, altKey, metaKey = false);
833
854
  }
834
855
  };
835
856
 
836
857
 
837
- Utils.keyEvent = function(context, element, type, keyCode, charCode,
858
+ Utils.keyEvent = function(doc, element, type, keyCode, charCode,
838
859
  controlState, shiftState, altState, metaState,
839
860
  shouldPreventDefault) {
840
861
  var preventDefault = shouldPreventDefault == undefined ? false
841
862
  : shouldPreventDefault;
842
863
 
843
- var keyboardEvent =
844
- Utils.currentDocument(context).createEvent("KeyEvents");
845
- var currentView =
846
- Utils.currentDocument(context).defaultView;
864
+ var keyboardEvent = doc.createEvent("KeyEvents");
865
+ var currentView = doc.defaultView;
847
866
 
848
867
  keyboardEvent.initKeyEvent(
849
868
  type, // in DOMString typeArg,
@@ -865,7 +884,7 @@ Utils.keyEvent = function(context, element, type, keyCode, charCode,
865
884
  };
866
885
 
867
886
 
868
- Utils.fireHtmlEvent = function(context, element, eventName) {
887
+ Utils.fireHtmlEvent = function(element, eventName) {
869
888
  var doc = element.ownerDocument;
870
889
  var e = doc.createEvent("HTMLEvents");
871
890
  e.initEvent(eventName, true, true);
@@ -899,7 +918,7 @@ Utils.findForm = function(element) {
899
918
  };
900
919
 
901
920
 
902
- Utils.fireMouseEventOn = function(context, element, eventName) {
921
+ Utils.fireMouseEventOn = function(element, eventName) {
903
922
  Utils.triggerMouseEvent(element, eventName, 0, 0);
904
923
  };
905
924
 
@@ -955,12 +974,24 @@ Utils.findFrame = function(browser, frameId) {
955
974
 
956
975
 
957
976
  Utils.dumpText = function(text) {
977
+ if (!Utils.dumpText.isLoggingInit_) {
978
+ var prefs =
979
+ Utils.getService("@mozilla.org/preferences-service;1", "nsIPrefBranch");
980
+ Utils.dumpText.isLoggingInit_ = true;
981
+ Utils.dumpText.logToConsole_ =
982
+ prefs.prefHasUserValue("webdriver_log_to_console") &&
983
+ prefs.getBoolPref("webdriver_log_to_console");
984
+ }
958
985
  var consoleService = Utils.getService(
959
986
  "@mozilla.org/consoleservice;1", "nsIConsoleService");
960
- if (consoleService)
987
+ if (consoleService) {
961
988
  consoleService.logStringMessage(text);
962
- else
989
+ if (Utils.dumpText.logToConsole_) {
990
+ dump(text);
991
+ }
992
+ } else {
963
993
  dump(text);
994
+ }
964
995
  };
965
996
 
966
997
 
@@ -1032,7 +1063,7 @@ Utils.stackTrace = function() {
1032
1063
  };
1033
1064
 
1034
1065
 
1035
- Utils.getElementLocation = function(element, context) {
1066
+ Utils.getElementLocation = function(element) {
1036
1067
  var x = element.offsetLeft;
1037
1068
  var y = element.offsetTop;
1038
1069
  var elementParent = element.offsetParent;
@@ -1074,14 +1105,13 @@ Utils.getElementLocation = function(element, context) {
1074
1105
  };
1075
1106
 
1076
1107
 
1077
- Utils.findElementsByXPath = function (xpath, contextNode, context) {
1078
- var doc = Utils.getDocument(context);
1108
+ Utils.findElementsByXPath = function (xpath, contextNode, doc) {
1079
1109
  var result = doc.evaluate(xpath, contextNode, null,
1080
1110
  Components.interfaces.nsIDOMXPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
1081
1111
  var indices = [];
1082
1112
  var element = result.iterateNext();
1083
1113
  while (element) {
1084
- var index = Utils.addToKnownElements(element, context);
1114
+ var index = Utils.addToKnownElements(element, doc);
1085
1115
  indices.push(index);
1086
1116
  element = result.iterateNext();
1087
1117
  }
@@ -1185,25 +1215,37 @@ Utils.getLocationOnceScrolledIntoView = function(element) {
1185
1215
  };
1186
1216
 
1187
1217
 
1188
- Utils.unwrapParameters = function(wrappedParameters, resultArray, context) {
1218
+ Utils.unwrapParameters = function(wrappedParameters, doc) {
1219
+ var converted = [];
1189
1220
  while (wrappedParameters && wrappedParameters.length > 0) {
1190
1221
  var t = wrappedParameters.shift();
1191
-
1192
- if (t != null && t.length !== undefined && t.length != null && (t['type']
1193
- === undefined || t['type'] == null)) {
1194
- var innerArray = [];
1195
- Utils.unwrapParameters(t, innerArray);
1196
- resultArray.push(innerArray);
1197
- return;
1198
- }
1199
-
1200
- if (t['type'] == "ELEMENT") {
1201
- var element = Utils.getElementAt(t['value'], context);
1202
- t['value'] = element.wrappedJSObject ? element.wrappedJSObject : element;
1222
+ switch (typeof t) {
1223
+ case 'number':
1224
+ case 'string':
1225
+ case 'boolean':
1226
+ converted.push(t);
1227
+ break;
1228
+ case 'object':
1229
+ if (t == null) {
1230
+ converted.push(null);
1231
+ } else if (typeof t.length === 'number' &&
1232
+ !(t.propertyIsEnumerable('length'))) {
1233
+ converted.push(Utils.unwrapParameters(t, doc));
1234
+ } else if (typeof t['ELEMENT'] === 'string') {
1235
+ var element = Utils.getElementAt(t['ELEMENT'], doc);
1236
+ element = element.wrappedJSObject ? element.wrappedJSObject : element;
1237
+ converted.push(element);
1238
+ } else {
1239
+ var convertedObj = {};
1240
+ for (var prop in t) {
1241
+ convertedObj[prop] = Utils.unwrapParameters(t[prop], doc);
1242
+ }
1243
+ converted.push(convertedObj);
1244
+ }
1245
+ break;
1203
1246
  }
1204
-
1205
- resultArray.push(t['value']);
1206
1247
  }
1248
+ return converted;
1207
1249
  };
1208
1250
 
1209
1251
 
@@ -1219,23 +1261,49 @@ Utils.isHtmlCollection_ = function(obj) {
1219
1261
  }
1220
1262
 
1221
1263
 
1222
- Utils.wrapResult = function(result, context) {
1264
+ Utils.wrapResult = function(result, doc) {
1223
1265
  // Sophisticated.
1224
- if (null === result || undefined === result) {
1225
- return {type: "NULL", value: null};
1226
- } else if (result['tagName']) {
1227
- return {type: "ELEMENT",
1228
- value: Utils.addToKnownElements(result, context)};
1229
- } else if (Utils.isArray_(result) || Utils.isHtmlCollection_(result)) {
1230
- var array = [];
1231
- for (var i = 0; i < result.length; i++) {
1232
- array.push(Utils.wrapResult(result[i], context));
1233
- }
1234
- return {type: "ARRAY", value: array};
1235
- } else {
1236
- return {type: "OTHER", value: result};
1266
+ switch (typeof result) {
1267
+ case 'string':
1268
+ case 'number':
1269
+ case 'boolean':
1270
+ return result;
1271
+
1272
+ case 'function':
1273
+ return result.toString();
1274
+
1275
+ case 'undefined':
1276
+ return null;
1277
+
1278
+ case 'object':
1279
+ if (result == null) {
1280
+ return null;
1281
+ }
1282
+
1283
+ // There's got to be a more intelligent way of detecting this.
1284
+ if (result['tagName']) {
1285
+ return {'ELEMENT': Utils.addToKnownElements(result, doc)};
1286
+ }
1287
+
1288
+ if (typeof result.length === 'number' &&
1289
+ !(result.propertyIsEnumerable('length'))) {
1290
+ var array = [];
1291
+ for (var i = 0; i < result.length; i++) {
1292
+ array.push(Utils.wrapResult(result[i], doc));
1293
+ }
1294
+ return array;
1295
+ }
1296
+
1297
+ var convertedObj = {};
1298
+ for (var prop in result) {
1299
+ convertedObj[prop] = Utils.wrapResult(result[prop], doc);
1300
+ }
1301
+ return convertedObj;
1302
+
1303
+ default:
1304
+ return result;
1237
1305
  }
1238
- }
1306
+ };
1239
1307
 
1240
1308
  /**
1241
1309
  * Gets canonical xpath of the passed element, e.g. /HTML[1]/BODY[1]/P[1]