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
@@ -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
|
|