selenium-webdriver 0.0.18 → 0.0.19
Sign up to get free protection for your applications and to get access to all the features.
- data/chrome/src/extension/background.js +19 -1
- data/chrome/src/extension/content_script.js +97 -51
- data/chrome/src/extension/manifest-nonwin.json +1 -1
- data/chrome/src/extension/manifest-win.json +1 -1
- data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +6 -2
- data/chrome/src/rb/lib/selenium/webdriver/chrome/launcher.rb +2 -0
- data/common/src/js/core/scripts/selenium-version.js +1 -1
- data/common/src/rb/CHANGES +11 -0
- data/common/src/rb/lib/selenium/webdriver.rb +2 -0
- data/common/src/rb/lib/selenium/webdriver/file_reaper.rb +31 -0
- data/common/src/rb/lib/selenium/webdriver/options.rb +4 -0
- data/common/src/rb/lib/selenium/webdriver/platform.rb +34 -19
- data/common/src/rb/lib/selenium/webdriver/timeouts.rb +19 -0
- data/firefox/prebuilt/Win32/Release/webdriver-firefox.dll +0 -0
- data/firefox/prebuilt/linux/Release/libwebdriver-firefox.so +0 -0
- data/firefox/prebuilt/linux/Release/x_ignore_nofocus.so +0 -0
- data/firefox/prebuilt/linux64/Release/libwebdriver-firefox.so +0 -0
- data/firefox/prebuilt/linux64/Release/x_ignore_nofocus.so +0 -0
- data/firefox/src/extension/components/badCertListener.js +2 -1
- data/firefox/src/extension/components/dispatcher.js +3 -0
- data/firefox/src/extension/components/firefoxDriver.js +51 -9
- data/firefox/src/extension/components/session.js +33 -0
- data/firefox/src/extension/components/utils.js +4 -0
- data/firefox/src/extension/install.rdf +1 -1
- data/firefox/src/rb/lib/selenium/webdriver/firefox.rb +7 -6
- data/firefox/src/rb/lib/selenium/webdriver/firefox/launcher.rb +1 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +18 -4
- 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 +4 -2
- data/jobbie/src/rb/lib/selenium/webdriver/ie/bridge.rb +5 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie/lib.rb +7 -2
- data/remote/client/src/rb/lib/selenium/webdriver/remote/bridge.rb +8 -5
- data/remote/client/src/rb/lib/selenium/webdriver/remote/commands.rb +1 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/default_http_client.rb +15 -5
- metadata +271 -266
@@ -180,6 +180,19 @@ ChromeDriver.timeoutUntilGiveUpOnContentScriptLoading = 5000;
|
|
180
180
|
*/
|
181
181
|
ChromeDriver.currentlyWaitingUntilGiveUpOnContentScriptLoading;
|
182
182
|
|
183
|
+
/**
|
184
|
+
* The amount of time, in milliseconds, to wait for an element to be located
|
185
|
+
* when performing a search.
|
186
|
+
* When searching for a single element, the driver will wait up to this amount
|
187
|
+
* of time for the element to be located before returning an error.
|
188
|
+
* When searching for multiple elements, the driver will wait up to this amount
|
189
|
+
* of time for at least one element to be located before returning an empty
|
190
|
+
* list.
|
191
|
+
* @type {number}
|
192
|
+
* @private
|
193
|
+
*/
|
194
|
+
ChromeDriver.implicitWait_ = 0;
|
195
|
+
|
183
196
|
//Set ChromeDriver.currentlyWaitingUntilGiveUpOnContentScriptLoading;
|
184
197
|
resetCurrentlyWaitingOnContentScriptTime();
|
185
198
|
|
@@ -488,6 +501,10 @@ function parseRequest(request) {
|
|
488
501
|
case "screenshot":
|
489
502
|
getScreenshot();
|
490
503
|
break;
|
504
|
+
case "implicitlyWait":
|
505
|
+
ChromeDriver.implicitWait_ = request.ms || 0;
|
506
|
+
sendResponseToParsedRequest({status: 0});
|
507
|
+
break;
|
491
508
|
case "clickElement":
|
492
509
|
case "hoverOverElement":
|
493
510
|
// Falling through, as native events are handled the same
|
@@ -547,7 +564,8 @@ function parseRequest(request) {
|
|
547
564
|
ChromeDriver.requestSequenceNumber++;
|
548
565
|
sendMessageOnActivePortAndAlsoKeepTrackOfIt({
|
549
566
|
request: request,
|
550
|
-
sequenceNumber: sequenceNumber
|
567
|
+
sequenceNumber: sequenceNumber,
|
568
|
+
implicitWait: ChromeDriver.implicitWait_
|
551
569
|
});
|
552
570
|
break;
|
553
571
|
}
|
@@ -114,21 +114,12 @@ function parsePortMessage(message) {
|
|
114
114
|
response.wait = false;
|
115
115
|
break;
|
116
116
|
case "findChildElement":
|
117
|
-
response.value = getElement(false, message.request.using, message.request.value, message.request.id);
|
118
|
-
response.wait = false;
|
119
|
-
break;
|
120
117
|
case "findChildElements":
|
121
|
-
response.value = getElement(true, message.request.using, message.request.value, message.request.id);
|
122
|
-
response.wait = false;
|
123
|
-
break;
|
124
118
|
case "findElement":
|
125
|
-
response.value = getElement(false, message.request.using, message.request.value);
|
126
|
-
response.wait = false;
|
127
|
-
break;
|
128
119
|
case "findElements":
|
129
|
-
response.value = getElement(true, message.request.using, message.request.value);
|
130
120
|
response.wait = false;
|
131
|
-
|
121
|
+
findElement(message, response);
|
122
|
+
return; // Nothing more to do.
|
132
123
|
case "getElementAttribute":
|
133
124
|
response.value = getElementAttribute(element, message.request.name);
|
134
125
|
response.wait = false;
|
@@ -419,22 +410,95 @@ function setCookie(cookie) {
|
|
419
410
|
}
|
420
411
|
}
|
421
412
|
|
413
|
+
/**
|
414
|
+
* Responds to a request to find an element on the page.
|
415
|
+
* @param {Object} message The request from the background page.
|
416
|
+
* @param {Object} resp The response to send when the search has completed.
|
417
|
+
*/
|
418
|
+
function findElement(message, resp) {
|
419
|
+
var req = message.request;
|
420
|
+
var startTime = new Date().getTime();
|
421
|
+
var plural = req.request == 'findChildElements' ||
|
422
|
+
req.request == 'findElements';
|
423
|
+
var wait = message.implicitWait;
|
424
|
+
|
425
|
+
function send(response) {
|
426
|
+
ChromeDriverContentScript.port.postMessage({
|
427
|
+
response: response,
|
428
|
+
sequenceNumber: message.sequenceNumber
|
429
|
+
});
|
430
|
+
console.log("Sent response: " + JSON.stringify(response) +
|
431
|
+
" (seq:" + message.sequenceNumber + ")");
|
432
|
+
}
|
433
|
+
|
434
|
+
function doSearch() {
|
435
|
+
var found;
|
436
|
+
try {
|
437
|
+
found = getElement(req.using, req.value, req.id);
|
438
|
+
} catch (ex) {
|
439
|
+
console.error('Caught exception; sending error response', ex);
|
440
|
+
send({
|
441
|
+
statusCode: 13,
|
442
|
+
value: {
|
443
|
+
message: "An unexpected error occured while executing " +
|
444
|
+
req.request + ", exception dump: " + ex
|
445
|
+
}
|
446
|
+
});
|
447
|
+
}
|
448
|
+
|
449
|
+
var done = !wait || found.length;
|
450
|
+
if (done) {
|
451
|
+
if (!plural && !found.length) {
|
452
|
+
resp.value = {
|
453
|
+
statusCode: 7,
|
454
|
+
value: {
|
455
|
+
message: 'After ' + (new Date().getTime() - startTime) + 'ms, ' +
|
456
|
+
'unable to find element with ' +
|
457
|
+
req.using + ' ' + req.value
|
458
|
+
}
|
459
|
+
};
|
460
|
+
} else {
|
461
|
+
resp.value = {
|
462
|
+
statusCode: 0,
|
463
|
+
value: (plural ? found : found[0])
|
464
|
+
};
|
465
|
+
}
|
466
|
+
send(resp);
|
467
|
+
} else if (new Date().getTime() - startTime > wait) {
|
468
|
+
if (plural) {
|
469
|
+
resp.value = {statusCode: 0, value: []};
|
470
|
+
} else {
|
471
|
+
resp.value = {
|
472
|
+
statusCode: 7,
|
473
|
+
value: {
|
474
|
+
message: 'Unable to find element with ' +
|
475
|
+
req.using + ' ' + req.value
|
476
|
+
}
|
477
|
+
};
|
478
|
+
}
|
479
|
+
send(resp);
|
480
|
+
} else {
|
481
|
+
setTimeout(doSearch, 100);
|
482
|
+
}
|
483
|
+
}
|
484
|
+
|
485
|
+
doSearch();
|
486
|
+
}
|
487
|
+
|
488
|
+
|
422
489
|
/**
|
423
490
|
* Get an element, or a set of elements, by some lookup
|
424
|
-
*
|
425
|
-
* @param
|
426
|
-
* @param
|
427
|
-
*
|
491
|
+
* @param {string} lookupBy The lookup strategy to use.
|
492
|
+
* @param {string} lookupValue What to lookup.
|
493
|
+
* @param {string} id Internal ID of the parent element to restrict the lookup
|
494
|
+
* to.
|
495
|
+
* @return {Array} An array of the elements matching the search criteria.
|
428
496
|
*/
|
429
|
-
function getElement(
|
497
|
+
function getElement(lookupBy, lookupValue, id) {
|
430
498
|
var root = "";
|
431
499
|
var parent = null;
|
432
500
|
if (id !== undefined && id != null) {
|
433
|
-
|
434
|
-
parent = internalGetElement(id);
|
435
|
-
} catch (e) {
|
436
|
-
return e;
|
437
|
-
}
|
501
|
+
parent = internalGetElement(id);
|
438
502
|
//Looking for children
|
439
503
|
root = getXPathOfElement(parent);
|
440
504
|
} else {
|
@@ -483,38 +547,20 @@ function getElement(plural, lookupBy, lookupValue, id) {
|
|
483
547
|
if (attribute != '') {
|
484
548
|
elements = getElementsByXPath(root + "//*[@" + attribute + "='" + lookupValue + "']");
|
485
549
|
}
|
550
|
+
|
486
551
|
if (elements == null || elements.length == 0) {
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
if (plural) {
|
498
|
-
toReturn = [];
|
499
|
-
//Add all found elements to the page's elements, and push each to the array to return
|
500
|
-
var addedElements = addElementsToInternalArray(elements);
|
501
|
-
for (var addedElement in addedElements) {
|
502
|
-
toReturn.push({
|
503
|
-
'ELEMENT': addedElements[addedElement].toString()
|
504
|
-
});
|
505
|
-
}
|
506
|
-
} else {
|
507
|
-
if (!elements[0]) {
|
508
|
-
return {statusCode: 7, value: {
|
509
|
-
message: "Unable to find element with " + lookupBy + " " + lookupValue}};
|
510
|
-
}
|
511
|
-
//Add the first found elements to the page's elements, and push it to the array to return
|
512
|
-
toReturn = {
|
513
|
-
'ELEMENT': addElementToInternalArray(elements[0]).toString()
|
514
|
-
};
|
515
|
-
}
|
516
|
-
return {statusCode: 0, value: toReturn};
|
552
|
+
return [];
|
553
|
+
}
|
554
|
+
|
555
|
+
var toReturn = [];
|
556
|
+
//Add all found elements to the page's elements, and push each to the array to return
|
557
|
+
var addedElements = addElementsToInternalArray(elements);
|
558
|
+
for (var addedElement in addedElements) {
|
559
|
+
toReturn.push({
|
560
|
+
'ELEMENT': addedElements[addedElement].toString()
|
561
|
+
});
|
517
562
|
}
|
563
|
+
return toReturn;
|
518
564
|
}
|
519
565
|
|
520
566
|
/**
|
@@ -47,11 +47,11 @@ module Selenium
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def findElementByCssSelector(parent, selector)
|
50
|
-
find_element_by 'css
|
50
|
+
find_element_by 'css', selector, parent
|
51
51
|
end
|
52
52
|
|
53
53
|
def findElementsByCssSelector(parent, selector)
|
54
|
-
find_elements_by 'css
|
54
|
+
find_elements_by 'css', selector, parent
|
55
55
|
end
|
56
56
|
|
57
57
|
def getAllCookies
|
@@ -62,6 +62,10 @@ module Selenium
|
|
62
62
|
execute :deleteCookie, :name => name
|
63
63
|
end
|
64
64
|
|
65
|
+
def setImplicitWaitTimeout(milliseconds)
|
66
|
+
execute :implicitlyWait, :ms => milliseconds
|
67
|
+
end
|
68
|
+
|
65
69
|
private
|
66
70
|
|
67
71
|
def execute(command_name, opts = {}, args = nil)
|
@@ -83,6 +83,7 @@ module Selenium
|
|
83
83
|
@tmp_extension_dir ||= begin
|
84
84
|
dir = Dir.mktmpdir("webdriver-chrome-extension")
|
85
85
|
Platform.make_writable(dir)
|
86
|
+
FileReaper << dir
|
86
87
|
|
87
88
|
dir
|
88
89
|
end
|
@@ -92,6 +93,7 @@ module Selenium
|
|
92
93
|
@tmp_profile_dir ||= begin
|
93
94
|
dir = Dir.mktmpdir("webdriver-chrome-profile")
|
94
95
|
Platform.make_writable(dir)
|
96
|
+
FileReaper << dir
|
95
97
|
|
96
98
|
dir
|
97
99
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
2010-05-31
|
2
|
+
==========
|
3
|
+
|
4
|
+
* Add a max redirect check to the remote driver
|
5
|
+
* Add Firefox::Profile#assume_untrusted_certificate_issuer=
|
6
|
+
* Add implicit waits (Selenium::WebDriver::Timeouts)
|
7
|
+
* at_exit hook to clean temporary profiles
|
8
|
+
* Fix for Errno::ECONNABORTED errors on Windows
|
9
|
+
* Fix issue where Firefox::Profile#secure_ssl= would have no effect
|
10
|
+
* Fix issue where locating elements by :css would fail in the Chrome driver.
|
11
|
+
* IE driver now works on 64-bit rubies.
|
@@ -38,8 +38,10 @@ require "selenium/webdriver/core_ext/string"
|
|
38
38
|
require "selenium/webdriver/error"
|
39
39
|
require "selenium/webdriver/platform"
|
40
40
|
require "selenium/webdriver/child_process"
|
41
|
+
require "selenium/webdriver/file_reaper"
|
41
42
|
require "selenium/webdriver/target_locator"
|
42
43
|
require "selenium/webdriver/navigation"
|
44
|
+
require "selenium/webdriver/timeouts"
|
43
45
|
require "selenium/webdriver/options"
|
44
46
|
require "selenium/webdriver/find"
|
45
47
|
require "selenium/webdriver/driver_extensions/takes_screenshot"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Selenium
|
2
|
+
module WebDriver
|
3
|
+
module FileReaper
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def reap=(bool)
|
7
|
+
@reap = bool
|
8
|
+
end
|
9
|
+
|
10
|
+
def reap?
|
11
|
+
@reap.nil? || @reap
|
12
|
+
end
|
13
|
+
|
14
|
+
def tmp_files
|
15
|
+
@tmp_files ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
def <<(file)
|
19
|
+
tmp_files << file
|
20
|
+
end
|
21
|
+
|
22
|
+
def reap!
|
23
|
+
tmp_files.each { |file| FileUtils.rm_rf(file) } if reap?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
at_exit { reap! }
|
28
|
+
|
29
|
+
end # FileReaper
|
30
|
+
end # WebDriver
|
31
|
+
end # Selenium
|
@@ -10,35 +10,49 @@ module Selenium
|
|
10
10
|
|
11
11
|
def home
|
12
12
|
# jruby has an issue with ENV['HOME'] on Windows
|
13
|
-
@home ||=
|
13
|
+
@home ||= jruby? ? ENV_JAVA['user.home'] : ENV['HOME']
|
14
14
|
end
|
15
15
|
|
16
16
|
def platform
|
17
|
-
@platform ||=
|
17
|
+
@platform ||= (
|
18
18
|
if defined? RUBY_ENGINE
|
19
19
|
RUBY_ENGINE.to_sym
|
20
20
|
else
|
21
21
|
:ruby
|
22
22
|
end
|
23
|
-
|
23
|
+
)
|
24
24
|
end
|
25
25
|
|
26
26
|
def os
|
27
|
-
@os ||=
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
27
|
+
@os ||= (
|
28
|
+
host_os = RbConfig::CONFIG['host_os']
|
29
|
+
case host_os
|
30
|
+
when /mswin|msys|mingw32/
|
31
|
+
:windows
|
32
|
+
when /darwin|mac os/
|
33
|
+
:macosx
|
34
|
+
when /linux/
|
35
|
+
:linux
|
36
|
+
when /solaris|bsd/
|
37
|
+
:unix
|
38
|
+
else
|
39
|
+
raise Error::WebDriverError, "unknown os: #{host_os.inspect}"
|
40
|
+
end
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def bitsize
|
45
|
+
@bitsize ||= (
|
46
|
+
if defined?(FFI::BITSIZE)
|
47
|
+
FFI::BITSIZE
|
48
|
+
elsif defined?(FFI)
|
49
|
+
FFI.type_size :pointer
|
50
|
+
elsif jruby?
|
51
|
+
Integer(ENV_JAVA['sun.arch.data.model'])
|
52
|
+
else
|
53
|
+
1.size == 4 ? 32 : 64
|
54
|
+
end
|
55
|
+
)
|
42
56
|
end
|
43
57
|
|
44
58
|
def jruby?
|
@@ -98,5 +112,6 @@ if __FILE__ == $0
|
|
98
112
|
:ruby19? => Selenium::WebDriver::Platform.ruby19?,
|
99
113
|
:jruby? => Selenium::WebDriver::Platform.jruby?,
|
100
114
|
:win? => Selenium::WebDriver::Platform.win?,
|
101
|
-
:home => Selenium::WebDriver::Platform.home
|
115
|
+
:home => Selenium::WebDriver::Platform.home,
|
116
|
+
:bitsize => Selenium::WebDriver::Platform.bitsize
|
102
117
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Selenium
|
2
|
+
module WebDriver
|
3
|
+
class Timeouts
|
4
|
+
|
5
|
+
def initialize(bridge)
|
6
|
+
@bridge = bridge
|
7
|
+
end
|
8
|
+
|
9
|
+
#
|
10
|
+
# Set the amount of time the driver should wait when searching for elements.
|
11
|
+
#
|
12
|
+
|
13
|
+
def implicit_wait=(seconds)
|
14
|
+
@bridge.setImplicitWaitTimeout seconds * 1000
|
15
|
+
end
|
16
|
+
|
17
|
+
end # Timeouts
|
18
|
+
end # WebDriver
|
19
|
+
end # Selenium
|