selenium-webdriver 0.0.17 → 0.0.18
Sign up to get free protection for your applications and to get access to all the features.
- data/chrome/prebuilt/Win32/Release/npchromedriver.dll +0 -0
- data/chrome/prebuilt/x64/Release/npchromedriver.dll +0 -0
- data/chrome/src/extension/background.js +64 -48
- data/chrome/src/extension/content_script.js +253 -132
- data/chrome/src/extension/manifest-nonwin.json +1 -1
- data/chrome/src/extension/manifest-win.json +1 -1
- data/chrome/src/extension/utils.js +8 -8
- data/chrome/src/rb/lib/selenium/webdriver/chrome.rb +9 -0
- data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +38 -280
- data/chrome/src/rb/lib/selenium/webdriver/chrome/command_executor.rb +119 -117
- data/chrome/src/rb/lib/selenium/webdriver/chrome/launcher.rb +36 -26
- data/common/src/js/abstractcommandprocessor.js +9 -11
- data/common/src/js/command.js +159 -83
- data/common/src/js/core/RemoteRunner.html +2 -2
- data/common/src/js/core/TestRunner-splash.html +3 -3
- data/common/src/js/core/TestRunner.html +5 -17
- data/common/src/js/core/scripts/htmlutils.js +4208 -2506
- data/common/src/js/core/scripts/selenium-api.js +2 -2
- data/common/src/js/core/scripts/selenium-browserbot.js +66 -58
- data/common/src/js/core/scripts/selenium-version.js +1 -1
- data/common/src/js/localcommandprocessor.js +5 -19
- data/common/src/js/testcase.js +2 -0
- data/common/src/js/webdriver.js +63 -93
- data/common/src/js/webelement.js +40 -42
- data/common/src/rb/lib/selenium/webdriver.rb +23 -14
- data/common/src/rb/lib/selenium/webdriver/bridge_helper.rb +8 -35
- data/common/src/rb/lib/selenium/webdriver/child_process.rb +2 -0
- data/common/src/rb/lib/selenium/webdriver/core_ext/dir.rb +1 -0
- data/common/src/rb/lib/selenium/webdriver/core_ext/string.rb +5 -0
- data/common/src/rb/lib/selenium/webdriver/driver.rb +20 -15
- data/common/src/rb/lib/selenium/webdriver/driver_extensions/takes_screenshot.rb +7 -2
- data/common/src/rb/lib/selenium/webdriver/element.rb +11 -2
- data/common/src/rb/lib/selenium/webdriver/error.rb +9 -5
- data/common/src/rb/lib/selenium/webdriver/keys.rb +1 -2
- data/common/src/rb/lib/selenium/webdriver/navigation.rb +16 -0
- data/common/src/rb/lib/selenium/webdriver/options.rb +32 -0
- data/common/src/rb/lib/selenium/webdriver/platform.rb +17 -1
- data/firefox/prebuilt/Win32/Release/webdriver-firefox.dll +0 -0
- data/firefox/src/extension/components/dispatcher.js +492 -0
- data/firefox/src/extension/components/driver-component.js +4 -1
- data/firefox/src/extension/components/errorcode.js +70 -0
- data/firefox/src/extension/components/firefoxDriver.js +173 -154
- data/firefox/src/extension/components/nsCommandProcessor.js +171 -132
- data/firefox/src/extension/components/promptService.js +5 -5
- data/firefox/src/extension/components/request.js +219 -0
- data/firefox/src/extension/components/response.js +276 -0
- data/firefox/src/extension/components/session.js +281 -0
- data/firefox/src/extension/components/sessionstore.js +226 -0
- data/firefox/src/extension/components/socketListener.js +350 -100
- data/firefox/src/extension/components/utils.js +166 -98
- data/firefox/src/extension/components/webdriverserver.js +9 -5
- data/firefox/src/extension/components/wrappedElement.js +189 -166
- data/firefox/src/extension/install.rdf +1 -1
- data/firefox/src/rb/lib/selenium/webdriver/firefox.rb +2 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/binary.rb +39 -33
- data/firefox/src/rb/lib/selenium/webdriver/firefox/bridge.rb +7 -421
- data/firefox/src/rb/lib/selenium/webdriver/firefox/extension_connection.rb +7 -64
- data/firefox/src/rb/lib/selenium/webdriver/firefox/launcher.rb +2 -3
- data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +54 -10
- data/firefox/src/rb/lib/selenium/webdriver/firefox/profiles_ini.rb +2 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/util.rb +6 -0
- data/jobbie/prebuilt/Win32/Release/InternetExplorerDriver.dll +0 -0
- data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie.rb +2 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie/bridge.rb +38 -13
- data/jobbie/src/rb/lib/selenium/webdriver/ie/lib.rb +9 -2
- data/jobbie/src/rb/lib/selenium/webdriver/ie/util.rb +5 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote.rb +2 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/bridge.rb +42 -38
- data/remote/client/src/rb/lib/selenium/webdriver/remote/commands.rb +56 -47
- data/remote/client/src/rb/lib/selenium/webdriver/remote/default_http_client.rb +26 -26
- data/remote/client/src/rb/lib/selenium/webdriver/remote/patron_http_client.rb +58 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/response.rb +10 -12
- data/remote/client/src/rb/lib/selenium/webdriver/remote/server_error.rb +2 -17
- metadata +44 -23
- data/common/src/js/context.js +0 -58
- data/firefox/src/extension/components/context.js +0 -37
@@ -26,9 +26,12 @@ const CONTRACT_ID = "@googlecode.com/webdriver/fxdriver;1";
|
|
26
26
|
// Its copyrights belong to its original author.
|
27
27
|
|
28
28
|
var ExternalScripts = [
|
29
|
-
"
|
29
|
+
"errorcode.js",
|
30
|
+
"dispatcher.js",
|
30
31
|
"firefoxDriver.js",
|
31
32
|
"socketListener.js",
|
33
|
+
"request.js",
|
34
|
+
"response.js",
|
32
35
|
"utils.js",
|
33
36
|
"webdriverserver.js",
|
34
37
|
"webLoadingListener.js",
|
@@ -0,0 +1,70 @@
|
|
1
|
+
/*
|
2
|
+
Copyright 2007-2010 WebDriver committers
|
3
|
+
Copyright 2007-2010 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
|
+
/**
|
21
|
+
* Error codes used by the remote wire protocol.
|
22
|
+
* @enum {number}
|
23
|
+
*/
|
24
|
+
var ErrorCode = {
|
25
|
+
// Keep in sync with codes in org.openqa.selenium.remote.ErrorCodes
|
26
|
+
|
27
|
+
SUCCESS: 0,
|
28
|
+
NO_SUCH_ELEMENT: 7,
|
29
|
+
NO_SUCH_FRAME: 8,
|
30
|
+
UNKNOWN_COMMAND: 9,
|
31
|
+
STALE_ELEMENT_REFERENCE: 10,
|
32
|
+
ELEMENT_NOT_VISIBLE: 11,
|
33
|
+
INVALID_ELEMENT_STATE: 12,
|
34
|
+
UNHANDLED_ERROR: 13,
|
35
|
+
UNEXPECTED_JAVASCRIPT_ERROR: 17,
|
36
|
+
XPATH_LOOKUP_ERROR: 19,
|
37
|
+
NO_SUCH_WINDOW: 23,
|
38
|
+
INVALID_COOKIE_DOMAIN: 24,
|
39
|
+
UNABLE_TO_SET_COOKIE: 25
|
40
|
+
};
|
41
|
+
|
42
|
+
|
43
|
+
/**
|
44
|
+
* Converts an Error object to a JSON object compatible with WebDriver's remote
|
45
|
+
* wire protocol.
|
46
|
+
* @param {Error} ex The thrown error to convert.
|
47
|
+
* @return {Object} The converted object.
|
48
|
+
*/
|
49
|
+
ErrorCode.toJSON = function(ex) {
|
50
|
+
var stackFrames = [];
|
51
|
+
var json = {
|
52
|
+
'message': ex.message ? ex.message : ex.toString(),
|
53
|
+
'stackTrace': stackFrames,
|
54
|
+
};
|
55
|
+
|
56
|
+
if (ex.stack) {
|
57
|
+
var stack = ex.stack.replace(/\s*$/, '').split('\n');
|
58
|
+
|
59
|
+
for (var frame = stack.shift(); frame; frame = stack.shift()) {
|
60
|
+
var match = frame.match(/^([a-zA-Z_$][\w]*)?(?:\(.*\))?@(.+)?:(\d*)$/);
|
61
|
+
stackFrames.push({
|
62
|
+
'methodName': match[1],
|
63
|
+
'fileName': match[2],
|
64
|
+
'lineNumber': Number(match[3])
|
65
|
+
});
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
return json;
|
70
|
+
};
|
@@ -17,15 +17,27 @@
|
|
17
17
|
*/
|
18
18
|
|
19
19
|
|
20
|
-
function FirefoxDriver(server, enableNativeEvents) {
|
20
|
+
function FirefoxDriver(server, enableNativeEvents, win) {
|
21
21
|
this.server = server;
|
22
|
-
this.mouseSpeed = 1;
|
23
22
|
this.enableNativeEvents = enableNativeEvents;
|
23
|
+
this.window = win;
|
24
24
|
|
25
25
|
this.currentX = 0;
|
26
26
|
this.currentY = 0;
|
27
27
|
}
|
28
28
|
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Enumeration of supported speed values.
|
32
|
+
* @enum {number}
|
33
|
+
*/
|
34
|
+
FirefoxDriver.Speed = {
|
35
|
+
SLOW: 1,
|
36
|
+
MEDIUM: 10,
|
37
|
+
FAST: 100
|
38
|
+
};
|
39
|
+
|
40
|
+
|
29
41
|
FirefoxDriver.prototype.__defineGetter__("id", function() {
|
30
42
|
if (!this.id_) {
|
31
43
|
this.id_ = this.server.getNextId();
|
@@ -36,15 +48,16 @@ FirefoxDriver.prototype.__defineGetter__("id", function() {
|
|
36
48
|
|
37
49
|
|
38
50
|
FirefoxDriver.prototype.getCurrentWindowHandle = function(respond) {
|
39
|
-
respond.
|
51
|
+
respond.value = this.id;
|
40
52
|
respond.send();
|
41
53
|
};
|
42
54
|
|
43
55
|
|
44
|
-
FirefoxDriver.prototype.get = function(respond,
|
56
|
+
FirefoxDriver.prototype.get = function(respond, parameters) {
|
57
|
+
var url = parameters.url;
|
45
58
|
// Check to see if the given url is the same as the current one, but
|
46
59
|
// with a different anchor tag.
|
47
|
-
var current =
|
60
|
+
var current = respond.session.getWindow().location;
|
48
61
|
var ioService =
|
49
62
|
Utils.getService("@mozilla.org/network/io-service;1", "nsIIOService");
|
50
63
|
var currentUri = ioService.newURI(current, "", null);
|
@@ -62,16 +75,17 @@ FirefoxDriver.prototype.get = function(respond, url) {
|
|
62
75
|
}
|
63
76
|
|
64
77
|
if (loadEventExpected) {
|
65
|
-
new WebLoadingListener(
|
78
|
+
new WebLoadingListener(respond.session.getBrowser(), function() {
|
66
79
|
// TODO: Rescue the URI and response code from the event
|
67
80
|
var responseText = "";
|
68
|
-
|
69
|
-
respond.
|
81
|
+
// Focus on the top window.
|
82
|
+
respond.session.setWindow(respond.session.getBrowser().contentWindow);
|
83
|
+
respond.value = responseText;
|
70
84
|
respond.send();
|
71
85
|
});
|
72
86
|
}
|
73
87
|
|
74
|
-
|
88
|
+
respond.session.getBrowser().loadURI(url);
|
75
89
|
|
76
90
|
if (!loadEventExpected) {
|
77
91
|
respond.send();
|
@@ -89,13 +103,17 @@ FirefoxDriver.prototype.close = function(respond) {
|
|
89
103
|
|
90
104
|
// Here we go!
|
91
105
|
try {
|
92
|
-
var browser =
|
106
|
+
var browser = respond.session.getBrowser();
|
93
107
|
createSwitchFile("close:" + browser.id);
|
94
108
|
browser.contentWindow.close();
|
95
109
|
} catch(e) {
|
96
110
|
dump(e);
|
97
111
|
}
|
98
112
|
|
113
|
+
// Send the response so the client doesn't get a connection refused socket
|
114
|
+
// error.
|
115
|
+
respond.send();
|
116
|
+
|
99
117
|
// If we're on a Mac we might have closed all the windows but not quit, so
|
100
118
|
// ensure that we do actually quit :)
|
101
119
|
var allWindows = wm.getEnumerator("navigator:browser");
|
@@ -103,18 +121,13 @@ FirefoxDriver.prototype.close = function(respond) {
|
|
103
121
|
appService.quit(forceQuit);
|
104
122
|
return; // The client should catch the fact that the socket suddenly closes
|
105
123
|
}
|
106
|
-
|
107
|
-
// If we're still running, return
|
108
|
-
respond.send();
|
109
124
|
};
|
110
125
|
|
111
126
|
|
112
|
-
FirefoxDriver.prototype.executeScript = function(respond,
|
113
|
-
var
|
114
|
-
var
|
115
|
-
Utils.getBrowser(respond.context).contentWindow;
|
127
|
+
FirefoxDriver.prototype.executeScript = function(respond, parameters) {
|
128
|
+
var window = respond.session.getWindow();
|
129
|
+
var doc = window.document;
|
116
130
|
|
117
|
-
var parameters = new Array();
|
118
131
|
var runScript;
|
119
132
|
|
120
133
|
// Pre 2.0.0.15
|
@@ -123,11 +136,11 @@ FirefoxDriver.prototype.executeScript = function(respond, script) {
|
|
123
136
|
return window.eval(scriptSrc);
|
124
137
|
};
|
125
138
|
} else {
|
126
|
-
runScript = function(scriptSrc) {
|
139
|
+
runScript = function(scriptSrc, args) {
|
127
140
|
window = window.wrappedJSObject;
|
128
141
|
var sandbox = new Components.utils.Sandbox(window);
|
129
142
|
sandbox.window = window;
|
130
|
-
sandbox.__webdriverParams =
|
143
|
+
sandbox.__webdriverParams = args;
|
131
144
|
sandbox.document = window.document;
|
132
145
|
sandbox.unsafeWindow = window;
|
133
146
|
sandbox.__proto__ = window;
|
@@ -136,48 +149,44 @@ FirefoxDriver.prototype.executeScript = function(respond, script) {
|
|
136
149
|
};
|
137
150
|
}
|
138
151
|
|
152
|
+
var converted = Utils.unwrapParameters(
|
153
|
+
parameters.args, respond.session.getDocument());
|
154
|
+
|
139
155
|
try {
|
140
|
-
var scriptSrc = "var __webdriverFunc = function(){" + script
|
156
|
+
var scriptSrc = "var __webdriverFunc = function(){" + parameters.script
|
141
157
|
+ "}; __webdriverFunc.apply(window, __webdriverParams);";
|
142
|
-
|
143
|
-
var convert = script.shift();
|
144
|
-
|
145
|
-
Utils.unwrapParameters(convert, parameters, respond.context);
|
146
|
-
|
147
|
-
var result = runScript(scriptSrc, parameters);
|
148
|
-
|
149
|
-
respond.response = Utils.wrapResult(result, respond.context);
|
150
|
-
|
158
|
+
var result = runScript(scriptSrc, converted);
|
151
159
|
} catch (e) {
|
152
|
-
|
153
|
-
|
160
|
+
Utils.dumpn(JSON.stringify(e));
|
161
|
+
throw new WebDriverError(ErrorCode.UNEXPECTED_JAVASCRIPT_ERROR, e);
|
154
162
|
}
|
163
|
+
|
164
|
+
respond.value = Utils.wrapResult(result, respond.session.getDocument());
|
155
165
|
respond.send();
|
156
166
|
};
|
157
167
|
|
158
168
|
|
159
169
|
FirefoxDriver.prototype.getCurrentUrl = function(respond) {
|
160
|
-
var url =
|
170
|
+
var url = respond.session.getWindow().location;
|
161
171
|
if (!url) {
|
162
|
-
url =
|
172
|
+
url = respond.session.getBrowser().contentWindow.location;
|
163
173
|
}
|
164
|
-
respond.
|
174
|
+
respond.value = "" + url;
|
165
175
|
respond.send();
|
166
176
|
};
|
167
177
|
|
168
178
|
|
169
|
-
FirefoxDriver.prototype.
|
170
|
-
|
171
|
-
respond.response = browser.contentTitle;
|
179
|
+
FirefoxDriver.prototype.getTitle = function(respond) {
|
180
|
+
respond.value = respond.session.getBrowser().contentTitle;
|
172
181
|
respond.send();
|
173
182
|
};
|
174
183
|
|
175
184
|
|
176
185
|
FirefoxDriver.prototype.getPageSource = function(respond) {
|
177
|
-
var source =
|
186
|
+
var source = respond.session.getDocument().
|
178
187
|
getElementsByTagName("html")[0].innerHTML;
|
179
188
|
|
180
|
-
respond.
|
189
|
+
respond.value = "<html>" + source + "</html>";
|
181
190
|
respond.send();
|
182
191
|
};
|
183
192
|
|
@@ -278,9 +287,9 @@ FirefoxDriver.ElementLocator = {
|
|
278
287
|
FirefoxDriver.prototype.findElementInternal_ = function(respond, method,
|
279
288
|
selector,
|
280
289
|
opt_parentElementId) {
|
281
|
-
var theDocument =
|
290
|
+
var theDocument = respond.session.getDocument();
|
282
291
|
var rootNode = typeof opt_parentElementId == 'string' ?
|
283
|
-
Utils.getElementAt(opt_parentElementId,
|
292
|
+
Utils.getElementAt(opt_parentElementId, theDocument) : theDocument;
|
284
293
|
|
285
294
|
var element;
|
286
295
|
switch (method) {
|
@@ -310,10 +319,9 @@ FirefoxDriver.prototype.findElementInternal_ = function(respond, method,
|
|
310
319
|
if (rootNode['querySelector']) {
|
311
320
|
element = rootNode.querySelector(selector);
|
312
321
|
} else {
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
}
|
322
|
+
throw new WebDriverError(ErrorCode.UNKNOWN_COMMAND,
|
323
|
+
"CSS Selectors not supported natively");
|
324
|
+
}
|
317
325
|
break;
|
318
326
|
|
319
327
|
case FirefoxDriver.ElementLocator.TAG_NAME:
|
@@ -340,22 +348,22 @@ FirefoxDriver.prototype.findElementInternal_ = function(respond, method,
|
|
340
348
|
break;
|
341
349
|
|
342
350
|
default:
|
343
|
-
|
344
|
-
|
345
|
-
respond.send();
|
351
|
+
throw new WebDriverError(ErrorCode.UNKNOWN_COMMAND,
|
352
|
+
'Unsupported element locator method: ' + method);
|
346
353
|
return;
|
347
354
|
}
|
348
355
|
|
349
356
|
if (element) {
|
350
|
-
|
357
|
+
var id = Utils.addToKnownElements(element, respond.session.getDocument());
|
358
|
+
respond.value = {'ELEMENT': id};
|
359
|
+
respond.send();
|
351
360
|
} else {
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
361
|
+
throw new WebDriverError(ErrorCode.NO_SUCH_ELEMENT,
|
362
|
+
'Unable to locate element: ' + JSON.stringify({
|
363
|
+
method: method,
|
364
|
+
selector: selector
|
365
|
+
}));
|
357
366
|
}
|
358
|
-
respond.send();
|
359
367
|
};
|
360
368
|
|
361
369
|
|
@@ -363,12 +371,14 @@ FirefoxDriver.prototype.findElementInternal_ = function(respond, method,
|
|
363
371
|
* Finds an element on the current page. The response value will be the UUID of
|
364
372
|
* the located element, or an error message if an element could not be found.
|
365
373
|
* @param {Response} respond Object to send the command response with.
|
366
|
-
* @param {
|
367
|
-
*
|
368
|
-
*
|
374
|
+
* @param {{using: string, value: string}} parameters A JSON object
|
375
|
+
* specifying the search parameters:
|
376
|
+
* - using: A method to search with, as defined in the
|
377
|
+
* {@code Firefox.ElementLocator} enum.
|
378
|
+
* - value: What to search for.
|
369
379
|
*/
|
370
380
|
FirefoxDriver.prototype.findElement = function(respond, parameters) {
|
371
|
-
this.findElementInternal_(respond, parameters
|
381
|
+
this.findElementInternal_(respond, parameters.using, parameters.value);
|
372
382
|
};
|
373
383
|
|
374
384
|
|
@@ -377,17 +387,15 @@ FirefoxDriver.prototype.findElement = function(respond, parameters) {
|
|
377
387
|
* search parameter. The response value will be the UUID of the located element,
|
378
388
|
* or an error message if an element could not be found.
|
379
389
|
* @param {Response} respond Object to send the command response with.
|
380
|
-
* @param {
|
381
|
-
*
|
382
|
-
* the following fields:
|
390
|
+
* @param {{id: string, using: string, value: string}} parameters A JSON object
|
391
|
+
* specifying the search parameters:
|
383
392
|
* - id: UUID of the element to base the search from.
|
384
393
|
* - using: A method to search with, as defined in the
|
385
394
|
* {@code Firefox.ElementLocator} enum.
|
386
395
|
* - value: What to search for.
|
387
396
|
*/
|
388
397
|
FirefoxDriver.prototype.findChildElement = function(respond, parameters) {
|
389
|
-
|
390
|
-
this.findElementInternal_(respond, map.using, map.value, map.id);
|
398
|
+
this.findElementInternal_(respond, parameters.using, parameters.value, parameters.id);
|
391
399
|
};
|
392
400
|
|
393
401
|
|
@@ -405,9 +413,9 @@ FirefoxDriver.prototype.findChildElement = function(respond, parameters) {
|
|
405
413
|
FirefoxDriver.prototype.findElementsInternal_ = function(respond, method,
|
406
414
|
selector,
|
407
415
|
opt_parentElementId) {
|
408
|
-
var theDocument =
|
416
|
+
var theDocument = respond.session.getDocument();
|
409
417
|
var rootNode = typeof opt_parentElementId == 'string' ?
|
410
|
-
Utils.getElementAt(opt_parentElementId,
|
418
|
+
Utils.getElementAt(opt_parentElementId, theDocument) : theDocument;
|
411
419
|
|
412
420
|
var elements;
|
413
421
|
switch (method) {
|
@@ -430,9 +438,8 @@ FirefoxDriver.prototype.findElementsInternal_ = function(respond, method,
|
|
430
438
|
if (rootNode['querySelector']) {
|
431
439
|
elements = rootNode.querySelectorAll(selector);
|
432
440
|
} else {
|
433
|
-
|
434
|
-
|
435
|
-
respond.send();
|
441
|
+
throw new WebDriverError(ErrorCode.UNKNOWN_COMMAND,
|
442
|
+
"CSS Selectors not supported natively");
|
436
443
|
}
|
437
444
|
break;
|
438
445
|
|
@@ -462,19 +469,20 @@ FirefoxDriver.prototype.findElementsInternal_ = function(respond, method,
|
|
462
469
|
break;
|
463
470
|
|
464
471
|
default:
|
465
|
-
|
466
|
-
|
467
|
-
respond.send();
|
472
|
+
throw new WebDriverError(ErrorCode.UNKNOWN_COMMAND,
|
473
|
+
'Unsupported element locator method: ' + method);
|
468
474
|
return;
|
469
475
|
}
|
470
476
|
|
471
477
|
var elementIds = [];
|
472
478
|
for (var j = 0; j < elements.length; j++) {
|
473
479
|
var element = elements[j];
|
474
|
-
|
480
|
+
var elementId = Utils.addToKnownElements(
|
481
|
+
element, respond.session.getDocument());
|
482
|
+
elementIds.push({'ELEMENT': elementId});
|
475
483
|
}
|
476
484
|
|
477
|
-
respond.
|
485
|
+
respond.value = elementIds;
|
478
486
|
respond.send();
|
479
487
|
};
|
480
488
|
|
@@ -483,12 +491,14 @@ FirefoxDriver.prototype.findElementsInternal_ = function(respond, method,
|
|
483
491
|
* Searches for multiple elements on the page. The response value will be an
|
484
492
|
* array of UUIDs for the located elements.
|
485
493
|
* @param {Response} respond Object to send the command response with.
|
486
|
-
* @param {
|
487
|
-
*
|
488
|
-
*
|
494
|
+
* @param {{using: string, value: string}} parameters A JSON object
|
495
|
+
* specifying the search parameters:
|
496
|
+
* - using: A method to search with, as defined in the
|
497
|
+
* {@code Firefox.ElementLocator} enum.
|
498
|
+
* - value: What to search for.
|
489
499
|
*/
|
490
500
|
FirefoxDriver.prototype.findElements = function(respond, parameters) {
|
491
|
-
this.findElementsInternal_(respond, parameters
|
501
|
+
this.findElementsInternal_(respond, parameters.using, parameters.value);
|
492
502
|
};
|
493
503
|
|
494
504
|
|
@@ -496,51 +506,46 @@ FirefoxDriver.prototype.findElements = function(respond, parameters) {
|
|
496
506
|
* Searches for multiple elements on the page that are children of the
|
497
507
|
* corresponding search parameter. The response value will be an array of UUIDs
|
498
508
|
* for the located elements.
|
499
|
-
* @param {
|
500
|
-
*
|
501
|
-
* the following fields:
|
509
|
+
* @param {{id: string, using: string, value: string}} parameters A JSON object
|
510
|
+
* specifying the search parameters:
|
502
511
|
* - id: UUID of the element to base the search from.
|
503
512
|
* - using: A method to search with, as defined in the
|
504
513
|
* {@code Firefox.ElementLocator} enum.
|
505
514
|
* - value: What to search for.
|
506
515
|
*/
|
507
516
|
FirefoxDriver.prototype.findChildElements = function(respond, parameters) {
|
508
|
-
|
509
|
-
this.findElementsInternal_(respond, map.using, map.value, map.id);
|
517
|
+
this.findElementsInternal_(respond, parameters.using, parameters.value, parameters.id);
|
510
518
|
};
|
511
519
|
|
512
520
|
|
513
|
-
FirefoxDriver.prototype.switchToFrame = function(respond,
|
514
|
-
var browser =
|
515
|
-
|
516
|
-
|
517
|
-
if (frameDoc) {
|
518
|
-
respond.context = new Context(respond.context.windowId, frameId[0]);
|
519
|
-
respond.send();
|
521
|
+
FirefoxDriver.prototype.switchToFrame = function(respond, parameters) {
|
522
|
+
var browser = respond.session.getBrowser();
|
523
|
+
if (parameters.id == null) {
|
524
|
+
respond.session.setWindow(respond.session.getBrowser().contentWindow);
|
520
525
|
} else {
|
521
|
-
|
522
|
-
|
523
|
-
|
526
|
+
var frameDoc = Utils.findDocumentInFrame(browser, parameters.id);
|
527
|
+
if (frameDoc) {
|
528
|
+
respond.session.setWindow(frameDoc.defaultView);
|
529
|
+
} else {
|
530
|
+
throw new WebDriverError(ErrorCode.NO_SUCH_FRAME,
|
531
|
+
"Cannot find frame with id: " + parameters.id);
|
532
|
+
}
|
524
533
|
}
|
525
|
-
};
|
526
|
-
|
527
|
-
|
528
|
-
FirefoxDriver.prototype.switchToDefaultContent = function(respond) {
|
529
|
-
respond.context.frameId = "?";
|
530
534
|
respond.send();
|
531
535
|
};
|
532
536
|
|
533
537
|
|
534
|
-
FirefoxDriver.prototype.
|
535
|
-
var element = Utils.getActiveElement(respond.
|
538
|
+
FirefoxDriver.prototype.getActiveElement = function(respond) {
|
539
|
+
var element = Utils.getActiveElement(respond.session.getDocument());
|
540
|
+
var id = Utils.addToKnownElements(element, respond.session.getDocument());
|
536
541
|
|
537
|
-
respond.
|
542
|
+
respond.value = {'ELEMENT':id};
|
538
543
|
respond.send();
|
539
544
|
};
|
540
545
|
|
541
546
|
|
542
547
|
FirefoxDriver.prototype.goBack = function(respond) {
|
543
|
-
var browser =
|
548
|
+
var browser = respond.session.getBrowser();
|
544
549
|
|
545
550
|
if (browser.canGoBack) {
|
546
551
|
browser.goBack();
|
@@ -551,7 +556,7 @@ FirefoxDriver.prototype.goBack = function(respond) {
|
|
551
556
|
|
552
557
|
|
553
558
|
FirefoxDriver.prototype.goForward = function(respond) {
|
554
|
-
var browser =
|
559
|
+
var browser = respond.session.getBrowser();
|
555
560
|
|
556
561
|
if (browser.canGoForward) {
|
557
562
|
browser.goForward();
|
@@ -562,19 +567,23 @@ FirefoxDriver.prototype.goForward = function(respond) {
|
|
562
567
|
|
563
568
|
|
564
569
|
FirefoxDriver.prototype.refresh = function(respond) {
|
565
|
-
var browser =
|
570
|
+
var browser = respond.session.getBrowser();
|
566
571
|
browser.contentWindow.location.reload(true);
|
567
|
-
|
568
|
-
respond.
|
572
|
+
// Wait for the reload to finish before sending the response.
|
573
|
+
new WebLoadingListener(respond.session.getBrowser(), function() {
|
574
|
+
// Reset to the top window.
|
575
|
+
respond.session.setWindow(browser.contentWindow);
|
576
|
+
respond.send();
|
577
|
+
});
|
569
578
|
};
|
570
579
|
|
571
580
|
|
572
|
-
FirefoxDriver.prototype.addCookie = function(respond,
|
573
|
-
var cookie;
|
574
|
-
cookie = eval('(' + cookieString[0] + ')');
|
581
|
+
FirefoxDriver.prototype.addCookie = function(respond, parameters) {
|
582
|
+
var cookie = parameters.cookie;
|
575
583
|
|
576
584
|
if (cookie.expiry) {
|
577
|
-
cookie.expiry = new Date(cookie.expiry)
|
585
|
+
cookie.expiry = cookie.expiry.time ? new Date(cookie.expiry.time) :
|
586
|
+
new Date(cookie.expiry);
|
578
587
|
} else {
|
579
588
|
var date = new Date();
|
580
589
|
date.setYear(2030);
|
@@ -584,16 +593,14 @@ FirefoxDriver.prototype.addCookie = function(respond, cookieString) {
|
|
584
593
|
cookie.expiry = cookie.expiry.getTime() / 1000; // Stored in seconds
|
585
594
|
|
586
595
|
if (!cookie.domain) {
|
587
|
-
var location =
|
596
|
+
var location = respond.session.getBrowser().contentWindow.location;
|
588
597
|
cookie.domain = location.hostname;
|
589
598
|
} else {
|
590
|
-
var currLocation =
|
599
|
+
var currLocation = respond.session.getBrowser().contentWindow.location;
|
591
600
|
var currDomain = currLocation.host;
|
592
601
|
if (currDomain.indexOf(cookie.domain) == -1) { // Not quite right, but close enough
|
593
|
-
|
594
|
-
|
595
|
-
respond.send();
|
596
|
-
return;
|
602
|
+
throw new WebDriverError(ErrorCode.INVALID_COOKIE_DOMAIN,
|
603
|
+
"You may only set cookies for the current domain");
|
597
604
|
}
|
598
605
|
}
|
599
606
|
|
@@ -604,12 +611,10 @@ FirefoxDriver.prototype.addCookie = function(respond, cookieString) {
|
|
604
611
|
cookie.domain = cookie.domain.replace(/:\d+$/, "");
|
605
612
|
}
|
606
613
|
|
607
|
-
var document =
|
614
|
+
var document = respond.session.getDocument();
|
608
615
|
if (!document || !document.contentType.match(/html/i)) {
|
609
|
-
|
610
|
-
|
611
|
-
respond.send();
|
612
|
-
return;
|
616
|
+
throw new WebDriverError(ErrorCode.UNABLE_TO_SET_COOKIE,
|
617
|
+
"You may only set cookies on html documents");
|
613
618
|
}
|
614
619
|
|
615
620
|
var cookieManager =
|
@@ -657,37 +662,37 @@ function getVisibleCookies(location) {
|
|
657
662
|
return results;
|
658
663
|
};
|
659
664
|
|
660
|
-
FirefoxDriver.prototype.
|
661
|
-
var cookieToString = function(c) {
|
662
|
-
return c.name + "=" + c.value + ";" + "domain=" + c.host + ";"
|
663
|
-
+ "path=" + c.path + ";" + "expires=" + c.expires + ";"
|
664
|
-
+ (c.isSecure ? "secure ;" : "");
|
665
|
-
};
|
666
|
-
|
665
|
+
FirefoxDriver.prototype.getCookies = function(respond) {
|
667
666
|
var toReturn = [];
|
668
|
-
var cookies = getVisibleCookies(
|
667
|
+
var cookies = getVisibleCookies(respond.session.getBrowser().
|
669
668
|
contentWindow.location);
|
670
669
|
for (var i = 0; i < cookies.length; i++) {
|
671
|
-
|
670
|
+
var cookie = cookies[i];
|
671
|
+
toReturn.push({
|
672
|
+
'name': cookie.name,
|
673
|
+
'value': cookie.value,
|
674
|
+
'path': cookie.path,
|
675
|
+
'domain': cookie.host,
|
676
|
+
'secure': cookie.isSecure
|
677
|
+
});
|
672
678
|
}
|
673
679
|
|
674
|
-
respond.
|
680
|
+
respond.value = toReturn;
|
675
681
|
respond.send();
|
676
682
|
};
|
677
683
|
|
678
684
|
|
679
685
|
// This is damn ugly, but it turns out that just deleting a cookie from the document
|
680
686
|
// doesn't always do The Right Thing
|
681
|
-
FirefoxDriver.prototype.deleteCookie = function(respond,
|
687
|
+
FirefoxDriver.prototype.deleteCookie = function(respond, parameters) {
|
688
|
+
var toDelete = parameters.name;
|
682
689
|
var cm = Utils.getService("@mozilla.org/cookiemanager;1", "nsICookieManager");
|
683
|
-
// TODO(simon): Well, this is dumb. Sorry
|
684
|
-
var toDelete = eval('(' + cookieString + ')');
|
685
690
|
|
686
|
-
var cookies = getVisibleCookies(
|
691
|
+
var cookies = getVisibleCookies(respond.session.getBrowser().
|
687
692
|
contentWindow.location);
|
688
693
|
for (var i = 0; i < cookies.length; i++) {
|
689
694
|
var cookie = cookies[i];
|
690
|
-
if (cookie.name == toDelete
|
695
|
+
if (cookie.name == toDelete) {
|
691
696
|
cm.remove(cookie.host, cookie.name, cookie.path, false);
|
692
697
|
}
|
693
698
|
}
|
@@ -698,7 +703,7 @@ FirefoxDriver.prototype.deleteCookie = function(respond, cookieString) {
|
|
698
703
|
|
699
704
|
FirefoxDriver.prototype.deleteAllCookies = function(respond) {
|
700
705
|
var cm = Utils.getService("@mozilla.org/cookiemanager;1", "nsICookieManager");
|
701
|
-
var cookies = getVisibleCookies(
|
706
|
+
var cookies = getVisibleCookies(respond.session.getBrowser().
|
702
707
|
contentWindow.location);
|
703
708
|
|
704
709
|
for (var i = 0; i < cookies.length; i++) {
|
@@ -710,50 +715,64 @@ FirefoxDriver.prototype.deleteAllCookies = function(respond) {
|
|
710
715
|
};
|
711
716
|
|
712
717
|
|
713
|
-
FirefoxDriver.prototype.
|
714
|
-
|
718
|
+
FirefoxDriver.prototype.setSpeed = function(respond, parameters) {
|
719
|
+
if (!(parameters.speed in FirefoxDriver.Speed)) {
|
720
|
+
var validSpeeds = [];
|
721
|
+
for (var prop in FirefoxDriver.Speed) {
|
722
|
+
validSpeeds.push(prop);
|
723
|
+
}
|
724
|
+
throw new WebDriverError(ErrorCode.UNHANDLED_ERROR,
|
725
|
+
'Speed value expected to be one of ' + JSON.stringify(validSpeeds) +
|
726
|
+
', but was "' + parameters.speed + '"');
|
727
|
+
}
|
728
|
+
respond.session.setInputSpeed(FirefoxDriver.Speed[parameters.speed]);
|
715
729
|
respond.send();
|
716
730
|
};
|
717
731
|
|
718
732
|
|
719
|
-
FirefoxDriver.prototype.
|
720
|
-
|
733
|
+
FirefoxDriver.prototype.getSpeed = function(respond) {
|
734
|
+
var speed = respond.session.getInputSpeed();
|
735
|
+
for (var prop in FirefoxDriver.Speed) {
|
736
|
+
if (FirefoxDriver.Speed[prop] == speed) {
|
737
|
+
respond.value = prop;
|
738
|
+
}
|
739
|
+
}
|
721
740
|
respond.send();
|
722
741
|
};
|
723
742
|
|
724
743
|
|
725
744
|
FirefoxDriver.prototype.saveScreenshot = function(respond, pngFile) {
|
726
|
-
var window =
|
745
|
+
var window = respond.session.getBrowser().contentWindow;
|
727
746
|
try {
|
728
747
|
var canvas = Screenshooter.grab(window);
|
729
748
|
try {
|
730
749
|
Screenshooter.save(canvas, pngFile);
|
731
750
|
} catch(e) {
|
732
|
-
|
733
|
-
|
751
|
+
throw new WebDriverError(ErrorCode.UNHANDLED_ERROR,
|
752
|
+
'Could not save screenshot to ' + pngFile + ' - ' + e);
|
734
753
|
}
|
735
754
|
} catch(e) {
|
736
|
-
|
737
|
-
|
755
|
+
throw new WebDriverError(ErrorCode.UNHANDLED_ERROR,
|
756
|
+
'Could not take screenshot of current page - ' + e);
|
738
757
|
}
|
739
758
|
respond.send();
|
740
759
|
};
|
741
760
|
|
742
761
|
|
743
|
-
FirefoxDriver.prototype.
|
744
|
-
var window =
|
762
|
+
FirefoxDriver.prototype.screenshot = function(respond) {
|
763
|
+
var window = respond.session.getBrowser().contentWindow;
|
745
764
|
try {
|
746
765
|
var canvas = Screenshooter.grab(window);
|
747
|
-
respond.
|
748
|
-
respond.response = Screenshooter.toBase64(canvas);
|
766
|
+
respond.value = Screenshooter.toBase64(canvas);
|
749
767
|
} catch (e) {
|
750
|
-
|
751
|
-
|
768
|
+
throw new WebDriverError(ErrorCode.UNHANDLED_ERROR,
|
769
|
+
'Could not take screenshot of current page - ' + e);
|
752
770
|
}
|
753
771
|
respond.send();
|
754
772
|
};
|
755
773
|
|
756
|
-
FirefoxDriver.prototype.dismissAlert = function(respond,
|
774
|
+
FirefoxDriver.prototype.dismissAlert = function(respond, parameters) {
|
775
|
+
var alertText = parameters.text;
|
757
776
|
// TODO(simon): Is there a type for alerts?
|
758
777
|
var wm = Utils.getService("@mozilla.org/appshell/window-mediator;1", "nsIWindowMediator");
|
759
778
|
var allWindows = wm.getEnumerator("");
|