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.
- data/chrome/src/extension/background.js +19 -14
- data/chrome/src/extension/manifest-nonwin.json +1 -2
- data/chrome/src/extension/manifest-win.json +1 -2
- data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +5 -1
- data/common/src/js/abstractcommandprocessor.js +0 -33
- data/common/src/js/asserts.js +2 -2
- data/common/src/js/by.js +2 -0
- data/common/src/js/command.js +130 -36
- data/common/src/js/future.js +42 -23
- data/common/src/js/localcommandprocessor.js +0 -1
- data/common/src/js/testrunner.js +9 -16
- data/common/src/js/webdriver.js +225 -254
- data/common/src/js/webelement.js +76 -197
- data/common/src/rb/lib/selenium/webdriver/driver.rb +4 -0
- data/common/src/rb/lib/selenium/webdriver/element.rb +4 -0
- data/firefox/src/extension/components/badCertListener.js +186 -0
- data/firefox/src/extension/components/firefoxDriver.js +7 -16
- data/firefox/src/extension/components/nsCommandProcessor.js +10 -9
- data/firefox/src/extension/components/utils.js +5 -5
- data/firefox/src/extension/components/webdriverserver.js +5 -0
- data/firefox/src/extension/components/wrappedElement.js +10 -6
- data/firefox/src/rb/lib/selenium/webdriver/firefox/bridge.rb +11 -12
- data/firefox/src/rb/lib/selenium/webdriver/firefox/extension_connection.rb +2 -2
- data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +2 -1
- metadata +3 -4
- data/chrome/src/extension/toolstrip.html +0 -28
- data/common/src/js/wait.js +0 -199
@@ -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
|
-
|
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
|
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
|
-
|
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 =
|
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 {
|
381
|
-
*
|
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
|
-
|
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
|
416
|
+
// If we don't find the window, set a timeout and try again.
|
417
417
|
if (!windowFound) {
|
418
|
-
|
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,
|
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
|
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 {
|
1203
|
+
return {type: "NULL", value: null};
|
1204
1204
|
} else if (result['tagName']) {
|
1205
|
-
return {
|
1206
|
-
|
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 {
|
1213
|
+
return {type: "ARRAY", value: array};
|
1214
1214
|
} else {
|
1215
|
-
return {
|
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.
|
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 =
|
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 =
|
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
|
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.
|
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["
|
422
|
+
case arg["type"]
|
424
423
|
when "NULL"
|
425
424
|
nil
|
426
425
|
when "ELEMENT"
|
427
|
-
Element.new self, element_id_from(arg["
|
426
|
+
Element.new self, element_id_from(arg["value"])
|
428
427
|
when "ARRAY"
|
429
|
-
arg['
|
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["
|
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
|