selenium-webdriver 0.0.17 → 0.0.18
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/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("");
|