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
|
@@ -29,6 +29,13 @@ function WebDriverServer() {
|
|
|
29
29
|
// loaded and cause a "too deep recursion" error.
|
|
30
30
|
var overrideService = Components.classes["@mozilla.org/security/certoverride;1"]
|
|
31
31
|
.getService(Components.interfaces.nsICertOverrideService);
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* This server's request dispatcher.
|
|
35
|
+
* @type {Dispatcher}
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
this.dispatcher_ = new Dispatcher();
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
|
|
@@ -44,10 +51,7 @@ WebDriverServer.prototype.newDriver = function(window) {
|
|
|
44
51
|
prefs.getBoolPref("webdriver_enable_native_events") : false;
|
|
45
52
|
Utils.dumpn('Enable native events: ' + this.enableNativeEvents);
|
|
46
53
|
}
|
|
47
|
-
window.fxdriver = new FirefoxDriver(this, this.enableNativeEvents);
|
|
48
|
-
// Yuck. But it allows us to refer to it later.
|
|
49
|
-
window.fxdriver.window = window;
|
|
50
|
-
|
|
54
|
+
window.fxdriver = new FirefoxDriver(this, this.enableNativeEvents, window);
|
|
51
55
|
return window.fxdriver;
|
|
52
56
|
};
|
|
53
57
|
|
|
@@ -59,7 +63,7 @@ WebDriverServer.prototype.getNextId = function() {
|
|
|
59
63
|
|
|
60
64
|
WebDriverServer.prototype.onSocketAccepted = function(socket, transport) {
|
|
61
65
|
try {
|
|
62
|
-
var socketListener = new SocketListener(transport);
|
|
66
|
+
var socketListener = new SocketListener(this.dispatcher_, transport);
|
|
63
67
|
} catch(e) {
|
|
64
68
|
dump(e);
|
|
65
69
|
}
|
|
@@ -17,15 +17,23 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
FirefoxDriver.prototype.
|
|
21
|
-
var
|
|
20
|
+
FirefoxDriver.prototype.elementEquals = function(respond, parameters) {
|
|
21
|
+
var elementA = Utils.getElementAt(parameters.id,
|
|
22
|
+
respond.session.getDocument());
|
|
23
|
+
var elementB = Utils.getElementAt(parameters.other,
|
|
24
|
+
respond.session.getDocument());
|
|
25
|
+
respond.value = elementA == elementB;
|
|
26
|
+
respond.send();
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
FirefoxDriver.prototype.clickElement = function(respond, parameters) {
|
|
31
|
+
var element = Utils.getElementAt(parameters.id,
|
|
32
|
+
respond.session.getDocument());
|
|
22
33
|
|
|
23
34
|
if (!Utils.isDisplayed(element, true) && !Utils.isInHead(element)) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"Element is not currently visible and so may not be clicked";
|
|
27
|
-
respond.send();
|
|
28
|
-
return;
|
|
35
|
+
throw new WebDriverError(ErrorCode.ELEMENT_NOT_VISIBLE,
|
|
36
|
+
"Element is not currently visible and so may not be clicked");
|
|
29
37
|
}
|
|
30
38
|
|
|
31
39
|
var nativeEvents = Utils.getNativeEvents();
|
|
@@ -84,10 +92,7 @@ FirefoxDriver.prototype.click = function(respond) {
|
|
|
84
92
|
Utils.dumpn("Detected error when clicking: " + e.name);
|
|
85
93
|
|
|
86
94
|
if (e.name != "NS_ERROR_NOT_IMPLEMENTED") {
|
|
87
|
-
|
|
88
|
-
respond.response = e.toString();
|
|
89
|
-
respond.send();
|
|
90
|
-
return;
|
|
95
|
+
throw new WebDriverError(ErrorCode.INVALID_ELEMENT_STATE, e);
|
|
91
96
|
}
|
|
92
97
|
|
|
93
98
|
// Fall through to the synthesized click code.
|
|
@@ -95,11 +100,12 @@ FirefoxDriver.prototype.click = function(respond) {
|
|
|
95
100
|
}
|
|
96
101
|
|
|
97
102
|
Utils.dumpn("Falling back to synthesized click");
|
|
98
|
-
var
|
|
103
|
+
var doc = respond.session.getDocument()
|
|
104
|
+
var currentlyActive = Utils.getActiveElement(doc);
|
|
99
105
|
|
|
100
|
-
Utils.fireMouseEventOn(
|
|
101
|
-
Utils.fireMouseEventOn(
|
|
102
|
-
Utils.fireMouseEventOn(
|
|
106
|
+
Utils.fireMouseEventOn(element, "mouseover");
|
|
107
|
+
Utils.fireMouseEventOn(element, "mousemove");
|
|
108
|
+
Utils.fireMouseEventOn(element, "mousedown");
|
|
103
109
|
if (element != currentlyActive) {
|
|
104
110
|
// Some elements may not have blur, focus functions - for example,
|
|
105
111
|
// elements under an SVG element. Call those only if they exist.
|
|
@@ -111,10 +117,10 @@ FirefoxDriver.prototype.click = function(respond) {
|
|
|
111
117
|
}
|
|
112
118
|
}
|
|
113
119
|
|
|
114
|
-
Utils.fireMouseEventOn(
|
|
115
|
-
Utils.fireMouseEventOn(
|
|
120
|
+
Utils.fireMouseEventOn(element, "mouseup");
|
|
121
|
+
Utils.fireMouseEventOn(element, "click");
|
|
116
122
|
|
|
117
|
-
var browser =
|
|
123
|
+
var browser = respond.session.getBrowser();
|
|
118
124
|
var alreadyReplied = false;
|
|
119
125
|
|
|
120
126
|
var clickListener = new WebLoadingListener(browser, function(event) {
|
|
@@ -145,6 +151,8 @@ FirefoxDriver.prototype.click = function(respond) {
|
|
|
145
151
|
|
|
146
152
|
|
|
147
153
|
if (contentWindow.closed) {
|
|
154
|
+
// Nulls out the session; client will have to switch to another
|
|
155
|
+
// window on their own.
|
|
148
156
|
respond.send();
|
|
149
157
|
return;
|
|
150
158
|
}
|
|
@@ -152,52 +160,51 @@ FirefoxDriver.prototype.click = function(respond) {
|
|
|
152
160
|
};
|
|
153
161
|
|
|
154
162
|
|
|
155
|
-
FirefoxDriver.prototype.
|
|
156
|
-
var element = Utils.getElementAt(
|
|
163
|
+
FirefoxDriver.prototype.getElementText = function(respond, parameters) {
|
|
164
|
+
var element = Utils.getElementAt(parameters.id,
|
|
165
|
+
respond.session.getDocument());
|
|
157
166
|
|
|
158
167
|
if (element.tagName == "TITLE") {
|
|
159
|
-
respond.
|
|
168
|
+
respond.value = respond.session.getBrowser().contentTitle;
|
|
160
169
|
} else {
|
|
161
|
-
respond.
|
|
170
|
+
respond.value = Utils.getText(element, true);
|
|
162
171
|
}
|
|
163
172
|
|
|
164
173
|
respond.send();
|
|
165
174
|
};
|
|
166
175
|
|
|
167
176
|
|
|
168
|
-
FirefoxDriver.prototype.
|
|
169
|
-
var element = Utils.getElementAt(
|
|
177
|
+
FirefoxDriver.prototype.getElementValue = function(respond, parameters) {
|
|
178
|
+
var element = Utils.getElementAt(parameters.id,
|
|
179
|
+
respond.session.getDocument());
|
|
170
180
|
|
|
171
181
|
if (element["value"] !== undefined) {
|
|
172
|
-
respond.
|
|
182
|
+
respond.value = element.value;
|
|
173
183
|
respond.send();
|
|
174
184
|
return;
|
|
175
185
|
}
|
|
176
186
|
|
|
177
187
|
if (element.hasAttribute("value")) {
|
|
178
|
-
respond.
|
|
188
|
+
respond.value = element.getAttribute("value");
|
|
179
189
|
respond.send();
|
|
180
190
|
return;
|
|
181
191
|
}
|
|
182
192
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
respond.send();
|
|
193
|
+
throw new WebDriverError(ErrorCode.INVALID_ELEMENT_STATE,
|
|
194
|
+
'Element does not have a value attribute');
|
|
186
195
|
};
|
|
187
196
|
|
|
188
197
|
|
|
189
|
-
FirefoxDriver.prototype.
|
|
190
|
-
var element = Utils.getElementAt(
|
|
198
|
+
FirefoxDriver.prototype.sendKeysToElement = function(respond, parameters) {
|
|
199
|
+
var element = Utils.getElementAt(parameters.id,
|
|
200
|
+
respond.session.getDocument());
|
|
191
201
|
|
|
192
202
|
if (!Utils.isDisplayed(element, true) && !Utils.isInHead(element)) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
"Element is not currently visible and so may not be used for typing";
|
|
196
|
-
respond.send();
|
|
197
|
-
return;
|
|
203
|
+
throw new WebDriverError(ErrorCode.ELEMENT_NOT_VISIBLE,
|
|
204
|
+
"Element is not currently visible and so may not be used for typing");
|
|
198
205
|
}
|
|
199
206
|
|
|
200
|
-
var currentlyActive = Utils.getActiveElement(respond.
|
|
207
|
+
var currentlyActive = Utils.getActiveElement(respond.session.getDocument());
|
|
201
208
|
if (currentlyActive != element) {
|
|
202
209
|
currentlyActive.blur();
|
|
203
210
|
element.focus();
|
|
@@ -214,26 +221,24 @@ FirefoxDriver.prototype.sendKeys = function(respond, value) {
|
|
|
214
221
|
use = element.ownerDocument.getElementsByTagName("html")[0];
|
|
215
222
|
}
|
|
216
223
|
|
|
217
|
-
Utils.type(respond.
|
|
224
|
+
Utils.type(respond.session.getDocument(), use, parameters.value.join(''), this.enableNativeEvents);
|
|
218
225
|
|
|
219
226
|
respond.send();
|
|
220
227
|
};
|
|
221
228
|
|
|
222
229
|
|
|
223
|
-
FirefoxDriver.prototype.
|
|
224
|
-
var element = Utils.getElementAt(
|
|
230
|
+
FirefoxDriver.prototype.clearElement = function(respond, parameters) {
|
|
231
|
+
var element = Utils.getElementAt(parameters.id,
|
|
232
|
+
respond.session.getDocument());
|
|
225
233
|
|
|
226
234
|
if (!Utils.isDisplayed(element, true) && !Utils.isInHead(element)) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
"Element is not currently visible and so may not be cleared";
|
|
230
|
-
respond.send();
|
|
231
|
-
return;
|
|
235
|
+
throw new WebDriverError(ErrorCode.ELEMENT_NOT_VISIBLE,
|
|
236
|
+
"Element is not currently visible and so may not be cleared");
|
|
232
237
|
}
|
|
233
238
|
|
|
234
239
|
var isTextField = element["value"] !== undefined;
|
|
235
240
|
|
|
236
|
-
var currentlyActive = Utils.getActiveElement(respond.
|
|
241
|
+
var currentlyActive = Utils.getActiveElement(respond.session.getDocument());
|
|
237
242
|
if (currentlyActive != element) {
|
|
238
243
|
currentlyActive.blur();
|
|
239
244
|
element.focus();
|
|
@@ -253,37 +258,39 @@ FirefoxDriver.prototype.clear = function(respond) {
|
|
|
253
258
|
}
|
|
254
259
|
|
|
255
260
|
if (currentValue !== undefined && currentValue != "") {
|
|
256
|
-
Utils.fireHtmlEvent(
|
|
261
|
+
Utils.fireHtmlEvent(element, "change");
|
|
257
262
|
}
|
|
258
263
|
|
|
259
264
|
respond.send();
|
|
260
265
|
};
|
|
261
266
|
|
|
262
267
|
|
|
263
|
-
FirefoxDriver.prototype.
|
|
264
|
-
var element = Utils.getElementAt(
|
|
268
|
+
FirefoxDriver.prototype.getElementTagName = function(respond, parameters) {
|
|
269
|
+
var element = Utils.getElementAt(parameters.id,
|
|
270
|
+
respond.session.getDocument());
|
|
265
271
|
|
|
266
|
-
respond.
|
|
272
|
+
respond.value = element.tagName.toLowerCase();
|
|
267
273
|
respond.send();
|
|
268
274
|
};
|
|
269
275
|
|
|
270
276
|
|
|
271
|
-
FirefoxDriver.prototype.
|
|
272
|
-
var element = Utils.getElementAt(
|
|
277
|
+
FirefoxDriver.prototype.getElementAttribute = function(respond, parameters) {
|
|
278
|
+
var element = Utils.getElementAt(parameters.id,
|
|
279
|
+
respond.session.getDocument());
|
|
273
280
|
|
|
274
|
-
var attributeName =
|
|
281
|
+
var attributeName = parameters.name;
|
|
275
282
|
|
|
276
283
|
if (element.hasAttribute(attributeName)) {
|
|
277
|
-
respond.
|
|
284
|
+
respond.value = element.getAttribute(attributeName);
|
|
278
285
|
// Is this block necessary?
|
|
279
286
|
if (attributeName.toLowerCase() == "disabled") {
|
|
280
|
-
respond.
|
|
287
|
+
respond.value = element.disabled;
|
|
281
288
|
} else if (attributeName.toLowerCase() == "selected") {
|
|
282
|
-
respond.
|
|
289
|
+
respond.value = element.selected;
|
|
283
290
|
} else if (attributeName.toLowerCase() == "checked") {
|
|
284
|
-
respond.
|
|
291
|
+
respond.value = element.checked;
|
|
285
292
|
} else if (attributeName.toLowerCase() == "readonly") {
|
|
286
|
-
respond.
|
|
293
|
+
respond.value = element.readOnly;
|
|
287
294
|
}
|
|
288
295
|
|
|
289
296
|
respond.send();
|
|
@@ -293,32 +300,41 @@ FirefoxDriver.prototype.getAttribute = function(respond, value) {
|
|
|
293
300
|
attributeName = attributeName.toLowerCase();
|
|
294
301
|
|
|
295
302
|
if (attributeName == "disabled") {
|
|
296
|
-
respond.
|
|
303
|
+
respond.value = (element.disabled === undefined ? false : element.disabled);
|
|
297
304
|
respond.send();
|
|
298
305
|
return;
|
|
299
306
|
} else if ((attributeName == "checked" || attributeName == "selected") &&
|
|
300
307
|
element.tagName.toLowerCase() == "input") {
|
|
301
|
-
respond.
|
|
308
|
+
respond.value = element.checked;
|
|
302
309
|
respond.send();
|
|
303
310
|
return;
|
|
304
311
|
} else if (attributeName == "selected" && element.tagName.toLowerCase()
|
|
305
312
|
== "option") {
|
|
306
|
-
respond.
|
|
313
|
+
respond.value = element.selected;
|
|
307
314
|
respond.send();
|
|
308
315
|
return;
|
|
309
316
|
} else if (attributeName == "index" && element.tagName.toLowerCase()
|
|
310
317
|
== "option") {
|
|
311
|
-
respond.
|
|
318
|
+
respond.value = element.index;
|
|
312
319
|
respond.send();
|
|
313
320
|
return;
|
|
314
321
|
}
|
|
315
|
-
respond.
|
|
322
|
+
respond.value = null;
|
|
316
323
|
respond.send();
|
|
317
324
|
};
|
|
318
325
|
|
|
319
326
|
|
|
320
|
-
FirefoxDriver.prototype.
|
|
321
|
-
var element = Utils.getElementAt(
|
|
327
|
+
FirefoxDriver.prototype.isElementEnabled = function(respond, parameters) {
|
|
328
|
+
var element = Utils.getElementAt(parameters.id,
|
|
329
|
+
respond.session.getDocument());
|
|
330
|
+
respond.value = !!!element.disabled;
|
|
331
|
+
respond.send();
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
FirefoxDriver.prototype.hoverOverElement = function(respond, parameters) {
|
|
336
|
+
var element = Utils.getElementAt(parameters.id,
|
|
337
|
+
respond.session.getDocument());
|
|
322
338
|
|
|
323
339
|
var events = Utils.getNativeEvents();
|
|
324
340
|
var node = Utils.getNodeForNativeEvents(element);
|
|
@@ -333,23 +349,25 @@ FirefoxDriver.prototype.hover = function(respond) {
|
|
|
333
349
|
this.currentX = x;
|
|
334
350
|
this.currentY = y;
|
|
335
351
|
} else {
|
|
336
|
-
|
|
337
|
-
|
|
352
|
+
// TODO: use the correct error type here.
|
|
353
|
+
throw new WebDriverError(ErrorCode.INVALID_ELEMENT_STATE,
|
|
354
|
+
"Unable to hover over element");
|
|
338
355
|
}
|
|
339
356
|
|
|
340
357
|
respond.send();
|
|
341
358
|
};
|
|
342
359
|
|
|
343
|
-
FirefoxDriver.prototype.
|
|
344
|
-
var element = Utils.getElementAt(
|
|
360
|
+
FirefoxDriver.prototype.submitElement = function(respond, parameters) {
|
|
361
|
+
var element = Utils.getElementAt(parameters.id,
|
|
362
|
+
respond.session.getDocument());
|
|
345
363
|
|
|
346
364
|
if (element) {
|
|
347
365
|
while (element.parentNode != null && element.tagName.toLowerCase() != "form") {
|
|
348
366
|
element = element.parentNode;
|
|
349
367
|
}
|
|
350
368
|
if (element.tagName && element.tagName.toLowerCase() == "form") {
|
|
351
|
-
if (Utils.fireHtmlEvent(
|
|
352
|
-
new WebLoadingListener(
|
|
369
|
+
if (Utils.fireHtmlEvent(element, "submit")) {
|
|
370
|
+
new WebLoadingListener(respond.session.getBrowser(), function() {
|
|
353
371
|
respond.send();
|
|
354
372
|
});
|
|
355
373
|
element.submit();
|
|
@@ -360,10 +378,8 @@ FirefoxDriver.prototype.submit = function(respond) {
|
|
|
360
378
|
return;
|
|
361
379
|
}
|
|
362
380
|
} else {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
respond.send();
|
|
366
|
-
return;
|
|
381
|
+
throw new WebDriverError(ErrorCode.INVALID_ELEMENT_STATE,
|
|
382
|
+
"Element was not in a form so couldn't submit");
|
|
367
383
|
}
|
|
368
384
|
} else {
|
|
369
385
|
respond.send();
|
|
@@ -371,8 +387,9 @@ FirefoxDriver.prototype.submit = function(respond) {
|
|
|
371
387
|
}
|
|
372
388
|
};
|
|
373
389
|
|
|
374
|
-
FirefoxDriver.prototype.
|
|
375
|
-
var element = Utils.getElementAt(
|
|
390
|
+
FirefoxDriver.prototype.isElementSelected = function(respond, parameters) {
|
|
391
|
+
var element = Utils.getElementAt(parameters.id,
|
|
392
|
+
respond.session.getDocument());
|
|
376
393
|
|
|
377
394
|
var selected = false;
|
|
378
395
|
|
|
@@ -392,87 +409,87 @@ FirefoxDriver.prototype.isSelected = function(respond) {
|
|
|
392
409
|
} catch(e) {
|
|
393
410
|
}
|
|
394
411
|
|
|
395
|
-
respond.
|
|
412
|
+
respond.value = selected;
|
|
396
413
|
respond.send();
|
|
397
414
|
};
|
|
398
415
|
|
|
399
416
|
|
|
400
|
-
FirefoxDriver.prototype.
|
|
401
|
-
var element = Utils.getElementAt(
|
|
417
|
+
FirefoxDriver.prototype.setElementSelected = function(respond, parameters) {
|
|
418
|
+
var element = Utils.getElementAt(parameters.id,
|
|
419
|
+
respond.session.getDocument());
|
|
402
420
|
|
|
403
421
|
if (!Utils.isDisplayed(element, true) && !Utils.isInHead(element)) {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
"Element is not currently visible and so may not be selected";
|
|
407
|
-
respond.send();
|
|
408
|
-
return;
|
|
422
|
+
throw new WebDriverError(ErrorCode.ELEMENT_NOT_VISIBLE,
|
|
423
|
+
"Element is not currently visible and so may not be selected");
|
|
409
424
|
}
|
|
410
425
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
element.QueryInterface(Components.interfaces.nsIDOMHTMLInputElement);
|
|
417
|
-
if (inputElement.disabled) {
|
|
418
|
-
respond.response = "You may not select a disabled element";
|
|
419
|
-
respond.send();
|
|
420
|
-
return;
|
|
426
|
+
function safeQueryInterface(element, queryFor) {
|
|
427
|
+
try {
|
|
428
|
+
return element.QueryInterface(queryFor);
|
|
429
|
+
} catch (ignored) {
|
|
430
|
+
return null;
|
|
421
431
|
}
|
|
422
|
-
} catch(e) {
|
|
423
432
|
}
|
|
424
433
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
434
|
+
var option = safeQueryInterface(
|
|
435
|
+
element, Components.interfaces.nsIDOMHTMLOptionElement);
|
|
436
|
+
if (option) {
|
|
428
437
|
var select = element;
|
|
429
|
-
while (select.parentNode
|
|
438
|
+
while (select.parentNode && select.tagName.toLowerCase() != 'select') {
|
|
430
439
|
select = select.parentNode;
|
|
431
440
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
441
|
+
select = safeQueryInterface(
|
|
442
|
+
select, Components.interfaces.nsIDOMHTMLSelectElement);
|
|
443
|
+
if (!select) {
|
|
435
444
|
//If we're not within a select element, fire the event from the option, and hope that it bubbles up
|
|
436
445
|
Utils.dumpn("Falling back to event firing from option, not select element");
|
|
437
446
|
select = option;
|
|
438
447
|
}
|
|
439
|
-
|
|
448
|
+
|
|
440
449
|
if (!option.selected) {
|
|
441
450
|
option.selected = true;
|
|
442
|
-
Utils.fireHtmlEvent(
|
|
451
|
+
Utils.fireHtmlEvent(select, 'change');
|
|
443
452
|
}
|
|
444
|
-
|
|
445
|
-
|
|
453
|
+
|
|
454
|
+
respond.status = ErrorCode.SUCCESS;
|
|
455
|
+
respond.value = '';
|
|
456
|
+
respond.send();
|
|
457
|
+
return;
|
|
446
458
|
}
|
|
447
459
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
460
|
+
var inputElement = safeQueryInterface(
|
|
461
|
+
element, Components.interfaces.nsIDOMHTMLInputElement);
|
|
462
|
+
if (inputElement) {
|
|
463
|
+
if (inputElement.disabled) {
|
|
464
|
+
throw new WebDriverError(ErrorCode.INVALID_ELEMENT_STATE,
|
|
465
|
+
"You may not select a disabled element");
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
if (inputElement.type == 'checkbox' || inputElement.type == 'radio') {
|
|
469
|
+
if (!inputElement.checked) {
|
|
470
|
+
inputElement.checked = true;
|
|
471
|
+
Utils.fireHtmlEvent(inputElement, 'change');
|
|
456
472
|
}
|
|
457
|
-
|
|
473
|
+
|
|
474
|
+
respond.status = ErrorCode.SUCCESS;
|
|
475
|
+
respond.value = '';
|
|
476
|
+
respond.send();
|
|
477
|
+
return;
|
|
458
478
|
}
|
|
459
|
-
} catch(e) {
|
|
460
479
|
}
|
|
461
480
|
|
|
462
|
-
|
|
463
|
-
|
|
481
|
+
throw new WebDriverError(ErrorCode.INVALID_ELEMENT_STATE,
|
|
482
|
+
'You may not select an unselectable element');
|
|
464
483
|
};
|
|
465
484
|
|
|
466
485
|
|
|
467
|
-
FirefoxDriver.prototype.
|
|
468
|
-
var element = Utils.getElementAt(
|
|
486
|
+
FirefoxDriver.prototype.toggleElement = function(respond, parameters) {
|
|
487
|
+
var element = Utils.getElementAt(parameters.id,
|
|
488
|
+
respond.session.getDocument());
|
|
469
489
|
|
|
470
490
|
if (!Utils.isDisplayed(element) && !Utils.isInHead(element)) {
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
"Element is not currently visible and so may not be toggled";
|
|
474
|
-
respond.send();
|
|
475
|
-
return;
|
|
491
|
+
throw new WebDriverError(ErrorCode.ELEMENT_NOT_VISIBLE,
|
|
492
|
+
"Element is not currently visible and so may not be toggled");
|
|
476
493
|
}
|
|
477
494
|
|
|
478
495
|
try {
|
|
@@ -480,7 +497,8 @@ FirefoxDriver.prototype.toggle = function(respond) {
|
|
|
480
497
|
element.QueryInterface(Components.interfaces.nsIDOMHTMLInputElement);
|
|
481
498
|
if (checkbox.type == "checkbox") {
|
|
482
499
|
checkbox.checked = !checkbox.checked;
|
|
483
|
-
Utils.fireHtmlEvent(
|
|
500
|
+
Utils.fireHtmlEvent(checkbox, "change");
|
|
501
|
+
respond.value = checkbox.checked;
|
|
484
502
|
respond.send();
|
|
485
503
|
return;
|
|
486
504
|
}
|
|
@@ -499,47 +517,50 @@ FirefoxDriver.prototype.toggle = function(respond) {
|
|
|
499
517
|
|
|
500
518
|
if (select && select.multiple) {
|
|
501
519
|
option.selected = !option.selected;
|
|
502
|
-
Utils.fireHtmlEvent(
|
|
520
|
+
Utils.fireHtmlEvent(option, "change");
|
|
521
|
+
respond.value = option.selected;
|
|
503
522
|
respond.send();
|
|
504
523
|
return;
|
|
505
524
|
}
|
|
506
525
|
} catch(e) {
|
|
507
526
|
}
|
|
508
527
|
|
|
509
|
-
|
|
510
|
-
respond.response =
|
|
528
|
+
throw new WebDriverError(ErrorCode.INVALID_ELEMENT_STATE,
|
|
511
529
|
"You may only toggle an element that is either a checkbox or an " +
|
|
512
|
-
"option in a select that allows multiple selections";
|
|
513
|
-
respond.send();
|
|
530
|
+
"option in a select that allows multiple selections");
|
|
514
531
|
};
|
|
515
532
|
|
|
516
533
|
|
|
517
|
-
FirefoxDriver.prototype.
|
|
518
|
-
var element = Utils.getElementAt(
|
|
519
|
-
|
|
534
|
+
FirefoxDriver.prototype.isElementDisplayed = function(respond, parameters) {
|
|
535
|
+
var element = Utils.getElementAt(parameters.id,
|
|
536
|
+
respond.session.getDocument());
|
|
537
|
+
respond.value = Utils.isDisplayed(element, false);
|
|
520
538
|
respond.send();
|
|
521
539
|
};
|
|
522
540
|
|
|
523
541
|
|
|
524
|
-
FirefoxDriver.prototype.
|
|
525
|
-
var element = Utils.getElementAt(
|
|
542
|
+
FirefoxDriver.prototype.getElementLocation = function(respond, parameters) {
|
|
543
|
+
var element = Utils.getElementAt(parameters.id,
|
|
544
|
+
respond.session.getDocument());
|
|
526
545
|
|
|
527
|
-
var location = Utils.getElementLocation(element
|
|
546
|
+
var location = Utils.getElementLocation(element);
|
|
528
547
|
|
|
529
|
-
respond.
|
|
548
|
+
respond.value = {
|
|
530
549
|
x: Math.round(location.x),
|
|
531
550
|
y: Math.round(location.y)
|
|
532
551
|
};
|
|
552
|
+
|
|
533
553
|
respond.send();
|
|
534
554
|
};
|
|
535
555
|
|
|
536
556
|
|
|
537
|
-
FirefoxDriver.prototype.
|
|
538
|
-
var element = Utils.getElementAt(
|
|
557
|
+
FirefoxDriver.prototype.getElementSize = function(respond, parameters) {
|
|
558
|
+
var element = Utils.getElementAt(parameters.id,
|
|
559
|
+
respond.session.getDocument());
|
|
539
560
|
|
|
540
561
|
var box = Utils.getLocationOnceScrolledIntoView(element);
|
|
541
562
|
|
|
542
|
-
respond.
|
|
563
|
+
respond.value = {
|
|
543
564
|
width: Math.round(box.width),
|
|
544
565
|
height: Math.round(box.height)
|
|
545
566
|
};
|
|
@@ -547,27 +568,26 @@ FirefoxDriver.prototype.getSize = function(respond) {
|
|
|
547
568
|
};
|
|
548
569
|
|
|
549
570
|
|
|
550
|
-
FirefoxDriver.prototype.dragElement = function(respond,
|
|
551
|
-
var element = Utils.getElementAt(
|
|
571
|
+
FirefoxDriver.prototype.dragElement = function(respond, parameters) {
|
|
572
|
+
var element = Utils.getElementAt(parameters.id,
|
|
573
|
+
respond.session.getDocument());
|
|
552
574
|
|
|
553
575
|
if (!Utils.isDisplayed(element, true) && !Utils.isInHead(element)) {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
respond.send();
|
|
558
|
-
return;
|
|
576
|
+
throw new WebDriverError(ErrorCode.ELEMENT_NOT_VISIBLE,
|
|
577
|
+
"Element is not currently visible and so may not be used for " +
|
|
578
|
+
"drag and drop");
|
|
559
579
|
}
|
|
560
580
|
|
|
561
581
|
// Scroll the first element into view
|
|
562
582
|
// element.scrollIntoView(true);
|
|
563
583
|
|
|
564
|
-
var clientStartXY = Utils.getElementLocation(element
|
|
584
|
+
var clientStartXY = Utils.getElementLocation(element);
|
|
565
585
|
|
|
566
586
|
var clientStartX = clientStartXY.x;
|
|
567
587
|
var clientStartY = clientStartXY.y;
|
|
568
588
|
|
|
569
|
-
var movementX =
|
|
570
|
-
var movementY =
|
|
589
|
+
var movementX = parameters.x;
|
|
590
|
+
var movementY = parameters.y;
|
|
571
591
|
|
|
572
592
|
var clientFinishX = ((clientStartX + movementX) < 0) ? 0 : (clientStartX
|
|
573
593
|
+ movementX);
|
|
@@ -582,7 +602,7 @@ FirefoxDriver.prototype.dragElement = function(respond, movementString) {
|
|
|
582
602
|
if (clientFinishY > body.scrollHeight)
|
|
583
603
|
clientFinishY = body.scrollHeight;
|
|
584
604
|
|
|
585
|
-
var mouseSpeed =
|
|
605
|
+
var mouseSpeed = respond.session.getInputSpeed();
|
|
586
606
|
var move = function(current, dest) {
|
|
587
607
|
if (current == dest) return current;
|
|
588
608
|
if (Math.abs(current - dest) < mouseSpeed) return dest;
|
|
@@ -607,27 +627,29 @@ FirefoxDriver.prototype.dragElement = function(respond, movementString) {
|
|
|
607
627
|
// send the mouseup to that
|
|
608
628
|
Utils.triggerMouseEvent(element, 'mouseup', clientFinishX, clientFinishY);
|
|
609
629
|
|
|
610
|
-
var finalLoc = Utils.getElementLocation(element
|
|
630
|
+
var finalLoc = Utils.getElementLocation(element);
|
|
611
631
|
|
|
612
|
-
respond.
|
|
632
|
+
respond.value = finalLoc.x + "," + finalLoc.y;
|
|
613
633
|
respond.send();
|
|
614
634
|
};
|
|
615
635
|
|
|
616
636
|
|
|
617
|
-
FirefoxDriver.prototype.
|
|
618
|
-
|
|
619
|
-
var element = Utils.getElementAt(
|
|
620
|
-
|
|
621
|
-
respond.
|
|
637
|
+
FirefoxDriver.prototype.getElementValueOfCssProperty = function(respond,
|
|
638
|
+
parameters) {
|
|
639
|
+
var element = Utils.getElementAt(parameters.id,
|
|
640
|
+
respond.session.getDocument());
|
|
641
|
+
respond.value = Utils.getStyleProperty(element, parameters.propertyName); // Coeerce to a string
|
|
622
642
|
respond.send();
|
|
623
643
|
};
|
|
624
644
|
|
|
625
645
|
|
|
626
|
-
FirefoxDriver.prototype.
|
|
627
|
-
|
|
646
|
+
FirefoxDriver.prototype.getElementLocationOnceScrolledIntoView = function(
|
|
647
|
+
respond, parameters) {
|
|
648
|
+
var element = Utils.getElementAt(parameters.id,
|
|
649
|
+
respond.session.getDocument());
|
|
628
650
|
|
|
629
651
|
if (!Utils.isDisplayed(element, true)) {
|
|
630
|
-
respond.
|
|
652
|
+
respond.value = undefined;
|
|
631
653
|
respond.send();
|
|
632
654
|
return;
|
|
633
655
|
}
|
|
@@ -644,7 +666,7 @@ FirefoxDriver.prototype.getLocationOnceScrolledIntoView = function(respond) {
|
|
|
644
666
|
var x = {}, y = {}, width = {}, height = {};
|
|
645
667
|
accessible.getBounds(x, y, width, height);
|
|
646
668
|
|
|
647
|
-
respond.
|
|
669
|
+
respond.value = {
|
|
648
670
|
x : x.value,
|
|
649
671
|
y : y.value
|
|
650
672
|
};
|
|
@@ -655,6 +677,7 @@ FirefoxDriver.prototype.getLocationOnceScrolledIntoView = function(respond) {
|
|
|
655
677
|
}
|
|
656
678
|
|
|
657
679
|
// If we have the box object (which is deprecated) we could try using it
|
|
680
|
+
var theDoc = respond.session.getDocument();
|
|
658
681
|
if (theDoc.getBoxObjectFor) {
|
|
659
682
|
// Fallback. Use the (deprecated) method to find out where the element is in
|
|
660
683
|
// the viewport. This should be fine to use because we only fall down this
|
|
@@ -662,7 +685,7 @@ FirefoxDriver.prototype.getLocationOnceScrolledIntoView = function(respond) {
|
|
|
662
685
|
|
|
663
686
|
var box = theDoc.getBoxObjectFor(element);
|
|
664
687
|
|
|
665
|
-
respond.
|
|
688
|
+
respond.value = {
|
|
666
689
|
x : box.screenX,
|
|
667
690
|
y : box.screenY
|
|
668
691
|
};
|
|
@@ -675,7 +698,7 @@ FirefoxDriver.prototype.getLocationOnceScrolledIntoView = function(respond) {
|
|
|
675
698
|
var y = theDoc.defaultView.screenY;
|
|
676
699
|
|
|
677
700
|
var rect = element.getBoundingClientRect()
|
|
678
|
-
respond.
|
|
701
|
+
respond.value = {
|
|
679
702
|
x : x + rect.left,
|
|
680
703
|
y : y + rect.top
|
|
681
704
|
}
|