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