selenium-webdriver 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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