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.
- 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
@@ -348,7 +348,7 @@ function sendResponseToParsedRequest(toSend, wait) {
|
|
348
348
|
ChromeDriver.lastRequestToBeSentWhichHasntBeenAnsweredYet = null;
|
349
349
|
console.log("SENDING RESPOND TO PARSED REQUEST");
|
350
350
|
sendResponseByXHR(JSON.stringify(toSend), wait);
|
351
|
-
|
351
|
+
setExtensionBusyIndicator(false);
|
352
352
|
}
|
353
353
|
|
354
354
|
/**
|
@@ -387,7 +387,7 @@ function parseRequest(request) {
|
|
387
387
|
return;
|
388
388
|
}
|
389
389
|
ChromeDriver.isBlockedWaitingForResponse = true;
|
390
|
-
|
390
|
+
setExtensionBusyIndicator(true);
|
391
391
|
|
392
392
|
switch (request.request) {
|
393
393
|
case "get":
|
@@ -429,6 +429,9 @@ function parseRequest(request) {
|
|
429
429
|
}, false);
|
430
430
|
}
|
431
431
|
break;
|
432
|
+
case "screenshot":
|
433
|
+
getScreenshot();
|
434
|
+
break;
|
432
435
|
case "clickElement":
|
433
436
|
case "hoverOverElement":
|
434
437
|
// Falling through, as native events are handled the same
|
@@ -486,6 +489,19 @@ function parseRequest(request) {
|
|
486
489
|
}
|
487
490
|
}
|
488
491
|
|
492
|
+
function getScreenshot() {
|
493
|
+
chrome.tabs.captureVisibleTab(null, getScreenshotResult);
|
494
|
+
}
|
495
|
+
|
496
|
+
function getScreenshotResult(snapshotDataUrl) {
|
497
|
+
var index = snapshotDataUrl.indexOf('base64,');
|
498
|
+
if (index == -1) {
|
499
|
+
sendResponseToParsedRequest({statusCode: 99}, false);
|
500
|
+
return;
|
501
|
+
}
|
502
|
+
var base64 = snapshotDataUrl.substring(index + 'base64,'.length);
|
503
|
+
sendResponseToParsedRequest({statusCode: 0, value: base64}, false);
|
504
|
+
}
|
489
505
|
|
490
506
|
function sendMessageOnActivePortAndAlsoKeepTrackOfIt(message) {
|
491
507
|
ChromeDriver.lastRequestToBeSentWhichHasntBeenAnsweredYet = message.request;
|
@@ -889,23 +905,12 @@ function sendEmptyResponseWhenTabIsLoaded(tab) {
|
|
889
905
|
}
|
890
906
|
|
891
907
|
|
892
|
-
function
|
893
|
-
var toolstrips = chrome.extension.getToolstrips(ChromeDriver.activeWindowId);
|
908
|
+
function setExtensionBusyIndicator(busy) {
|
894
909
|
if (busy) {
|
895
910
|
chrome.browserAction.setIcon({path: "icons/busy.png"})
|
896
911
|
} else {
|
897
912
|
chrome.browserAction.setIcon({path: "icons/free.png"})
|
898
913
|
}
|
899
|
-
for (var toolstrip in toolstrips) {
|
900
|
-
if (toolstrips[toolstrip].setWebdriverToolstripBusy &&
|
901
|
-
toolstrips[toolstrip].setWebdriverToolstripFree) {
|
902
|
-
if (busy) {
|
903
|
-
toolstrips[toolstrip].setWebdriverToolstripBusy();
|
904
|
-
} else {
|
905
|
-
toolstrips[toolstrip].setWebdriverToolstripFree();
|
906
|
-
}
|
907
|
-
}
|
908
|
-
}
|
909
914
|
}
|
910
915
|
|
911
916
|
function setActivePortByWindowName(handle) {
|
@@ -2,7 +2,6 @@
|
|
2
2
|
"name": "WebDriver",
|
3
3
|
"version": "0.3",
|
4
4
|
"description": "WebDriver extension for Chrome",
|
5
|
-
"toolstrips": ["toolstrip.html"],
|
6
5
|
"browser_action": {
|
7
6
|
"default_title": "WebDriver",
|
8
7
|
"default_icon": "icons/free.png"
|
@@ -12,7 +11,7 @@
|
|
12
11
|
{
|
13
12
|
"matches": ["http://*/*", "https://*/*", "file:///*"],
|
14
13
|
"js": ["utils.js", "content_script.js"],
|
15
|
-
"run_at": "
|
14
|
+
"run_at": "document_end"
|
16
15
|
}
|
17
16
|
],
|
18
17
|
"permissions": ["http://*/*", "tabs"]
|
@@ -2,7 +2,6 @@
|
|
2
2
|
"name": "WebDriver",
|
3
3
|
"version": "0.2",
|
4
4
|
"description": "WebDriver extension for Chrome",
|
5
|
-
"toolstrips": ["toolstrip.html"],
|
6
5
|
"browser_action": {
|
7
6
|
"default_title": "WebDriver",
|
8
7
|
"default_icon": "icons/free.png"
|
@@ -12,7 +11,7 @@
|
|
12
11
|
{
|
13
12
|
"matches": ["http://*/*", "https://*/*", "file:///*"],
|
14
13
|
"js": ["utils.js", "content_script.js"],
|
15
|
-
"run_at": "
|
14
|
+
"run_at": "document_end"
|
16
15
|
}
|
17
16
|
],
|
18
17
|
"plugins": [{"path": "npchromedriver.dll", "public": true}],
|
@@ -17,7 +17,7 @@ module Selenium
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def driver_extensions
|
20
|
-
[]
|
20
|
+
[DriverExtensions::TakesScreenshot]
|
21
21
|
end
|
22
22
|
|
23
23
|
def get(url)
|
@@ -73,6 +73,10 @@ module Selenium
|
|
73
73
|
execute :request => 'getCurrentWindowHandle'
|
74
74
|
end
|
75
75
|
|
76
|
+
def getScreenshotAsBase64
|
77
|
+
execute :request => "screenshot"
|
78
|
+
end
|
79
|
+
|
76
80
|
def setSpeed(value)
|
77
81
|
@speed = value
|
78
82
|
end
|
@@ -96,10 +96,6 @@ webdriver.AbstractCommandProcessor.prototype.execute = function(command,
|
|
96
96
|
break;
|
97
97
|
|
98
98
|
case webdriver.CommandName.WAIT:
|
99
|
-
var callback = goog.bind(this.waitCallback_, this, command, context);
|
100
|
-
command.parameters[0].start(callback);
|
101
|
-
break;
|
102
|
-
|
103
99
|
case webdriver.CommandName.FUNCTION:
|
104
100
|
try {
|
105
101
|
var result = command.parameters[0]();
|
@@ -120,35 +116,6 @@ webdriver.AbstractCommandProcessor.prototype.execute = function(command,
|
|
120
116
|
};
|
121
117
|
|
122
118
|
|
123
|
-
/**
|
124
|
-
* Callback for {@code webdriver.CommandName.WAIT} commands.
|
125
|
-
* @param {webdriver.Command} command The wait command.
|
126
|
-
* @param {webdriver.Context} context The context the command executed in.
|
127
|
-
* @param {boolean} isTimeout Whether the wait finished from a timeout.
|
128
|
-
* @param {number} elapsedTime The amount of time spent waiting, in
|
129
|
-
* milliseconds.
|
130
|
-
* @param {Error} opt_ex If defined, an error that caused the wait to terminate
|
131
|
-
* early.
|
132
|
-
*/
|
133
|
-
webdriver.AbstractCommandProcessor.prototype.waitCallback_ = function(
|
134
|
-
command, context, isTimeout, elapsedTime, opt_ex) {
|
135
|
-
var message;
|
136
|
-
if (opt_ex) {
|
137
|
-
message = 'Error';
|
138
|
-
} else if (isTimeout) {
|
139
|
-
message = 'Timeout';
|
140
|
-
} else {
|
141
|
-
message = 'Ready';
|
142
|
-
}
|
143
|
-
var response = new webdriver.Response(isTimeout || opt_ex, context,
|
144
|
-
message + ' after ' + elapsedTime + 'ms');
|
145
|
-
if (opt_ex) {
|
146
|
-
response.errors.push(opt_ex);
|
147
|
-
}
|
148
|
-
command.setResponse(response);
|
149
|
-
};
|
150
|
-
|
151
|
-
|
152
119
|
/**
|
153
120
|
* Sends a command to be executed by a browser driver. This method must be
|
154
121
|
* implemented by each subclass.
|
data/common/src/js/asserts.js
CHANGED
@@ -164,7 +164,7 @@ webdriver.asserts.Matcher.isTheSameLocationAs = function(expected) {
|
|
164
164
|
function () {
|
165
165
|
return 'equal ' + webdriver.asserts.objToString(expected);
|
166
166
|
});
|
167
|
-
}
|
167
|
+
};
|
168
168
|
goog.exportSymbol('isTheSameLocationAs',
|
169
169
|
webdriver.asserts.Matcher.isTheSameLocationAs);
|
170
170
|
|
@@ -200,7 +200,7 @@ webdriver.asserts.assertThat = function(a, b, opt_c) {
|
|
200
200
|
'Expected to ' + matcher.describe() +
|
201
201
|
'\n but was ' + webdriver.asserts.objToString(future));
|
202
202
|
}
|
203
|
-
}
|
203
|
+
};
|
204
204
|
|
205
205
|
if (future instanceof webdriver.Future) {
|
206
206
|
// Schedule a function with the Future's controlling driver so the value
|
data/common/src/js/by.js
CHANGED
data/common/src/js/command.js
CHANGED
@@ -25,22 +25,44 @@ goog.provide('webdriver.CommandName');
|
|
25
25
|
goog.provide('webdriver.Response');
|
26
26
|
|
27
27
|
goog.require('goog.array');
|
28
|
+
goog.require('goog.events.EventTarget');
|
29
|
+
goog.require('goog.testing.stacktrace');
|
30
|
+
goog.require('webdriver.Future');
|
28
31
|
|
29
32
|
|
30
33
|
/**
|
31
34
|
* Describes a command to be executed by a
|
32
35
|
* {@code webdriver.AbstractCommandProcessor}.
|
33
|
-
* @param {
|
34
|
-
* @param {webdriver.
|
35
|
-
*
|
36
|
-
*
|
36
|
+
* @param {webdriver.WebDriver} driver The driver that this is a command for.
|
37
|
+
* @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.
|
37
41
|
* @constructor
|
42
|
+
* @extends {goog.events.EventTarget}
|
38
43
|
*/
|
39
|
-
webdriver.Command = function(name, opt_element) {
|
44
|
+
webdriver.Command = function(driver, name, opt_element) {
|
45
|
+
goog.events.EventTarget.call(this);
|
46
|
+
|
47
|
+
/**
|
48
|
+
* The driver that this is a command to.
|
49
|
+
* @type {webdriver.WebDriver}
|
50
|
+
* @private
|
51
|
+
*/
|
52
|
+
this.driver_ = driver;
|
53
|
+
|
54
|
+
/**
|
55
|
+
* A future that will be automatically updated with the value of this
|
56
|
+
* command's response when it is ready. If the command fails, the
|
57
|
+
* future's value will not be set.
|
58
|
+
* @type {webdriver.Future}
|
59
|
+
* @private
|
60
|
+
*/
|
61
|
+
this.futureResult_ = new webdriver.Future(this.driver_);
|
40
62
|
|
41
63
|
/**
|
42
64
|
* The name of this command.
|
43
|
-
* @type {
|
65
|
+
* @type {webdriver.CommandName}
|
44
66
|
*/
|
45
67
|
this.name = name;
|
46
68
|
|
@@ -75,26 +97,74 @@ webdriver.Command = function(name, opt_element) {
|
|
75
97
|
*/
|
76
98
|
this.onFailureCallbackFn = null;
|
77
99
|
|
78
|
-
/**
|
79
|
-
* Callback for when this command is completely finished, which is after the
|
80
|
-
* response is set and success/failure callbacks have been run. The function
|
81
|
-
* should take a single argument, a reference to this command.
|
82
|
-
* @type {?function}
|
83
|
-
* @private
|
84
|
-
*/
|
85
|
-
this.onCompleteCallbackFn_ = null;
|
86
|
-
|
87
100
|
/**
|
88
101
|
* The response to this command.
|
89
|
-
* @type {webdriver.Response}
|
102
|
+
* @type {?webdriver.Response}
|
90
103
|
*/
|
91
104
|
this.response = null;
|
92
105
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
106
|
+
};
|
107
|
+
goog.inherits(webdriver.Command, goog.events.EventTarget);
|
108
|
+
|
109
|
+
|
110
|
+
/**
|
111
|
+
* The event dispatched by a command when it fails.
|
112
|
+
* @type {string}
|
113
|
+
*/
|
114
|
+
webdriver.Command.ERROR_EVENT = 'ERROR';
|
115
|
+
|
116
|
+
|
117
|
+
/** @override */
|
118
|
+
webdriver.Command.prototype.disposeInternal = function() {
|
119
|
+
webdriver.Command.superClass_.disposeInternal.call(this);
|
120
|
+
this.futureResult_.dispose();
|
121
|
+
delete this.driver_;
|
122
|
+
delete this.futureResult_;
|
123
|
+
delete this.name;
|
124
|
+
delete this.element;
|
125
|
+
delete this.parameters;
|
126
|
+
delete this.onSuccessCallbackFn;
|
127
|
+
delete this.onFailureCallbackFn;
|
128
|
+
delete this.response;
|
129
|
+
};
|
130
|
+
|
131
|
+
|
132
|
+
/** @override */
|
133
|
+
webdriver.Command.prototype.toString = function() {
|
134
|
+
return this.name;
|
135
|
+
};
|
136
|
+
|
137
|
+
|
138
|
+
/**
|
139
|
+
* @return {webdriver.WebDriver} The driver that this is a command to.
|
140
|
+
*/
|
141
|
+
webdriver.Command.prototype.getDriver = function() {
|
142
|
+
return this.driver_;
|
143
|
+
};
|
144
|
+
|
145
|
+
|
146
|
+
/**
|
147
|
+
* @return {webdriver.CommandName} This command's name.
|
148
|
+
*/
|
149
|
+
webdriver.Command.prototype.getName = function() {
|
150
|
+
return this.name;
|
151
|
+
};
|
152
|
+
|
153
|
+
|
154
|
+
/**
|
155
|
+
* @return {webdriver.Future} The future result (value-only) of this command.
|
156
|
+
*/
|
157
|
+
webdriver.Command.prototype.getFutureResult = function() {
|
158
|
+
return this.futureResult_;
|
159
|
+
};
|
160
|
+
|
161
|
+
|
162
|
+
/**
|
163
|
+
* @return {boolean} Whether this command has finished; aborted commands are
|
164
|
+
* never considered finished.
|
165
|
+
*/
|
166
|
+
webdriver.Command.prototype.isFinished = function() {
|
167
|
+
return !!this.response;
|
98
168
|
};
|
99
169
|
|
100
170
|
|
@@ -143,17 +213,10 @@ webdriver.Command.prototype.setFailureCallback = function(callbackFn,
|
|
143
213
|
|
144
214
|
|
145
215
|
/**
|
146
|
-
*
|
147
|
-
* @param {function} callbackFn The function to call on command completion.
|
148
|
-
* @param {Object} opt_selfObj The object in whose context to execute the
|
149
|
-
* function.
|
216
|
+
* @return {?webdriver.Response} The response to this command if it is ready.
|
150
217
|
*/
|
151
|
-
webdriver.Command.prototype.
|
152
|
-
|
153
|
-
if (callbackFn) {
|
154
|
-
this.onCompleteCallbackFn_ = goog.bind(callbackFn, opt_selfObj);
|
155
|
-
}
|
156
|
-
return this;
|
218
|
+
webdriver.Command.prototype.getResponse = function() {
|
219
|
+
return this.response;
|
157
220
|
};
|
158
221
|
|
159
222
|
|
@@ -164,7 +227,7 @@ webdriver.Command.prototype.setCompleteCallback = function(callbackFn,
|
|
164
227
|
* @throws If the response was already set.
|
165
228
|
*/
|
166
229
|
webdriver.Command.prototype.setResponse = function(response) {
|
167
|
-
if (this.
|
230
|
+
if (this.isDisposed() || this.isFinished()) {
|
168
231
|
return;
|
169
232
|
}
|
170
233
|
this.response = response;
|
@@ -188,8 +251,10 @@ webdriver.Command.prototype.setResponse = function(response) {
|
|
188
251
|
}
|
189
252
|
}
|
190
253
|
|
191
|
-
if (this.
|
192
|
-
this.
|
254
|
+
if (!this.response.isFailure) {
|
255
|
+
this.futureResult_.setValue(this.response.value);
|
256
|
+
} else {
|
257
|
+
this.dispatchEvent(webdriver.Command.ERROR_EVENT);
|
193
258
|
}
|
194
259
|
};
|
195
260
|
|
@@ -259,7 +324,7 @@ webdriver.CommandName = {
|
|
259
324
|
* {@code true}, then {@code value} contains the error message.
|
260
325
|
* @param {webdriver.Context} context The (potentially new) context resulting
|
261
326
|
* from the command.
|
262
|
-
* @param {
|
327
|
+
* @param {*} value The value of the response, the meaning of which depends
|
263
328
|
* on the command.
|
264
329
|
* @parma {Error} opt_error An error that caused this command to fail
|
265
330
|
* prematurely.
|
@@ -270,5 +335,34 @@ webdriver.Response = function(isFailure, context, value, opt_error) {
|
|
270
335
|
this.context = context;
|
271
336
|
this.value = value;
|
272
337
|
this.errors = goog.array.slice(arguments, 3);
|
273
|
-
|
338
|
+
};
|
339
|
+
|
340
|
+
|
341
|
+
/**
|
342
|
+
* @return {?string} A formatted error message, or {@code null} if this is not a
|
343
|
+
* failure response.
|
344
|
+
*/
|
345
|
+
webdriver.Response.prototype.getErrorMessage = function() {
|
346
|
+
if (!this.isFailure) {
|
347
|
+
return null;
|
348
|
+
}
|
349
|
+
var message = [];
|
350
|
+
if (goog.isString(this.value)) {
|
351
|
+
message.push(this.value);
|
352
|
+
} else if (null != this.value && goog.isDef(this.value.message)) {
|
353
|
+
message.push(this.value.message);
|
354
|
+
if (goog.isDef(this.value.fileName)) {
|
355
|
+
message.push(this.value.fileName + '@' + this.value.lineNumber);
|
356
|
+
}
|
357
|
+
}
|
358
|
+
goog.array.extend(message, goog.array.map(this.errors, function(error) {
|
359
|
+
if (goog.isString(error)) {
|
360
|
+
return error;
|
361
|
+
}
|
362
|
+
var errMsg = error.message || error.description || error.toString();
|
363
|
+
var stack = error.stack ?
|
364
|
+
goog.testing.stacktrace.canonicalize(error.stack) : error['stackTrace'];
|
365
|
+
return errMsg + '\n' + stack;
|
366
|
+
}));
|
367
|
+
return message.join('\n');
|
274
368
|
};
|
data/common/src/js/future.js
CHANGED
@@ -23,24 +23,20 @@ limitations under the License.
|
|
23
23
|
|
24
24
|
goog.provide('webdriver.Future');
|
25
25
|
|
26
|
-
goog.require('goog.
|
27
|
-
goog.require('goog.
|
26
|
+
goog.require('goog.Disposable');
|
27
|
+
goog.require('goog.array');
|
28
28
|
|
29
29
|
|
30
30
|
/**
|
31
31
|
* Represents the result of an asynchronous {@code webdriver.Command}. Methods
|
32
32
|
* are provided to check if the result has been set and to retrieve the result.
|
33
|
-
* <p/>
|
34
|
-
* This instance will dispatch a {@code goog.events.EventType.CHANGE} event when
|
35
|
-
* its value is set. An {@code Error} will be thrown if {@code #getValue()} is
|
36
|
-
* called before the value has been set.
|
37
33
|
* @param {webdriver.WebDriver} driver The WebDriver instance that will
|
38
34
|
* eventually set this instance's value.
|
39
35
|
* @constructor
|
40
|
-
* @extends {goog.
|
36
|
+
* @extends {goog.Disposable}
|
41
37
|
*/
|
42
38
|
webdriver.Future = function(driver) {
|
43
|
-
goog.
|
39
|
+
goog.Disposable.call(this);
|
44
40
|
|
45
41
|
/**
|
46
42
|
* The WebDriver that will eventaully set this instance's value.
|
@@ -55,8 +51,16 @@ webdriver.Future = function(driver) {
|
|
55
51
|
* @private
|
56
52
|
*/
|
57
53
|
this.value_ = webdriver.Future.NOT_SET_;
|
54
|
+
|
55
|
+
/**
|
56
|
+
* Futures whose values are linked to this one. When this future's value is
|
57
|
+
* set, all of the linked futures will also be updated.
|
58
|
+
* @type {Array.<webdriver.Future>}
|
59
|
+
* @private
|
60
|
+
*/
|
61
|
+
this.linkedFutures_ = [];
|
58
62
|
};
|
59
|
-
goog.inherits(webdriver.Future, goog.
|
63
|
+
goog.inherits(webdriver.Future, goog.Disposable);
|
60
64
|
|
61
65
|
|
62
66
|
/**
|
@@ -68,6 +72,15 @@ goog.inherits(webdriver.Future, goog.events.EventTarget);
|
|
68
72
|
webdriver.Future.NOT_SET_ = {};
|
69
73
|
|
70
74
|
|
75
|
+
/** @override */
|
76
|
+
webdriver.Future.prototype.disposeInternal = function() {
|
77
|
+
delete this.driver_;
|
78
|
+
delete this.value_;
|
79
|
+
delete this.linkedFutures_;
|
80
|
+
webdriver.Future.superClass_.disposeInternal.call(this);
|
81
|
+
};
|
82
|
+
|
83
|
+
|
71
84
|
/**
|
72
85
|
* @return {*} The value of this Future.
|
73
86
|
* @throws If the value has not been set yet.
|
@@ -90,23 +103,29 @@ webdriver.Future.prototype.getDriver = function() {
|
|
90
103
|
|
91
104
|
|
92
105
|
/**
|
93
|
-
* Sets the value of this Future
|
94
|
-
* {@code goog.events.EventType.CHANGE} event.
|
106
|
+
* Sets the value of this Future and dispatches a
|
107
|
+
* {@code goog.events.EventType.CHANGE} event. If the given value is another
|
108
|
+
* future and its value has not been set, a callback will be registered to
|
109
|
+
* set this instance's value when the input future's value is set. Note that
|
110
|
+
* the value of a future may only be set once.
|
95
111
|
* @param {*} value The new value.
|
96
112
|
*/
|
97
113
|
webdriver.Future.prototype.setValue = function(value) {
|
98
|
-
this.
|
99
|
-
|
100
|
-
}
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
114
|
+
if (this.isSet()) {
|
115
|
+
return;
|
116
|
+
}
|
117
|
+
if (value instanceof webdriver.Future) {
|
118
|
+
if (value.isSet()) {
|
119
|
+
this.value_ = value.getValue();
|
120
|
+
} else {
|
121
|
+
value.linkedFutures_.push(this);
|
122
|
+
}
|
123
|
+
} else {
|
124
|
+
this.value_ = value;
|
125
|
+
goog.array.forEach(this.linkedFutures_, function(future) {
|
126
|
+
future.setValue(value);
|
127
|
+
});
|
128
|
+
}
|
110
129
|
};
|
111
130
|
|
112
131
|
|