watir-classic 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (213) hide show
  1. data/CHANGES +721 -0
  2. data/LICENSE +34 -0
  3. data/README.rdoc +78 -0
  4. data/VERSION +1 -0
  5. data/bin/watir-console +5 -0
  6. data/lib/watir-classic.rb +14 -0
  7. data/lib/watir-classic/IEDialog/Release/IEDialog.dll +0 -0
  8. data/lib/watir-classic/assertions.rb +44 -0
  9. data/lib/watir-classic/browser.rb +149 -0
  10. data/lib/watir-classic/browsers.rb +7 -0
  11. data/lib/watir-classic/close_all.rb +31 -0
  12. data/lib/watir-classic/container.rb +110 -0
  13. data/lib/watir-classic/contrib/enabled_popup.rb +21 -0
  14. data/lib/watir-classic/contrib/ie-new-process.rb +27 -0
  15. data/lib/watir-classic/contrib/page_checker.rb +29 -0
  16. data/lib/watir-classic/cookies.rb +80 -0
  17. data/lib/watir-classic/core.rb +43 -0
  18. data/lib/watir-classic/dialogs/file_field.rb +34 -0
  19. data/lib/watir-classic/dialogs/javascript.rb +43 -0
  20. data/lib/watir-classic/drag_and_drop_helper.rb +68 -0
  21. data/lib/watir-classic/element.rb +438 -0
  22. data/lib/watir-classic/element_collection.rb +109 -0
  23. data/lib/watir-classic/element_extensions.rb +69 -0
  24. data/lib/watir-classic/exceptions.rb +50 -0
  25. data/lib/watir-classic/form.rb +96 -0
  26. data/lib/watir-classic/frame.rb +47 -0
  27. data/lib/watir-classic/ie-class.rb +767 -0
  28. data/lib/watir-classic/ie-process.rb +47 -0
  29. data/lib/watir-classic/ie.rb +20 -0
  30. data/lib/watir-classic/image.rb +111 -0
  31. data/lib/watir-classic/input_elements.rb +480 -0
  32. data/lib/watir-classic/irb-history.rb +31 -0
  33. data/lib/watir-classic/link.rb +46 -0
  34. data/lib/watir-classic/locator.rb +243 -0
  35. data/lib/watir-classic/logger.rb +19 -0
  36. data/lib/watir-classic/matches.rb +23 -0
  37. data/lib/watir-classic/modal_dialog.rb +72 -0
  38. data/lib/watir-classic/module.rb +12 -0
  39. data/lib/watir-classic/non_control_elements.rb +114 -0
  40. data/lib/watir-classic/options.rb +56 -0
  41. data/lib/watir-classic/page-container.rb +114 -0
  42. data/lib/watir-classic/process.rb +20 -0
  43. data/lib/watir-classic/screen_capture.rb +115 -0
  44. data/lib/watir-classic/supported_elements.rb +172 -0
  45. data/lib/watir-classic/table.rb +224 -0
  46. data/lib/watir-classic/testcase.rb +97 -0
  47. data/lib/watir-classic/util.rb +35 -0
  48. data/lib/watir-classic/version.rb +4 -0
  49. data/lib/watir-classic/wait.rb +41 -0
  50. data/lib/watir-classic/wait_helper.rb +12 -0
  51. data/lib/watir-classic/waiter.rb +98 -0
  52. data/lib/watir-classic/win32.rb +40 -0
  53. data/lib/watir-classic/win32ole.rb +16 -0
  54. data/lib/watir-classic/win32ole/1.8.7/win32ole.so +0 -0
  55. data/lib/watir-classic/win32ole/1.9.3/win32ole.so +0 -0
  56. data/lib/watir-classic/window.rb +68 -0
  57. data/lib/watir-classic/xpath_locator.rb +52 -0
  58. data/rakefile.rb +54 -0
  59. data/unittests/all_tests.rb +10 -0
  60. data/unittests/buttons_xpath_test.rb +68 -0
  61. data/unittests/checkbox_test.rb +163 -0
  62. data/unittests/checkbox_xpath_test.rb +106 -0
  63. data/unittests/click_no_wait_test.rb +23 -0
  64. data/unittests/close_all_test.rb +17 -0
  65. data/unittests/core_tests.rb +17 -0
  66. data/unittests/css_selector_test.rb +44 -0
  67. data/unittests/css_test.rb +38 -0
  68. data/unittests/dialog_test.rb +64 -0
  69. data/unittests/div2_xpath_test.rb +21 -0
  70. data/unittests/div_test.rb +170 -0
  71. data/unittests/div_xpath_test.rb +95 -0
  72. data/unittests/document_standards.rb +63 -0
  73. data/unittests/element_collection_indexes_test.rb +57 -0
  74. data/unittests/element_collections_test.rb +100 -0
  75. data/unittests/element_test.rb +47 -0
  76. data/unittests/errorchecker_test.rb +31 -0
  77. data/unittests/filefield_test.rb +43 -0
  78. data/unittests/filefield_xpath_test.rb +35 -0
  79. data/unittests/form_test.rb +282 -0
  80. data/unittests/form_xpath_test.rb +254 -0
  81. data/unittests/frame_test.rb +165 -0
  82. data/unittests/google_form_test.rb +15 -0
  83. data/unittests/html/JavascriptClick.html +39 -0
  84. data/unittests/html/blankpage.html +11 -0
  85. data/unittests/html/buttons1.html +40 -0
  86. data/unittests/html/checkboxes1.html +89 -0
  87. data/unittests/html/click_no_wait.html +14 -0
  88. data/unittests/html/complex_table.html +35 -0
  89. data/unittests/html/cssTest.html +42 -0
  90. data/unittests/html/depot_store.html +59 -0
  91. data/unittests/html/div.html +92 -0
  92. data/unittests/html/div_xml.html +21 -0
  93. data/unittests/html/fileupload.html +44 -0
  94. data/unittests/html/formTest1.html +38 -0
  95. data/unittests/html/forms2.html +44 -0
  96. data/unittests/html/forms3.html +131 -0
  97. data/unittests/html/forms4.html +26 -0
  98. data/unittests/html/frame_buttons.html +4 -0
  99. data/unittests/html/frame_links.html +4 -0
  100. data/unittests/html/frame_multi.html +5 -0
  101. data/unittests/html/google_india.html +119 -0
  102. data/unittests/html/ie7_document_standards.html +9 -0
  103. data/unittests/html/ie8_document_standards.html +9 -0
  104. data/unittests/html/ie9_document_standards.html +9 -0
  105. data/unittests/html/iframe.html +3 -0
  106. data/unittests/html/iframeTest.html +17 -0
  107. data/unittests/html/iframeTest1.html +7 -0
  108. data/unittests/html/iframeTest2.html +5 -0
  109. data/unittests/html/images/1.gif +0 -0
  110. data/unittests/html/images/2.GIF +0 -0
  111. data/unittests/html/images/3.GIF +0 -0
  112. data/unittests/html/images/button.jpg +0 -0
  113. data/unittests/html/images/circle.jpg +0 -0
  114. data/unittests/html/images/map.GIF +0 -0
  115. data/unittests/html/images/map2.gif +0 -0
  116. data/unittests/html/images/minus.GIF +0 -0
  117. data/unittests/html/images/originaltriangle.jpg +0 -0
  118. data/unittests/html/images/plus.gif +0 -0
  119. data/unittests/html/images/square.jpg +0 -0
  120. data/unittests/html/images/triangle.jpg +0 -0
  121. data/unittests/html/images1.html +65 -0
  122. data/unittests/html/javascriptevents.html +33 -0
  123. data/unittests/html/link_pass.html +11 -0
  124. data/unittests/html/links1.html +37 -0
  125. data/unittests/html/links2.html +11 -0
  126. data/unittests/html/links_multi.html +12 -0
  127. data/unittests/html/list_matters.html +720 -0
  128. data/unittests/html/lists.html +18 -0
  129. data/unittests/html/map_test.html +30 -0
  130. data/unittests/html/modal_dialog.html +10 -0
  131. data/unittests/html/modal_dialog_launcher.html +12 -0
  132. data/unittests/html/multiple_specifiers.html +64 -0
  133. data/unittests/html/nestedFrames.html +6 -0
  134. data/unittests/html/new_browser.html +17 -0
  135. data/unittests/html/pass.html +13 -0
  136. data/unittests/html/popups1.html +59 -0
  137. data/unittests/html/pre.html +29 -0
  138. data/unittests/html/quirks_document_standards.html +8 -0
  139. data/unittests/html/radioButtons1.html +71 -0
  140. data/unittests/html/select_tealeaf.html +54 -0
  141. data/unittests/html/selectboxes1.html +52 -0
  142. data/unittests/html/simple_table.html +25 -0
  143. data/unittests/html/simple_table_buttons.html +104 -0
  144. data/unittests/html/simple_table_columns.html +75 -0
  145. data/unittests/html/table1.html +179 -0
  146. data/unittests/html/tableCell_using_xpath.html +19 -0
  147. data/unittests/html/table_and_tablerow_to_a.html +174 -0
  148. data/unittests/html/textarea.html +30 -0
  149. data/unittests/html/textfields1.html +100 -0
  150. data/unittests/html/textsearch.html +44 -0
  151. data/unittests/html/wallofcheckboxes.html +1003 -0
  152. data/unittests/html/xpath_nbsp.html +11 -0
  153. data/unittests/html/zeroindex.html +11 -0
  154. data/unittests/ie_exists_test.rb +16 -0
  155. data/unittests/ie_mock.rb +94 -0
  156. data/unittests/ie_test.rb +54 -0
  157. data/unittests/images_test.rb +156 -0
  158. data/unittests/images_xpath_test.rb +90 -0
  159. data/unittests/index_specifier_test.rb +31 -0
  160. data/unittests/js_events_test.rb +31 -0
  161. data/unittests/links_multi_test.rb +34 -0
  162. data/unittests/links_test.rb +131 -0
  163. data/unittests/links_xpath_test.rb +38 -0
  164. data/unittests/lists_test.rb +23 -0
  165. data/unittests/map_test.rb +98 -0
  166. data/unittests/minmax_test.rb +37 -0
  167. data/unittests/navigate_test.rb +38 -0
  168. data/unittests/nbsp_xpath_test.rb +16 -0
  169. data/unittests/no_wait_test.rb +28 -0
  170. data/unittests/non_core_tests.rb +12 -0
  171. data/unittests/other/all_tests_concurrent.rb +57 -0
  172. data/unittests/other/navigate_exception_test.rb +24 -0
  173. data/unittests/other/rexml_unit_test.rb +27 -0
  174. data/unittests/other/screen_capture_test.rb +53 -0
  175. data/unittests/other/testcase_method_order_test.rb +36 -0
  176. data/unittests/other/testcase_verify_test.rb +25 -0
  177. data/unittests/other/wait_until_test.rb +102 -0
  178. data/unittests/pagecontainstext_test.rb +69 -0
  179. data/unittests/parent_child_test.rb +27 -0
  180. data/unittests/perf_test.rb +20 -0
  181. data/unittests/pre_test.rb +49 -0
  182. data/unittests/radios_test.rb +181 -0
  183. data/unittests/radios_xpath_test.rb +100 -0
  184. data/unittests/security_setting_test.rb +24 -0
  185. data/unittests/selectbox_test.rb +144 -0
  186. data/unittests/selectbox_xpath_test.rb +102 -0
  187. data/unittests/setup.rb +69 -0
  188. data/unittests/speed_settings_test.rb +67 -0
  189. data/unittests/table_cell_using_xpath_test.rb +34 -0
  190. data/unittests/table_test.rb +296 -0
  191. data/unittests/table_xpath_test.rb +109 -0
  192. data/unittests/test_tests.rb +9 -0
  193. data/unittests/textarea_test.rb +92 -0
  194. data/unittests/textarea_xpath_test.rb +77 -0
  195. data/unittests/textfield_for_ch_char_test.rb +32 -0
  196. data/unittests/textfields_test.rb +184 -0
  197. data/unittests/textfields_xpath_test.rb +110 -0
  198. data/unittests/version_test.rb +15 -0
  199. data/unittests/win32ole_so_test.rb +35 -0
  200. data/unittests/window_tests.rb +10 -0
  201. data/unittests/windows/attach_to_existing_window_test.rb +52 -0
  202. data/unittests/windows/attach_to_new_window_test.rb +74 -0
  203. data/unittests/windows/close_window_test.rb +20 -0
  204. data/unittests/windows/frame_links_test.rb +23 -0
  205. data/unittests/windows/ie-each_test.rb +46 -0
  206. data/unittests/windows/modal_dialog_test.rb +95 -0
  207. data/unittests/windows/new_process_test.rb +24 -0
  208. data/unittests/windows/new_test.rb +58 -0
  209. data/unittests/windows/open_close_test.rb +19 -0
  210. data/unittests/windows/send_keys_test.rb +26 -0
  211. data/unittests/xpath_tests.rb +11 -0
  212. data/watir-rdoc.rb +7 -0
  213. metadata +370 -0
@@ -0,0 +1,47 @@
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
+ startup_command << " -nomerge" if IE.version_parts.first.to_i == 8
10
+ startup_command << " -noframemerging" if IE.version_parts.first.to_i >= 9
11
+ process_info = ::Process.create('app_name' => "#{startup_command} about:blank")
12
+ process_id = process_info.process_id
13
+ new process_id
14
+ end
15
+
16
+ def initialize process_id
17
+ @process_id = process_id
18
+ end
19
+ attr_reader :process_id
20
+
21
+ def window
22
+ Wait.until do
23
+ found_window = nil
24
+ IE.each do | ie |
25
+ window = ie.ie
26
+ hwnd = ie.hwnd
27
+ process_id = Process.process_id_from_hwnd hwnd
28
+ if process_id == @process_id
29
+ found_window = window
30
+ break
31
+ end
32
+ end
33
+ found_window
34
+ end
35
+ end
36
+
37
+ # Returns the process id for the specifed hWnd.
38
+ def self.process_id_from_hwnd hwnd
39
+ pid_info = ' ' * 32
40
+ Win32API.new('user32', 'GetWindowThreadProcessId', 'ip', 'i').
41
+ call(hwnd, pid_info)
42
+ process_id = pid_info.unpack("L")[0]
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,20 @@
1
+ require 'watir-classic'
2
+ require 'watir-classic/core'
3
+ require 'watir-classic/close_all'
4
+ require 'watir-classic/ie-process'
5
+
6
+ # these switches need to be deleted from ARGV to enable the Test::Unit
7
+ # functionality that grabs
8
+ # the remaining ARGV as a filter on what tests to run.
9
+ # Note: this means that watir-classic must be require'd BEFORE test/unit.
10
+ # (Alternatively, you could require test/unit first and then put the Watir::IE
11
+ # arguments after the '--'.)
12
+
13
+ # Make Internet Explorer invisible. -b stands for background
14
+ $HIDE_IE ||= ARGV.delete('-b')
15
+
16
+ # Run fast
17
+ $FAST_SPEED = ARGV.delete('-f')
18
+
19
+ # Eat the -s command line switch (deprecated)
20
+ ARGV.delete('-s')
@@ -0,0 +1,111 @@
1
+ module Watir
2
+
3
+ # This class is the means of accessing an image on a page.
4
+ # Normally a user would not need to create this object as it is returned by the Watir::Container#image method
5
+ #
6
+ # many of the methods available to this object are inherited from the Element class
7
+ #
8
+ class Image < Element
9
+ attr_ole :alt
10
+ attr_ole :src
11
+ attr_ole :file_created_date, :fileCreatedDate
12
+
13
+ # this method produces the properties for an image as an array
14
+ def image_string_creator
15
+ n = []
16
+ n << "src:".ljust(TO_S_SIZE) + self.src.to_s
17
+ n << "file date:".ljust(TO_S_SIZE) + self.fileCreatedDate.to_s
18
+ n << "file size:".ljust(TO_S_SIZE) + self.fileSize.to_s
19
+ n << "width:".ljust(TO_S_SIZE) + self.width.to_s
20
+ n << "height:".ljust(TO_S_SIZE) + self.height.to_s
21
+ n << "alt:".ljust(TO_S_SIZE) + self.alt.to_s
22
+ return n
23
+ end
24
+ private :image_string_creator
25
+
26
+ # returns a string representation of the object
27
+ def to_s
28
+ assert_exists
29
+ r = string_creator
30
+ r += image_string_creator
31
+ return r.join("\n")
32
+ end
33
+
34
+ # this method returns the filesize of the image, as an int
35
+ def file_size
36
+ assert_exists
37
+ @o.invoke("fileSize").to_i
38
+ end
39
+
40
+ # returns the width in pixels of the image, as an int
41
+ def width
42
+ assert_exists
43
+ @o.invoke("width").to_i
44
+ end
45
+
46
+ # returns the height in pixels of the image, as an int
47
+ def height
48
+ assert_exists
49
+ @o.invoke("height").to_i
50
+ end
51
+
52
+ # This method attempts to find out if the image was actually loaded by the web browser.
53
+ # If the image was not loaded, the browser is unable to determine some of the properties.
54
+ # We look for these missing properties to see if the image is really there or not.
55
+ # If the Disk cache is full (tools menu -> Internet options -> Temporary Internet Files), it may produce incorrect responses.
56
+ def loaded?
57
+ assert_exists
58
+ !file_created_date.empty? && file_size != -1
59
+ end
60
+
61
+ # this method highlights the image (in fact it adds or removes a border around the image)
62
+ # * set_or_clear - symbol - :set to set the border, :clear to remove it
63
+ def highlight(set_or_clear)
64
+ if set_or_clear == :set
65
+ begin
66
+ @original_border = @o.border
67
+ @o.border = 1
68
+ rescue
69
+ @original_border = nil
70
+ end
71
+ else
72
+ begin
73
+ @o.border = @original_border
74
+ @original_border = nil
75
+ rescue
76
+ # we could be here for a number of reasons...
77
+ ensure
78
+ @original_border = nil
79
+ end
80
+ end
81
+ end
82
+ private :highlight
83
+
84
+ # This method saves the image to the file path that is given. The
85
+ # path must be in windows format (c:\\dirname\\somename.gif). This method
86
+ # will not overwrite a previously existing image. If an image already
87
+ # exists at the given path then a dialog will be displayed prompting
88
+ # for overwrite.
89
+ # path - directory path and file name of where image should be saved
90
+ def save(path)
91
+ @container.goto(src)
92
+ begin
93
+ fill_save_image_dialog(path)
94
+ @container.document.execCommand("SaveAs")
95
+ ensure
96
+ @container.back
97
+ end
98
+ end
99
+
100
+ def fill_save_image_dialog(path)
101
+ command = "require 'rubygems';require 'rautomation';" <<
102
+ "window=::RAutomation::Window.new(:title => 'Save Picture');" <<
103
+ "window.text_field(:class => 'Edit', :index => 0).set('#{path.gsub(File::SEPARATOR, File::ALT_SEPARATOR)}');" <<
104
+ "window.button(:value => '&Save').click"
105
+ IO.popen("ruby -e \"#{command}\"")
106
+ end
107
+ private :fill_save_image_dialog
108
+
109
+ end
110
+
111
+ end
@@ -0,0 +1,480 @@
1
+ module Watir
2
+
3
+ class InputElement < Element #:nodoc:all
4
+ def locate
5
+ @o = @container.locator_for(InputElementLocator, @specifiers, self.class).locate
6
+ end
7
+
8
+ attr_ole :disabled?
9
+ attr_ole :name
10
+ attr_ole :value
11
+ attr_ole :alt
12
+ attr_ole :src
13
+ attr_ole :type
14
+ end
15
+
16
+ #
17
+ # Input: Select
18
+ #
19
+
20
+ # This class is the way in which select boxes are manipulated.
21
+ # Normally a user would not need to create this object as it is returned by the Watir::Container#select_list method
22
+ class SelectList < InputElement
23
+ attr_ole :multiple?
24
+
25
+ # This method clears the selected items in the select box
26
+ def clear
27
+ perform_action do
28
+ options.each {|option| option.clear}
29
+ end
30
+ end
31
+
32
+ # This method selects an item, or items in a select box, by text.
33
+ # Raises NoValueFoundException if the specified value is not found.
34
+ # * item - the thing to select, string or reg exp
35
+ def select(item)
36
+ matching_options = []
37
+ perform_action do
38
+ matching_options = matching_items_in_select_list(:text, item) +
39
+ matching_items_in_select_list(:label, item) +
40
+ matching_items_in_select_list(:value, item)
41
+ raise NoValueFoundException, "No option with :text, :label or :value of #{item.inspect} in this select element" if matching_options.empty?
42
+ matching_options.each(&:select)
43
+ end
44
+ matching_options.first.text
45
+ end
46
+
47
+ # Selects an item, or items in a select box, by value.
48
+ # Raises NoValueFoundException if the specified value is not found.
49
+ # * item - the value of the thing to select, string or reg exp
50
+ def select_value(item)
51
+ matching_options = matching_items_in_select_list(:value, item)
52
+ raise NoValueFoundException, "No option with :value of #{item.inspect} in this select element" if matching_options.empty?
53
+ matching_options.each(&:select)
54
+ matching_options.first.value
55
+ end
56
+
57
+ # Returns array of the selected text items in a select box
58
+ # Raises UnknownObjectException if the select box is not found.
59
+ def selected_options
60
+ options.select(&:selected?)
61
+ end
62
+
63
+ # Does the SelectList include the specified option (text)?
64
+ def include? text_or_regexp
65
+ !options.map(&:text).grep(text_or_regexp).empty?
66
+ end
67
+
68
+ # Is the specified option (text) selected? Raises exception of option does not exist.
69
+ def selected? text_or_regexp
70
+ raise UnknownObjectException, "Option #{text_or_regexp.inspect} not found." unless include? text_or_regexp
71
+ !selected_options.map(&:text).grep(text_or_regexp).empty?
72
+ end
73
+
74
+ private
75
+
76
+ def matching_items_in_select_list(attribute, value)
77
+ options.select do |opt|
78
+ if value.is_a?(Regexp)
79
+ opt.send(attribute) =~ value
80
+ elsif value.is_a?(String) || value.is_a?(Numeric)
81
+ opt.send(attribute) == value.to_s
82
+ else
83
+ raise TypeError, "#{value.inspect} can be only String, Regexp or Numeric!"
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ class Option < Element
90
+ attr_ole :disabled?
91
+ attr_ole :name
92
+ attr_ole :value
93
+ attr_ole :label
94
+
95
+ def select
96
+ perform_action do
97
+ unless selected?
98
+ ole_object.selected = true
99
+ select_list.dispatch_event("onChange")
100
+ @container.wait
101
+ end
102
+ end
103
+ end
104
+
105
+ def clear
106
+ raise TypeError, "you can only clear multi-selects" unless select_list.multiple?
107
+
108
+ perform_action do
109
+ if selected?
110
+ ole_object.selected = false
111
+ select_list.dispatch_event("onChange")
112
+ @container.wait
113
+ end
114
+ end
115
+ end
116
+
117
+ def selected?
118
+ assert_exists
119
+ ole_object.selected
120
+ end
121
+
122
+ def text
123
+ l = label
124
+ l.empty? ? super : l rescue ''
125
+ end
126
+
127
+ private
128
+
129
+ def select_list
130
+ return @select_list if @select_list
131
+ el = parent
132
+ el = el.parent until el.is_a?(SelectList)
133
+
134
+ raise "SELECT element was not found for #{self}!" unless el
135
+ @select_list = el
136
+ end
137
+ end
138
+
139
+ #
140
+ # Input: Button
141
+ #
142
+
143
+ # Returned by the Watir::Container#button method
144
+ class Button < InputElement
145
+ alias_method :__value, :value
146
+
147
+ def text
148
+ val = __value
149
+ val.empty? ? super : val
150
+ end
151
+
152
+ alias_method :value, :text
153
+ end
154
+
155
+ #
156
+ # Input: Text
157
+ #
158
+
159
+ # This class is the main class for Text Fields
160
+ # Normally a user would not need to create this object as it is returned by the Watir::Container#text_field method
161
+ class TextField < InputElement
162
+ attr_ole :size
163
+ attr_ole :readonly?
164
+ alias_method :text, :value
165
+
166
+ #:startdoc:
167
+
168
+ # return number of maxlength attribute
169
+ def maxlength
170
+ assert_exists unless @o
171
+ begin
172
+ ole_object.invoke('maxlength').to_i
173
+ rescue WIN32OLERuntimeError
174
+ 0
175
+ end
176
+ end
177
+
178
+ def text_string_creator
179
+ n = []
180
+ n << "length:".ljust(TO_S_SIZE) + self.size.to_s
181
+ n << "max length:".ljust(TO_S_SIZE) + self.maxlength.to_s
182
+ n << "read only:".ljust(TO_S_SIZE) + self.readonly?.to_s
183
+ n
184
+ end
185
+ private :text_string_creator
186
+
187
+ def to_s
188
+ assert_exists
189
+ r = string_creator
190
+ r += text_string_creator
191
+ r.join("\n")
192
+ end
193
+
194
+ def assert_not_readonly #:nodoc:
195
+ if self.readonly?
196
+ raise ObjectReadOnlyException,
197
+ "Textfield #{@specifiers.inspect} is read only."
198
+ end
199
+ end
200
+
201
+ # Returns true if the text field contents is matches the specified target,
202
+ # which can be either a string or a regular expression.
203
+ # Raises UnknownObjectException if the object can't be found
204
+ #--
205
+ # I vote for deprecating this
206
+ # we should use text_field().text.include?(some) or text.match(/some/) instead of this method
207
+ def verify_contains(target) #:nodoc:
208
+ assert_exists
209
+ if target.kind_of? String
210
+ return true if self.value == target
211
+ elsif target.kind_of? Regexp
212
+ return true if self.value.match(target) != nil
213
+ end
214
+ return false
215
+ end
216
+
217
+ # Drag the entire contents of the text field to another text field
218
+ # 19 Jan 2005 - It is added as prototype functionality, and may change
219
+ # * destination_how - symbol, :id, :name how we identify the drop target
220
+ # * destination_what - string or regular expression, the name, id, etc of the text field that will be the drop target
221
+ def drag_contents_to(destination_how, destination_what)
222
+ assert_exists
223
+ destination = @container.text_field(destination_how, destination_what)
224
+ unless destination.exists?
225
+ raise UnknownObjectException, "Unable to locate destination using #{destination_how } and #{destination_what } "
226
+ end
227
+
228
+ @o.focus(0)
229
+ @o.select(0)
230
+ value = self.value
231
+
232
+ dispatch_event("onSelect")
233
+ dispatch_event("ondragstart")
234
+ dispatch_event("ondrag")
235
+ destination.dispatch_event("onDragEnter")
236
+ destination.dispatch_event("onDragOver")
237
+ destination.dispatch_event("ondrop")
238
+
239
+ dispatch_event("ondragend")
240
+ destination.value = destination.value + value.to_s
241
+ self.value = ""
242
+ end
243
+
244
+ # Clears the contents of the text box.
245
+ # Raises UnknownObjectException if the object can't be found
246
+ # Raises ObjectDisabledException if the object is disabled
247
+ # Raises ObjectReadOnlyException if the object is read only
248
+ def clear
249
+ assert_exists
250
+ assert_enabled
251
+ assert_not_readonly
252
+
253
+ highlight(:set)
254
+
255
+ @o.scrollIntoView
256
+ @o.focus(0)
257
+ @o.select(0)
258
+ dispatch_event("onSelect")
259
+ @o.value = ""
260
+ dispatch_event("onKeyPress")
261
+ dispatch_event("onChange")
262
+ @container.wait
263
+ highlight(:clear)
264
+ end
265
+
266
+ # Appends the specified string value to the contents of the text box.
267
+ # Raises UnknownObjectException if the object cant be found
268
+ # Raises ObjectDisabledException if the object is disabled
269
+ # Raises ObjectReadOnlyException if the object is read only
270
+ def append(value)
271
+ assert_exists
272
+ assert_enabled
273
+ assert_not_readonly
274
+
275
+ highlight(:set)
276
+ @o.scrollIntoView
277
+ @o.focus(0)
278
+ type_by_character(value)
279
+ highlight(:clear)
280
+ end
281
+
282
+ # Sets the contents of the text box to the specified text value
283
+ # Raises UnknownObjectException if the object cant be found
284
+ # Raises ObjectDisabledException if the object is disabled
285
+ # Raises ObjectReadOnlyException if the object is read only
286
+ def set(value)
287
+ assert_exists
288
+ assert_enabled
289
+ assert_not_readonly
290
+
291
+ highlight(:set)
292
+ @o.scrollIntoView
293
+ if type_keys
294
+ @o.focus(0)
295
+ @o.select(0)
296
+ dispatch_event("onSelect")
297
+ dispatch_event("onKeyPress")
298
+ @o.value = ""
299
+ type_by_character(value)
300
+ dispatch_event("onChange")
301
+ dispatch_event("onBlur")
302
+ else
303
+ @o.value = limit_to_maxlength(value)
304
+ end
305
+ highlight(:clear)
306
+ end
307
+
308
+ # Sets the value of the text field directly.
309
+ # It causes no events to be fired or exceptions to be raised,
310
+ # so generally shouldn't be used.
311
+ # It is preffered to use the set method.
312
+ def value=(v)
313
+ assert_exists
314
+ @o.value = v.to_s
315
+ end
316
+
317
+ def requires_typing #:nodoc:
318
+ @type_keys = true
319
+ self
320
+ end
321
+ def abhors_typing #:nodoc:
322
+ @type_keys = false
323
+ self
324
+ end
325
+
326
+ def label
327
+ @container.label(:for => name).text
328
+ end
329
+
330
+ private
331
+
332
+ # Type the characters in the specified string (value) one by one.
333
+ # It should not be used externally.
334
+ # * value - string - The string to enter into the text field
335
+ def type_by_character(value)
336
+ value = limit_to_maxlength(value)
337
+ characters_in(value) do |c|
338
+ sleep @container.typingspeed
339
+ @o.value = @o.value.to_s + c
340
+ dispatch_event("onKeyDown")
341
+ dispatch_event("onKeyPress")
342
+ dispatch_event("onKeyUp")
343
+ end
344
+ end
345
+
346
+ # Supports double-byte characters
347
+ def characters_in(value, &blk)
348
+ if RUBY_VERSION =~ /^1\.8/
349
+ index = 0
350
+ while index < value.length
351
+ len = value[index] > 128 ? 2 : 1
352
+ yield value[index, len]
353
+ index += len
354
+ end
355
+ else
356
+ value.each_char(&blk)
357
+ end
358
+ end
359
+
360
+ # Return the value (a string), limited to the maxlength of the element.
361
+ def limit_to_maxlength(value)
362
+ return value if @o.invoke('type') =~ /textarea/i # text areas don't have maxlength
363
+ if value.length > maxlength
364
+ value = value[0 .. maxlength - 1]
365
+ @container.log " Supplied string is #{value.length} chars, which exceeds the max length (#{maxlength}) of the field. Using value: #{value}"
366
+ end
367
+ value
368
+ end
369
+
370
+ end
371
+
372
+ # this class can be used to access hidden field objects
373
+ # Normally a user would not need to create this object as it is returned by the Watir::Container#hidden method
374
+ class Hidden < TextField
375
+ # set is overriden in this class, as there is no way to set focus to a hidden field
376
+ def set(n)
377
+ self.value = n
378
+ end
379
+
380
+ # override the append method, so that focus isnt set to the hidden object
381
+ def append(n)
382
+ self.value = self.value.to_s + n.to_s
383
+ end
384
+
385
+ # override the clear method, so that focus isnt set to the hidden object
386
+ def clear
387
+ self.value = ""
388
+ end
389
+
390
+ # this method will do nothing, as you cant set focus to a hidden field
391
+ def focus
392
+ end
393
+
394
+ # Hidden element is never visible - returns false.
395
+ def visible?
396
+ assert_exists
397
+ false
398
+ end
399
+ end
400
+
401
+ # This module contains common methods to both radio buttons and check boxes.
402
+ # Normally a user would not need to create this object as it is returned by the Watir::Container#checkbox or by Watir::Container#radio methods
403
+ module RadioCheckCommon
404
+ def self.included(base)
405
+ base.instance_eval do
406
+ attr_ole :set?, :checked
407
+ alias_method :checked?, :set?
408
+ end
409
+ end
410
+
411
+ def inspect
412
+ '#<%s:0x%x located=%s specifiers=%s value=%s>' % [self.class, hash*2, !!ole_object, @specifiers.inspect, @value.inspect]
413
+ end
414
+ end
415
+
416
+ #--
417
+ # this class makes the docs better
418
+ #++
419
+ # This class is the watir representation of a radio button.
420
+ # Normally a user would not need to create this object as it is returned by the Watir::Container#radio method
421
+ class Radio < InputElement
422
+ include RadioCheckCommon
423
+ # This method clears a radio button. One of them will almost always be set.
424
+ # Returns true if set or false if not set.
425
+ # Raises UnknownObjectException if its unable to locate an object
426
+ # ObjectDisabledException IF THE OBJECT IS DISABLED
427
+ def clear
428
+ assert_exists
429
+ assert_enabled
430
+ highlight(:set)
431
+ @o.checked = false
432
+ highlight(:clear)
433
+ highlight(:clear)
434
+ end
435
+
436
+ # This method sets the radio list item.
437
+ # Raises UnknownObjectException if it's unable to locate an object
438
+ # ObjectDisabledException if the object is disabled
439
+ def set
440
+ assert_exists
441
+ assert_enabled
442
+ highlight(:set)
443
+ @o.scrollIntoView
444
+ @o.checked = true
445
+ click
446
+ highlight(:clear)
447
+ end
448
+
449
+ end
450
+
451
+ # This class is the watir representation of a check box.
452
+ # Normally a user would not need to create this object as it is returned by the Watir::Container#checkbox method
453
+ class CheckBox < InputElement
454
+ include RadioCheckCommon
455
+ # This method checks or unchecks the checkbox.
456
+ # With no arguments supplied it sets the checkbox.
457
+ # Setting false argument unchecks/clears the checkbox.
458
+ # Raises UnknownObjectException if it's unable to locate an object
459
+ # ObjectDisabledException if the object is disabled
460
+ def set(value=true)
461
+ assert_exists
462
+ assert_enabled
463
+ highlight :set
464
+ current_value = @o.checked
465
+ unless value == current_value
466
+ click
467
+ end
468
+ highlight :clear
469
+ end
470
+
471
+ # Clears a check box.
472
+ # Raises UnknownObjectException if its unable to locate an object
473
+ # ObjectDisabledException if the object is disabled
474
+ def clear
475
+ set false
476
+ end
477
+
478
+ end
479
+
480
+ end