watir 1.4.1 → 1.5.2
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/bin/watir-console +1 -0
- data/changes.rb +119 -0
- data/license.rb +37 -0
- data/readme.rb +55 -120
- data/unittests/buttons_test.rb +107 -104
- data/unittests/buttons_xpath_test.rb +69 -0
- data/unittests/checkbox_test.rb +154 -141
- data/unittests/checkbox_xpath_test.rb +107 -0
- data/unittests/core_tests.rb +6 -2
- data/unittests/css_test.rb +50 -50
- data/unittests/defer_test.rb +47 -0
- data/unittests/dialog_test.rb +78 -0
- data/unittests/div2_xpath_test.rb +22 -0
- data/unittests/div_test.rb +159 -159
- data/unittests/div_xpath_test.rb +96 -0
- data/unittests/errorchecker_test.rb +22 -22
- data/unittests/filefield_test.rb +30 -23
- data/unittests/filefield_xpath_test.rb +35 -0
- data/unittests/form_test.rb +250 -229
- data/unittests/form_xpath_test.rb +253 -0
- data/unittests/frame_test.rb +123 -108
- data/unittests/google_form_test.rb +17 -0
- data/unittests/html/JavascriptClick.html +39 -0
- data/unittests/html/buttons1.html +3 -2
- data/unittests/html/checkboxes1.html +32 -14
- data/unittests/html/complex_table.html +1 -1
- data/unittests/html/depot_store.html +59 -0
- data/unittests/html/div.html +3 -21
- data/unittests/html/div_xml.html +21 -0
- data/unittests/html/fileupload.html +2 -2
- data/unittests/html/forms2.html +3 -3
- data/unittests/html/forms3.html +2 -2
- data/unittests/html/frame_links.html +2 -2
- data/unittests/html/google_india.html +119 -0
- data/unittests/html/iframeTest.html +2 -2
- data/unittests/html/images/map.GIF +0 -0
- data/unittests/html/images/map2.gif +0 -0
- data/unittests/html/images1.html +17 -2
- data/unittests/html/javascriptevents.html +3 -7
- data/unittests/html/links1.html +9 -8
- data/unittests/html/links_multi.html +14 -0
- data/unittests/html/list_matters.html +720 -0
- data/unittests/html/lists.html +18 -0
- data/unittests/html/map_test.html +31 -0
- data/unittests/html/modal_dialog.html +10 -0
- data/unittests/html/modal_dialog_launcher.html +12 -0
- data/unittests/html/new_browser.html +17 -0
- data/unittests/html/pass.html +3 -0
- data/unittests/html/popups1.html +1 -1
- data/unittests/html/pre.html +28 -0
- data/unittests/html/radioButtons1.html +6 -5
- data/unittests/html/selectboxes1.html +12 -11
- data/unittests/html/simple_table.html +1 -1
- data/unittests/html/simple_table_columns.html +1 -1
- data/unittests/html/table1.html +1 -1
- data/unittests/html/tableCell_using_xpath.html +19 -0
- data/unittests/html/textfields1.html +6 -4
- data/unittests/html/xpath_nbsp.html +12 -0
- data/unittests/ie_exists_test.rb +32 -0
- data/unittests/ie_mock.rb +78 -79
- data/unittests/ie_test.rb +39 -39
- data/unittests/images_test.rb +132 -155
- data/unittests/images_xpath_test.rb +91 -0
- data/unittests/links_multi_test.rb +36 -0
- data/unittests/links_test.rb +158 -152
- data/unittests/links_xpath_test.rb +40 -0
- data/unittests/lists_test.rb +29 -0
- data/unittests/map_test.rb +99 -0
- data/unittests/minmax_test.rb +23 -23
- data/unittests/navigate_test.rb +43 -51
- data/unittests/nbsp_xpath_test.rb +18 -0
- data/unittests/other/WindowLogonExample.rb +28 -0
- data/unittests/{WindowLogonExtra.rb → other/WindowLogonExtra.rb} +0 -0
- data/unittests/{all_tests_concurrent.rb → other/all_tests_concurrent.rb} +23 -23
- data/unittests/other/navigate_exception_test.rb +14 -0
- data/unittests/other/rexml_unit_test.rb +24 -0
- data/unittests/other/testcase_method_order_test.rb +36 -0
- data/unittests/other/testcase_verify_test.rb +25 -0
- data/unittests/other/wait_until_test.rb +99 -0
- data/unittests/pagecontainstext_test.rb +56 -37
- data/unittests/parent_child_test.rb +55 -0
- data/unittests/popups_test.rb +37 -37
- data/unittests/pre_test.rb +52 -0
- data/unittests/radios_test.rb +186 -155
- data/unittests/radios_xpath_test.rb +101 -0
- data/unittests/screen_capture_test.rb +41 -41
- data/unittests/selectbox_test.rb +223 -181
- data/unittests/selectbox_xpath_test.rb +113 -0
- data/unittests/setup.rb +29 -25
- data/unittests/speed_settings_test.rb +22 -0
- data/unittests/table_cell_using_xpath_test.rb +40 -0
- data/unittests/table_test.rb +315 -284
- data/unittests/table_xpath_test.rb +114 -0
- data/unittests/textarea_test.rb +81 -0
- data/unittests/textarea_xpath_test.rb +82 -0
- data/unittests/textfields_test.rb +205 -229
- data/unittests/textfields_xpath_test.rb +111 -0
- data/unittests/window_tests.rb +7 -0
- data/unittests/windows/attach_to_existing_window_test.rb +52 -0
- data/unittests/windows/attach_to_new_window_test.rb +82 -0
- data/unittests/windows/close_window_test.rb +22 -0
- data/unittests/windows/frame_links_test.rb +25 -0
- data/unittests/windows/ie-each_test.rb +48 -0
- data/unittests/windows/iedialog_test.rb +55 -0
- data/unittests/windows/js_events_test.rb +57 -0
- data/unittests/windows/jscriptExtraAlert.rb +6 -0
- data/unittests/windows/jscriptExtraConfirmCancel.rb +7 -0
- data/unittests/windows/jscriptExtraConfirmOk.rb +7 -0
- data/unittests/{jscriptPushButton.rb → windows/jscriptPushButton.rb} +1 -1
- data/unittests/windows/jscript_test.rb +64 -0
- data/unittests/windows/modal_dialog_test.rb +127 -0
- data/unittests/windows/new.rb +56 -0
- data/unittests/windows/open_close_test.rb +22 -0
- data/unittests/windows/send_keys_test.rb +34 -0
- data/unittests/xpath_tests.rb +10 -0
- data/watir.rb +4344 -3565
- data/watir/IEDialog/Release/IEDialog.dll +0 -0
- data/watir/WindowHelper.rb +13 -11
- data/watir/assertions.rb +36 -0
- data/watir/camel_case.rb +14 -5
- data/watir/close_all.rb +38 -0
- data/watir/contrib/enabled_popup.rb +21 -0
- data/watir/contrib/ie-new-process.rb +27 -0
- data/watir/contrib/page_checker.rb +29 -0
- data/watir/contrib/visible.rb +47 -0
- data/watir/cookiemanager.rb +4 -4
- data/watir/datahandler.rb +107 -0
- data/watir/dialog.rb +46 -0
- data/watir/elements.rb +65 -0
- data/watir/exceptions.rb +18 -36
- data/watir/ie-process.rb +40 -0
- data/watir/irb-history.rb +31 -0
- data/watir/process.rb +20 -0
- data/watir/testUnitAddons.rb +3 -42
- data/watir/testcase.rb +58 -0
- data/watir/utils.rb +20 -0
- data/watir/waiter.rb +88 -0
- data/watir/watir_simple.rb +4 -4
- data/watir/win32ole.rb +8 -0
- data/watir/win32ole/win32ole.so +0 -0
- data/watir/winClicker.rb +374 -400
- metadata +209 -128
- data/unittests/WindowLogonExample.rb +0 -30
- data/unittests/attachToExistingWindow_test.rb +0 -40
- data/unittests/js_events_test.rb +0 -77
- data/unittests/jscriptExtraAlert.rb +0 -6
- data/unittests/jscriptExtraConfirmCancel.rb +0 -7
- data/unittests/jscriptExtraConfirmOk.rb +0 -7
- data/unittests/jscript_test.rb +0 -57
- data/unittests/send_keys_test.rb +0 -29
- data/unittests/textAreafields_test.rb +0 -81
data/watir/elements.rb
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Watir
|
|
2
|
+
class Ul < NonControlElement
|
|
3
|
+
TAG = 'UL'
|
|
4
|
+
end
|
|
5
|
+
module Container
|
|
6
|
+
def ul(how, what)
|
|
7
|
+
return Ul.new(self, how, what)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class H1 < NonControlElement
|
|
12
|
+
TAG = 'H1'
|
|
13
|
+
end
|
|
14
|
+
module Container
|
|
15
|
+
def h1(how, what)
|
|
16
|
+
return H1.new(self, how, what)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class H2 < NonControlElement
|
|
21
|
+
TAG = 'H2'
|
|
22
|
+
end
|
|
23
|
+
module Container
|
|
24
|
+
def h2(how, what)
|
|
25
|
+
return H2.new(self, how, what)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class H3 < NonControlElement
|
|
30
|
+
TAG = 'H3'
|
|
31
|
+
end
|
|
32
|
+
module Container
|
|
33
|
+
def h3(how, what)
|
|
34
|
+
return H3.new(self, how, what)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class H4 < NonControlElement
|
|
39
|
+
TAG = 'H4'
|
|
40
|
+
end
|
|
41
|
+
module Container
|
|
42
|
+
def h4(how, what)
|
|
43
|
+
return H4.new(self, how, what)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
class H5 < NonControlElement
|
|
48
|
+
TAG = 'H5'
|
|
49
|
+
end
|
|
50
|
+
module Container
|
|
51
|
+
def h5(how, what)
|
|
52
|
+
return H5.new(self, how, what)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
class H6 < NonControlElement
|
|
56
|
+
TAG = 'H6'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
module Container
|
|
60
|
+
def h6(how, what)
|
|
61
|
+
return H6.new(self, how, what)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
data/watir/exceptions.rb
CHANGED
|
@@ -9,52 +9,34 @@ module Watir
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
# This exception is thrown if an attempt is made to access an object that doesn't exist
|
|
12
|
-
class UnknownObjectException < WatirException
|
|
13
|
-
end
|
|
14
|
-
|
|
12
|
+
class UnknownObjectException < WatirException; end
|
|
15
13
|
# This exception is thrown if an attempt is made to access an object that is in a disabled state
|
|
16
|
-
class ObjectDisabledException < WatirException
|
|
17
|
-
end
|
|
18
|
-
|
|
14
|
+
class ObjectDisabledException < WatirException; end
|
|
19
15
|
# This exception is thrown if an attempt is made to access a frame that cannot be found
|
|
20
|
-
class UnknownFrameException< WatirException
|
|
21
|
-
end
|
|
22
|
-
|
|
16
|
+
class UnknownFrameException< WatirException; end
|
|
23
17
|
# This exception is thrown if an attempt is made to access a form that cannot be found
|
|
24
|
-
class UnknownFormException< WatirException
|
|
25
|
-
end
|
|
26
|
-
|
|
18
|
+
class UnknownFormException< WatirException; end
|
|
27
19
|
# This exception is thrown if an attempt is made to access an object that is in a read only state
|
|
28
|
-
class ObjectReadOnlyException < WatirException
|
|
29
|
-
end
|
|
30
|
-
|
|
20
|
+
class ObjectReadOnlyException < WatirException; end
|
|
31
21
|
# This exception is thrown if an attempt is made to access an object when the specified value cannot be found
|
|
32
|
-
class NoValueFoundException < WatirException
|
|
33
|
-
end
|
|
34
|
-
|
|
22
|
+
class NoValueFoundException < WatirException; end
|
|
35
23
|
# This exception gets raised if part of finding an object is missing
|
|
36
|
-
class MissingWayOfFindingObjectException < WatirException
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# This exception is raised if an attempt is made to access a table that doesn't exist
|
|
40
|
-
class UnknownTableException < WatirException
|
|
41
|
-
end
|
|
42
|
-
|
|
24
|
+
class MissingWayOfFindingObjectException < WatirException; end
|
|
43
25
|
# this exception is raised if an attempt is made to access a table cell that doesnt exist
|
|
44
|
-
class UnknownCellException < WatirException
|
|
45
|
-
end
|
|
46
|
-
|
|
26
|
+
class UnknownCellException < WatirException; end
|
|
47
27
|
# This exception is thrown if the window cannot be found
|
|
48
|
-
class NoMatchingWindowFoundException < WatirException
|
|
49
|
-
end
|
|
50
|
-
|
|
28
|
+
class NoMatchingWindowFoundException < WatirException; end
|
|
51
29
|
# This exception is thrown if an attemp is made to acces the status bar of the browser when it doesnt exist
|
|
52
|
-
class NoStatusBarException < WatirException
|
|
53
|
-
end
|
|
54
|
-
|
|
30
|
+
class NoStatusBarException < WatirException; end
|
|
55
31
|
# This exception is thrown if an http error, such as a 404, 500 etc is encountered while navigating
|
|
56
|
-
class NavigationException < WatirException
|
|
32
|
+
class NavigationException < WatirException; end
|
|
33
|
+
# This exception is raised if a timeout is exceeded
|
|
34
|
+
class TimeOutException < WatirException
|
|
35
|
+
def initialize(duration, timeout)
|
|
36
|
+
@duration, @timeout = duration, timeout
|
|
37
|
+
end
|
|
38
|
+
attr_reader :duration, :timeout
|
|
57
39
|
end
|
|
58
|
-
|
|
40
|
+
|
|
59
41
|
end
|
|
60
42
|
end
|
data/watir/ie-process.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'win32/process'
|
|
2
|
+
|
|
3
|
+
module Watir
|
|
4
|
+
class IE
|
|
5
|
+
class Process
|
|
6
|
+
def self.start
|
|
7
|
+
program_files = ENV['ProgramFiles'] || "c:\\Program Files"
|
|
8
|
+
startup_command = "#{program_files}\\Internet Explorer\\iexplore.exe"
|
|
9
|
+
process_info = ::Process.create('app_name' => "#{startup_command} about:blank")
|
|
10
|
+
process_id = process_info.process_id
|
|
11
|
+
new process_id
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize process_id
|
|
15
|
+
@process_id = process_id
|
|
16
|
+
end
|
|
17
|
+
attr_reader :process_id
|
|
18
|
+
|
|
19
|
+
def window
|
|
20
|
+
Waiter.wait_until do
|
|
21
|
+
IE.each do | ie |
|
|
22
|
+
window = ie.ie
|
|
23
|
+
hwnd = ie.hwnd
|
|
24
|
+
process_id = Process.process_id_from_hwnd hwnd
|
|
25
|
+
return window if process_id == @process_id
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns the process id for the specifed hWnd.
|
|
31
|
+
def self.process_id_from_hwnd hwnd
|
|
32
|
+
pid_info = ' ' * 32
|
|
33
|
+
Win32API.new('user32', 'GetWindowThreadProcessId', 'ip', 'i').
|
|
34
|
+
call(hwnd, pid_info)
|
|
35
|
+
process_id = pid_info.unpack("L")[0]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# snarfed from http://blog.nicksieger.com/articles/2006/04/23/tweaking-irb
|
|
2
|
+
module Readline
|
|
3
|
+
module History
|
|
4
|
+
@@log ||= File.join(Dir.pwd, 'console.log')
|
|
5
|
+
|
|
6
|
+
def self.log= log
|
|
7
|
+
@@log = log
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.write_log(line)
|
|
11
|
+
begin
|
|
12
|
+
File.open(@@log, 'ab') {|f| f << "#{line}\n"}
|
|
13
|
+
rescue
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.start_session_log
|
|
18
|
+
write_log("# session start: #{Time.now}")
|
|
19
|
+
at_exit { write_log("# session stop: #{Time.now}\n") }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
alias :old_readline :readline
|
|
24
|
+
def readline(*args)
|
|
25
|
+
ln = old_readline(*args)
|
|
26
|
+
History.write_log(ln)
|
|
27
|
+
ln
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Readline::History.start_session_log
|
data/watir/process.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Watir
|
|
2
|
+
module Process
|
|
3
|
+
|
|
4
|
+
# Returns the number of windows processes running with the specified name.
|
|
5
|
+
def self.count name
|
|
6
|
+
mgmt = WIN32OLE.connect('winmgmts:\\\\.')
|
|
7
|
+
processes = mgmt.InstancesOf('win32_process')
|
|
8
|
+
processes.extend Enumerable
|
|
9
|
+
processes.select{|x| x.name == name}.length
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class IE
|
|
15
|
+
# Returns the number of IEXPLORE processes currently running.
|
|
16
|
+
def self.process_count
|
|
17
|
+
Watir::Process.count 'iexplore.exe'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/watir/testUnitAddons.rb
CHANGED
|
@@ -1,47 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
module Test::Unit::Assertions
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def assert_false(boolean, message=nil)
|
|
2
|
+
def assert_false(boolean, message=nil)
|
|
7
3
|
_wrap_assertion do
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
assert_block("assert should not be called with a block.") { !block_given? }
|
|
5
|
+
assert_block(build_message(message, "<?> is not false.", boolean)) { !boolean }
|
|
10
6
|
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def compareArrays( expectArray, actualArray)
|
|
15
|
-
result = true
|
|
16
|
-
expectArray.each_with_index do |element,i|
|
|
17
|
-
#puts "Comparing #{element} #{element.class} with #{actualArray[i]} #{actualArray[i].class} "
|
|
18
|
-
if element != actualArray[i]
|
|
19
|
-
result = false
|
|
20
|
-
break
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
return result
|
|
25
|
-
|
|
26
7
|
end
|
|
27
|
-
|
|
28
|
-
def assert_arrayEquals(expectArray, actualArray, message = nil )
|
|
29
|
-
_wrap_assertion do
|
|
30
|
-
assert_block("assert should not be called with a block.") { !block_given? }
|
|
31
|
-
assert_equal(expectArray.length, actualArray.length, "Lengths did not match")
|
|
32
|
-
|
|
33
|
-
assert_block("contents are different." ){ compareArrays( expectArray, actualArray) }
|
|
34
|
-
end #_wrap
|
|
35
|
-
end #def
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def assert_arrayContains(array, string , message =nil)
|
|
39
|
-
|
|
40
|
-
_wrap_assertion do
|
|
41
|
-
assert_block("assert should not be called with a block.") { !block_given? }
|
|
42
|
-
assert(array.kind_of?(Array) , "Must have an array")
|
|
43
|
-
assert(array.include?(string) , message)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
8
|
end # module test
|
data/watir/testcase.rb
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'watir/assertions'
|
|
3
|
+
|
|
4
|
+
module Watir
|
|
5
|
+
|
|
6
|
+
class TestCase < Test::Unit::TestCase
|
|
7
|
+
include Watir::Assertions
|
|
8
|
+
@@order = :sequentially
|
|
9
|
+
def initialize name
|
|
10
|
+
throw :invalid_test if name == :default_test && self.class == Watir::TestCase
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
class << self
|
|
14
|
+
attr_accessor :test_methods, :order
|
|
15
|
+
def test_methods
|
|
16
|
+
@test_methods ||= []
|
|
17
|
+
end
|
|
18
|
+
def order
|
|
19
|
+
@order || @@order
|
|
20
|
+
end
|
|
21
|
+
def default_order= order
|
|
22
|
+
@@order = order
|
|
23
|
+
end
|
|
24
|
+
def sorted_test_methods
|
|
25
|
+
case order
|
|
26
|
+
when :alphabetically: test_methods.sort
|
|
27
|
+
when :sequentially: test_methods
|
|
28
|
+
when :reversed_sequentially: test_methods.reverse
|
|
29
|
+
when :reversed_alphabetically: test_methods.sort.reverse
|
|
30
|
+
else raise ArgumentError, "Execute option not supported: #{@order}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
def suite
|
|
34
|
+
suite = Test::Unit::TestSuite.new(name)
|
|
35
|
+
sorted_test_methods.each do |test|
|
|
36
|
+
catch :invalid_test do
|
|
37
|
+
suite << new(test)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
if (suite.empty?)
|
|
41
|
+
catch :invalid_test do
|
|
42
|
+
suite << new(:default_test)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
return suite
|
|
46
|
+
end
|
|
47
|
+
def method_added id
|
|
48
|
+
name = id.id2name
|
|
49
|
+
test_methods << name if name =~ /^test./
|
|
50
|
+
end
|
|
51
|
+
def execute order
|
|
52
|
+
@order = order
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
public :add_assertion
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
data/watir/utils.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# watir/utils.rb
|
|
2
|
+
|
|
3
|
+
module Watir
|
|
4
|
+
module Utils
|
|
5
|
+
|
|
6
|
+
# Eval the provided block. If a WIN32OLERuntimeError is raised by the block,
|
|
7
|
+
# return false.
|
|
8
|
+
def suppress_ole_error
|
|
9
|
+
begin
|
|
10
|
+
yield
|
|
11
|
+
true
|
|
12
|
+
rescue WIN32OLERuntimeError
|
|
13
|
+
false
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
data/watir/waiter.rb
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'watir/exceptions'
|
|
2
|
+
|
|
3
|
+
module Watir
|
|
4
|
+
|
|
5
|
+
class TimeKeeper
|
|
6
|
+
attr_reader :sleep_time
|
|
7
|
+
def initialize
|
|
8
|
+
@sleep_time = 0.0
|
|
9
|
+
end
|
|
10
|
+
def sleep seconds
|
|
11
|
+
@sleep_time += Kernel.sleep seconds
|
|
12
|
+
end
|
|
13
|
+
def now
|
|
14
|
+
Time.now
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Waiter
|
|
19
|
+
# This is an interface to a TimeKeeper which proxies
|
|
20
|
+
# calls to "sleep" and "Time.now".
|
|
21
|
+
# Useful for unit testing Waiter.
|
|
22
|
+
attr_accessor :timer
|
|
23
|
+
|
|
24
|
+
# How long to wait between each iteration through the wait_until
|
|
25
|
+
# loop. In seconds.
|
|
26
|
+
attr_accessor :polling_interval
|
|
27
|
+
|
|
28
|
+
# Timeout for wait_until.
|
|
29
|
+
attr_accessor :timeout
|
|
30
|
+
|
|
31
|
+
@@default_polling_interval = 0.5
|
|
32
|
+
@@default_timeout = 60.0
|
|
33
|
+
|
|
34
|
+
def initialize(timeout=@@default_timeout,
|
|
35
|
+
polling_interval=@@default_polling_interval)
|
|
36
|
+
@timeout = timeout
|
|
37
|
+
@polling_interval = polling_interval
|
|
38
|
+
@timer = TimeKeeper.new
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Execute the provided block until either (1) it returns true, or
|
|
42
|
+
# (2) the timeout (in seconds) has been reached. If the timeout is reached,
|
|
43
|
+
# a TimeOutException will be raised. The block will always
|
|
44
|
+
# execute at least once.
|
|
45
|
+
#
|
|
46
|
+
# waiter = Waiter.new(5)
|
|
47
|
+
# waiter.wait_until {puts 'hello'}
|
|
48
|
+
#
|
|
49
|
+
# This code will print out "hello" for five seconds, and then raise a
|
|
50
|
+
# Watir::TimeOutException.
|
|
51
|
+
def wait_until # block
|
|
52
|
+
start_time = now
|
|
53
|
+
until yield do
|
|
54
|
+
if (duration = now - start_time) > @timeout
|
|
55
|
+
raise Watir::Exception::TimeOutException.new(duration, @timeout),
|
|
56
|
+
"Timed out after #{duration} seconds."
|
|
57
|
+
end
|
|
58
|
+
sleep @polling_interval
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Execute the provided block until either (1) it returns true, or
|
|
63
|
+
# (2) the timeout (in seconds) has been reached. If the timeout is reached,
|
|
64
|
+
# a TimeOutException will be raised. The block will always
|
|
65
|
+
# execute at least once.
|
|
66
|
+
#
|
|
67
|
+
# Waiter.wait_until(5) {puts 'hello'}
|
|
68
|
+
#
|
|
69
|
+
# This code will print out "hello" for five seconds, and then raise a
|
|
70
|
+
# Watir::TimeOutException.
|
|
71
|
+
|
|
72
|
+
# IDEA: wait_until: remove defaults from Waiter.wait_until
|
|
73
|
+
def self.wait_until(timeout=@@default_timeout,
|
|
74
|
+
polling_interval=@@default_polling_interval)
|
|
75
|
+
waiter = new(timeout, polling_interval)
|
|
76
|
+
waiter.wait_until { yield }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
def sleep seconds
|
|
81
|
+
@timer.sleep seconds
|
|
82
|
+
end
|
|
83
|
+
def now
|
|
84
|
+
@timer.now
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end # module
|