selenium-webdriver 0.0.7 → 0.0.8

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.
@@ -34,6 +34,10 @@ module Selenium
34
34
  @bridge = bridge
35
35
  end
36
36
 
37
+ def inspect
38
+ '#<%s:0x%x browser=%s>' % [self.class, hash*2, bridge.browser.inspect]
39
+ end
40
+
37
41
  def navigate
38
42
  @navigate ||= WebDriver::Navigation.new(self)
39
43
  end
@@ -9,6 +9,10 @@ module Selenium
9
9
  @bridge, @id = bridge, id
10
10
  end
11
11
 
12
+ def inspect
13
+ '#<%s:0x%x id=%s tag_name=%s>' % [self.class, hash*2, @id.inspect, tag_name.inspect]
14
+ end
15
+
12
16
  def click
13
17
  bridge.clickElement @id
14
18
  end
@@ -0,0 +1,186 @@
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
+ * a custom nsICertOverrideService. This class will forward requests to the
22
+ * original certificate override service - unless it was told to accept all
23
+ * of them.
24
+ */
25
+
26
+ const CC = Components.classes;
27
+ const CI = Components.interfaces;
28
+
29
+ const CONSOLE = CC["@mozilla.org/consoleservice;1"].
30
+ getService(CI["nsIConsoleService"]);
31
+
32
+ function localdump(message) {
33
+ try {
34
+ CONSOLE.logStringMessage(message + "\n");
35
+ } catch (e) {
36
+ dump(message + "\n");
37
+ }
38
+ }
39
+
40
+ function WdCertOverrideService() {
41
+ var prefs =
42
+ CC["@mozilla.org/preferences-service;1"].getService(CI["nsIPrefBranch"]);
43
+
44
+ this.acceptAll = undefined;
45
+ if (!prefs.prefHasUserValue("webdriver_accept_untrusted_certs")) {
46
+ localdump('webdriver_accept_untrusted_certs not set; defaulting to true');
47
+ this.acceptAll = true;
48
+ } else {
49
+ localdump("Found preference for webdriver_accept_untrusted_certs: " +
50
+ prefs.getBoolPref("webdriver_accept_untrusted_certs"));
51
+ this.acceptAll = prefs.getBoolPref("webdriver_accept_untrusted_certs");
52
+ }
53
+ // UUID of the original implementor of this service.
54
+ var ORIGINAL_OVERRIDE_SERVICE_ID = "{67ba681d-5485-4fff-952c-2ee337ffdcd6}";
55
+
56
+ localdump("Accept untrusted certificates: " + this.acceptAll);
57
+
58
+ // Keep a reference to the original bad certificate listener.
59
+ var originalService = Components.classesByID[ORIGINAL_OVERRIDE_SERVICE_ID].
60
+ getService();
61
+
62
+ this.origListener_ =
63
+ originalService.QueryInterface(
64
+ Components.interfaces.nsICertOverrideService);
65
+ };
66
+
67
+ WdCertOverrideService.prototype = {
68
+ ERROR_UNTRUSTED: 1,
69
+ ERROR_MISMATCH: 2,
70
+ ERROR_TIME: 4
71
+ };
72
+
73
+ WdCertOverrideService.prototype.hasMatchingOverride = function(
74
+ aHostName, aPort, aCert, aOverrideBits, aIsTemporary) {
75
+ var retval = false;
76
+
77
+ if (this.acceptAll === true) {
78
+ localdump("Allowing certificate from site: " + aHostName + ":" + aPort);
79
+ retval = true;
80
+ aIsTemporary.value = false;
81
+ aOverrideBits.value = this.ERROR_UNTRUSTED | this.ERROR_MISMATCH |
82
+ this.ERROR_TIME;
83
+ localdump("Bits: " + aOverrideBits.value);
84
+ } else {
85
+ retval = this.origListener.hasMatchingOverride(aHostName, aPort,
86
+ aCert, aOverrideBits, aIsTemporary);
87
+ }
88
+
89
+ return retval;
90
+ };
91
+
92
+ // Delegate the rest of the functions - they are not interesting as they are not
93
+ // called during validation of invalid certificate normally.
94
+ WdCertOverrideService.prototype.clearValidityOverride = function(aHostName,
95
+ aPort) {
96
+ this.origListener_.clearValidityOverride(aHostName, aPort);
97
+ };
98
+
99
+ WdCertOverrideService.prototype.getAllOverrideHostsWithPorts = function(
100
+ aCount, aHostsWithPortsArray) {
101
+ this.origListener_.getAllOverrideHostsWithPorts(aCert, aHostsWithPortsArray);
102
+ };
103
+
104
+ WdCertOverrideService.prototype.getValidityOverride = function(
105
+ aHostName, aPort, aHashAlg, aFingerprint, aOverrideBits, aIsTemporary) {
106
+ return this.origListener_.getValidityOverride(
107
+ aHostName, aPort, aHashAlg, aFingerprint, aOverrideBits, aIsTemporary);
108
+ };
109
+
110
+ WdCertOverrideService.prototype.isCertUsedForOverrides = function(
111
+ aCert, aCheckTemporaries, aCheckPermanents) {
112
+ return this.origListener_.isCertUsedForOverrides(
113
+ aCert, aCheckTemporaries, aCheckPermanents);
114
+ };
115
+
116
+ WdCertOverrideService.prototype.rememberValidityOverride = function(
117
+ aHostName, aPort, aCert, aOverrideBits, aTemporary) {
118
+ this.origListener_.rememberValidityOverride(
119
+ aHostName, aPort, aCert, aOverrideBits, aTemporary);
120
+ };
121
+
122
+ // Service contract ID which we override
123
+ const CERTOVERRIDE_CONTRACT_ID = "@mozilla.org/security/certoverride;1";
124
+ // UUID for this instance specifically.
125
+ const DUMMY_BADCERT_SERVICE_CLASS_ID =
126
+ Components.ID('{c8fffaba-9b7a-41aa-872d-7e7366c16715}');
127
+
128
+ var service = undefined;
129
+
130
+ var WDBadCertListenerFactory = {
131
+ createInstance: function (aOuter, aIID) {
132
+ if (aOuter != null)
133
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
134
+ if (service == undefined) {
135
+ service = new WdCertOverrideService();
136
+ }
137
+ return service;
138
+ }
139
+ };
140
+
141
+ function WDBadCertListenerModule() {
142
+ this.firstTime_ = true;
143
+ }
144
+
145
+ WDBadCertListenerModule.prototype.registerSelf = function(
146
+ aCompMgr, aFileSpec, aLocation, aType) {
147
+
148
+ if (this.firstTime_) {
149
+ this.firstTime_ = false;
150
+ throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
151
+ }
152
+
153
+ localdump("Registering Override Certificate service.");
154
+ aCompMgr = aCompMgr.QueryInterface(
155
+ Components.interfaces.nsIComponentRegistrar);
156
+ aCompMgr.registerFactoryLocation(
157
+ DUMMY_BADCERT_SERVICE_CLASS_ID, "WebDriver Override Cert Service",
158
+ CERTOVERRIDE_CONTRACT_ID, aFileSpec, aLocation, aType);
159
+ };
160
+
161
+ WDBadCertListenerModule.prototype.unregisterSelf = function(
162
+ aCompMgr, aLocation, aType) {
163
+ localdump("Un-registering Override Certificate service.");
164
+ aCompMgr =
165
+ aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
166
+ aCompMgr.unregisterFactoryLocation(DUMMY_BADCERT_SERVICE_CLASS_ID, aLocation);
167
+ };
168
+
169
+ WDBadCertListenerModule.prototype.getClassObject = function(
170
+ aCompMgr, aCID, aIID) {
171
+ if (!aIID.equals(Components.interfaces.nsIFactory))
172
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
173
+
174
+ if (aCID.equals(DUMMY_BADCERT_SERVICE_CLASS_ID))
175
+ return WDBadCertListenerFactory;
176
+
177
+ throw Components.results.NS_ERROR_NO_INTERFACE;
178
+ };
179
+
180
+ WDBadCertListenerModule.prototype.canUnload = function(aCompMgr) {
181
+ return true;
182
+ };
183
+
184
+ function NSGetModule(comMgr, fileSpec) {
185
+ return new WDBadCertListenerModule();
186
+ }
@@ -146,15 +146,7 @@ FirefoxDriver.prototype.executeScript = function(respond, script) {
146
146
 
147
147
  var result = runScript(scriptSrc, parameters);
148
148
 
149
- var wrappedResult = Utils.wrapResult(result, respond.context);
150
-
151
- if (wrappedResult.resultType !== undefined) {
152
- respond.setField("resultType", wrappedResult.resultType);
153
- }
154
-
155
- if (wrappedResult.response !== undefined) {
156
- respond.response = wrappedResult.response;
157
- }
149
+ respond.response = Utils.wrapResult(result, respond.context);
158
150
 
159
151
  } catch (e) {
160
152
  respond.isError = true;
@@ -460,7 +452,7 @@ FirefoxDriver.prototype.findElementsInternal_ = function(respond, method,
460
452
  elementIds.push(Utils.addToKnownElements(element, respond.context));
461
453
  }
462
454
 
463
- respond.response = elementIds.join(',');
455
+ respond.response = elementIds;
464
456
  respond.send();
465
457
  };
466
458
 
@@ -650,12 +642,11 @@ FirefoxDriver.prototype.getCookie = function(respond) {
650
642
  + (c.isSecure ? "secure ;" : "");
651
643
  };
652
644
 
653
- var toReturn = "";
645
+ var toReturn = [];
654
646
  var cookies = getVisibleCookies(Utils.getBrowser(respond.context).
655
647
  contentWindow.location);
656
648
  for (var i = 0; i < cookies.length; i++) {
657
- var toAdd = cookieToString(cookies[i]);
658
- toReturn += toAdd + "\n";
649
+ toReturn.push(cookieToString(cookies[i]));
659
650
  }
660
651
 
661
652
  respond.response = toReturn;
@@ -698,13 +689,13 @@ FirefoxDriver.prototype.deleteAllCookies = function(respond) {
698
689
 
699
690
 
700
691
  FirefoxDriver.prototype.setMouseSpeed = function(respond, speed) {
701
- this.mouseSpeed = speed;
692
+ this.mouseSpeed = speed.shift();
702
693
  respond.send();
703
694
  };
704
695
 
705
696
 
706
697
  FirefoxDriver.prototype.getMouseSpeed = function(respond) {
707
- respond.response = "" + this.mouseSpeed;
698
+ respond.response = this.mouseSpeed;
708
699
  respond.send();
709
700
  };
710
701
 
@@ -754,4 +745,4 @@ FirefoxDriver.prototype.dismissAlert = function(respond, alertText) {
754
745
  }
755
746
  }
756
747
  respond.send();
757
- };
748
+ };
@@ -377,11 +377,11 @@ nsCommandProcessor.prototype.execute = function(jsonCommandString,
377
377
  * @param {Array.<*>} windowId The parameters sent with the original command.
378
378
  * The first element in the array must be the ID of the window to switch to.
379
379
  * Note all other command parameters are ignored.
380
- * @param {boolean} opt_isSecondSearch Whether this is the second attempt to
381
- * find the window.
380
+ * @param {number} opt_searchAttempt Which attempt this is at finding the
381
+ * window to switch to.
382
382
  */
383
383
  nsCommandProcessor.prototype.switchToWindow = function(response, windowId,
384
- opt_isSecondSearch) {
384
+ opt_searchAttempt) {
385
385
  var lookFor = windowId[0];
386
386
  var matches = function(win, lookFor) {
387
387
  return !win.closed &&
@@ -413,9 +413,12 @@ nsCommandProcessor.prototype.switchToWindow = function(response, windowId,
413
413
  // typically true for anchors with a target attribute set. This search could
414
414
  // execute before the target window has finished loaded, meaning the content
415
415
  // window won't have a name or FirefoxDriver instance yet (see matches above).
416
- // If we don't find the window, set a timeout to try one more time.
416
+ // If we don't find the window, set a timeout and try again.
417
417
  if (!windowFound) {
418
- if (opt_isSecondSearch) {
418
+ // TODO(jmleyba): We should be sniffing the current windows to detect if
419
+ // one is still loading vs. a brute force "try again"
420
+ var searchAttempt = opt_searchAttempt || 0;
421
+ if (searchAttempt > 3) {
419
422
  response.isError = true;
420
423
  response.response = 'Unable to locate window "' + lookFor + '"';
421
424
  response.send();
@@ -423,7 +426,7 @@ nsCommandProcessor.prototype.switchToWindow = function(response, windowId,
423
426
  var self = this;
424
427
  this.wm.getMostRecentWindow('navigator:browser').
425
428
  setTimeout(function() {
426
- self.switchToWindow(response, windowId, true);
429
+ self.switchToWindow(response, windowId, (searchAttempt + 1));
427
430
  }, 500);
428
431
  }
429
432
  }
@@ -442,11 +445,9 @@ nsCommandProcessor.prototype.getWindowHandles = function(response) {
442
445
  res.push(win.top.fxdriver.id);
443
446
  } else if (win.content) {
444
447
  res.push(win.content.name);
445
- } else {
446
- res.push('');
447
448
  }
448
449
  });
449
- response.response = res.join(',');
450
+ response.response = res;
450
451
  response.send();
451
452
  };
452
453
 
@@ -1200,18 +1200,18 @@ Utils.unwrapParameters = function(wrappedParameters, resultArray, context) {
1200
1200
  Utils.wrapResult = function(result, context) {
1201
1201
  // Sophisticated.
1202
1202
  if (null === result || undefined === result) {
1203
- return {resultType: "NULL"};
1203
+ return {type: "NULL", value: null};
1204
1204
  } else if (result['tagName']) {
1205
- return {resultType: "ELEMENT",
1206
- response: Utils.addToKnownElements(result, context)};
1205
+ return {type: "ELEMENT",
1206
+ value: Utils.addToKnownElements(result, context)};
1207
1207
  } else if (result !== undefined &&
1208
1208
  result.constructor.toString().indexOf("Array") != -1) {
1209
1209
  var array = [];
1210
1210
  for (var i = 0; i < result.length; i++) {
1211
1211
  array.push(Utils.wrapResult(result[i], context));
1212
1212
  }
1213
- return {resultType: "ARRAY", response: array};
1213
+ return {type: "ARRAY", value: array};
1214
1214
  } else {
1215
- return {resultType: "OTHER", response: result};
1215
+ return {type: "OTHER", value: result};
1216
1216
  }
1217
1217
  }
@@ -24,6 +24,11 @@ function WebDriverServer() {
24
24
  createInstance(Components.interfaces.nsIServerSocket);
25
25
  this.generator = Utils.getService("@mozilla.org/uuid-generator;1", "nsIUUIDGenerator");
26
26
  this.enableNativeEvents = null;
27
+
28
+ // Force our cert override service to be loaded - otherwise, it will not be
29
+ // loaded and cause a "too deep recursion" error.
30
+ var overrideService = Components.classes["@mozilla.org/security/certoverride;1"]
31
+ .getService(Components.interfaces.nsICertOverrideService);
27
32
  }
28
33
 
29
34
 
@@ -287,8 +287,7 @@ FirefoxDriver.prototype.getAttribute = function(respond, value) {
287
287
  respond.send();
288
288
  return;
289
289
  }
290
- respond.isError = true;
291
- respond.response = "No match";
290
+ respond.response = null;
292
291
  respond.send();
293
292
  };
294
293
 
@@ -469,8 +468,7 @@ FirefoxDriver.prototype.toggle = function(respond) {
469
468
 
470
469
  FirefoxDriver.prototype.isDisplayed = function(respond) {
471
470
  var element = Utils.getElementAt(respond.elementId, respond.context);
472
-
473
- respond.response = Utils.isDisplayed(element) ? "true" : "false";
471
+ respond.response = Utils.isDisplayed(element);
474
472
  respond.send();
475
473
  };
476
474
 
@@ -480,7 +478,10 @@ FirefoxDriver.prototype.getLocation = function(respond) {
480
478
 
481
479
  var location = Utils.getElementLocation(element, respond.context);
482
480
 
483
- respond.response = location.x + ", " + location.y;
481
+ respond.response = {
482
+ x: Math.round(location.x),
483
+ y: Math.round(location.y)
484
+ };
484
485
  respond.send();
485
486
  };
486
487
 
@@ -490,7 +491,10 @@ FirefoxDriver.prototype.getSize = function(respond) {
490
491
 
491
492
  var box = Utils.getLocationOnceScrolledIntoView(element);
492
493
 
493
- respond.response = box.width + ", " + box.height;
494
+ respond.response = {
495
+ width: Math.round(box.width),
496
+ height: Math.round(box.height)
497
+ };
494
498
  respond.send();
495
499
  };
496
500
 
@@ -36,7 +36,7 @@ module Selenium
36
36
  end
37
37
 
38
38
  def getWindowHandles
39
- execute(:getWindowHandles).to_s.split(", ")
39
+ execute :getWindowHandles
40
40
  end
41
41
 
42
42
  def getCurrentWindowHandle
@@ -77,8 +77,9 @@ module Selenium
77
77
  typed_args = args.map { |e| wrap_script_argument(e) }
78
78
 
79
79
  resp = raw_execute :executeScript, :parameters => [string, typed_args]
80
+ raise TypeError, "expected Hash" unless resp.kind_of? Hash
80
81
 
81
- unwrap_script_argument resp
82
+ unwrap_script_argument resp["response"]
82
83
  end
83
84
 
84
85
  #
@@ -180,8 +181,7 @@ module Selenium
180
181
  # data = execute :getElementLocation, :element_id => element
181
182
  data = execute :getLocation,
182
183
  :element_id => element
183
-
184
- Point.new(*data.split(",").map { |e| Integer(e.strip) })
184
+ Point.new(data["x"], data["y"])
185
185
  end
186
186
 
187
187
  def getElementSize(element)
@@ -293,8 +293,7 @@ module Selenium
293
293
 
294
294
  def getAllCookies
295
295
  data = execute :getCookie
296
-
297
- data.strip.split("\n").map do |c|
296
+ data.map do |c|
298
297
  parse_cookie_string(c) unless c.strip.empty?
299
298
  end.compact
300
299
  end
@@ -349,7 +348,7 @@ module Selenium
349
348
  :parameters => [how, what]
350
349
  end
351
350
 
352
- id_string.split(",").map { |id| Element.new self, element_id_from(id) }
351
+ id_string.map { |id| Element.new self, element_id_from(id) }
353
352
  end
354
353
 
355
354
  def newSession
@@ -420,13 +419,13 @@ module Selenium
420
419
 
421
420
  def unwrap_script_argument(arg)
422
421
  raise TypeError, "expected Hash" unless arg.kind_of? Hash
423
- case arg["resultType"]
422
+ case arg["type"]
424
423
  when "NULL"
425
424
  nil
426
425
  when "ELEMENT"
427
- Element.new self, element_id_from(arg["response"])
426
+ Element.new self, element_id_from(arg["value"])
428
427
  when "ARRAY"
429
- arg['response'].map { |e| unwrap_script_argument(e) }
428
+ arg['value'].map { |e| unwrap_script_argument(e) }
430
429
  # when "POINT"
431
430
  # Point.new arg['x'], arg['y']
432
431
  # when "DIMENSION"
@@ -434,7 +433,7 @@ module Selenium
434
433
  # when "COOKIE"
435
434
  # {:name => arg['name'], :value => arg['value']}
436
435
  else
437
- arg["response"]
436
+ arg["value"]
438
437
  end
439
438
  end
440
439
 
@@ -442,4 +441,4 @@ module Selenium
442
441
  end # Bridge
443
442
  end # Firefox
444
443
  end # WebDriver
445
- end # Selenium
444
+ end # Selenium